rspec-change_to_now 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +4 -0
- data/Changelog.md +4 -0
- data/Gemfile +27 -0
- data/Gemfile.lock +313 -0
- data/LICENSE.txt +28 -0
- data/README.md +122 -0
- data/Rakefile +17 -0
- data/cucumber.yml +2 -0
- data/features/change_to_now.feature +29 -0
- data/features/detect.feature +28 -0
- data/features/negate.feature +29 -0
- data/features/step_definitions/additional_cli_steps.rb +13 -0
- data/features/support/env.rb +23 -0
- data/lib/rspec/change_to_now/detect.rb +90 -0
- data/lib/rspec/change_to_now/negate.rb +71 -0
- data/lib/rspec/change_to_now/version.rb +5 -0
- data/lib/rspec/change_to_now.rb +55 -0
- data/rspec-change_to_now.gemspec +27 -0
- data/script/test_all +20 -0
- data/spec/rspec/change_to_now_spec.rb +101 -0
- data/spec/rspec/detect_spec.rb +71 -0
- data/spec/rspec/negate_spec.rb +27 -0
- data/spec/spec_helper.rb +16 -0
- data/spec/support/matchers.rb +20 -0
- metadata +163 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 96abeed0aef61d5688b975afee27033b111b25f3
|
4
|
+
data.tar.gz: 1045809fa03e4269ddb3f8af6c956b6f13a02906
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: fcb079155e85e560fcc96e6ccc29afbceb69975cdecbfe6d0812c7fd992935c04d4e54aa3726910e11dab6f19826a4106b893a694dd8a5c157595660b0b0d893
|
7
|
+
data.tar.gz: 70a8ae0a72150d5fec58c18f57ab0abe1c544f67ef9497d324b90f175b8983f066b1f5751ee9b5caa45bb3301da2f93831ef042f1260dff5f528f3122d3b85b7
|
data/.gitignore
ADDED
data/Changelog.md
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
# Specify your gem's dependencies in rspec-change_to_now.gemspec
|
4
|
+
gemspec
|
5
|
+
|
6
|
+
%w[rspec rspec-core rspec-expectations rspec-mocks rspec-support].each do |lib|
|
7
|
+
branch = ENV.fetch('BRANCH','master')
|
8
|
+
next if branch == '2-99-maintenance' && lib == 'rspec-support'
|
9
|
+
library_path = File.expand_path("../../#{lib}", __FILE__)
|
10
|
+
if File.exist?(library_path)
|
11
|
+
gem lib, :path => library_path
|
12
|
+
else
|
13
|
+
gem lib, :git => "git://github.com/rspec/#{lib}.git",
|
14
|
+
:branch => branch
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# test coverage
|
19
|
+
# gem 'simplecov', :require => false
|
20
|
+
|
21
|
+
gem 'coveralls', :require => false, :platform => :mri_20
|
22
|
+
|
23
|
+
eval File.read('Gemfile-custom') if File.exist?('Gemfile-custom')
|
24
|
+
|
25
|
+
platform :rbx do
|
26
|
+
gem 'rubysl'
|
27
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,313 @@
|
|
1
|
+
GIT
|
2
|
+
remote: git://github.com/rspec/rspec-core.git
|
3
|
+
revision: e0a8404b0ab3f7803eedca9572f3fbfbea915bd6
|
4
|
+
branch: master
|
5
|
+
specs:
|
6
|
+
rspec-core (3.1.0.pre)
|
7
|
+
rspec-support (= 3.1.0.pre)
|
8
|
+
|
9
|
+
GIT
|
10
|
+
remote: git://github.com/rspec/rspec-expectations.git
|
11
|
+
revision: e4674ca2440d22ecfe59be6fe351396dbe9b4369
|
12
|
+
branch: master
|
13
|
+
specs:
|
14
|
+
rspec-expectations (3.1.0.pre)
|
15
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
16
|
+
rspec-support (= 3.1.0.pre)
|
17
|
+
|
18
|
+
GIT
|
19
|
+
remote: git://github.com/rspec/rspec-mocks.git
|
20
|
+
revision: 873d755efe61d500444c230dc3b7f4f9d24aed43
|
21
|
+
branch: master
|
22
|
+
specs:
|
23
|
+
rspec-mocks (3.1.0.pre)
|
24
|
+
rspec-support (= 3.1.0.pre)
|
25
|
+
|
26
|
+
GIT
|
27
|
+
remote: git://github.com/rspec/rspec-support.git
|
28
|
+
revision: ba5b67666514d5808da13ddaafefc8c597e553e1
|
29
|
+
branch: master
|
30
|
+
specs:
|
31
|
+
rspec-support (3.1.0.pre)
|
32
|
+
|
33
|
+
GIT
|
34
|
+
remote: git://github.com/rspec/rspec.git
|
35
|
+
revision: 2b826653e1f55f63e4f99d8dd1f14b5d35d0a0b7
|
36
|
+
branch: master
|
37
|
+
specs:
|
38
|
+
rspec (3.1.0.pre)
|
39
|
+
rspec-core (= 3.1.0.pre)
|
40
|
+
rspec-expectations (= 3.1.0.pre)
|
41
|
+
rspec-mocks (= 3.1.0.pre)
|
42
|
+
|
43
|
+
PATH
|
44
|
+
remote: .
|
45
|
+
specs:
|
46
|
+
rspec-change_to_now (1.0.0)
|
47
|
+
rspec-core (>= 3.0.0)
|
48
|
+
rspec-expectations (>= 3.0.0)
|
49
|
+
|
50
|
+
GEM
|
51
|
+
remote: https://rubygems.org/
|
52
|
+
specs:
|
53
|
+
aruba (0.6.0)
|
54
|
+
childprocess (>= 0.3.6)
|
55
|
+
cucumber (>= 1.1.1)
|
56
|
+
rspec-expectations (>= 2.7.0)
|
57
|
+
builder (3.2.2)
|
58
|
+
childprocess (0.5.3)
|
59
|
+
ffi (~> 1.0, >= 1.0.11)
|
60
|
+
coveralls (0.7.0)
|
61
|
+
multi_json (~> 1.3)
|
62
|
+
rest-client
|
63
|
+
simplecov (>= 0.7)
|
64
|
+
term-ansicolor
|
65
|
+
thor
|
66
|
+
cucumber (1.3.16)
|
67
|
+
builder (>= 2.1.2)
|
68
|
+
diff-lcs (>= 1.1.3)
|
69
|
+
gherkin (~> 2.12)
|
70
|
+
multi_json (>= 1.7.5, < 2.0)
|
71
|
+
multi_test (>= 0.1.1)
|
72
|
+
diff-lcs (1.2.5)
|
73
|
+
docile (1.1.5)
|
74
|
+
ffi (1.9.3)
|
75
|
+
ffi2-generators (0.1.1)
|
76
|
+
gherkin (2.12.2)
|
77
|
+
multi_json (~> 1.3)
|
78
|
+
mime-types (2.3)
|
79
|
+
multi_json (1.10.1)
|
80
|
+
multi_test (0.1.1)
|
81
|
+
netrc (0.7.7)
|
82
|
+
rake (10.1.1)
|
83
|
+
rest-client (1.7.2)
|
84
|
+
mime-types (>= 1.16, < 3.0)
|
85
|
+
netrc (~> 0.7)
|
86
|
+
rubysl (2.0.15)
|
87
|
+
rubysl-abbrev (~> 2.0)
|
88
|
+
rubysl-base64 (~> 2.0)
|
89
|
+
rubysl-benchmark (~> 2.0)
|
90
|
+
rubysl-bigdecimal (~> 2.0)
|
91
|
+
rubysl-cgi (~> 2.0)
|
92
|
+
rubysl-cgi-session (~> 2.0)
|
93
|
+
rubysl-cmath (~> 2.0)
|
94
|
+
rubysl-complex (~> 2.0)
|
95
|
+
rubysl-continuation (~> 2.0)
|
96
|
+
rubysl-coverage (~> 2.0)
|
97
|
+
rubysl-csv (~> 2.0)
|
98
|
+
rubysl-curses (~> 2.0)
|
99
|
+
rubysl-date (~> 2.0)
|
100
|
+
rubysl-delegate (~> 2.0)
|
101
|
+
rubysl-digest (~> 2.0)
|
102
|
+
rubysl-drb (~> 2.0)
|
103
|
+
rubysl-e2mmap (~> 2.0)
|
104
|
+
rubysl-english (~> 2.0)
|
105
|
+
rubysl-enumerator (~> 2.0)
|
106
|
+
rubysl-erb (~> 2.0)
|
107
|
+
rubysl-etc (~> 2.0)
|
108
|
+
rubysl-expect (~> 2.0)
|
109
|
+
rubysl-fcntl (~> 2.0)
|
110
|
+
rubysl-fiber (~> 2.0)
|
111
|
+
rubysl-fileutils (~> 2.0)
|
112
|
+
rubysl-find (~> 2.0)
|
113
|
+
rubysl-forwardable (~> 2.0)
|
114
|
+
rubysl-getoptlong (~> 2.0)
|
115
|
+
rubysl-gserver (~> 2.0)
|
116
|
+
rubysl-io-console (~> 2.0)
|
117
|
+
rubysl-io-nonblock (~> 2.0)
|
118
|
+
rubysl-io-wait (~> 2.0)
|
119
|
+
rubysl-ipaddr (~> 2.0)
|
120
|
+
rubysl-irb (~> 2.0)
|
121
|
+
rubysl-logger (~> 2.0)
|
122
|
+
rubysl-mathn (~> 2.0)
|
123
|
+
rubysl-matrix (~> 2.0)
|
124
|
+
rubysl-mkmf (~> 2.0)
|
125
|
+
rubysl-monitor (~> 2.0)
|
126
|
+
rubysl-mutex_m (~> 2.0)
|
127
|
+
rubysl-net-ftp (~> 2.0)
|
128
|
+
rubysl-net-http (~> 2.0)
|
129
|
+
rubysl-net-imap (~> 2.0)
|
130
|
+
rubysl-net-pop (~> 2.0)
|
131
|
+
rubysl-net-protocol (~> 2.0)
|
132
|
+
rubysl-net-smtp (~> 2.0)
|
133
|
+
rubysl-net-telnet (~> 2.0)
|
134
|
+
rubysl-nkf (~> 2.0)
|
135
|
+
rubysl-observer (~> 2.0)
|
136
|
+
rubysl-open-uri (~> 2.0)
|
137
|
+
rubysl-open3 (~> 2.0)
|
138
|
+
rubysl-openssl (~> 2.0)
|
139
|
+
rubysl-optparse (~> 2.0)
|
140
|
+
rubysl-ostruct (~> 2.0)
|
141
|
+
rubysl-pathname (~> 2.0)
|
142
|
+
rubysl-prettyprint (~> 2.0)
|
143
|
+
rubysl-prime (~> 2.0)
|
144
|
+
rubysl-profile (~> 2.0)
|
145
|
+
rubysl-profiler (~> 2.0)
|
146
|
+
rubysl-pstore (~> 2.0)
|
147
|
+
rubysl-pty (~> 2.0)
|
148
|
+
rubysl-rational (~> 2.0)
|
149
|
+
rubysl-readline (~> 2.0)
|
150
|
+
rubysl-resolv (~> 2.0)
|
151
|
+
rubysl-rexml (~> 2.0)
|
152
|
+
rubysl-rinda (~> 2.0)
|
153
|
+
rubysl-rss (~> 2.0)
|
154
|
+
rubysl-scanf (~> 2.0)
|
155
|
+
rubysl-securerandom (~> 2.0)
|
156
|
+
rubysl-set (~> 2.0)
|
157
|
+
rubysl-shellwords (~> 2.0)
|
158
|
+
rubysl-singleton (~> 2.0)
|
159
|
+
rubysl-socket (~> 2.0)
|
160
|
+
rubysl-stringio (~> 2.0)
|
161
|
+
rubysl-strscan (~> 2.0)
|
162
|
+
rubysl-sync (~> 2.0)
|
163
|
+
rubysl-syslog (~> 2.0)
|
164
|
+
rubysl-tempfile (~> 2.0)
|
165
|
+
rubysl-thread (~> 2.0)
|
166
|
+
rubysl-thwait (~> 2.0)
|
167
|
+
rubysl-time (~> 2.0)
|
168
|
+
rubysl-timeout (~> 2.0)
|
169
|
+
rubysl-tmpdir (~> 2.0)
|
170
|
+
rubysl-tsort (~> 2.0)
|
171
|
+
rubysl-un (~> 2.0)
|
172
|
+
rubysl-uri (~> 2.0)
|
173
|
+
rubysl-weakref (~> 2.0)
|
174
|
+
rubysl-webrick (~> 2.0)
|
175
|
+
rubysl-xmlrpc (~> 2.0)
|
176
|
+
rubysl-yaml (~> 2.0)
|
177
|
+
rubysl-zlib (~> 2.0)
|
178
|
+
rubysl-abbrev (2.0.4)
|
179
|
+
rubysl-base64 (2.0.0)
|
180
|
+
rubysl-benchmark (2.0.1)
|
181
|
+
rubysl-bigdecimal (2.0.2)
|
182
|
+
rubysl-cgi (2.0.1)
|
183
|
+
rubysl-cgi-session (2.0.1)
|
184
|
+
rubysl-cmath (2.0.0)
|
185
|
+
rubysl-complex (2.0.0)
|
186
|
+
rubysl-continuation (2.0.0)
|
187
|
+
rubysl-coverage (2.0.3)
|
188
|
+
rubysl-csv (2.0.2)
|
189
|
+
rubysl-english (~> 2.0)
|
190
|
+
rubysl-curses (2.0.1)
|
191
|
+
rubysl-date (2.0.6)
|
192
|
+
rubysl-delegate (2.0.1)
|
193
|
+
rubysl-digest (2.0.3)
|
194
|
+
rubysl-drb (2.0.1)
|
195
|
+
rubysl-e2mmap (2.0.0)
|
196
|
+
rubysl-english (2.0.0)
|
197
|
+
rubysl-enumerator (2.0.0)
|
198
|
+
rubysl-erb (2.0.1)
|
199
|
+
rubysl-etc (2.0.3)
|
200
|
+
ffi2-generators (~> 0.1)
|
201
|
+
rubysl-expect (2.0.0)
|
202
|
+
rubysl-fcntl (2.0.4)
|
203
|
+
ffi2-generators (~> 0.1)
|
204
|
+
rubysl-fiber (2.0.0)
|
205
|
+
rubysl-fileutils (2.0.3)
|
206
|
+
rubysl-find (2.0.1)
|
207
|
+
rubysl-forwardable (2.0.1)
|
208
|
+
rubysl-getoptlong (2.0.0)
|
209
|
+
rubysl-gserver (2.0.0)
|
210
|
+
rubysl-socket (~> 2.0)
|
211
|
+
rubysl-thread (~> 2.0)
|
212
|
+
rubysl-io-console (2.0.0)
|
213
|
+
rubysl-io-nonblock (2.0.0)
|
214
|
+
rubysl-io-wait (2.0.0)
|
215
|
+
rubysl-ipaddr (2.0.0)
|
216
|
+
rubysl-irb (2.0.4)
|
217
|
+
rubysl-e2mmap (~> 2.0)
|
218
|
+
rubysl-mathn (~> 2.0)
|
219
|
+
rubysl-readline (~> 2.0)
|
220
|
+
rubysl-thread (~> 2.0)
|
221
|
+
rubysl-logger (2.0.0)
|
222
|
+
rubysl-mathn (2.0.0)
|
223
|
+
rubysl-matrix (2.1.0)
|
224
|
+
rubysl-e2mmap (~> 2.0)
|
225
|
+
rubysl-mkmf (2.0.1)
|
226
|
+
rubysl-fileutils (~> 2.0)
|
227
|
+
rubysl-shellwords (~> 2.0)
|
228
|
+
rubysl-monitor (2.0.0)
|
229
|
+
rubysl-mutex_m (2.0.0)
|
230
|
+
rubysl-net-ftp (2.0.1)
|
231
|
+
rubysl-net-http (2.0.4)
|
232
|
+
rubysl-cgi (~> 2.0)
|
233
|
+
rubysl-erb (~> 2.0)
|
234
|
+
rubysl-singleton (~> 2.0)
|
235
|
+
rubysl-net-imap (2.0.1)
|
236
|
+
rubysl-net-pop (2.0.1)
|
237
|
+
rubysl-net-protocol (2.0.1)
|
238
|
+
rubysl-net-smtp (2.0.1)
|
239
|
+
rubysl-net-telnet (2.0.0)
|
240
|
+
rubysl-nkf (2.0.1)
|
241
|
+
rubysl-observer (2.0.0)
|
242
|
+
rubysl-open-uri (2.0.0)
|
243
|
+
rubysl-open3 (2.0.0)
|
244
|
+
rubysl-openssl (2.1.0)
|
245
|
+
rubysl-optparse (2.0.1)
|
246
|
+
rubysl-shellwords (~> 2.0)
|
247
|
+
rubysl-ostruct (2.0.4)
|
248
|
+
rubysl-pathname (2.0.0)
|
249
|
+
rubysl-prettyprint (2.0.3)
|
250
|
+
rubysl-prime (2.0.1)
|
251
|
+
rubysl-profile (2.0.0)
|
252
|
+
rubysl-profiler (2.0.1)
|
253
|
+
rubysl-pstore (2.0.0)
|
254
|
+
rubysl-pty (2.0.2)
|
255
|
+
rubysl-rational (2.0.1)
|
256
|
+
rubysl-readline (2.0.2)
|
257
|
+
rubysl-resolv (2.1.0)
|
258
|
+
rubysl-rexml (2.0.2)
|
259
|
+
rubysl-rinda (2.0.1)
|
260
|
+
rubysl-rss (2.0.0)
|
261
|
+
rubysl-scanf (2.0.0)
|
262
|
+
rubysl-securerandom (2.0.0)
|
263
|
+
rubysl-set (2.0.1)
|
264
|
+
rubysl-shellwords (2.0.0)
|
265
|
+
rubysl-singleton (2.0.0)
|
266
|
+
rubysl-socket (2.0.1)
|
267
|
+
rubysl-stringio (2.0.0)
|
268
|
+
rubysl-strscan (2.0.0)
|
269
|
+
rubysl-sync (2.0.0)
|
270
|
+
rubysl-syslog (2.0.1)
|
271
|
+
ffi2-generators (~> 0.1)
|
272
|
+
rubysl-tempfile (2.0.1)
|
273
|
+
rubysl-thread (2.0.2)
|
274
|
+
rubysl-thwait (2.0.0)
|
275
|
+
rubysl-time (2.0.3)
|
276
|
+
rubysl-timeout (2.0.0)
|
277
|
+
rubysl-tmpdir (2.0.1)
|
278
|
+
rubysl-tsort (2.0.1)
|
279
|
+
rubysl-un (2.0.0)
|
280
|
+
rubysl-fileutils (~> 2.0)
|
281
|
+
rubysl-optparse (~> 2.0)
|
282
|
+
rubysl-uri (2.0.0)
|
283
|
+
rubysl-weakref (2.0.0)
|
284
|
+
rubysl-webrick (2.0.0)
|
285
|
+
rubysl-xmlrpc (2.0.0)
|
286
|
+
rubysl-yaml (2.0.4)
|
287
|
+
rubysl-zlib (2.0.1)
|
288
|
+
simplecov (0.8.2)
|
289
|
+
docile (~> 1.1.0)
|
290
|
+
multi_json
|
291
|
+
simplecov-html (~> 0.8.0)
|
292
|
+
simplecov-html (0.8.0)
|
293
|
+
term-ansicolor (1.3.0)
|
294
|
+
tins (~> 1.0)
|
295
|
+
thor (0.19.1)
|
296
|
+
tins (1.3.0)
|
297
|
+
|
298
|
+
PLATFORMS
|
299
|
+
ruby
|
300
|
+
|
301
|
+
DEPENDENCIES
|
302
|
+
aruba (~> 0.5)
|
303
|
+
bundler (~> 1.3)
|
304
|
+
coveralls
|
305
|
+
cucumber (~> 1.3.8)
|
306
|
+
rake (~> 10.1.0)
|
307
|
+
rspec!
|
308
|
+
rspec-change_to_now!
|
309
|
+
rspec-core!
|
310
|
+
rspec-expectations!
|
311
|
+
rspec-mocks!
|
312
|
+
rspec-support!
|
313
|
+
rubysl
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
(The MIT License)
|
2
|
+
|
3
|
+
Copyright (c) 2014 Andrew Brown
|
4
|
+
Copyright (c) 2013 Peter Alfvin
|
5
|
+
Copyright (c) 2012 David Chelimsky, Myron Marston
|
6
|
+
Copyright (c) 2006 David Chelimsky, The RSpec Development Team
|
7
|
+
Copyright (c) 2005 Steven Baker
|
8
|
+
|
9
|
+
MIT License
|
10
|
+
|
11
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
12
|
+
a copy of this software and associated documentation files (the
|
13
|
+
"Software"), to deal in the Software without restriction, including
|
14
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
15
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
16
|
+
permit persons to whom the Software is furnished to do so, subject to
|
17
|
+
the following conditions:
|
18
|
+
|
19
|
+
The above copyright notice and this permission notice shall be
|
20
|
+
included in all copies or substantial portions of the Software.
|
21
|
+
|
22
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
23
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
24
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
25
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
26
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
27
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
28
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
# RSpec::ChangeToNow [`rdoc`](http://rubydoc.info/github/dontfidget/rspec-change_to_now/) [![Build Status](https://travis-ci.org/dontfidget/rspec-change_to_now.png)](https://travis-ci.org/dontfidget/rspec-change_to_now)
|
2
|
+
[![Code Climate](https://codeclimate.com/github/dontfidget/rspec-change_to_now/badges/gpa.svg)](https://codeclimate.com/github/dontfidget/rspec-change_to_now)
|
3
|
+
[![Dependency Status](https://gemnasium.com/dontfidget/rspec-change_to_now.svg)](https://gemnasium.com/dontfidget/rspec-change_to_now)
|
4
|
+
|
5
|
+
RSpec::ChangeTo adds the `to_now` and `not_to_now` methods to `change` matcher to describe how executing a block should change a matcher expectation.
|
6
|
+
|
7
|
+
## Usage
|
8
|
+
|
9
|
+
Use the `to_now` and `not_to_now` (or `not_to`, for short) methods to make assertions about the effect of an rspec `change` block:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
expect { @x = 1 }.to change { @x }.to_now eq 1
|
13
|
+
```
|
14
|
+
|
15
|
+
or
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
expect { @x = 1 }.to change { @x }.not_to eq 2
|
19
|
+
```
|
20
|
+
|
21
|
+
The method `to_now` will check both that the matcher *does not* match prior to the change and that it *does* match after the change. The method `not_to_now` (`not_to` for short) will do the opposite, ensuring that the matcher matches prior to the change, and fails only after the change. All methods will ensure that a change actually takes place.
|
22
|
+
|
23
|
+
Also supported are aliases for those who don't want to split their infinitives and for those who would like to differently split them:
|
24
|
+
|
25
|
+
* `to_now` can also be called as `now_to`
|
26
|
+
* `not_to_now` can also be called `not_to`, `to_not`, `to_not_now` and `not_now_to`
|
27
|
+
|
28
|
+
## Installation
|
29
|
+
|
30
|
+
Add this line to your application's Gemfile:
|
31
|
+
|
32
|
+
gem 'rspec-change_to_now'
|
33
|
+
|
34
|
+
And then execute:
|
35
|
+
|
36
|
+
$ bundle
|
37
|
+
|
38
|
+
Or install it yourself as:
|
39
|
+
|
40
|
+
$ gem install rspec-change_to_now
|
41
|
+
|
42
|
+
And require it as:
|
43
|
+
|
44
|
+
require 'rspec/change_to_now'
|
45
|
+
|
46
|
+
## Why is this useful?
|
47
|
+
|
48
|
+
`change { }.from().to()` adds expectation of pre- and post-conditions for a change, but it is restricted only to object values. With `to_now`, you can write
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
list = []
|
52
|
+
expect { list << :a }.to change { list }.to_now include :a
|
53
|
+
```
|
54
|
+
|
55
|
+
whereas previously you would have to fully specify the original and final values of the list:
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
list = []
|
59
|
+
expect { list << :a }.to change { list }.from([]).to([:a])
|
60
|
+
```
|
61
|
+
|
62
|
+
While that may not seem like a big deal, the real values comes in more complex statements like:
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
person = Person.create(name: 'Taylor')
|
66
|
+
expect { person.siblings.create(name: 'Sam') }.to change { Person.all.map(&:name) }.to_now include('Taylor')
|
67
|
+
```
|
68
|
+
|
69
|
+
Arguably, I should be injecting some dependencies here instead of relying on globals, but Rails code doesn't always look like that. I'm looking forward to playing around with this and seeing if it really helps simplify specs. I'd love to hear your feedback.
|
70
|
+
|
71
|
+
## Additional Matchers Provided
|
72
|
+
|
73
|
+
This gem also provides some additional matchers as detailed below.
|
74
|
+
|
75
|
+
### `negate(&block)`
|
76
|
+
|
77
|
+
This gem also introduces the `negate` matcher, which negates an existing matcher. You can use it like so:
|
78
|
+
|
79
|
+
|
80
|
+
```ruby
|
81
|
+
expect(1).to negate(ne(1))
|
82
|
+
```
|
83
|
+
|
84
|
+
While it doesn't read every well, it serves an internal purpose, allowing a very simple implementation of `to_now` using composable matcher inputs to the `from` and `to` methods as [added in rspec 3.0](http://myronmars.to/n/dev-blog/2014/01/new-in-rspec-3-composable-matchers).
|
85
|
+
|
86
|
+
### `detect(&block)`
|
87
|
+
|
88
|
+
This gem also adds the `detect` matcher, which behaves like the `include` matcher when passed a `satisfy` matcher created using the given block. You can use it like so:
|
89
|
+
|
90
|
+
|
91
|
+
```ruby
|
92
|
+
list = []
|
93
|
+
expect { list << 1 }.to change { list }.to detect(&:even?)
|
94
|
+
```
|
95
|
+
|
96
|
+
This is the same as:
|
97
|
+
|
98
|
+
```ruby
|
99
|
+
list = []
|
100
|
+
expect { list << 1 }.to change { list }.to include satisfy(&:even?)
|
101
|
+
```
|
102
|
+
|
103
|
+
A more interesting use might be:
|
104
|
+
|
105
|
+
```ruby
|
106
|
+
person = Person.create(name: 'Taylor')
|
107
|
+
expect { person.siblings.create(name: 'Sam') }.to change {
|
108
|
+
Person.all
|
109
|
+
}.to_now detect { |person|
|
110
|
+
person.name == 'Taylor'
|
111
|
+
}
|
112
|
+
```
|
113
|
+
|
114
|
+
`detect` behaves exactly like `include` when it is not passed a block and will raise an exception if passed both expected items/matchers and a block.
|
115
|
+
|
116
|
+
## Contributing
|
117
|
+
|
118
|
+
1. Fork it
|
119
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
120
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
121
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
122
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require "bundler"
|
2
|
+
Bundler.setup
|
3
|
+
Bundler::GemHelper.install_tasks
|
4
|
+
|
5
|
+
require "rake"
|
6
|
+
require "rspec/core/rake_task"
|
7
|
+
|
8
|
+
require "cucumber/rake/task"
|
9
|
+
Cucumber::Rake::Task.new(:cucumber)
|
10
|
+
|
11
|
+
desc "Run all examples"
|
12
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
13
|
+
t.ruby_opts = %w[-w]
|
14
|
+
end
|
15
|
+
|
16
|
+
task :default => [:spec, :cucumber]
|
17
|
+
|
data/cucumber.yml
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
Feature: expecting a matcher to change
|
2
|
+
|
3
|
+
Scenario: when the matcher matches only after the block
|
4
|
+
Given a file named "example_spec.rb" with:
|
5
|
+
"""ruby
|
6
|
+
|
7
|
+
describe "adding one" do
|
8
|
+
it "adds one" do
|
9
|
+
x = 1
|
10
|
+
expect { x += 1 }.to change { x }.to_now eq 2
|
11
|
+
end
|
12
|
+
end
|
13
|
+
"""
|
14
|
+
When I run rspec
|
15
|
+
Then the examples should all pass
|
16
|
+
|
17
|
+
Scenario: failures are correctly reported
|
18
|
+
Given a file named "example_spec.rb" with:
|
19
|
+
"""ruby
|
20
|
+
|
21
|
+
describe "adding one" do
|
22
|
+
it "adds one" do
|
23
|
+
x = 1
|
24
|
+
expect { x += 1 }.to change { x }.to_now eq 3
|
25
|
+
end
|
26
|
+
end
|
27
|
+
"""
|
28
|
+
When I run rspec
|
29
|
+
Then the output should contain "Failure/Error: expect { x += 1 }.to change { x }.to_now eq 3"
|
@@ -0,0 +1,28 @@
|
|
1
|
+
Feature: detect matcher
|
2
|
+
|
3
|
+
Scenario: when the matcher matches
|
4
|
+
Given a file named "example_spec.rb" with:
|
5
|
+
"""ruby
|
6
|
+
|
7
|
+
describe "detecting even numbers" do
|
8
|
+
it "detects even" do
|
9
|
+
expect([2]).to detect(&:even?)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
"""
|
13
|
+
When I run rspec
|
14
|
+
Then the examples should all pass
|
15
|
+
|
16
|
+
Scenario: failures are correctly reported
|
17
|
+
Given a file named "example_spec.rb" with:
|
18
|
+
"""ruby
|
19
|
+
|
20
|
+
describe "detecting even numbers" do
|
21
|
+
it "fails for odd numbers" do
|
22
|
+
expect([1]).to detect(&:even?)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
"""
|
26
|
+
When I run rspec
|
27
|
+
Then the output should contain "Failure/Error: expect([1]).to detect(&:even?)"
|
28
|
+
And the output should contain "expected [1] to include (satisfy block)"
|
@@ -0,0 +1,29 @@
|
|
1
|
+
Feature: negating a matcher
|
2
|
+
|
3
|
+
Scenario: when the matcher is negated
|
4
|
+
Given a file named "example_spec.rb" with:
|
5
|
+
"""ruby
|
6
|
+
|
7
|
+
describe "testing equality" do
|
8
|
+
it "is the same as negated inequality" do
|
9
|
+
expect(1).to negate(eq(2))
|
10
|
+
end
|
11
|
+
end
|
12
|
+
"""
|
13
|
+
When I run rspec
|
14
|
+
Then the examples should all pass
|
15
|
+
|
16
|
+
Scenario: failures are correctly reported
|
17
|
+
Given a file named "example_spec.rb" with:
|
18
|
+
"""ruby
|
19
|
+
|
20
|
+
describe "testing equality" do
|
21
|
+
it "fails if the the negated matcher does match" do
|
22
|
+
expect(1).to negate(eq(1))
|
23
|
+
end
|
24
|
+
end
|
25
|
+
"""
|
26
|
+
When I run rspec
|
27
|
+
Then the output should contain "Failure/Error: expect(1).to negate(eq(1))"
|
28
|
+
And the output should contain "expected: value != 1"
|
29
|
+
|
@@ -0,0 +1,13 @@
|
|
1
|
+
When /^I run rspec( with the documentation option)?$/ do |documentation|
|
2
|
+
rspec_change_to_now_gem_location = File.expand_path('../../../lib/rspec/change_to_now', __FILE__)
|
3
|
+
require_option = "--require #{rspec_change_to_now_gem_location}"
|
4
|
+
format_option = documentation ? "--format documentation" : ""
|
5
|
+
rspec_command = ['rspec', require_option, format_option, 'example_spec.rb'].join(' ')
|
6
|
+
step "I run `#{rspec_command}`"
|
7
|
+
end
|
8
|
+
|
9
|
+
Then /^the example(?:s)? should(?: all)? pass$/ do
|
10
|
+
step %q{the output should contain "0 failures"}
|
11
|
+
step %q{the output should not contain "0 examples"}
|
12
|
+
step %q{the exit status should be 0}
|
13
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'aruba/cucumber'
|
2
|
+
require 'rspec/core'
|
3
|
+
require 'rspec/change_to_now'
|
4
|
+
|
5
|
+
Before do
|
6
|
+
if RUBY_PLATFORM =~ /java/ || defined?(Rubinius)
|
7
|
+
@aruba_timeout_seconds = 60
|
8
|
+
else
|
9
|
+
@aruba_timeout_seconds = 10
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
Aruba.configure do |config|
|
14
|
+
config.before_cmd do |cmd|
|
15
|
+
set_env('JRUBY_OPTS', "-X-C #{ENV['JRUBY_OPTS']}") # disable JIT since these processes are so short lived
|
16
|
+
end
|
17
|
+
end if RUBY_PLATFORM == 'java'
|
18
|
+
|
19
|
+
Aruba.configure do |config|
|
20
|
+
config.before_cmd do |cmd|
|
21
|
+
set_env('RBXOPT', "-Xint=true #{ENV['RBXOPT']}") # disable JIT since these processes are so short lived
|
22
|
+
end
|
23
|
+
end if defined?(Rubinius)
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'rspec/core'
|
2
|
+
require 'rspec/expectations'
|
3
|
+
|
4
|
+
module RSpec
|
5
|
+
module Matchers
|
6
|
+
# @api private
|
7
|
+
# Provides the implementation for `detect`.
|
8
|
+
# Not intended to be instantiated directly.
|
9
|
+
class Detect < BuiltIn::Include
|
10
|
+
def initialize(*expected, &block)
|
11
|
+
if @block = block
|
12
|
+
block_matcher = RSpec::Matchers::BuiltIn::Satisfy.new(&block)
|
13
|
+
expected << block_matcher
|
14
|
+
end
|
15
|
+
super(*expected)
|
16
|
+
end
|
17
|
+
|
18
|
+
# @api private
|
19
|
+
# @return [Boolean]
|
20
|
+
def matches?(actual)
|
21
|
+
handle_arguments_for_match(actual) do |new_actual|
|
22
|
+
super(new_actual)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# @api private
|
27
|
+
# @return [Boolean]
|
28
|
+
def does_not_match?(actual)
|
29
|
+
handle_arguments_for_match(actual) do |new_actual|
|
30
|
+
super(new_actual)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# @api private
|
35
|
+
# @return [String]
|
36
|
+
def failure_message
|
37
|
+
check_arguments || super
|
38
|
+
end
|
39
|
+
|
40
|
+
# @api private
|
41
|
+
# @return [String]
|
42
|
+
def failure_message_when_negated
|
43
|
+
check_arguments || super
|
44
|
+
end
|
45
|
+
|
46
|
+
# @api private
|
47
|
+
# @return [Boolean]
|
48
|
+
def diffable?
|
49
|
+
@block.nil?
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def block_and_arguments_together_failure_message
|
55
|
+
"detect can take arguments or a block but not both"
|
56
|
+
end
|
57
|
+
|
58
|
+
def has_both_block_and_arguments?
|
59
|
+
@block && @expected.length > 1
|
60
|
+
end
|
61
|
+
|
62
|
+
def check_arguments
|
63
|
+
block_and_arguments_together_failure_message if has_both_block_and_arguments?
|
64
|
+
end
|
65
|
+
|
66
|
+
def handle_arguments_for_match(actual)
|
67
|
+
return false if has_both_block_and_arguments?
|
68
|
+
original_actual = actual
|
69
|
+
actual = actual.to_a if @block && actual.is_a?(Hash)
|
70
|
+
value = yield(actual)
|
71
|
+
@actual = original_actual
|
72
|
+
value
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# If given a block, passes if the block returns a truthy value for any of the actual items or for the key-value pair is the actual item list is a hash.
|
77
|
+
# Without a block, it behaves identically to +include+.
|
78
|
+
# +expected+ must be empty if a block is provided.
|
79
|
+
#
|
80
|
+
# @example
|
81
|
+
# expect([2]).to detect(&:even?)
|
82
|
+
# expect({a: 2}).to detect { |k,v| v.even? }
|
83
|
+
# expect([1]).to detect 1
|
84
|
+
def detect(*expected, &block)
|
85
|
+
AliasedMatcher.new(Detect.new(*expected, &block), lambda do |old_desc|
|
86
|
+
old_desc.gsub(Pretty.split_words('include'), Pretty.split_words('detect'))
|
87
|
+
end)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'rspec/core'
|
2
|
+
require 'rspec/expectations'
|
3
|
+
|
4
|
+
module RSpec
|
5
|
+
module Matchers
|
6
|
+
# @api private
|
7
|
+
# Provides the implementation for `negate`.
|
8
|
+
# Not intended to be instantiated directly.
|
9
|
+
class Negate
|
10
|
+
include Composable
|
11
|
+
include Pretty
|
12
|
+
|
13
|
+
def initialize(matcher)
|
14
|
+
@matcher = matcher
|
15
|
+
end
|
16
|
+
|
17
|
+
# @api private
|
18
|
+
# @return [Boolean]
|
19
|
+
def matches?(*args, &block)
|
20
|
+
if @matcher.respond_to?(:does_not_match?)
|
21
|
+
@matcher.does_not_match?(*args, &block)
|
22
|
+
else
|
23
|
+
!@matcher.matches?(*args, &block)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# @api private
|
28
|
+
# @return [Boolean]
|
29
|
+
def does_not_match?(*args, &block)
|
30
|
+
@matcher.matches?(*args, &block)
|
31
|
+
end
|
32
|
+
|
33
|
+
# @private
|
34
|
+
# @return [String]
|
35
|
+
def failure_message
|
36
|
+
if @matcher.respond_to? :failure_message_when_negated
|
37
|
+
@matcher.failure_message_when_negated
|
38
|
+
elsif @matcher.respond_to :description
|
39
|
+
"expected #{surface_descriptions_in(@actual).inspect} not to #{surface_descriptions_in(@matcher).inspect}"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# @api private
|
44
|
+
# @return [String]
|
45
|
+
def failure_message_when_negated
|
46
|
+
failure_message
|
47
|
+
end
|
48
|
+
|
49
|
+
# @api private
|
50
|
+
# @return [String]
|
51
|
+
def description
|
52
|
+
"~#{surface_descriptions_in(@matcher).inspect}"
|
53
|
+
end
|
54
|
+
|
55
|
+
# @api private
|
56
|
+
# @return [Boolean]
|
57
|
+
def supports_block_expectations?
|
58
|
+
@matcher.supports_block_expectations?
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# Passes if provided +matcher+ fails and vice-versa.
|
63
|
+
#
|
64
|
+
# @example
|
65
|
+
# expect([1]).to negate(eq(2))
|
66
|
+
# expect([1]).not_to negate(eq(1))
|
67
|
+
def negate(matcher)
|
68
|
+
Negate.new(matcher)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'rspec/change_to_now/version'
|
2
|
+
require 'rspec/change_to_now/detect'
|
3
|
+
require 'rspec/change_to_now/negate'
|
4
|
+
require 'rspec/core'
|
5
|
+
require 'rspec/expectations'
|
6
|
+
|
7
|
+
module RSpec::Matchers
|
8
|
+
class BuiltIn::Change
|
9
|
+
# @api public
|
10
|
+
# Passes if +matcher+ fails on the result of the change block before the expectation block and passes after.
|
11
|
+
#
|
12
|
+
# @example
|
13
|
+
# expect({ @x = 1 }.to change { @x }.to_now eq 1
|
14
|
+
#
|
15
|
+
# In implementation, this is identical to
|
16
|
+
# change {}.to eq { }`
|
17
|
+
# is the same as
|
18
|
+
# change {}.to_now eq(1)
|
19
|
+
# change {}.from(negate(eq(1))).to(eq(1))
|
20
|
+
def to_now(matcher)
|
21
|
+
RSpec::Matchers::BuiltIn::ChangeToValue.new(@change_details, matcher).from(negate(matcher))
|
22
|
+
end
|
23
|
+
|
24
|
+
# @api public
|
25
|
+
# Passes if +matcher+ passes on the result of the change block before the expectation block and fails after.
|
26
|
+
#
|
27
|
+
# @example
|
28
|
+
# expect({ @x = 1 }.to change { @x }.not_to_now eq 1
|
29
|
+
def not_to_now(matcher)
|
30
|
+
RSpec::Matchers::BuiltIn::ChangeToValue.new(@change_details, negate(matcher)).from(matcher)
|
31
|
+
end
|
32
|
+
|
33
|
+
# @api public
|
34
|
+
alias_method :now_to, :to_now
|
35
|
+
|
36
|
+
# @api public
|
37
|
+
alias_method :not_to, :not_to_now
|
38
|
+
|
39
|
+
# @api public
|
40
|
+
alias_method :not_now_to, :not_to_now
|
41
|
+
|
42
|
+
# @api public
|
43
|
+
alias_method :to_not, :not_to_now
|
44
|
+
|
45
|
+
# @api public
|
46
|
+
alias_method :to_not_now, :not_to_now
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
# @private
|
51
|
+
def negate(matcher)
|
52
|
+
RSpec::Matchers::Negate.new(matcher)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'rspec/change_to_now/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "rspec-change_to_now"
|
8
|
+
spec.version = RSpec::ChangeToNow::VERSION
|
9
|
+
spec.authors = ["Andrew S. Brown"]
|
10
|
+
spec.email = ["andrew@dontfidget.com"]
|
11
|
+
spec.description = %q{RSpec extension gem for attribute matching}
|
12
|
+
spec.summary = %q{Provides "change_to_now" method formally part of rspec-core}
|
13
|
+
spec.homepage = "https://github.com/dontfidget/rspec-change_to_now"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_runtime_dependency 'rspec-core', '>= 3.0.0'
|
22
|
+
spec.add_runtime_dependency 'rspec-expectations', '>= 3.0.0'
|
23
|
+
spec.add_development_dependency 'cucumber', '~> 1.3.8'
|
24
|
+
spec.add_development_dependency 'bundler', '~> 1.3'
|
25
|
+
spec.add_development_dependency 'rake', '~> 10.1.0'
|
26
|
+
spec.add_development_dependency 'aruba', '~> 0.5'
|
27
|
+
end
|
data/script/test_all
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
set -e -x
|
4
|
+
|
5
|
+
# idea taken from: http://blog.headius.com/2010/03/jruby-startup-time-tips.html
|
6
|
+
export JRUBY_OPTS='-X-C' # disable JIT since these processes are so short lived
|
7
|
+
|
8
|
+
# force jRuby to use client mode JVM or a compilation mode thats as close as possible,
|
9
|
+
# idea taken from https://github.com/jruby/jruby/wiki/Improving-startup-time
|
10
|
+
export JAVA_OPTS='-client -XX:+TieredCompilation -XX:TieredStopAtLevel=1'
|
11
|
+
|
12
|
+
echo "Running rspec specs"
|
13
|
+
bin/rspec spec --format progress --profile
|
14
|
+
|
15
|
+
echo "Running cucumber specs"
|
16
|
+
# TODO: it would be nice to figure out how to run the cukes w/o the overhead of
|
17
|
+
# bundler, but just running `bin/cucumber` can fail due to the fact that it
|
18
|
+
# shells out (via aruba) and executes `rspec`--which can pick up the wrong
|
19
|
+
# rspec version if we're not running with bundler.
|
20
|
+
bundle exec cucumber
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
describe Matchers::BuiltIn::Change do
|
5
|
+
describe "#to_now" do
|
6
|
+
it "succeeds when the condition changes to the expected state" do
|
7
|
+
number = 1
|
8
|
+
expect {
|
9
|
+
number += 1
|
10
|
+
}.to change { number }.to_now eq 2
|
11
|
+
end
|
12
|
+
it "fails when there is no change" do
|
13
|
+
number = 1
|
14
|
+
expect {
|
15
|
+
expect {
|
16
|
+
}.to change { number }.to_now eq 2
|
17
|
+
}.to fail_matching("expected result to have changed to eq 2 from ~(eq 2), but did not change")
|
18
|
+
end
|
19
|
+
it "fails without an expectation block" do
|
20
|
+
expect {
|
21
|
+
expect(1).to change { }.to_now eq 2
|
22
|
+
}.to fail_matching("was not given a block")
|
23
|
+
end
|
24
|
+
it "fails when the final expectation is never met" do
|
25
|
+
number = 1
|
26
|
+
expect {
|
27
|
+
expect {
|
28
|
+
number += 1
|
29
|
+
}.to change { number }.to_now eq 3
|
30
|
+
}.to fail_matching("expected result to have changed to eq 3, but is now 2")
|
31
|
+
end
|
32
|
+
it "fails when the final expectation is already met" do
|
33
|
+
number = 2
|
34
|
+
expect {
|
35
|
+
expect {
|
36
|
+
number += 1
|
37
|
+
}.to change { number }.to_now eq 2
|
38
|
+
}.to fail_matching("expected result to have initially been ~(eq 2), but was 2")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "#not_to" do
|
43
|
+
it "succeeds when the final expectation is met" do
|
44
|
+
number = 1
|
45
|
+
expect {
|
46
|
+
number += 2
|
47
|
+
}.to change { number }.not_to eq 1
|
48
|
+
end
|
49
|
+
it "fails when there is no change" do
|
50
|
+
number = 1
|
51
|
+
expect {
|
52
|
+
expect {
|
53
|
+
}.to change { number }.not_to eq 1
|
54
|
+
}.to fail_matching("expected result to have changed to ~(eq 1) from eq 1, but did not change")
|
55
|
+
end
|
56
|
+
it "fails when the final expectation is already met" do
|
57
|
+
number = 2
|
58
|
+
expect {
|
59
|
+
expect {
|
60
|
+
}.to change { number }.not_to eq 1
|
61
|
+
}.to fail_matching("expected result to have initially been eq 1, but was 2")
|
62
|
+
end
|
63
|
+
it "fails when the final expectation is never met" do
|
64
|
+
number = 2
|
65
|
+
expect {
|
66
|
+
expect {
|
67
|
+
number = 4
|
68
|
+
}.to change { number }.not_to satisfy(&:even?)
|
69
|
+
}.to fail_matching("expected result to have changed to ~(satisfy block), but is now 4")
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "aliases" do
|
74
|
+
before do
|
75
|
+
@x = nil
|
76
|
+
end
|
77
|
+
|
78
|
+
it "specify #now_to is the same as #to_now" do
|
79
|
+
expect { @x = 1 }.to change { @x }.now_to eq 1
|
80
|
+
end
|
81
|
+
|
82
|
+
describe "negative cases" do
|
83
|
+
specify "#to_not is the same as #not_to" do
|
84
|
+
expect { @x = 1 }.to change { @x }.to_not eq nil
|
85
|
+
end
|
86
|
+
|
87
|
+
specify "#to_not_now is the same as #not_to_now" do
|
88
|
+
expect { @x = 1 }.to change { @x }.to_not_now eq nil
|
89
|
+
end
|
90
|
+
|
91
|
+
specify "#not_now to_is the same as #not_to_now" do
|
92
|
+
expect { @x = 1 }.to change { @x }.not_now_to eq nil
|
93
|
+
end
|
94
|
+
|
95
|
+
specify "#to_not_now to_is the same as #not_to_now" do
|
96
|
+
expect { @x = 1 }.to change { @x }.to_not_now eq nil
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe "#detect matcher" do
|
4
|
+
describe "expect(...).to detect(&with_block)" do
|
5
|
+
context "for an array target" do
|
6
|
+
it "passes if target detects expected" do
|
7
|
+
expect([1,2,3]).to detect(&:even?)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "fails if target does not detect expected" do
|
11
|
+
expect {
|
12
|
+
expect([1,3]).to detect(&:even?)
|
13
|
+
}.to fail_matching("expected [1, 3] to include (satisfy block)")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context "for a hash target" do
|
18
|
+
it 'passes if target has the expected as a key' do
|
19
|
+
expect({:key => 0}).to detect { |key,value| value.even? }
|
20
|
+
end
|
21
|
+
|
22
|
+
it "fails if target does not detect expected" do
|
23
|
+
expect {
|
24
|
+
expect({:key => 1}).to detect { |key,value| value.even? }
|
25
|
+
}.to fail_matching("expected {:key => 1} to include (satisfy block)")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "expect(...).not_to detect(&with_block)" do
|
31
|
+
context "for an array target" do
|
32
|
+
it "passes if target detects expected" do
|
33
|
+
expect([1,3]).not_to detect(&:even?)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "fails if target does not detect expected" do
|
37
|
+
expect {
|
38
|
+
expect([1,3]).not_to detect(&:odd?)
|
39
|
+
}.to fail_matching("expected [1, 3] not to include (satisfy block)")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context "for a hash target" do
|
44
|
+
it 'passes if target has the expected as a key' do
|
45
|
+
expect({:key => 0}).not_to detect { |key,value| value.odd? }
|
46
|
+
end
|
47
|
+
|
48
|
+
it "fails if target does not detect expected" do
|
49
|
+
expect {
|
50
|
+
expect({:key => 1}).not_to detect { |key,value| value.odd? }
|
51
|
+
}.to fail_matching("expected {:key => 1} not to include (satisfy block)")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "expect(...).to detect(with, args, and, &block)" do
|
57
|
+
it "fails with a message" do
|
58
|
+
expect {
|
59
|
+
expect([0, 1]).to detect(0) { true }
|
60
|
+
}.to fail_matching(%Q{can take arguments or a block but not both})
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "expect(...).not_to detect(with, args, and, &block)" do
|
65
|
+
it "fails with a message" do
|
66
|
+
expect {
|
67
|
+
expect([0, 1]).not_to detect(0) { true }
|
68
|
+
}.to fail_matching(%Q{can take arguments or a block but not both})
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe RSpec::Matchers::Negate do
|
4
|
+
describe "with literal expectations" do
|
5
|
+
it "passes if the original matcher fails" do
|
6
|
+
expect(1).to negate(eq(2))
|
7
|
+
end
|
8
|
+
it "fails if the original matcher passes" do
|
9
|
+
expect {
|
10
|
+
expect(1).to negate(eq(1))
|
11
|
+
}.to fail_matching(/expected: value != 1.*got: 1/m)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "with block expectations" do
|
16
|
+
before do
|
17
|
+
@x = 1
|
18
|
+
end
|
19
|
+
|
20
|
+
it "fails for `change` because it doesn't support negation" do
|
21
|
+
expect {
|
22
|
+
expect {@x += 1}.to negate(change { @x }.to(1))
|
23
|
+
}.to raise_error(NotImplementedError,
|
24
|
+
"`expect { }.not_to change { }.to()` is not supported")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rspec/change_to_now'
|
2
|
+
require 'rspec/mocks'
|
3
|
+
|
4
|
+
Dir['./spec/support/**/*'].each {|f| require f}
|
5
|
+
|
6
|
+
class NullFormatter
|
7
|
+
private
|
8
|
+
def method_missing(method, *args, &block)
|
9
|
+
# ignore
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
RSpec.configure do |config|
|
14
|
+
config.run_all_when_everything_filtered = true
|
15
|
+
config.order = 'random'
|
16
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module RSpec
|
2
|
+
module Matchers
|
3
|
+
def fail
|
4
|
+
raise_error(RSpec::Expectations::ExpectationNotMetError)
|
5
|
+
end
|
6
|
+
|
7
|
+
def fail_with(message)
|
8
|
+
raise_error(RSpec::Expectations::ExpectationNotMetError, message)
|
9
|
+
end
|
10
|
+
|
11
|
+
def fail_matching(message)
|
12
|
+
if String === message
|
13
|
+
regexp = /#{Regexp.escape(message)}/
|
14
|
+
else
|
15
|
+
regexp = message
|
16
|
+
end
|
17
|
+
raise_error(RSpec::Expectations::ExpectationNotMetError, regexp)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
metadata
ADDED
@@ -0,0 +1,163 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rspec-change_to_now
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Andrew S. Brown
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-08-02 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rspec-core
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 3.0.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 3.0.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec-expectations
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 3.0.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 3.0.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: cucumber
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 1.3.8
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.3.8
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bundler
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.3'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.3'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 10.1.0
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 10.1.0
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: aruba
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0.5'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0.5'
|
97
|
+
description: RSpec extension gem for attribute matching
|
98
|
+
email:
|
99
|
+
- andrew@dontfidget.com
|
100
|
+
executables: []
|
101
|
+
extensions: []
|
102
|
+
extra_rdoc_files: []
|
103
|
+
files:
|
104
|
+
- ".gitignore"
|
105
|
+
- Changelog.md
|
106
|
+
- Gemfile
|
107
|
+
- Gemfile.lock
|
108
|
+
- LICENSE.txt
|
109
|
+
- README.md
|
110
|
+
- Rakefile
|
111
|
+
- cucumber.yml
|
112
|
+
- features/change_to_now.feature
|
113
|
+
- features/detect.feature
|
114
|
+
- features/negate.feature
|
115
|
+
- features/step_definitions/additional_cli_steps.rb
|
116
|
+
- features/support/env.rb
|
117
|
+
- lib/rspec/change_to_now.rb
|
118
|
+
- lib/rspec/change_to_now/detect.rb
|
119
|
+
- lib/rspec/change_to_now/negate.rb
|
120
|
+
- lib/rspec/change_to_now/version.rb
|
121
|
+
- rspec-change_to_now.gemspec
|
122
|
+
- script/test_all
|
123
|
+
- spec/rspec/change_to_now_spec.rb
|
124
|
+
- spec/rspec/detect_spec.rb
|
125
|
+
- spec/rspec/negate_spec.rb
|
126
|
+
- spec/spec_helper.rb
|
127
|
+
- spec/support/matchers.rb
|
128
|
+
homepage: https://github.com/dontfidget/rspec-change_to_now
|
129
|
+
licenses:
|
130
|
+
- MIT
|
131
|
+
metadata: {}
|
132
|
+
post_install_message:
|
133
|
+
rdoc_options: []
|
134
|
+
require_paths:
|
135
|
+
- lib
|
136
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
137
|
+
requirements:
|
138
|
+
- - ">="
|
139
|
+
- !ruby/object:Gem::Version
|
140
|
+
version: '0'
|
141
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
requirements: []
|
147
|
+
rubyforge_project:
|
148
|
+
rubygems_version: 2.2.2
|
149
|
+
signing_key:
|
150
|
+
specification_version: 4
|
151
|
+
summary: Provides "change_to_now" method formally part of rspec-core
|
152
|
+
test_files:
|
153
|
+
- features/change_to_now.feature
|
154
|
+
- features/detect.feature
|
155
|
+
- features/negate.feature
|
156
|
+
- features/step_definitions/additional_cli_steps.rb
|
157
|
+
- features/support/env.rb
|
158
|
+
- spec/rspec/change_to_now_spec.rb
|
159
|
+
- spec/rspec/detect_spec.rb
|
160
|
+
- spec/rspec/negate_spec.rb
|
161
|
+
- spec/spec_helper.rb
|
162
|
+
- spec/support/matchers.rb
|
163
|
+
has_rdoc:
|