README in remarkable-3.1.8 vs README in remarkable-3.1.9

- old
+ new

@@ -1,212 +1,212 @@ -= Remarkable - -This is the core package of Remarkable. It provides a DSL for creating matchers += Remarkable + +This is the core package of Remarkable. It provides a DSL for creating matchers with I18n support, decouples messages from matchers logic, add rspec extra features, -create macros automatically and allow those macros to be configurable wth blocks. - -== Macros - -Each matcher in Remarkable is also available as a macro. So this matcher: +create macros automatically and allow those macros to be configurable wth blocks. +== Macros + +Each matcher in Remarkable is also available as a macro. So this matcher: + it { should validate_numericality_of(:age, :greater_than => 18, :only_integer => true) } - it { should validate_numericality_of(:age).greater_than(18).only_integer } - -Can also be written as: - + it { should validate_numericality_of(:age).greater_than(18).only_integer } + +Can also be written as: + should_validate_numericality_of :age, :greater_than => 18, :only_integer => true Which can be also written as: should_validate_numericality_of :age do |m| m.only_integer m.greater_than 18 # Or: m.greater_than = 18 - end + end Choose your style! == Disabled Macros - -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! + +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!