Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Worked a little bit on Remarkable core documentation.
- Loading branch information
Showing
9 changed files
with
252 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,40 @@ | ||
Remarkable | ||
========== | ||
= Remarkable 3.0 | ||
|
||
Remarkable is a framework for rspec matchers that supports macros and I18n. It's | ||
constituted of three pieces: | ||
|
||
+ Remarkable: the framework with helpers, DSL, I18n and rspec features; | ||
|
||
+ Remarkable ActiveRecord: a collection of matchers for ActiveRecord. It | ||
supports all ActiveRecord validations, associations and some extra matchers. | ||
|
||
+ Remarkable Rails: a collection of matchers for ActionController. It also | ||
includes MacroStubs, which is a clean DSL for stubbing your controller methods. | ||
|
||
In each folder above, you can find a README more detailed description of each piece. | ||
|
||
== Install & Upgrade | ||
|
||
Install the gem: | ||
|
||
sudo gem install remarkable_rails | ||
|
||
This will install remarkable, remarkable_activerecord and remarkable_rails gems. | ||
|
||
If you are developing matchers, for example hpricot matchers, you should install | ||
only the remarkable "core" gem: | ||
|
||
sudo gem install remarkable | ||
|
||
Users who are upgrading to Remarkable 3.0, should not find any problem if their | ||
tests are running without deprecation warnings. | ||
|
||
== More information | ||
|
||
Google group: http://groups.google.com/group/remarkable-core | ||
Bug tracking: http://carlosbrando.lighthouseapp.com/projects/19775-remarkable/overview | ||
|
||
== LICENSE | ||
|
||
All projects are under MIT LICENSE. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,199 @@ | ||
Remarkable | ||
========== | ||
= Remarkable | ||
|
||
This is the core package of Remarkable. It provides a DSL for creating matchers | ||
with I18n support, decoupling messages from matcher's logic and adding rspec | ||
extra features. | ||
|
||
== Macros | ||
|
||
Each matcher in Remarkable is also available as a macro. So this matcher: | ||
|
||
it { should validate_presence_of(:name) } | ||
|
||
Can also be written as: | ||
|
||
should_validate_presence_of :name | ||
|
||
Remarkable adds the possibility to disable macros. So as you could do: | ||
|
||
xit { should validate_presence_of(:name) } | ||
|
||
You can also do: | ||
|
||
xshould_validate_presence_of :name | ||
|
||
And it will show in your specs output: | ||
|
||
"Example disabled: require name to be set" | ||
|
||
== Pending macros | ||
|
||
In Rspec you can mark some examples as pending: | ||
|
||
it "should have one manager" do | ||
pending("create managers resource") | ||
end | ||
|
||
it "should validate associated manager" do | ||
pending("create managers resource") | ||
end | ||
|
||
To allow this to work with macros, we created the pending group: | ||
|
||
pending "create managers resource" do | ||
should_have_one :manager | ||
should_validate_associated :manager | ||
end | ||
|
||
This outputs the same as above. | ||
|
||
== I18n | ||
|
||
All matchers come with I18n support. You can find an example locale file under | ||
the locale folder of each project. | ||
|
||
To change the locale, you have first to add your locale file: | ||
|
||
Remarkable.add_locale 'path/to/my_locale.yml' | ||
|
||
And then: | ||
|
||
Remarkable.locale = :my_locale | ||
|
||
Internationalization is powered by the I18n gem. If you are using it with Rails, | ||
it will use the built in gem, otherwise you will have to install the gem by hand: | ||
|
||
gem sources -a http://gems.github.com | ||
sudo gem install svenfuchs-i18n | ||
|
||
== Creating you own matcher | ||
|
||
Create a new matcher is easy. Let's create validate_inclusion_of matcher for | ||
ActiveRecord as an example. A first matcher version would be: | ||
|
||
module Remarkable | ||
module ActiveRecord | ||
module Matchers | ||
class ValidateInclusionOfMatcher < Remarkable::ActiveRecord::Base | ||
arguments :attribute | ||
assertion :is_valid? | ||
|
||
optional :in | ||
optional :allow_blank, :allow_nil, :default => true | ||
|
||
protected | ||
|
||
def is_valid? | ||
@options[:in].each do |value| | ||
@subject.send(:"#{@attribute}=", value) | ||
return false, :value => value unless @subject.valid? | ||
end | ||
true | ||
end | ||
end | ||
|
||
def validate_inclusion_of(*args) | ||
ValidateInclusionOfMatcher.new(*args).spec(self) | ||
end | ||
end | ||
end | ||
end | ||
|
||
This creates a matcher which requires one attribute and has :in, :allow_blank | ||
and :allow_nil as options. So you can call the matcher in the following way: | ||
|
||
should_validate_inclusion_of :size, :in => %w(S M L XL) | ||
should_validate_inclusion_of :size, :in => %w(S M L XL), :allow_blank => true | ||
|
||
it { should validate_inclusion_of(:size, :in => %w(S M L XL)).allow_nil(true) } | ||
it { should validate_inclusion_of(:size, :in => %w(S M L XL)).allow_nil } | ||
|
||
it { should validate_inclusion_of(:size, :in => %w(S M L XL)) } | ||
it { should validate_inclusion_of(:size, :in => %w(S M L XL), :allow_nil => true) } | ||
|
||
The assertions methods (in this case, :is_valid?) makes the matcher pass when | ||
it returns true and fail when returns false. | ||
|
||
As you noticed, the matcher doesn't have any message on it. You add them on I18n | ||
file. A file for this example would be: | ||
|
||
remarkable: | ||
active_record: | ||
validate_inclusion_of: | ||
description: "validate inclusion of {{attribute}}" | ||
expectations: | ||
is_valid: "to be valid when {{attribute}} is {{value}}" | ||
optionals: | ||
in: | ||
positive: "in {{inspect}}" | ||
allow_nil: | ||
positive: "allowing nil values" | ||
negative: "not allowing nil values" | ||
allow_blank: | ||
positive: "allowing blank values" | ||
negative: "allowing blank values" | ||
|
||
The optionals are just added to the description message when they are supplied. | ||
Look some description messages examples: | ||
|
||
should_validate_inclusion_of :size, :in => %w(S M L XL) | ||
#=> should validate inclusion of size in ["S", "M", "L", "XL"] | ||
|
||
should_validate_inclusion_of :size, :in => %w(S M L XL), :allow_nil => true | ||
#=> should validate inclusion of size in ["S", "M", "L", "XL"] and allowing nil values | ||
|
||
should_validate_inclusion_of :size, :in => %w(S M L XL), :allow_nil => false | ||
#=> should validate inclusion of size in ["S", "M", "L", "XL"] and not allowing nil values | ||
|
||
Please notice that the arguments are available as interpolation option, as well | ||
as the optionals. | ||
|
||
The expectations message are set whenever one of the assertions returns false. | ||
In this case, whenever the assertion fails, we are also returning a hash, with | ||
the value that failed: | ||
|
||
return false, :value => value | ||
|
||
This will tell remarkable to make value as interpolation option too. | ||
|
||
Whenever you create all your matchers, you tell remarkable to add them to the | ||
desired rspec example group: | ||
|
||
Remarkable.include_matchers!(Remarkable::ActiveRecord, Spec::Example::ExampleGroup) | ||
|
||
== Working with collections | ||
|
||
Finally, Remarkable also makes easy to deal with collections. The same matcher | ||
could be easily extended to accept a collection of attributes instead of just one: | ||
|
||
should_validate_inclusion_of :first_size, :second_size, :in => %w(S M L XL) | ||
|
||
For this we have just those two lines: | ||
|
||
arguments :attribute | ||
assertion :is_valid? | ||
|
||
For: | ||
|
||
arguments :collection => :attributes, :as => :attribute | ||
collection_assertion :is_valid? | ||
|
||
This means that the collection will be kept in the @attributes instance variable | ||
and for each value in the collection, it will run the :is_valid? assertion. | ||
|
||
Whenever running the assertion, it will also set the @attribute (in singular) | ||
variable. In your I18n files, you just need to change your description: | ||
|
||
validate_inclusion_of: | ||
description: "validate inclusion of {{attributes}}" | ||
|
||
And this will output: | ||
|
||
should_validate_inclusion_of :first_size, :second_size, :in => %w(S M L XL) | ||
#=> should validate inclusion of first size and second size in ["S", "M", "L", "XL"] | ||
|
||
== More | ||
|
||
This is just an overview of the API. You can add extra options to interpolation | ||
by overwriting the interpolation_options methods, you can add callbacks after | ||
initialize your matcher or before asserting and much more! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters