remarkable 3.1.6 → 3.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +42 -42
- data/lib/remarkable/base.rb +3 -3
- data/lib/remarkable/dsl/assertions.rb +216 -216
- data/lib/remarkable/messages.rb +6 -6
- data/lib/remarkable/version.rb +1 -1
- metadata +2 -2
data/CHANGELOG
CHANGED
|
@@ -1,45 +1,45 @@
|
|
|
1
|
-
# v3.1
|
|
2
|
-
|
|
3
|
-
* Remarkable.include_matchers! require just one argument [#80]
|
|
4
|
-
|
|
5
|
-
* Pending groups show proper backtrace and run by default in execute mode [#49]
|
|
6
|
-
|
|
7
|
-
* Added support to blocks configuration. All Remarkable matcher and macros can
|
|
8
|
-
now be configured using a block:
|
|
9
|
-
|
|
10
|
-
should_accept_nested_attributes_for :tasks do |m|
|
|
11
|
-
m.allow_destroy
|
|
12
|
-
m.accept(:name => 'cool')
|
|
13
|
-
m.reject(:name => '')
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
* Added support to {{sentence}} as interpolation option in optionals.
|
|
17
|
-
Previously we had:
|
|
18
|
-
|
|
19
|
-
validate_uniqueness_of :id, :scope => [:project_id, :company_id]
|
|
20
|
-
# Description: "should require unique attributes for id scoped to [:project_id, :company_id]"
|
|
21
|
-
|
|
22
|
-
Now with the new sentence option, we can have:
|
|
23
|
-
|
|
24
|
-
validate_uniqueness_of :id, :scope => [:project_id, :company_id]
|
|
25
|
-
# Description: "should require unique attributes for id scoped to project_id and company_id"
|
|
26
|
-
|
|
27
|
-
* Added support to splat and block to optionals
|
|
28
|
-
|
|
29
|
-
* Added namespace lookup to optionals and expectations. For example, in ActiveRecord
|
|
30
|
-
several matchers have :allow_nil and :allow_blank as options. So you can store
|
|
31
|
-
the translation at:
|
|
32
|
-
|
|
33
|
-
remarkable:
|
|
34
|
-
activerecord:
|
|
35
|
-
optionals:
|
|
36
|
-
allow_nil:
|
|
37
|
-
# ...
|
|
38
|
-
allow_blank:
|
|
39
|
-
# ...
|
|
40
|
-
|
|
41
|
-
* Added a repository to hold I18n files
|
|
42
|
-
|
|
1
|
+
# v3.1
|
|
2
|
+
|
|
3
|
+
* Remarkable.include_matchers! require just one argument [#80]
|
|
4
|
+
|
|
5
|
+
* Pending groups show proper backtrace and run by default in execute mode [#49]
|
|
6
|
+
|
|
7
|
+
* Added support to blocks configuration. All Remarkable matcher and macros can
|
|
8
|
+
now be configured using a block:
|
|
9
|
+
|
|
10
|
+
should_accept_nested_attributes_for :tasks do |m|
|
|
11
|
+
m.allow_destroy
|
|
12
|
+
m.accept(:name => 'cool')
|
|
13
|
+
m.reject(:name => '')
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
* Added support to {{sentence}} as interpolation option in optionals.
|
|
17
|
+
Previously we had:
|
|
18
|
+
|
|
19
|
+
validate_uniqueness_of :id, :scope => [:project_id, :company_id]
|
|
20
|
+
# Description: "should require unique attributes for id scoped to [:project_id, :company_id]"
|
|
21
|
+
|
|
22
|
+
Now with the new sentence option, we can have:
|
|
23
|
+
|
|
24
|
+
validate_uniqueness_of :id, :scope => [:project_id, :company_id]
|
|
25
|
+
# Description: "should require unique attributes for id scoped to project_id and company_id"
|
|
26
|
+
|
|
27
|
+
* Added support to splat and block to optionals
|
|
28
|
+
|
|
29
|
+
* Added namespace lookup to optionals and expectations. For example, in ActiveRecord
|
|
30
|
+
several matchers have :allow_nil and :allow_blank as options. So you can store
|
|
31
|
+
the translation at:
|
|
32
|
+
|
|
33
|
+
remarkable:
|
|
34
|
+
activerecord:
|
|
35
|
+
optionals:
|
|
36
|
+
allow_nil:
|
|
37
|
+
# ...
|
|
38
|
+
allow_blank:
|
|
39
|
+
# ...
|
|
40
|
+
|
|
41
|
+
* Added a repository to hold I18n files
|
|
42
|
+
|
|
43
43
|
# v3.0
|
|
44
44
|
|
|
45
45
|
* Added Remarkable::Matchers. Now you can include your Remarkable matchers and
|
data/lib/remarkable/base.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
module Remarkable
|
|
2
|
-
# This class holds the basic structure for Remarkable matchers. All matchers
|
|
3
|
-
# must inherit from it.
|
|
1
|
+
module Remarkable
|
|
2
|
+
# This class holds the basic structure for Remarkable matchers. All matchers
|
|
3
|
+
# must inherit from it.
|
|
4
4
|
class Base
|
|
5
5
|
include Remarkable::Messages
|
|
6
6
|
extend Remarkable::DSL
|
|
@@ -1,119 +1,119 @@
|
|
|
1
1
|
module Remarkable
|
|
2
|
-
module DSL
|
|
3
|
-
# This module is responsable to create a basic matcher structure using a DSL.
|
|
4
|
-
#
|
|
5
|
-
# A matcher that checks if an element is included in an array can be done
|
|
6
|
-
# just with:
|
|
7
|
-
#
|
|
8
|
-
# class IncludedMatcher < Remarkable::Base
|
|
9
|
-
# arguments :value
|
|
10
|
-
# assertion :is_included?
|
|
11
|
-
#
|
|
12
|
-
# protected
|
|
13
|
-
# def is_included?
|
|
14
|
-
# @subject.include?(@value)
|
|
15
|
-
# end
|
|
16
|
-
# end
|
|
17
|
-
#
|
|
18
|
-
# As you have noticed, the DSL also allows you to remove the messages from
|
|
19
|
-
# matcher. Since it will look for it on I18n yml file.
|
|
20
|
-
#
|
|
21
|
-
# If you want to create a matcher that accepts multile values to be tested,
|
|
22
|
-
# you just need to do:
|
|
23
|
-
#
|
|
24
|
-
# class IncludedMatcher < Remarkable::Base
|
|
25
|
-
# arguments :collection => :values, :as => :value
|
|
26
|
-
# collection_assertion :is_included?
|
|
27
|
-
#
|
|
28
|
-
# protected
|
|
29
|
-
# def is_included?
|
|
30
|
-
# @subject.include?(@value)
|
|
31
|
-
# end
|
|
32
|
-
# end
|
|
33
|
-
#
|
|
34
|
-
# Notice that the :is_included? logic didn't have to change, because Remarkable
|
|
35
|
-
# handle this automatically for you.
|
|
2
|
+
module DSL
|
|
3
|
+
# This module is responsable to create a basic matcher structure using a DSL.
|
|
36
4
|
#
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
5
|
+
# A matcher that checks if an element is included in an array can be done
|
|
6
|
+
# just with:
|
|
7
|
+
#
|
|
8
|
+
# class IncludedMatcher < Remarkable::Base
|
|
9
|
+
# arguments :value
|
|
10
|
+
# assertion :is_included?
|
|
11
|
+
#
|
|
12
|
+
# protected
|
|
13
|
+
# def is_included?
|
|
14
|
+
# @subject.include?(@value)
|
|
15
|
+
# end
|
|
16
|
+
# end
|
|
17
|
+
#
|
|
18
|
+
# As you have noticed, the DSL also allows you to remove the messages from
|
|
19
|
+
# matcher. Since it will look for it on I18n yml file.
|
|
20
|
+
#
|
|
21
|
+
# If you want to create a matcher that accepts multile values to be tested,
|
|
22
|
+
# you just need to do:
|
|
23
|
+
#
|
|
24
|
+
# class IncludedMatcher < Remarkable::Base
|
|
25
|
+
# arguments :collection => :values, :as => :value
|
|
26
|
+
# collection_assertion :is_included?
|
|
27
|
+
#
|
|
28
|
+
# protected
|
|
29
|
+
# def is_included?
|
|
30
|
+
# @subject.include?(@value)
|
|
31
|
+
# end
|
|
32
|
+
# end
|
|
33
|
+
#
|
|
34
|
+
# Notice that the :is_included? logic didn't have to change, because Remarkable
|
|
35
|
+
# handle this automatically for you.
|
|
36
|
+
#
|
|
37
|
+
module Assertions
|
|
38
|
+
|
|
39
|
+
def self.included(base) # :nodoc:
|
|
40
|
+
base.extend ClassMethods
|
|
41
41
|
end
|
|
42
|
-
|
|
43
|
-
module ClassMethods
|
|
42
|
+
|
|
43
|
+
module ClassMethods
|
|
44
44
|
|
|
45
45
|
protected
|
|
46
46
|
|
|
47
|
-
# It sets the arguments your matcher receives on initialization.
|
|
48
|
-
#
|
|
47
|
+
# It sets the arguments your matcher receives on initialization.
|
|
48
|
+
#
|
|
49
49
|
# == Options
|
|
50
|
-
#
|
|
51
|
-
# * <tt>:collection</tt> - if a collection is expected.
|
|
52
|
-
# * <tt>:as</tt> - how each item of the collection will be available.
|
|
53
|
-
# * <tt>:block</tt> - tell the matcher can receive blocks as argument and store
|
|
54
|
-
# them under the variable given.
|
|
55
|
-
#
|
|
56
|
-
# Note: the expected block cannot have arity 1. This is already reserved
|
|
57
|
-
# for macro configuration.
|
|
58
|
-
#
|
|
59
|
-
# == Examples
|
|
60
|
-
#
|
|
61
|
-
# Let's see for each example how the arguments declarion reflects on
|
|
62
|
-
# the matcher API:
|
|
63
|
-
#
|
|
64
|
-
# arguments :assign
|
|
65
|
-
# # Can be called as:
|
|
66
|
-
# #=> should_assign :task
|
|
67
|
-
# #=> should_assign :task, :with => Task.new
|
|
68
|
-
#
|
|
69
|
-
# This is roughly the same as:
|
|
70
|
-
#
|
|
50
|
+
#
|
|
51
|
+
# * <tt>:collection</tt> - if a collection is expected.
|
|
52
|
+
# * <tt>:as</tt> - how each item of the collection will be available.
|
|
53
|
+
# * <tt>:block</tt> - tell the matcher can receive blocks as argument and store
|
|
54
|
+
# them under the variable given.
|
|
55
|
+
#
|
|
56
|
+
# Note: the expected block cannot have arity 1. This is already reserved
|
|
57
|
+
# for macro configuration.
|
|
58
|
+
#
|
|
59
|
+
# == Examples
|
|
60
|
+
#
|
|
61
|
+
# Let's see for each example how the arguments declarion reflects on
|
|
62
|
+
# the matcher API:
|
|
63
|
+
#
|
|
64
|
+
# arguments :assign
|
|
65
|
+
# # Can be called as:
|
|
66
|
+
# #=> should_assign :task
|
|
67
|
+
# #=> should_assign :task, :with => Task.new
|
|
68
|
+
#
|
|
69
|
+
# This is roughly the same as:
|
|
70
|
+
#
|
|
71
71
|
# def initialize(assign, options = {})
|
|
72
72
|
# @assign = name
|
|
73
73
|
# @options = options
|
|
74
|
-
# end
|
|
75
|
-
#
|
|
76
|
-
# As you noticed, a matcher can always receive options on initialization.
|
|
77
|
-
# If you have a matcher that accepts only options, for example,
|
|
78
|
-
# have_default_scope you just need to call <tt>arguments</tt>:
|
|
79
|
-
#
|
|
80
|
-
# arguments
|
|
81
|
-
# # Can be called as:
|
|
82
|
-
# #=> should_have_default_scope :limit => 10
|
|
83
|
-
#
|
|
84
|
-
# arguments :collection => :assigns, :as => :assign
|
|
85
|
-
# # Can be called as:
|
|
86
|
-
# #=> should_assign :task1, :task2
|
|
87
|
-
# #=> should_assign :task1, :task2, :with => Task.new
|
|
88
|
-
#
|
|
89
|
-
# arguments :collection => :assigns, :as => :assign, :block => :buildeer
|
|
90
|
-
# # Can be called as:
|
|
91
|
-
# #=> should_assign :task1, :task2
|
|
92
|
-
# #=> should_assign(:task1, :task2){ Task.new }
|
|
93
|
-
#
|
|
94
|
-
# The block will be available under the instance variable @builder.
|
|
95
|
-
#
|
|
96
|
-
# == I18n
|
|
97
|
-
#
|
|
98
|
-
# All the parameters given to arguments are available for interpolation
|
|
99
|
-
# in I18n. So if you have the following declarion:
|
|
100
|
-
#
|
|
101
|
-
# class InRange < Remarkable::Base
|
|
102
|
-
# arguments :range, :collection => :names, :as => :name
|
|
103
|
-
#
|
|
104
|
-
# You will have {{range}}, {{names}} and {{name}} available for I18n
|
|
105
|
-
# messages:
|
|
106
|
-
#
|
|
107
|
-
# in_range:
|
|
108
|
-
# description: "have {{names}} to be on range {{range}}"
|
|
109
|
-
#
|
|
110
|
-
# Before a collection is sent to I18n, it's transformed to a sentence.
|
|
111
|
-
# So if the following matcher:
|
|
112
|
-
#
|
|
113
|
-
# in_range(2..20, :username, :password)
|
|
114
|
-
#
|
|
115
|
-
# Has the following description:
|
|
116
|
-
#
|
|
74
|
+
# end
|
|
75
|
+
#
|
|
76
|
+
# As you noticed, a matcher can always receive options on initialization.
|
|
77
|
+
# If you have a matcher that accepts only options, for example,
|
|
78
|
+
# have_default_scope you just need to call <tt>arguments</tt>:
|
|
79
|
+
#
|
|
80
|
+
# arguments
|
|
81
|
+
# # Can be called as:
|
|
82
|
+
# #=> should_have_default_scope :limit => 10
|
|
83
|
+
#
|
|
84
|
+
# arguments :collection => :assigns, :as => :assign
|
|
85
|
+
# # Can be called as:
|
|
86
|
+
# #=> should_assign :task1, :task2
|
|
87
|
+
# #=> should_assign :task1, :task2, :with => Task.new
|
|
88
|
+
#
|
|
89
|
+
# arguments :collection => :assigns, :as => :assign, :block => :buildeer
|
|
90
|
+
# # Can be called as:
|
|
91
|
+
# #=> should_assign :task1, :task2
|
|
92
|
+
# #=> should_assign(:task1, :task2){ Task.new }
|
|
93
|
+
#
|
|
94
|
+
# The block will be available under the instance variable @builder.
|
|
95
|
+
#
|
|
96
|
+
# == I18n
|
|
97
|
+
#
|
|
98
|
+
# All the parameters given to arguments are available for interpolation
|
|
99
|
+
# in I18n. So if you have the following declarion:
|
|
100
|
+
#
|
|
101
|
+
# class InRange < Remarkable::Base
|
|
102
|
+
# arguments :range, :collection => :names, :as => :name
|
|
103
|
+
#
|
|
104
|
+
# You will have {{range}}, {{names}} and {{name}} available for I18n
|
|
105
|
+
# messages:
|
|
106
|
+
#
|
|
107
|
+
# in_range:
|
|
108
|
+
# description: "have {{names}} to be on range {{range}}"
|
|
109
|
+
#
|
|
110
|
+
# Before a collection is sent to I18n, it's transformed to a sentence.
|
|
111
|
+
# So if the following matcher:
|
|
112
|
+
#
|
|
113
|
+
# in_range(2..20, :username, :password)
|
|
114
|
+
#
|
|
115
|
+
# Has the following description:
|
|
116
|
+
#
|
|
117
117
|
# "should have username and password in range 2..20"
|
|
118
118
|
#
|
|
119
119
|
def arguments(*names)
|
|
@@ -140,14 +140,14 @@ module Remarkable
|
|
|
140
140
|
set_collection = ''
|
|
141
141
|
end
|
|
142
142
|
|
|
143
|
-
if block = options.delete(:block)
|
|
144
|
-
block = :block unless block.is_a?(Symbol)
|
|
143
|
+
if block = options.delete(:block)
|
|
144
|
+
block = :block unless block.is_a?(Symbol)
|
|
145
145
|
@matcher_arguments[:block] = block
|
|
146
|
-
end
|
|
147
|
-
|
|
148
|
-
# Blocks are always appended. If they have arity 1, they are used for
|
|
149
|
-
# macro configuration, otherwise, they are stored in the :block variable.
|
|
150
|
-
#
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
# Blocks are always appended. If they have arity 1, they are used for
|
|
149
|
+
# macro configuration, otherwise, they are stored in the :block variable.
|
|
150
|
+
#
|
|
151
151
|
args << "&block"
|
|
152
152
|
|
|
153
153
|
assignments = names.map do |name|
|
|
@@ -155,111 +155,111 @@ module Remarkable
|
|
|
155
155
|
end.join("\n ")
|
|
156
156
|
|
|
157
157
|
class_eval <<-END, __FILE__, __LINE__
|
|
158
|
-
def initialize(#{args.join(',')})
|
|
159
|
-
_builder, block = block, nil if block && block.arity == 1
|
|
160
|
-
#{assignments}
|
|
158
|
+
def initialize(#{args.join(',')})
|
|
159
|
+
_builder, block = block, nil if block && block.arity == 1
|
|
160
|
+
#{assignments}
|
|
161
161
|
#{"@#{block} = block" if block}
|
|
162
162
|
@options = default_options.merge(#{get_options})
|
|
163
|
-
#{set_collection}
|
|
164
|
-
run_after_initialize_callbacks
|
|
163
|
+
#{set_collection}
|
|
164
|
+
run_after_initialize_callbacks
|
|
165
165
|
_builder.call(self) if _builder
|
|
166
166
|
end
|
|
167
167
|
END
|
|
168
168
|
end
|
|
169
169
|
|
|
170
|
-
# Declare the assertions that are runned for each element in the collection.
|
|
171
|
-
# It must be used with <tt>arguments</tt> methods in order to work properly.
|
|
172
|
-
#
|
|
173
|
-
# == Examples
|
|
174
|
-
#
|
|
175
|
-
# The example given in <tt>assertions</tt> can be transformed to
|
|
176
|
-
# accept a collection just doing:
|
|
177
|
-
#
|
|
178
|
-
# class IncludedMatcher < Remarkable::Base
|
|
179
|
-
# arguments :collection => :values, :as => :value
|
|
180
|
-
# collection_assertion :is_included?
|
|
181
|
-
#
|
|
182
|
-
# protected
|
|
183
|
-
# def is_included?
|
|
184
|
-
# @subject.include?(@value)
|
|
185
|
-
# end
|
|
186
|
-
# end
|
|
187
|
-
#
|
|
188
|
-
# All further consideration done in <tt>assertions</tt> are also valid here.
|
|
189
|
-
#
|
|
170
|
+
# Declare the assertions that are runned for each element in the collection.
|
|
171
|
+
# It must be used with <tt>arguments</tt> methods in order to work properly.
|
|
172
|
+
#
|
|
173
|
+
# == Examples
|
|
174
|
+
#
|
|
175
|
+
# The example given in <tt>assertions</tt> can be transformed to
|
|
176
|
+
# accept a collection just doing:
|
|
177
|
+
#
|
|
178
|
+
# class IncludedMatcher < Remarkable::Base
|
|
179
|
+
# arguments :collection => :values, :as => :value
|
|
180
|
+
# collection_assertion :is_included?
|
|
181
|
+
#
|
|
182
|
+
# protected
|
|
183
|
+
# def is_included?
|
|
184
|
+
# @subject.include?(@value)
|
|
185
|
+
# end
|
|
186
|
+
# end
|
|
187
|
+
#
|
|
188
|
+
# All further consideration done in <tt>assertions</tt> are also valid here.
|
|
189
|
+
#
|
|
190
190
|
def collection_assertions(*methods, &block)
|
|
191
191
|
define_method methods.last, &block if block_given?
|
|
192
192
|
@matcher_collection_assertions += methods
|
|
193
193
|
end
|
|
194
194
|
alias :collection_assertion :collection_assertions
|
|
195
195
|
|
|
196
|
-
# Declares the assertions that are run once per matcher.
|
|
197
|
-
#
|
|
198
|
-
# == Examples
|
|
199
|
-
#
|
|
200
|
-
# A matcher that checks if an element is included in an array can be done
|
|
201
|
-
# just with:
|
|
202
|
-
#
|
|
203
|
-
# class IncludedMatcher < Remarkable::Base
|
|
204
|
-
# arguments :value
|
|
205
|
-
# assertion :is_included?
|
|
206
|
-
#
|
|
207
|
-
# protected
|
|
208
|
-
# def is_included?
|
|
209
|
-
# @subject.include?(@value)
|
|
210
|
-
# end
|
|
211
|
-
# end
|
|
212
|
-
#
|
|
213
|
-
# Whenever the matcher is called, the :is_included? action is automatically
|
|
214
|
-
# triggered. Each assertion must return true or false. In case it's false
|
|
215
|
-
# it will seach for an expectation message on the I18n file. In this
|
|
216
|
-
# case, the error message would be on:
|
|
217
|
-
#
|
|
218
|
-
# included:
|
|
219
|
-
# description: "check {{value}} is included in the array"
|
|
220
|
-
# expectations:
|
|
221
|
-
# is_included: "{{value}} is included in the array"
|
|
222
|
-
#
|
|
223
|
-
# In case of failure, it will output:
|
|
224
|
-
#
|
|
225
|
-
# "Expected {{value}} is included in the array"
|
|
226
|
-
#
|
|
227
|
-
# Notice that on the yml file the question mark is removed for readability.
|
|
228
|
-
#
|
|
229
|
-
# == Shortcut declaration
|
|
230
|
-
#
|
|
231
|
-
# You can shortcut declaration by giving a name and block to assertion
|
|
232
|
-
# method:
|
|
233
|
-
#
|
|
234
|
-
# class IncludedMatcher < Remarkable::Base
|
|
235
|
-
# arguments :value
|
|
236
|
-
#
|
|
237
|
-
# assertion :is_included? do
|
|
238
|
-
# @subject.include?(@value)
|
|
239
|
-
# end
|
|
240
|
-
# end
|
|
241
|
-
#
|
|
242
|
-
def assertions(*methods, &block)
|
|
196
|
+
# Declares the assertions that are run once per matcher.
|
|
197
|
+
#
|
|
198
|
+
# == Examples
|
|
199
|
+
#
|
|
200
|
+
# A matcher that checks if an element is included in an array can be done
|
|
201
|
+
# just with:
|
|
202
|
+
#
|
|
203
|
+
# class IncludedMatcher < Remarkable::Base
|
|
204
|
+
# arguments :value
|
|
205
|
+
# assertion :is_included?
|
|
206
|
+
#
|
|
207
|
+
# protected
|
|
208
|
+
# def is_included?
|
|
209
|
+
# @subject.include?(@value)
|
|
210
|
+
# end
|
|
211
|
+
# end
|
|
212
|
+
#
|
|
213
|
+
# Whenever the matcher is called, the :is_included? action is automatically
|
|
214
|
+
# triggered. Each assertion must return true or false. In case it's false
|
|
215
|
+
# it will seach for an expectation message on the I18n file. In this
|
|
216
|
+
# case, the error message would be on:
|
|
217
|
+
#
|
|
218
|
+
# included:
|
|
219
|
+
# description: "check {{value}} is included in the array"
|
|
220
|
+
# expectations:
|
|
221
|
+
# is_included: "{{value}} is included in the array"
|
|
222
|
+
#
|
|
223
|
+
# In case of failure, it will output:
|
|
224
|
+
#
|
|
225
|
+
# "Expected {{value}} is included in the array"
|
|
226
|
+
#
|
|
227
|
+
# Notice that on the yml file the question mark is removed for readability.
|
|
228
|
+
#
|
|
229
|
+
# == Shortcut declaration
|
|
230
|
+
#
|
|
231
|
+
# You can shortcut declaration by giving a name and block to assertion
|
|
232
|
+
# method:
|
|
233
|
+
#
|
|
234
|
+
# class IncludedMatcher < Remarkable::Base
|
|
235
|
+
# arguments :value
|
|
236
|
+
#
|
|
237
|
+
# assertion :is_included? do
|
|
238
|
+
# @subject.include?(@value)
|
|
239
|
+
# end
|
|
240
|
+
# end
|
|
241
|
+
#
|
|
242
|
+
def assertions(*methods, &block)
|
|
243
243
|
if block_given?
|
|
244
|
-
define_method methods.last, &block
|
|
245
|
-
protected methods.last
|
|
246
|
-
end
|
|
244
|
+
define_method methods.last, &block
|
|
245
|
+
protected methods.last
|
|
246
|
+
end
|
|
247
247
|
|
|
248
248
|
@matcher_single_assertions += methods
|
|
249
249
|
end
|
|
250
250
|
alias :assertion :assertions
|
|
251
251
|
|
|
252
|
-
# Class method that accepts a block or a hash to set matcher's default
|
|
253
|
-
# options. It's called on matcher initialization and stores the default
|
|
254
|
-
# value in the @options instance variable.
|
|
255
|
-
#
|
|
256
|
-
# == Examples
|
|
257
|
-
#
|
|
258
|
-
# default_options do
|
|
259
|
-
# { :name => @subject.name }
|
|
260
|
-
# end
|
|
261
|
-
#
|
|
262
|
-
# default_options :message => :invalid
|
|
252
|
+
# Class method that accepts a block or a hash to set matcher's default
|
|
253
|
+
# options. It's called on matcher initialization and stores the default
|
|
254
|
+
# value in the @options instance variable.
|
|
255
|
+
#
|
|
256
|
+
# == Examples
|
|
257
|
+
#
|
|
258
|
+
# default_options do
|
|
259
|
+
# { :name => @subject.name }
|
|
260
|
+
# end
|
|
261
|
+
#
|
|
262
|
+
# default_options :message => :invalid
|
|
263
263
|
#
|
|
264
264
|
def default_options(hash = {}, &block)
|
|
265
265
|
if block_given?
|
|
@@ -267,15 +267,15 @@ module Remarkable
|
|
|
267
267
|
else
|
|
268
268
|
class_eval "def default_options; #{hash.inspect}; end"
|
|
269
269
|
end
|
|
270
|
-
end
|
|
270
|
+
end
|
|
271
271
|
end
|
|
272
|
-
|
|
272
|
+
|
|
273
273
|
# This method is responsable for connecting <tt>arguments</tt>, <tt>assertions</tt>
|
|
274
|
-
# and <tt>collection_assertions</tt>.
|
|
275
|
-
#
|
|
276
|
-
# It's the one that executes the assertions once, executes the collection
|
|
277
|
-
# assertions for each element in the collection and also responsable to set
|
|
278
|
-
# the I18n messages.
|
|
274
|
+
# and <tt>collection_assertions</tt>.
|
|
275
|
+
#
|
|
276
|
+
# It's the one that executes the assertions once, executes the collection
|
|
277
|
+
# assertions for each element in the collection and also responsable to set
|
|
278
|
+
# the I18n messages.
|
|
279
279
|
#
|
|
280
280
|
def matches?(subject)
|
|
281
281
|
@subject = subject
|
|
@@ -291,7 +291,7 @@ module Remarkable
|
|
|
291
291
|
|
|
292
292
|
protected
|
|
293
293
|
|
|
294
|
-
# You can overwrite this instance method to provide default options on
|
|
294
|
+
# You can overwrite this instance method to provide default options on
|
|
295
295
|
# initialization.
|
|
296
296
|
#
|
|
297
297
|
def default_options
|
|
@@ -368,21 +368,21 @@ module Remarkable
|
|
|
368
368
|
methods.each do |method|
|
|
369
369
|
bool, hash = send(method)
|
|
370
370
|
|
|
371
|
-
unless bool
|
|
372
|
-
parent_scope = matcher_i18n_scope.split('.')
|
|
373
|
-
matcher_name = parent_scope.pop
|
|
374
|
-
lookup = :"expectations.#{method.to_s.gsub(/(\?|\!)$/, '')}"
|
|
375
|
-
|
|
376
|
-
hash = { :scope => parent_scope, :default => lookup }.merge(hash || {})
|
|
377
|
-
@expectation ||= Remarkable.t "#{matcher_name}.#{lookup}", default_i18n_options.merge(hash)
|
|
371
|
+
unless bool
|
|
372
|
+
parent_scope = matcher_i18n_scope.split('.')
|
|
373
|
+
matcher_name = parent_scope.pop
|
|
374
|
+
lookup = :"expectations.#{method.to_s.gsub(/(\?|\!)$/, '')}"
|
|
375
|
+
|
|
376
|
+
hash = { :scope => parent_scope, :default => lookup }.merge(hash || {})
|
|
377
|
+
@expectation ||= Remarkable.t "#{matcher_name}.#{lookup}", default_i18n_options.merge(hash)
|
|
378
378
|
|
|
379
379
|
return false
|
|
380
380
|
end
|
|
381
381
|
end
|
|
382
382
|
|
|
383
383
|
return true
|
|
384
|
-
end
|
|
385
|
-
|
|
384
|
+
end
|
|
385
|
+
|
|
386
386
|
|
|
387
387
|
end
|
|
388
388
|
end
|
data/lib/remarkable/messages.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
module Remarkable
|
|
2
|
-
# Holds the methods required by rspec for each matcher plus a collection of
|
|
3
|
-
# helpers to deal with I18n.
|
|
1
|
+
module Remarkable
|
|
2
|
+
# Holds the methods required by rspec for each matcher plus a collection of
|
|
3
|
+
# helpers to deal with I18n.
|
|
4
4
|
#
|
|
5
5
|
module Messages
|
|
6
6
|
|
|
@@ -84,8 +84,8 @@ module Remarkable
|
|
|
84
84
|
words_connector = Remarkable.t 'remarkable.core.helpers.words_connector'
|
|
85
85
|
two_words_connector = Remarkable.t 'remarkable.core.helpers.two_words_connector'
|
|
86
86
|
last_word_connector = Remarkable.t 'remarkable.core.helpers.last_word_connector'
|
|
87
|
-
|
|
88
|
-
array.map
|
|
87
|
+
|
|
88
|
+
array = array.map { |i| i.inspect } if inspect
|
|
89
89
|
|
|
90
90
|
case array.length
|
|
91
91
|
when 0
|
|
@@ -97,7 +97,7 @@ module Remarkable
|
|
|
97
97
|
else
|
|
98
98
|
"#{array[0...-1].join(words_connector)}#{last_word_connector}#{array[-1]}"
|
|
99
99
|
end
|
|
100
|
-
end
|
|
100
|
+
end
|
|
101
101
|
|
|
102
102
|
end
|
|
103
103
|
end
|
data/lib/remarkable/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: remarkable
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.1.
|
|
4
|
+
version: 3.1.7
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Carlos Brando
|
|
@@ -10,7 +10,7 @@ autorequire:
|
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
12
|
|
|
13
|
-
date: 2009-
|
|
13
|
+
date: 2009-07-05 00:00:00 +02:00
|
|
14
14
|
default_executable:
|
|
15
15
|
dependencies:
|
|
16
16
|
- !ruby/object:Gem::Dependency
|