rspec-sleeping_king_studios 2.0.0.beta.0 → 2.0.0.beta.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +84 -13
- data/DEVELOPMENT.md +16 -0
- data/README.md +203 -100
- data/lib/rspec/sleeping_king_studios/all.rb +4 -0
- data/lib/rspec/sleeping_king_studios/configuration.rb +42 -0
- data/lib/rspec/sleeping_king_studios/examples/all.rb +5 -0
- data/lib/rspec/sleeping_king_studios/examples/property_examples.rb +58 -0
- data/lib/rspec/sleeping_king_studios/examples/rspec_matcher_examples.rb +105 -0
- data/lib/rspec/sleeping_king_studios/examples/shared_example_group.rb +62 -0
- data/lib/rspec/sleeping_king_studios/examples.rb +8 -0
- data/lib/rspec/sleeping_king_studios/matchers/active_model/all.rb +5 -0
- data/lib/rspec/sleeping_king_studios/matchers/active_model/have_errors/error_expectation.rb +0 -1
- data/lib/rspec/sleeping_king_studios/matchers/active_model/have_errors/message_expectation.rb +1 -2
- data/lib/rspec/sleeping_king_studios/matchers/active_model/have_errors.rb +75 -24
- data/lib/rspec/sleeping_king_studios/matchers/active_model.rb +6 -3
- data/lib/rspec/sleeping_king_studios/matchers/all.rb +5 -0
- data/lib/rspec/sleeping_king_studios/matchers/base_matcher.rb +20 -1
- data/lib/rspec/sleeping_king_studios/matchers/built_in/all.rb +5 -0
- data/lib/rspec/sleeping_king_studios/matchers/built_in/be_kind_of.rb +16 -10
- data/lib/rspec/sleeping_king_studios/matchers/built_in/include.rb +14 -9
- data/lib/rspec/sleeping_king_studios/matchers/built_in/respond_to.rb +45 -31
- data/lib/rspec/sleeping_king_studios/matchers/built_in.rb +5 -3
- data/lib/rspec/sleeping_king_studios/matchers/core/all.rb +5 -0
- data/lib/rspec/sleeping_king_studios/matchers/core/be_boolean.rb +11 -4
- data/lib/rspec/sleeping_king_studios/matchers/core/construct.rb +56 -32
- data/lib/rspec/sleeping_king_studios/matchers/core/have_property.rb +59 -29
- data/lib/rspec/sleeping_king_studios/matchers/core/have_reader.rb +31 -22
- data/lib/rspec/sleeping_king_studios/matchers/core/have_writer.rb +21 -55
- data/lib/rspec/sleeping_king_studios/matchers/core.rb +5 -3
- data/lib/rspec/sleeping_king_studios/matchers/shared/match_parameters.rb +1 -3
- data/lib/rspec/sleeping_king_studios/matchers/shared/match_property.rb +52 -0
- data/lib/rspec/sleeping_king_studios/matchers.rb +10 -3
- data/lib/rspec/sleeping_king_studios/version.rb +22 -1
- data/lib/rspec/sleeping_king_studios.rb +7 -1
- metadata +38 -16
- data/lib/rspec/sleeping_king_studios/matchers/active_model/have_errors/require.rb +0 -7
- data/lib/rspec/sleeping_king_studios/matchers/active_model/require.rb +0 -8
- data/lib/rspec/sleeping_king_studios/matchers/built_in/require.rb +0 -7
- data/lib/rspec/sleeping_king_studios/matchers/core/require.rb +0 -7
- data/lib/rspec/sleeping_king_studios/matchers/meta/fail_with_actual.rb +0 -107
- data/lib/rspec/sleeping_king_studios/matchers/meta/pass_with_actual.rb +0 -95
- data/lib/rspec/sleeping_king_studios/matchers/meta/require.rb +0 -7
- data/lib/rspec/sleeping_king_studios/matchers/meta.rb +0 -5
- data/lib/rspec/sleeping_king_studios/matchers/require.rb +0 -12
- data/lib/rspec/sleeping_king_studios/matchers/shared/require.rb +0 -7
- data/lib/rspec/sleeping_king_studios/require.rb +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4f6b435b34abdf1b87b2496605d4472339e97b51
|
4
|
+
data.tar.gz: 9ab33137c4cdb76bdd1957e060814a5a8a6a23cd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3fadfe034ff61756ef19b23eb4d4f15e7239b0e26a770cfa9711445d216e27efb487206b20848cae983732def47b3c45c2225778ddd9dc00023d2a742a5996ff
|
7
|
+
data.tar.gz: 6ea0170359b50b8b5a012085430ea5fa3cb92ee9fe563b38dcdc53ffdcee2ae7f0a9802c31d6f394a6d5b91759e4f5c15c90c225996eee865dd3ba6034348067
|
data/CHANGELOG.md
CHANGED
@@ -2,28 +2,99 @@
|
|
2
2
|
|
3
3
|
## 2.0.0
|
4
4
|
|
5
|
-
Update the entire library to support RSpec 3. Most of the updates are purely
|
6
|
-
internal, but there are a few changes that are not backward compatible to be
|
7
|
-
aware of.
|
5
|
+
Update the entire library to support RSpec 3. Most of the updates are purely internal, but there are a few changes that are not backward compatible to be aware of.
|
8
6
|
|
9
|
-
###
|
7
|
+
### Ruby 1.9.3 Support
|
8
|
+
|
9
|
+
Support for Ruby 1.9.3 is officially dropped.
|
10
|
+
|
11
|
+
### Concerns
|
12
|
+
|
13
|
+
Added module RSpec::SleepingKingStudios::Examples::SharedExampleGroup as a mixin for defining scoped shared example groups. Extend into a module to define shared example groups scoped to that module (and automatically included in example groups when the module is included), or extend into an example group to allow aliasing shared example groups with alternate or more expressive names.
|
14
|
+
|
15
|
+
### Custom Examples
|
16
|
+
|
17
|
+
Added custom shared example groups for easier/more expressive tests.
|
18
|
+
|
19
|
+
#### Property Examples
|
20
|
+
|
21
|
+
Added 'has reader', 'has writer', and 'has property' examples as shorthand for defining property and attribute expectations.
|
22
|
+
|
23
|
+
#### RSpec Matcher Examples
|
24
|
+
|
25
|
+
Added custom examples for testing RSpec matchers. Replaces the (now removed) `pass_with_actual` and `fail_with_actual` matchers, which were fiddly and confusing (even for me) and couldn't handle all cases (such as failing on both `expect().to` and `expect().not_to`).
|
26
|
+
|
27
|
+
### Custom Matchers
|
10
28
|
|
11
29
|
All matchers have been updated to support the RSpec 3 matcher API.
|
12
30
|
|
13
|
-
####
|
31
|
+
#### `construct` Matcher
|
32
|
+
|
33
|
+
Now has a fluent method for both `#argument` and `#arguments` to support the singular and plural use cases, similar to the built-in `respond_to` matcher.
|
34
|
+
|
35
|
+
expect(FooClass).to construct.with(1).argument
|
36
|
+
expect(BarClass).to construct.with(3).arguments
|
37
|
+
|
38
|
+
#### `fail_with_actual` Matcher
|
39
|
+
|
40
|
+
Removed. To test custom matchers, use the new shared examples (see Shared Examples, below).
|
41
|
+
|
42
|
+
#### `have_errors` Matcher
|
43
|
+
|
44
|
+
Adds the `#with` fluent method as an alias to `#with_messages`, as follows:
|
45
|
+
|
46
|
+
expect(model).to have_errors.on(:my_field).with("can't be blank")
|
47
|
+
|
48
|
+
In addition, the have_errors matcher will fail on both a positive expectation (`expect().to`) and a negative expectation (`expect().not_to` or `expect().to_not`) if the actual object does not respond to `#valid?`. The failure message has also been clarified for cases like `expect().not_to have_errors.on(attribute)`.
|
14
49
|
|
15
|
-
|
50
|
+
#### `have_property` Matcher
|
16
51
|
|
17
|
-
|
52
|
+
Removed the functionality checking the value of `:property` after `:property=` has been invoked. The syntax for doing so was not expressive, and the feature was rarely used. To verify that invoking `:property=` will change `:property` to the desired value, set up the change expectation directly using a `#change` matcher.
|
18
53
|
|
19
|
-
|
20
|
-
|
54
|
+
Now supports composable matchers, as follows:
|
55
|
+
|
56
|
+
expect(object).to have_property(:my_method).with(an_instance_of(Fixnum))
|
57
|
+
|
58
|
+
Also added `#with_value` as an alias for `with`, and the error messages have been edited for clarity.
|
59
|
+
|
60
|
+
#### `have_reader` Matcher
|
61
|
+
|
62
|
+
Now supports composable matchers, as follows:
|
63
|
+
|
64
|
+
expect(object).to have_reader(:my_method).with(an_instance_of(String))
|
65
|
+
|
66
|
+
Also added `#with_value` as an alias for `with`, and the error messages have been edited for clarity.
|
67
|
+
|
68
|
+
#### `have_writer` Matcher
|
69
|
+
|
70
|
+
Removed the functionality checking the value of `:property` after `:property=` has been invoked. The syntax for doing so was not expressive, and the feature was rarely used. To verify that invoking `:property=` will change `:property` to the desired value, set up the change expectation directly using a `#change` matcher.
|
71
|
+
|
72
|
+
The error messages have also been edited for clarity.
|
73
|
+
|
74
|
+
#### `pass_with_actual` Matcher
|
75
|
+
|
76
|
+
Removed. To test custom matchers, use the new shared examples (see Shared Examples, below).
|
77
|
+
|
78
|
+
#### `respond_to` Matcher
|
79
|
+
|
80
|
+
The `#and` fluent method has been removed, and the `#a_block` method for verifying the presence of a block argument has been renamed to `#with_a_block`. In addition, by passing in `true` as the last argument, can check for the presence and arguments of protected or private methods, similar to the Ruby `Object#respond_to?` method.
|
21
81
|
|
22
82
|
### Mocks
|
23
83
|
|
24
|
-
The #custom_double mock method has been completely removed. The recommended
|
25
|
-
|
26
|
-
|
84
|
+
The #custom_double mock method has been completely removed. The recommended solution for that use case is `double('My Double').extend(MyModule)`, for some `MyModule` that implements the desired actual (non-stubbed) functionality.
|
85
|
+
|
86
|
+
### Shared Examples
|
87
|
+
|
88
|
+
Adds a new category of features, Shared Example groups, that can be included for easier or more expressive spec definitions.
|
89
|
+
|
90
|
+
#### Examples for Custom RSpec Matchers
|
91
|
+
|
92
|
+
Added four new shared examples to test custom matchers:
|
93
|
+
|
94
|
+
include_examples 'passes with a positive expectation'
|
95
|
+
include_examples 'passes with a negative expectation'
|
96
|
+
include_examples 'fails with a positive expectation'
|
97
|
+
include_examples 'fails with a negative expectation'
|
27
98
|
|
28
99
|
## 1.0.1
|
29
100
|
|
@@ -31,7 +102,7 @@ solution for that use case is `double('My Double').extend(MyModule)`, for some
|
|
31
102
|
|
32
103
|
* The #construct and #respond_to matchers now support 2.1.0 required keyword
|
33
104
|
arguments, of the form def foo(bar:, baz:). If the class constructor or
|
34
|
-
method requires one or more keyword arguments, and one or more of those
|
105
|
+
method requires one or more keyword arguments, and one or more of those
|
35
106
|
keywords are not provided when checking arguments using the #with
|
36
107
|
method, the matcher will fail with the message "missing keywords" and a list
|
37
108
|
of the keywords that were not provided as arguments to #with.
|
data/DEVELOPMENT.md
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# Development Notes
|
2
|
+
|
3
|
+
## Tasks
|
4
|
+
|
5
|
+
### High Priority
|
6
|
+
|
7
|
+
### Medium Priority
|
8
|
+
|
9
|
+
[RC1]
|
10
|
+
- Thorough documentation pass.
|
11
|
+
- Test against both RSpec 3.0 and 3.1 (multiple gemfiles? See ActiveModel::Collection for how it's done)
|
12
|
+
|
13
|
+
### Low Priority
|
14
|
+
|
15
|
+
[RC1]
|
16
|
+
- Cucumber features for testing matchers, including returned text?
|
data/README.md
CHANGED
@@ -1,15 +1,11 @@
|
|
1
1
|
# RSpec::SleepingKingStudios [![Build Status](https://travis-ci.org/sleepingkingstudios/rspec-sleeping_king_studios.svg?branch=master)](https://travis-ci.org/sleepingkingstudios/rspec-sleeping_king_studios)
|
2
2
|
|
3
|
-
A collection of matchers and extensions to ease TDD/BDD using RSpec. Extends
|
4
|
-
built-in matchers with new functionality, such as support for Ruby 2.0+ keyword
|
5
|
-
arguments, and adds new matchers for testing boolean-ness, object reader/writer
|
6
|
-
properties, object constructor arguments, ActiveModel validations, and more.
|
3
|
+
A collection of matchers and extensions to ease TDD/BDD using RSpec. Extends built-in matchers with new functionality, such as support for Ruby 2.0+ keyword arguments, and adds new matchers for testing boolean-ness, object reader/writer properties, object constructor arguments, ActiveModel validations, and more. Also defines shared example groups for more expressive testing.
|
7
4
|
|
8
5
|
## Supported Ruby Versions
|
9
6
|
|
10
7
|
Currently, the following versions of Ruby are officially supported:
|
11
8
|
|
12
|
-
* 1.9.3
|
13
9
|
* 2.0.0
|
14
10
|
* 2.1.0
|
15
11
|
|
@@ -19,30 +15,70 @@ Currently, the following versions of Ruby are officially supported:
|
|
19
15
|
|
20
16
|
### A Note From The Developer
|
21
17
|
|
22
|
-
Hi, I'm Rob Smith, the
|
23
|
-
developer, I use these tools every day. If you find this project helpful in
|
24
|
-
your own work, or if you have any questions, suggestions or critiques, please
|
25
|
-
feel free to get in touch! I can be reached on GitHub (see above, and feel
|
26
|
-
encouraged to submit bug reports or merge requests there) or via email at
|
27
|
-
merlin@sleepingkingstudios.com. I look forward to hearing from you!
|
18
|
+
Hi, I'm Rob Smith, a Ruby Engineer and the developer of this library. I use these tools every day, but they're not just written for me. If you find this project helpful in your own work, or if you have any questions, suggestions or critiques, please feel free to get in touch! I can be reached on GitHub (see above, and feel encouraged to submit bug reports or merge requests there) or via email at `merlin@sleepingkingstudios.com`. I look forward to hearing from you!
|
28
19
|
|
29
|
-
##
|
20
|
+
## Configuration
|
21
|
+
|
22
|
+
RSpec::SleepingKingStudios now has configuration options available through `RSpec.configuration`. For example, to set the behavior of the matcher examples when a failure message expectation is undefined (see RSpec Matcher Examples, below), put the following in your `spec_helper` or other configuration file:
|
23
|
+
|
24
|
+
RSpec.configure do |config|
|
25
|
+
config.sleeping_king_studios do |config|
|
26
|
+
config.examples do |config|
|
27
|
+
config.handle_missing_failure_message_with = :ignore
|
28
|
+
end # config
|
29
|
+
end # config
|
30
|
+
end # config
|
31
|
+
|
32
|
+
### Configuration Options
|
33
|
+
|
34
|
+
#### Handle Missing Failure Message With
|
35
|
+
|
36
|
+
This option is used with the RSpec matcher examples (see Examples, below), and determines the behavior when a matcher is expected to fail, but the corresponding failure message is not defined (via `let(:failure_message)` or `let(:failure_message_when_negated)`). The default option is `:pending`, which marks the generated example as skipped (and will show up as pending in the formatter). Other options include `:skip`, which marks the generated example as passing, and `:exception`, which marks the generated example as failing.
|
37
|
+
|
38
|
+
## Concerns
|
39
|
+
|
40
|
+
RSpec::SleepingKingStudios defines a few concerns that can be included in or extended into modules or example groups for additional functionality.
|
41
|
+
|
42
|
+
### Shared Example Groups
|
43
|
+
|
44
|
+
require 'rspec/sleeping_king_studios/examples/shared_example_group'
|
45
|
+
|
46
|
+
module MyCustomExamples
|
47
|
+
extend RSpec::SleepingKingStudios::Examples::SharedExampleGroup
|
48
|
+
|
49
|
+
shared_examples 'has custom behavior' do
|
50
|
+
# Define expectations here...
|
51
|
+
end # shared_examples
|
52
|
+
alias_shared_examples 'should have custom behavior', 'has custom behavior'
|
53
|
+
end # module
|
54
|
+
|
55
|
+
Utility functions for defining shared examples. If included in a module, any shared examples defined in that module are scoped to the module, rather than placed in a global scope. This allows you to define different shared examples with the same name in different contexts, similar to the current behavior when defining a shared example inside an example group. To use the defined examples, simply `include` the module in an example group. **Important Note:** Shared examples and aliases must be defined **before** including the module in an example group. Any shared examples or aliases defined afterword will not be available inside the example group.
|
56
|
+
|
57
|
+
### `::alias_shared_examples`
|
58
|
+
|
59
|
+
Aliases a defined shared example group, allowing it to be accessed using a new name. The example group must be defined in the current context using `shared_examples`. The aliases must be defined before including the module into an example group, or they will not be available in the example group.
|
60
|
+
|
61
|
+
### `::shared_examples`
|
62
|
+
|
63
|
+
Defines a shared example group within the context of the current module. Unlike a top-level example group defined using RSpec#shared_examples, these examples are not globally available, and must be mixed into an example group by including the module. The shared examples must be defined before including the module, or they will not be available in the example group.
|
64
|
+
|
65
|
+
## Custom Matchers
|
30
66
|
|
31
67
|
To enable a custom matcher, simply require the associated file. Matchers can be
|
32
68
|
required individually or by category:
|
33
69
|
|
34
|
-
require 'rspec/sleeping_king_studios'
|
70
|
+
require 'rspec/sleeping_king_studios/all'
|
35
71
|
#=> requires all features, including matchers
|
36
72
|
|
37
|
-
require 'rspec/sleeping_king_studios/matchers/core'
|
73
|
+
require 'rspec/sleeping_king_studios/matchers/core/all'
|
38
74
|
#=> requires all of the core matchers
|
39
|
-
|
75
|
+
|
40
76
|
require 'rspec/sleeping_king_studios/matchers/core/construct'
|
41
77
|
#=> requires only the :construct matcher
|
42
78
|
|
43
79
|
### ActiveModel
|
44
80
|
|
45
|
-
require 'rspec/sleeping_king_studios/matchers/active_model'
|
81
|
+
require 'rspec/sleeping_king_studios/matchers/active_model/all'
|
46
82
|
|
47
83
|
These matchers validate ActiveModel functionality, such as validations.
|
48
84
|
|
@@ -56,21 +92,26 @@ individual fields to validate, or even specific messages for each attribute.
|
|
56
92
|
**How To Use:**
|
57
93
|
|
58
94
|
expect(instance).to have_errors
|
59
|
-
|
95
|
+
|
60
96
|
expect(instance).to have_errors.on(:name)
|
61
|
-
|
97
|
+
|
62
98
|
expect(instance).to have_errors.on(:name).with_message('not to be nil')
|
63
99
|
|
64
100
|
**Chaining:**
|
65
101
|
|
66
102
|
* **on:** [String, Symbol] Adds a field to validate; the matcher only passes if
|
67
103
|
all validated fields have errors.
|
104
|
+
* **with:** [Array<String>] Adds one or more messages to the previously-defined
|
105
|
+
field validation. Raises ArgumentError if no field was previously set.
|
68
106
|
* **with\_message:** [String] Adds a message to the previously-defined field
|
69
107
|
validation. Raises ArgumentError if no field was previously set.
|
108
|
+
* **with\_messages:** [Array<String>] Adds one or more messages to the
|
109
|
+
previously-defined field validation. Raises ArgumentError if no field was
|
110
|
+
previously set.
|
70
111
|
|
71
112
|
### BuiltIn
|
72
113
|
|
73
|
-
require 'rspec/sleeping_king_studios/matchers/built_in'
|
114
|
+
require 'rspec/sleeping_king_studios/matchers/built_in/all'
|
74
115
|
|
75
116
|
These extend the built-in RSpec matchers with additional functionality.
|
76
117
|
|
@@ -104,41 +145,24 @@ now accepts an optional block as a shortcut for adding a proc expectation.
|
|
104
145
|
|
105
146
|
require 'rspec/sleeping_king_studios/matchers/built_in/respond_to'
|
106
147
|
|
107
|
-
Now has additional chaining functionality to validate the number of arguments
|
108
|
-
accepted by the method, and whether the method accepts a block argument.
|
148
|
+
Now has additional chaining functionality to validate the number of arguments accepted by the method, the keyword arguments (if any) accepted by the method, and whether the method accepts a block argument.
|
109
149
|
|
110
150
|
**How To Use:**
|
111
151
|
|
152
|
+
# With a variable number of arguments.
|
112
153
|
expect(instance).to respond_to(:foo).with(2..3).arguments.with_a_block
|
113
154
|
|
114
|
-
|
115
|
-
|
116
|
-
* **with:** Expects one Integer or Range argument. If an Integer, verifies that
|
117
|
-
the method accepts that number of arguments; if a Range, verifies that the
|
118
|
-
method accepts both the minimum and maximum number of arguments.
|
119
|
-
* **with\_a\_block:** No parameters. Verifies that the method requires a block
|
120
|
-
argument of the form &my_argument. _Important note:_ A negative result does
|
121
|
-
_not* mean the method cannot accept a block, merely that it does not require
|
122
|
-
one. Also, does _not_ check whether the block is called or yielded.
|
123
|
-
|
124
|
-
##### Ruby 2.0+
|
125
|
-
|
126
|
-
Has additional functionality to support Ruby 2.0 keyword arguments.
|
127
|
-
|
128
|
-
**How To Use:**
|
129
|
-
expect(instance).to respond_to(:foo).with(0, :bar, :baz)
|
155
|
+
# With keyword arguments.
|
156
|
+
expect(instance).to respond_to(:foo).with(0, :bar, :baz)
|
130
157
|
|
131
158
|
**Chaining:**
|
132
159
|
|
133
|
-
* **with:** Expects at most one Integer or Range argument, and zero or more
|
134
|
-
|
135
|
-
accepts that keyword, or has a variadic keyword of the form \*\*params. As
|
136
|
-
of 2.1.0 and required keywords, verifies that all required keywords are
|
137
|
-
provided.
|
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\_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.
|
138
162
|
|
139
163
|
### Core
|
140
164
|
|
141
|
-
require 'rspec/sleeping_king_studios/matchers/core'
|
165
|
+
require 'rspec/sleeping_king_studios/matchers/core/all'
|
142
166
|
|
143
167
|
These matchers check core functionality, such as object boolean-ness, the
|
144
168
|
existence of properties, and so on.
|
@@ -187,28 +211,28 @@ Has additional functionality to support Ruby 2.0 keyword arguments.
|
|
187
211
|
* **with:** Expects one Integer, Range, or nil argument, and zero or more
|
188
212
|
Symbol arguments corresponding to optional keywords. Verifies that the
|
189
213
|
class's constructor accepts that keyword, or has a variadic keyword of the
|
190
|
-
form \*\*params. As of 2.1.0 and required keywords, verifies that all
|
214
|
+
form \*\*params. As of 2.1.0 and required keywords, verifies that all
|
191
215
|
required keywords are provided.
|
192
216
|
|
193
217
|
#### have\_property Matcher
|
194
218
|
|
195
219
|
require 'rspec/sleeping_king_studios/matchers/core/have_property'
|
196
220
|
|
197
|
-
Checks if the actual object responds to :property and :property=, and
|
198
|
-
optionally if a value written to actual.property= can then be read by
|
199
|
-
actual.property.
|
221
|
+
Checks if the actual object responds to :property and :property=, and optionally if the curernt value of actual.property is equal to a specified value.
|
200
222
|
|
201
223
|
**How To Use:**
|
202
224
|
|
203
225
|
expect(instance).to have_property(:foo).with("foo")
|
204
226
|
|
205
|
-
**Parameters:** Property. Expects a string or symbol that is a valid
|
206
|
-
identifier.
|
227
|
+
**Parameters:** Property. Expects a string or symbol that is a valid identifier.
|
207
228
|
|
208
229
|
**Chaining:**
|
209
230
|
|
210
|
-
* **with:** Expects one object, which is
|
211
|
-
|
231
|
+
* **with:** Expects one object, which is checked against the current value of actual.property if actual responds to :property. Can also be used with an RSpec matcher:
|
232
|
+
|
233
|
+
expect(instance).to have_property(:bar).with(an_instance_of(String))
|
234
|
+
|
235
|
+
* **with_value:** Alias for `#with`, above.
|
212
236
|
|
213
237
|
#### have\_reader Matcher
|
214
238
|
|
@@ -221,37 +245,30 @@ current value of actual.property is equal to a specified value.
|
|
221
245
|
|
222
246
|
expect(instance).to have_reader(:foo).with("foo")
|
223
247
|
|
224
|
-
**Parameters:** Property. Expects a string or symbol that is a valid
|
225
|
-
identifier.
|
248
|
+
**Parameters:** Property. Expects a string or symbol that is a valid identifier.
|
226
249
|
|
227
250
|
**Chaining:**
|
228
251
|
|
229
|
-
* **with:** Expects one object, which is checked against the current value of
|
230
|
-
|
231
|
-
|
252
|
+
* **with:** Expects one object, which is checked against the current value of actual.property if actual responds to :property. Can also be used with an RSpec matcher:
|
253
|
+
|
254
|
+
expect(instance).to have_reader(:bar).with(an_instance_of(String))
|
255
|
+
|
256
|
+
* **with_value:** Alias for `#with`, above.
|
257
|
+
|
232
258
|
#### have\_writer Matcher
|
233
259
|
|
234
260
|
require 'rspec/sleeping_king_studios/matchers/core/have_writer'
|
235
261
|
|
236
|
-
Checks if the actual object responds to :property
|
237
|
-
object.property = value sets object.property to value.
|
262
|
+
Checks if the actual object responds to :property=.
|
238
263
|
|
239
264
|
**How To Use:**
|
240
265
|
|
241
|
-
expect(instance).to have_writer(:foo=)
|
266
|
+
expect(instance).to have_writer(:foo=)
|
242
267
|
|
243
268
|
**Parameters:** Property. Expects a string or symbol that is a valid
|
244
269
|
identifier. An equals sign '=' is automatically added if the identifier does
|
245
270
|
not already terminate in '='.
|
246
271
|
|
247
|
-
**Chaining:**
|
248
|
-
|
249
|
-
* **with:** Expects one object. The matcher attempts to set the actual's value
|
250
|
-
using actual.property=, then compare the value with actual.property.
|
251
|
-
|
252
|
-
_Note:_ Currently, write-only properties cannot be checked using with().
|
253
|
-
Attempting to do so will raise an exception.
|
254
|
-
|
255
272
|
#### include\_matching Matcher
|
256
273
|
|
257
274
|
require 'rspec/sleeping_king_studios/matchers/core/include_matching'
|
@@ -265,57 +282,143 @@ matches the given pattern.
|
|
265
282
|
|
266
283
|
**Parameters:** Pattern. Expects a Regexp.
|
267
284
|
|
268
|
-
|
285
|
+
## Shared Examples
|
269
286
|
|
270
|
-
|
287
|
+
To use a custom example group, `require` the associated file and then `include`
|
288
|
+
the module in your example group:
|
271
289
|
|
272
|
-
|
290
|
+
require 'rspec/sleeping_king_studios/examples/some_examples'
|
273
291
|
|
274
|
-
|
292
|
+
RSpec.describe MyCustomMatcher do
|
293
|
+
include RSpec::SleepingKingStudios::Examples::SomeExamples
|
275
294
|
|
276
|
-
|
295
|
+
# You can use the custom shared examples here.
|
296
|
+
include_examples 'some examples'
|
297
|
+
end # describe
|
277
298
|
|
278
|
-
|
279
|
-
take an optional string to check the expected failure message when the matcher
|
280
|
-
is expected to pass, but does not.
|
299
|
+
Unless otherwise noted, these shared examples expect the example group to define either an explicit `#instance` method (using `let(:instance) {}`) or an implicit `subject`. Their behavior is **undefined** if neither `#instance` nor `subject` is defined.
|
281
300
|
|
282
|
-
|
283
|
-
pass\_with\_actual matcher, below.
|
301
|
+
### Property Examples
|
284
302
|
|
285
|
-
|
303
|
+
These examples are shorthand for defining a reader and/or writer expectation.
|
286
304
|
|
287
|
-
|
288
|
-
|
289
|
-
**Parameters:** Matcher. Expects an object that, at minimum, responds to
|
290
|
-
:matches? and :failure\_message.
|
305
|
+
#### Has Property
|
291
306
|
|
292
|
-
|
307
|
+
include_examples 'has property', :foo, 42
|
293
308
|
|
294
|
-
|
295
|
-
against the given matcher's failure\_message.
|
309
|
+
Delegates to the `#has_reader` and `#has_writer` matchers (see Core/Has Reader and Core/Has Writer, above) and passes if the actual object responds to the specified property and property writer methods. If a value is specified, the object must respond to the property and return the specified value. Alternatively, you can set a proc as the expected value, which can contain a comparison, an RSpec expectation, or a more complex expression:
|
296
310
|
|
297
|
-
|
311
|
+
include_examples 'has property', :bar, ->() { an_instance_of(String) }
|
298
312
|
|
299
|
-
|
313
|
+
include_examples 'has property', :baz, ->(value) { value.count = 3 }
|
300
314
|
|
301
|
-
|
302
|
-
optional string to check the expected failure message when the matcher is
|
303
|
-
expected to fail, but does not.
|
315
|
+
#### Has Reader
|
304
316
|
|
305
|
-
|
306
|
-
fail\_with\_actual matcher, above.
|
317
|
+
include_examples 'has reader', :foo, 42
|
307
318
|
|
308
|
-
|
319
|
+
Delegates to the `#has_reader` matcher (see Core/Has Reader, above) and passes if the actual object responds to the specified property. If a value is specified, the object must respond to the property and return the specified value. Alternatively, you can set a proc as the expected value, which can contain a comparison, an RSpec expectation, or a more complex expression:
|
309
320
|
|
310
|
-
|
311
|
-
|
312
|
-
**Parameters:** Matcher. Expects an object that, at minimum, responds to
|
313
|
-
:matches? and :failure\_message\_when\_negated.
|
321
|
+
include_examples 'has reader', :bar, ->() { an_instance_of(String) }
|
314
322
|
|
315
|
-
|
323
|
+
include_examples 'has reader', :baz, ->(value) { value.count = 3 }
|
324
|
+
|
325
|
+
#### Has Writer
|
326
|
+
|
327
|
+
include_examples 'has writer', :foo=
|
328
|
+
|
329
|
+
Delegates to the `#has_writer` matcher (see Core/Has Writer, above) and passes if the actual object responds to the specified property writer.
|
330
|
+
|
331
|
+
### RSpec Matcher Examples
|
332
|
+
|
333
|
+
These examples are used for validating custom RSpec matchers. They are used
|
334
|
+
internally by RSpec::SleepingKingStudios to verify the functionality of the
|
335
|
+
new and modified matchers.
|
336
|
+
|
337
|
+
require 'rspec/sleeping_king_studios/examples/rspec_matcher_examples'
|
338
|
+
|
339
|
+
RSpec.describe MyCustomMatcher do
|
340
|
+
include RSpec::SleepingKingStudios::Examples::RSpecMatcherExamples
|
341
|
+
|
342
|
+
# You can use the custom shared examples here.
|
343
|
+
end # describe
|
344
|
+
|
345
|
+
The `#instance` or `subject` for these examples should be an instance of a class matching the RSpec matcher API. For example, consider a matcher that checks if a number is a multiple of another number. This matcher would be used as follows:
|
346
|
+
|
347
|
+
expect(12).to be_a_multiple_of(3)
|
348
|
+
#=> true
|
349
|
+
|
350
|
+
expect(14).to be_a_multiple_of(3)
|
351
|
+
#=> false
|
352
|
+
|
353
|
+
Therefore, the `#instance` or `subject` should be defined as `BeAMultipleMatcher.new(3)`. If the custom matcher has additional fluent methods or options, these can be added to the instance as well, e.g. `expect(15).to be_a_multiple_of(3).and_of(5)` would be tested as `BeAMultipleMatcher.new(3).and_of(5)`.
|
354
|
+
|
355
|
+
In addition, all of these examples require a defined `#actual` method in the example group containing the object to be tested. The actual object is the object used in the expectation. In the above examples, the actual object is `12` in the first example, and `14` in the second. You can define the `#actual` method using `#let()`, e.g. `let(:actual) { Object.new }`.
|
356
|
+
|
357
|
+
Putting it all together:
|
358
|
+
|
359
|
+
require 'rspec/sleeping_king_studios/examples/rspec_matcher_examples'
|
360
|
+
|
361
|
+
RSpec.describe BeAMultipleOfMatcher do
|
362
|
+
include RSpec::SleepingKingStudios::Examples::RSpecMatcherExamples
|
363
|
+
|
364
|
+
let(:instance) { BeAMultipleOfMatcher.new(3) }
|
365
|
+
|
366
|
+
describe 'with a valid number' do
|
367
|
+
let(:actual) { 15 }
|
368
|
+
|
369
|
+
# Include examples here.
|
370
|
+
|
371
|
+
describe 'with a second factor' do
|
372
|
+
let(:instance) { BeAMultipleOfMatcher.new(3).and_of(5) }
|
373
|
+
|
374
|
+
# Include examples here.
|
375
|
+
end # describe
|
376
|
+
end # describe
|
377
|
+
end # describe
|
378
|
+
|
379
|
+
#### Passes With A Positive Expectation
|
380
|
+
|
381
|
+
include_examples 'passes with a positive expectation'
|
382
|
+
|
383
|
+
Verifies that the instance matcher will pass with a positive expectation (e.g. `expect().to`). Equivalent to verifying the result of the following:
|
384
|
+
|
385
|
+
expect(actual).to match_my_custom_matcher(*expected_values)
|
386
|
+
#=> passes
|
387
|
+
|
388
|
+
#### Passes With A Negative Expectation
|
389
|
+
|
390
|
+
include_examples 'passes with a negative expectation'
|
391
|
+
|
392
|
+
Verifies that the instance matcher will pass with a negative expectation (e.g. `expect().not_to`). Equivalent to verifying the result of the following:
|
393
|
+
|
394
|
+
expect(actual).not_to match_my_custom_matcher(*expected_values)
|
395
|
+
#=> passes
|
396
|
+
|
397
|
+
#### Fails With A Positive Expectation
|
398
|
+
|
399
|
+
include_examples 'fails with a positive expectation'
|
400
|
+
|
401
|
+
Verifies that the instance matcher will fail with a positive expectation (e.g. `expect().to`), and have the expected failure message. Equivalent to verifying the result of the following:
|
402
|
+
|
403
|
+
expect(actual).to match_my_custom_matcher(*expected_values)
|
404
|
+
#=> fails
|
405
|
+
|
406
|
+
In addition, verifies the `#failure_message` of the matcher by comparing it against a `#failure_message` method in the example group. This should be defined using `let(:failure_message) { 'expected to match' }`.
|
407
|
+
|
408
|
+
The behavior if the example group does not define `#failure_message` depends on the value of the `RSpec.configure.sleeping_king_studios.examples.handle_missing_failure_message_with` option (see Configuration, above). Accepted values are `:ignore`, `:pending` (default; marks the example as pending), and `:exception` (raises an exception).
|
409
|
+
|
410
|
+
#### Fails With A Negative Expectation
|
411
|
+
|
412
|
+
include_examples 'fails with a negative expectation'
|
413
|
+
|
414
|
+
Verifies that the instance matcher will fail with a negative expectation (e.g. `expect().not_to`), and have the expected failure message. Equivalent to verifying the result of the following:
|
415
|
+
|
416
|
+
expect(actual).not_to match_my_custom_matcher(*expected_values)
|
417
|
+
#=> fails
|
418
|
+
|
419
|
+
In addition, verifies the `#failure_message_when_negated` of the matcher by comparing it against a `#failure_message_when_negated` method in the example group. This should be defined using `let(:failure_message_when_negated) { 'expected not to match' }`.
|
316
420
|
|
317
|
-
|
318
|
-
against the given matcher's failure\_message\_when\_negated.
|
421
|
+
See Fails With A Positive Expectation, above, for behavior when the example group does not define `#failure_message_when_negated`.
|
319
422
|
|
320
423
|
## License
|
321
424
|
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# lib/rspec/sleeping_king_studios/configuration.rb
|
2
|
+
|
3
|
+
require 'rspec/sleeping_king_studios'
|
4
|
+
|
5
|
+
module RSpec::SleepingKingStudios
|
6
|
+
class Configuration
|
7
|
+
class Examples
|
8
|
+
MISSING_FAILURE_MESSAGE_HANDLERS = %w(ignore pending exception).map(&:intern)
|
9
|
+
|
10
|
+
def handle_missing_failure_message_with
|
11
|
+
@handle_missing_failure_message_with ||= :pending
|
12
|
+
end # method missing_failure_message
|
13
|
+
|
14
|
+
def handle_missing_failure_message_with= value
|
15
|
+
unless MISSING_FAILURE_MESSAGE_HANDLERS.include?(value)
|
16
|
+
message = "unrecognized handler value -- must be in #{MISSING_FAILURE_MESSAGE_HANDLERS.join ', '}"
|
17
|
+
raise ArgumentError.new message
|
18
|
+
end # unless
|
19
|
+
|
20
|
+
@handle_missing_failure_message_with = value
|
21
|
+
end # message missing_failure_message=
|
22
|
+
end # class
|
23
|
+
|
24
|
+
def examples &block
|
25
|
+
(@examples ||= RSpec::SleepingKingStudios::Configuration::Examples.new).tap do |config|
|
26
|
+
if block_given?
|
27
|
+
config.instance_eval &block
|
28
|
+
end # if
|
29
|
+
end # tap
|
30
|
+
end # method examples
|
31
|
+
end # class
|
32
|
+
end # module
|
33
|
+
|
34
|
+
class RSpec::Core::Configuration
|
35
|
+
def sleeping_king_studios &block
|
36
|
+
(@sleeping_king_studios ||= RSpec::SleepingKingStudios::Configuration.new).tap do |config|
|
37
|
+
if block_given?
|
38
|
+
config.instance_eval &block
|
39
|
+
end # if
|
40
|
+
end # tap
|
41
|
+
end # method sleeping_king_studios
|
42
|
+
end # class
|