rspec-sleeping_king_studios 2.0.1 → 2.0.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e15c55731182411a98203f48327a37c8bfade042
4
- data.tar.gz: 6ade1136197ac618a4551b2f2c7f9845b35832c7
3
+ metadata.gz: 001e7809e65b97646a63c8a663bcba7472df5327
4
+ data.tar.gz: a0309fd6b2ace7e0cceb015929d0b3449cb327df
5
5
  SHA512:
6
- metadata.gz: ce9912aa7af89a8c55363d716506ce91dbbd4db7ecb4f31f0a12ddd90015800a93ab8e4b63ac6f3d8381575cc68540e0471fc80132b729cbf67a0707c34f5211
7
- data.tar.gz: 3b1ee772ab9e74bdb0176988efeb1a636716f6575cec3bf84a2a73a586235a7554458b0531069ea5f7c1e973d3a3088be60c909d2ae843539e8a55bb99b82e30
6
+ metadata.gz: 23957e513898499443a028ed1aadbed73aa31b19a7deec654988c418710c25cc7362791ea627344a1b2ed87ff25bf4580b4b819d2a9f553f5529da4874245296
7
+ data.tar.gz: 4ff7d63a7da8145d064e6c7902be789332ffd6613aa52c51db8540b2639a4c16e671ce5c7322f04fa51cdea4670b46749a80f1a31bb42c04910da961b110f6a7
data/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.0.2
4
+
5
+ #### `construct` and `respond_to` Matchers
6
+
7
+ Added new fluent syntax for keyword expectations:
8
+
9
+ expect(my_object).to respond_to(:my_method).with(1..2).arguments.and_keywords(:foo, :bar)
10
+
11
+ Also added support for expecting splatted arguments (`*args`) or keywords (`**kwargs`) using the `#with_unlimited_arguments` and `#with_arbitrary_keywords` methods.
12
+
13
+ The old syntax (`respond_to(:my_method).with(1, :foo, :bar)`) will be supported through 3.0.
14
+
3
15
  ## 2.0.1
4
16
 
5
17
  Created suite of [Cucumber features](features) to validate and document the gem.
data/DEVELOPMENT.md CHANGED
@@ -4,25 +4,26 @@
4
4
 
5
5
  ### Release Candidate
6
6
 
7
- ### 2.0.1
7
+ ### 2.0.2
8
8
 
9
- - Add cucumber features
10
- - Matcher features, including returned text DONE
11
- - Concern features DONE
12
- - Shared examples features DONE
13
- - Alias `construct` as `be_constructable`.
14
- - Rewrite failure messages "to construct" => "to be constructable".
9
+ - Add additional syntax option for #respond_to keywords, e.g. 'expect().to respond_to(:method).with(1).arguments.and_keywords(:foo, :bar)' DONE
10
+ - `expect().to respond_to().with_keywords()'
11
+ - `expect().to respond_to().with_arbitrary_keywords'
12
+ - Add additional syntax (see above) to #be_constructible. DONE
15
13
 
16
14
  ### 2.1.0+
17
15
 
18
16
  - Add #wrap_context, #wrap_examples (alias encapsulate_X ?) for pattern `describe ""; include_examples "": end`
19
17
  - Configuration option 'alias_wrap_examples'?
20
- - Add shared examples for #belongs_to, #has_one, #has_many, #embedded_in, #embeds_one, #embeds_many.
21
- - Add shared examples for core ActiveModel validations.
18
+ - Automatically-focused #fwrap_context, #fwrap_examples?
19
+ - Add #have_constant matcher.
20
+ - Add shared examples for 'should not have reader/writer/property'
22
21
 
23
22
  ### 2.2.0+
24
23
 
25
- - Add alt doc test formatted - --format=list ? --format=documentation-list ?
24
+ - Add shared examples for #belongs_to, #has_one, #has_many, #embedded_in, #embeds_one, #embeds_many.
25
+ - Add shared examples for core ActiveModel validations.
26
+ - Add alt doc test formatter - --format=list ? --format=documentation-list ?
26
27
  - Prints full expanded example name for each example
27
28
  - Add minimal test formatter - --format=smoke ? --format=librarian ?
28
29
  - Prints nothing for examples
@@ -31,3 +32,9 @@
31
32
  ### 3.0.0
32
33
 
33
34
  - Ensure behavior of `#have_reader`, `#have_writer`, `#have_property` is consistent.
35
+
36
+ ### Maintenance
37
+
38
+ - Remove SCENARIOS from spec files.
39
+ - Revisit failure messages for #respond_to, #be_constructible.
40
+ - Pare down Cucumber features for matchers - repurpose as documentation/examples only.
data/README.md CHANGED
@@ -158,7 +158,10 @@ Now has additional chaining functionality to validate the number of arguments ac
158
158
  **Chaining:**
159
159
 
160
160
  * **`#with`:** Expects at most one Integer or Range argument, and zero or more Symbol arguments corresponding to optional keywords. Verifies that the method accepts that keyword, or has a variadic keyword of the form `**params`. As of 2.1.0 and required keywords, verifies that all required keywords are provided.
161
+ * **`#with_unlimited_arguments`:** (also `and_unlimited_arguments`) No parameters. Verifies that the method accepts any number of arguments via a variadic argument of the form `*args`.
161
162
  * **`#with_a_block`:** (also `and_a_block`) No parameters. Verifies that the method requires a block argument of the form `&my_argument`. _Important note:_ A negative result _does not_ mean the method cannot accept a block, merely that it does not require one. Also, _does not_ check whether the block is called or yielded.
163
+ * **`#with_keywords`:** (also `and_keywords`) Expects one or more String or Symbol arguments. Verifies that the method accepts each provided keyword or has a variadic keyword of the form `**params`. As of 2.1.0 and required keywords, verifies that all required keywords are provided.
164
+ * **`#with_arbitrary_keywords`:** (also `and_arbitrary_keywords`) No parameters. Verifies that the method accepts any keyword arguments via a variadic keyword of the form `**params`.
162
165
 
163
166
  ### Core
164
167
 
@@ -197,6 +200,9 @@ Verifies that the actual object can be constructed using `::new`. Can take an op
197
200
  **Chaining:**
198
201
 
199
202
  * **`#with`:** Expects one Integer, Range, or nil argument, and zero or more Symbol arguments corresponding to optional keywords. Verifies that the class's constructor accepts that keyword, or has a variadic keyword of the form `**params`. As of Ruby 2.1 and required keywords, verifies that all required keywords are provided.
203
+ * **`#with_unlimited_arguments`:** (also `and_unlimited_arguments`) No parameters. Verifies that the class's constructor accepts any number of arguments via a variadic argument of the form `*args`.
204
+ * **`#with_keywords`:** (also `and_keywords`) Expects one or more String or Symbol arguments. Verifies that the class's constructor accepts each provided keyword or has a variadic keyword of the form `**params`. As of 2.1.0 and required keywords, verifies that all required keywords are provided.
205
+ * **`#with_arbitrary_keywords`:** (also `and_arbitrary_keywords`) No parameters. Verifies that the class's constructor accepts any keyword arguments via a variadic keyword of the form `**params`.
200
206
 
201
207
  #### `#have_property` Matcher
202
208
 
@@ -53,12 +53,48 @@ module RSpec::SleepingKingStudios::Matchers::BuiltIn
53
53
  #
54
54
  # @return [RespondToMatcher] self
55
55
  def with *keywords
56
- @expected_arity = keywords.shift if Integer === keywords.first || Range === keywords.first
57
- @expected_keywords = keywords
56
+ @expected_arity = keywords.shift if Integer === keywords.first || Range === keywords.first
57
+
58
+ # TODO: Deprecate this behavior (for version 3.0?) - use the
59
+ # #with_keywords or #and_keywords methods instead.
60
+ (@expected_keywords ||= []).concat(keywords)
58
61
 
59
62
  self
60
63
  end # method with
61
64
 
65
+ # Adds an unlimited parameter count expectation, e.g. that the method
66
+ # supports splatted array arguments of the form *args.
67
+ #
68
+ # @return [RespondToMatcher] self
69
+ def with_unlimited_arguments
70
+ @expect_unlimited_arguments = true
71
+
72
+ self
73
+ end # method with_unlimited_arguments
74
+ alias_method :and_unlimited_arguments, :with_unlimited_arguments
75
+
76
+ # Adds one or more keyword expectations.
77
+ #
78
+ # @param [Array<String, Symbol>] keywords List of keyword arguments
79
+ # accepted by the method.
80
+ #
81
+ # @return [RespondToMatcher] self
82
+ def with_keywords *keywords
83
+ (@expected_keywords ||= []).concat(keywords)
84
+
85
+ self
86
+ end # method with_keywords
87
+ alias_method :and_keywords, :with_keywords
88
+
89
+ # Adds an arbitrary keyword expectation, e.g. that the method supports
90
+ # any keywords with splatted hash arguments of the form **kwargs.
91
+ def with_arbitrary_keywords
92
+ @expect_arbitrary_keywords = true
93
+
94
+ self
95
+ end # method with_arbitrary_keywords
96
+ alias_method :and_arbitrary_keywords, :with_arbitrary_keywords
97
+
62
98
  # Adds a block expectation. The actual object will only match a block
63
99
  # expectation if it expects a parameter of the form &block.
64
100
  #
@@ -115,9 +151,9 @@ module RSpec::SleepingKingStudios::Matchers::BuiltIn
115
151
  end # method find_failing_method_names
116
152
 
117
153
  def matches_arity? actual, name
118
- return true unless @expected_arity
154
+ return true unless @expected_arity || @expect_unlimited_arguments
119
155
 
120
- if result = check_method_arity(actual.method(name), @expected_arity)
156
+ if result = check_method_arity(actual.method(name), @expected_arity, expect_unlimited_arguments: @expect_unlimited_arguments)
121
157
  (@failing_method_reasons[name] ||= {}).update result
122
158
  return false
123
159
  end # if
@@ -127,9 +163,10 @@ module RSpec::SleepingKingStudios::Matchers::BuiltIn
127
163
 
128
164
  def matches_keywords? actual, name
129
165
  return true unless @expected_keywords ||
166
+ @expect_arbitrary_keywords ||
130
167
  (@expected_arity && RUBY_VERSION >= "2.1.0")
131
168
 
132
- if result = check_method_keywords(actual.method(name), @expected_keywords)
169
+ if result = check_method_keywords(actual.method(name), @expected_keywords, expect_arbitrary_keywords: @expect_arbitrary_keywords)
133
170
  (@failing_method_reasons[name] ||= {}).update result
134
171
  return false
135
172
  end # if
@@ -164,10 +201,18 @@ module RSpec::SleepingKingStudios::Matchers::BuiltIn
164
201
  messages << "#{@expected_arity.inspect} #{pluralize @expected_arity, 'argument', 'arguments'}"
165
202
  end # if
166
203
 
204
+ if @expect_unlimited_arguments
205
+ messages << 'unlimited arguments'
206
+ end # if
207
+
167
208
  if !(@expected_keywords.nil? || @expected_keywords.empty?)
168
209
  messages << "#{pluralize @expected_keywords.count, 'keyword', 'keywords'} #{humanize_list @expected_keywords.map(&:inspect)}"
169
210
  end # if
170
211
 
212
+ if @expect_arbitrary_keywords
213
+ messages << 'arbitrary keywords'
214
+ end # if
215
+
171
216
  if @expected_block
172
217
  messages << "a block"
173
218
  end # if
@@ -180,9 +225,19 @@ module RSpec::SleepingKingStudios::Matchers::BuiltIn
180
225
 
181
226
  if hsh = reasons.fetch(:not_enough_args, false)
182
227
  messages << " expected at least #{hsh[:count]} arguments, but received #{hsh[:arity]}"
183
- elsif hsh = reasons.fetch(:too_many_args, false)
228
+ end # if
229
+
230
+ if hsh = reasons.fetch(:too_many_args, false)
184
231
  messages << " expected at most #{hsh[:count]} arguments, but received #{hsh[:arity]}"
185
- end # if-elsif
232
+ end # if
233
+
234
+ if hsh = reasons.fetch(:expected_unlimited_arguments, false)
235
+ messages << " expected at most #{hsh[:count]} arguments, but received unlimited arguments"
236
+ end # if
237
+
238
+ if reasons.fetch(:expected_arbitrary_keywords, false)
239
+ messages << " expected arbitrary keywords"
240
+ end # if
186
241
 
187
242
  if ary = reasons.fetch(:missing_keywords, false)
188
243
  messages << " missing #{pluralize ary.count, 'keyword', 'keywords'} #{humanize_list ary.map(&:inspect)}"
@@ -73,6 +73,39 @@ module RSpec::SleepingKingStudios::Matchers::Core
73
73
  self
74
74
  end # method with
75
75
 
76
+ # Adds an unlimited parameter count expectation, e.g. that the method
77
+ # supports splatted array arguments of the form *args.
78
+ #
79
+ # @return [RespondToMatcher] self
80
+ def with_unlimited_arguments
81
+ @expect_unlimited_arguments = true
82
+
83
+ self
84
+ end # method with_unlimited_arguments
85
+ alias_method :and_unlimited_arguments, :with_unlimited_arguments
86
+
87
+ # Adds one or more keyword expectations.
88
+ #
89
+ # @param [Array<String, Symbol>] keywords List of keyword arguments
90
+ # accepted by the method.
91
+ #
92
+ # @return [RespondToMatcher] self
93
+ def with_keywords *keywords
94
+ (@expected_keywords ||= []).concat(keywords)
95
+
96
+ self
97
+ end # method with_keywords
98
+ alias_method :and_keywords, :with_keywords
99
+
100
+ # Adds an arbitrary keyword expectation, e.g. that the method supports
101
+ # any keywords with splatted hash arguments of the form **kwargs.
102
+ def with_arbitrary_keywords
103
+ @expect_arbitrary_keywords = true
104
+
105
+ self
106
+ end # method with_arbitrary_keywords
107
+ alias_method :and_arbitrary_keywords, :with_arbitrary_keywords
108
+
76
109
  # Convenience method for more fluent specs. Does nothing and returns self.
77
110
  #
78
111
  # @return [ConstructMatcher] self
@@ -102,9 +135,9 @@ module RSpec::SleepingKingStudios::Matchers::Core
102
135
  private
103
136
 
104
137
  def matches_arity? actual
105
- return true unless @expected_arity
138
+ return true unless @expected_arity || @expect_unlimited_arguments
106
139
 
107
- if result = check_method_arity(actual.allocate.method(:initialize), @expected_arity)
140
+ if result = check_method_arity(actual.allocate.method(:initialize), @expected_arity, expect_unlimited_arguments: @expect_unlimited_arguments)
108
141
  @failing_method_reasons.update result
109
142
  return false
110
143
  end # if
@@ -114,9 +147,10 @@ module RSpec::SleepingKingStudios::Matchers::Core
114
147
 
115
148
  def matches_keywords? actual
116
149
  return true unless @expected_keywords ||
150
+ @expect_arbitrary_keywords ||
117
151
  (@expected_arity && RUBY_VERSION >= "2.1.0")
118
152
 
119
- if result = check_method_keywords(actual.allocate.method(:initialize), @expected_keywords)
153
+ if result = check_method_keywords(actual.allocate.method(:initialize), @expected_keywords, expect_arbitrary_keywords: @expect_arbitrary_keywords)
120
154
  @failing_method_reasons.update result
121
155
  return false
122
156
  end # if
@@ -131,10 +165,18 @@ module RSpec::SleepingKingStudios::Matchers::Core
131
165
  messages << "#{@expected_arity.inspect} argument#{1 == @expected_arity ? "" : "s"}"
132
166
  end # if
133
167
 
168
+ if @expect_unlimited_arguments
169
+ messages << 'unlimited arguments'
170
+ end # if
171
+
134
172
  if !(@expected_keywords.nil? || @expected_keywords.empty?)
135
173
  messages << "#{pluralize @expected_keywords.count, 'keyword', 'keywords'} #{humanize_list @expected_keywords.map(&:inspect)}"
136
174
  end # if
137
175
 
176
+ if @expect_arbitrary_keywords
177
+ messages << 'arbitrary keywords'
178
+ end # if
179
+
138
180
  humanize_list messages
139
181
  end # method format_expected_arguments
140
182
 
@@ -147,6 +189,10 @@ module RSpec::SleepingKingStudios::Matchers::Core
147
189
  messages << " expected at most #{hsh[:count]} arguments, but received #{hsh[:arity]}"
148
190
  end # if-elsif
149
191
 
192
+ if hsh = reasons.fetch(:expected_unlimited_arguments, false)
193
+ messages << " expected at most #{hsh[:count]} arguments, but received unlimited arguments"
194
+ end # if
195
+
150
196
  if ary = reasons.fetch(:missing_keywords, false)
151
197
  messages << " missing #{pluralize ary.count, 'keyword', 'keywords'} #{humanize_list ary.map(&:inspect)}"
152
198
  end # if
@@ -155,6 +201,10 @@ module RSpec::SleepingKingStudios::Matchers::Core
155
201
  messages << " unexpected #{pluralize ary.count, 'keyword', 'keywords'} #{humanize_list ary.map(&:inspect)}"
156
202
  end # if
157
203
 
204
+ if reasons.fetch(:expected_arbitrary_keywords, false)
205
+ messages << " expected arbitrary keywords"
206
+ end # if
207
+
158
208
  messages.join "\n"
159
209
  end # method format_errors
160
210
  end # class
@@ -8,39 +8,42 @@ module RSpec::SleepingKingStudios::Matchers::Shared
8
8
  module MatchParameters
9
9
  # Checks whether the method accepts the specified number or range of
10
10
  # arguments.
11
- #
11
+ #
12
12
  # @param [Method] method the method to check
13
13
  # @param [Integer, Range] arity the expected number or range of parameters
14
- #
14
+ #
15
15
  # @return [Boolean] true if the method accepts the specified number or both
16
16
  # the specified minimum and maximum number of parameters; otherwise false
17
- def check_method_arity method, arity
17
+ def check_method_arity method, arity, expect_unlimited_arguments: false
18
18
  parameters = method.parameters
19
19
  required = parameters.count { |type, | :req == type }
20
20
  optional = parameters.count { |type, | :opt == type }
21
21
  variadic = parameters.count { |type, | :rest == type }
22
+ reasons = {}
23
+
24
+ reasons[:expected_unlimited_arguments] = { count: required + optional } if 0 == variadic && expect_unlimited_arguments
22
25
 
23
26
  min, max = arity.is_a?(Range) ?
24
27
  [arity.begin, arity.end] :
25
28
  [arity, arity]
26
29
 
27
- if min < required
28
- return { :not_enough_args => { arity: min, count: required } }
29
- elsif 0 == variadic && max > required + optional
30
- return { :too_many_args => { arity: max, count: required + optional } }
30
+ if min && min < required
31
+ reasons[:not_enough_args] = { arity: min, count: required }
32
+ elsif max && 0 == variadic && max > required + optional
33
+ reasons[:too_many_args] = { arity: max, count: required + optional }
31
34
  end # if
32
35
 
33
- nil
36
+ reasons.empty? ? nil : reasons
34
37
  end # method check_method_arity
35
38
 
36
39
  # Checks whether the method accepts the specified keywords.
37
- #
40
+ #
38
41
  # @param [Method] method the method to check
39
42
  # @param [Array<String, Symbol>] keywords the expected keywords
40
- #
43
+ #
41
44
  # @return [Boolean] true if the method accepts the specified keywords;
42
45
  # otherwise false
43
- def check_method_keywords method, keywords
46
+ def check_method_keywords method, keywords, expect_arbitrary_keywords: false
44
47
  keywords ||= []
45
48
  parameters = method.parameters
46
49
  reasons = {}
@@ -51,11 +54,13 @@ module RSpec::SleepingKingStudios::Matchers::Shared
51
54
  parameters.select { |type, _| :keyreq == type }.each do |_, keyword|
52
55
  missing << keyword unless keywords.include?(keyword)
53
56
  end # each
54
-
57
+
55
58
  reasons[:missing_keywords] = missing unless missing.empty?
56
59
  end # if
57
60
 
58
61
  unless 0 < parameters.count { |type, _| :keyrest == type }
62
+ reasons[:expected_arbitrary_keywords] = true if expect_arbitrary_keywords
63
+
59
64
  mismatch = []
60
65
  keywords.each do |keyword|
61
66
  mismatch << keyword unless
@@ -70,9 +75,9 @@ module RSpec::SleepingKingStudios::Matchers::Shared
70
75
  end # method check_method_keywords
71
76
 
72
77
  # Checks whether the method expects a block.
73
- #
78
+ #
74
79
  # @param [Method] method the method to check
75
- #
80
+ #
76
81
  # @return [Boolean] true if the method expects a block argument; otherwise
77
82
  # false
78
83
  def check_method_block method
@@ -13,7 +13,7 @@ module RSpec
13
13
  # Minor version.
14
14
  MINOR = 0
15
15
  # Patch version.
16
- PATCH = 1
16
+ PATCH = 2
17
17
  # Prerelease version.
18
18
  PRERELEASE = nil
19
19
  # Build metadata.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-sleeping_king_studios
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rob "Merlin" Smith
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-27 00:00:00.000000000 Z
11
+ date: 2015-06-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec