minispec 0.0.1

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.
Files changed (83) hide show
  1. checksums.yaml +7 -0
  2. data/.pryrc +2 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE +22 -0
  5. data/README.md +2140 -0
  6. data/Rakefile +11 -0
  7. data/bin/minispec +4 -0
  8. data/lib/minispec.rb +175 -0
  9. data/lib/minispec/api.rb +2 -0
  10. data/lib/minispec/api/class.rb +195 -0
  11. data/lib/minispec/api/class/after.rb +49 -0
  12. data/lib/minispec/api/class/around.rb +54 -0
  13. data/lib/minispec/api/class/before.rb +101 -0
  14. data/lib/minispec/api/class/helpers.rb +116 -0
  15. data/lib/minispec/api/class/let.rb +44 -0
  16. data/lib/minispec/api/class/tests.rb +33 -0
  17. data/lib/minispec/api/instance.rb +158 -0
  18. data/lib/minispec/api/instance/mocks/doubles.rb +36 -0
  19. data/lib/minispec/api/instance/mocks/mocks.rb +319 -0
  20. data/lib/minispec/api/instance/mocks/spies.rb +17 -0
  21. data/lib/minispec/api/instance/mocks/stubs.rb +105 -0
  22. data/lib/minispec/helpers.rb +1 -0
  23. data/lib/minispec/helpers/array.rb +56 -0
  24. data/lib/minispec/helpers/booleans.rb +108 -0
  25. data/lib/minispec/helpers/generic.rb +24 -0
  26. data/lib/minispec/helpers/mocks/expectations.rb +29 -0
  27. data/lib/minispec/helpers/mocks/spies.rb +36 -0
  28. data/lib/minispec/helpers/raise.rb +44 -0
  29. data/lib/minispec/helpers/throw.rb +29 -0
  30. data/lib/minispec/mocks.rb +11 -0
  31. data/lib/minispec/mocks/expectations.rb +77 -0
  32. data/lib/minispec/mocks/stubs.rb +178 -0
  33. data/lib/minispec/mocks/validations.rb +80 -0
  34. data/lib/minispec/mocks/validations/amount.rb +63 -0
  35. data/lib/minispec/mocks/validations/arguments.rb +161 -0
  36. data/lib/minispec/mocks/validations/caller.rb +43 -0
  37. data/lib/minispec/mocks/validations/order.rb +47 -0
  38. data/lib/minispec/mocks/validations/raise.rb +111 -0
  39. data/lib/minispec/mocks/validations/return.rb +74 -0
  40. data/lib/minispec/mocks/validations/throw.rb +91 -0
  41. data/lib/minispec/mocks/validations/yield.rb +141 -0
  42. data/lib/minispec/proxy.rb +201 -0
  43. data/lib/minispec/reporter.rb +185 -0
  44. data/lib/minispec/utils.rb +139 -0
  45. data/lib/minispec/utils/differ.rb +325 -0
  46. data/lib/minispec/utils/pretty_print.rb +51 -0
  47. data/lib/minispec/utils/raise.rb +123 -0
  48. data/lib/minispec/utils/throw.rb +140 -0
  49. data/minispec.gemspec +27 -0
  50. data/test/mocks/expectations/amount.rb +67 -0
  51. data/test/mocks/expectations/arguments.rb +126 -0
  52. data/test/mocks/expectations/caller.rb +55 -0
  53. data/test/mocks/expectations/generic.rb +35 -0
  54. data/test/mocks/expectations/order.rb +46 -0
  55. data/test/mocks/expectations/raise.rb +166 -0
  56. data/test/mocks/expectations/return.rb +71 -0
  57. data/test/mocks/expectations/throw.rb +113 -0
  58. data/test/mocks/expectations/yield.rb +109 -0
  59. data/test/mocks/spies/amount.rb +68 -0
  60. data/test/mocks/spies/arguments.rb +57 -0
  61. data/test/mocks/spies/generic.rb +61 -0
  62. data/test/mocks/spies/order.rb +38 -0
  63. data/test/mocks/spies/raise.rb +158 -0
  64. data/test/mocks/spies/return.rb +71 -0
  65. data/test/mocks/spies/throw.rb +113 -0
  66. data/test/mocks/spies/yield.rb +101 -0
  67. data/test/mocks/test__doubles.rb +98 -0
  68. data/test/mocks/test__expectations.rb +27 -0
  69. data/test/mocks/test__mocks.rb +197 -0
  70. data/test/mocks/test__proxies.rb +61 -0
  71. data/test/mocks/test__spies.rb +43 -0
  72. data/test/mocks/test__stubs.rb +427 -0
  73. data/test/proxified_asserts.rb +34 -0
  74. data/test/setup.rb +53 -0
  75. data/test/test__around.rb +58 -0
  76. data/test/test__assert.rb +510 -0
  77. data/test/test__before_and_after.rb +117 -0
  78. data/test/test__before_and_after_all.rb +71 -0
  79. data/test/test__helpers.rb +197 -0
  80. data/test/test__raise.rb +104 -0
  81. data/test/test__skip.rb +41 -0
  82. data/test/test__throw.rb +103 -0
  83. metadata +196 -0
@@ -0,0 +1,61 @@
1
+ class MinispecTest
2
+ class Proxies < self
3
+ class Unit
4
+ include Minispec
5
+
6
+ def restore_originals
7
+ __ms__mocks__restore_originals
8
+ end
9
+
10
+ class O
11
+ def x; __method__; end
12
+
13
+ protected
14
+ def y; __method__; end
15
+
16
+ private
17
+ def z; __method__; end
18
+ end
19
+
20
+ let(:o) { O.new }
21
+
22
+ it 'is proxying only once' do
23
+ proxy(o, :x)
24
+ position = @__ms__proxies[o].index(:x)
25
+ assert(position).not.nil?
26
+ proxy(o, :x)
27
+ expect(o).to_receive(:x)
28
+ o.x
29
+ assert(@__ms__proxies[o][position]) == :x
30
+ end
31
+
32
+ it 'is proxying public methods' do
33
+ proxy(o, :x)
34
+ expect(o).to_receive(:x)
35
+ assert(o.x) == :x
36
+ assert(o).received(:x)
37
+ end
38
+
39
+ it 'is proxying protected methods' do
40
+ proxy(o, :y)
41
+ expect(o).to_receive(:y)
42
+ assert(o.send(:y)) == :y
43
+ assert(o).received(:y)
44
+ end
45
+
46
+ it 'is proxying private methods' do
47
+ proxy(o, :z)
48
+ expect(o).to_receive(:z)
49
+ assert(o.send(:z)) == :z
50
+ assert(o).received(:z)
51
+ end
52
+
53
+ should 'raise NoMethodError when trying to proxify an un-existing method' do
54
+ does { proxy(o, :a) }.raise? NoMethodError
55
+ end
56
+
57
+ end
58
+
59
+ define_tests(Unit)
60
+ end
61
+ end
@@ -0,0 +1,43 @@
1
+ class MinispecTest
2
+ class Spies < self
3
+
4
+ class O
5
+ def a(*a); :a; end
6
+ def b(*a); :b; end
7
+ def c(*a); :c; end
8
+ def d; :d; end
9
+ def e; raise(ArgumentError, 'some blah'); end
10
+ def r; raise(ArgumentError, 'some blah'); end
11
+ def t; throw(:s); end
12
+ def w; throw(:s); end
13
+ def x(&b); yield(1, 2); end
14
+ def y(&b); yield(1, 2); end
15
+ def z; :a; end
16
+ end
17
+
18
+ class Unit
19
+ include Minispec
20
+ continue_on_failures true
21
+ let(:o) { O.new }
22
+ before do
23
+ %w[
24
+ a
25
+ b
26
+ c
27
+ d
28
+ e
29
+ r
30
+ t
31
+ w
32
+ x
33
+ y
34
+ z
35
+ ].each {|m| proxy(o, m.to_sym)}
36
+ end
37
+ end
38
+
39
+ Dir[File.expand_path('../spies/*.rb', __FILE__)].each {|f| require(f)}
40
+
41
+ define_tests(Unit)
42
+ end
43
+ end
@@ -0,0 +1,427 @@
1
+ class MinispecTest
2
+ class Stubs < self
3
+ class Unit
4
+ include Minispec
5
+ continue_on_failures true
6
+
7
+ def restore_originals
8
+ __ms__mocks__restore_originals
9
+ end
10
+
11
+ let(:o) { Object.new }
12
+
13
+ it 'creates stubs' do
14
+ stub(o, :a)
15
+ does(o).respond_to?(:a)
16
+ end
17
+
18
+ it 'uses hash value as return value' do
19
+ stub(o, a: :x, b: :y)
20
+ does(o).respond_to?(:a)
21
+ is(o.a) == :x
22
+ does(o).respond_to?(:b)
23
+ is(o.b) == :y
24
+ end
25
+
26
+ it 'raise ArgumentError when using constraints on Hash stubs' do
27
+ does { stub(o, a: :b).with(1) {1} }.raise?(ArgumentError, /can not be used/i)
28
+ # though error raised, methods should be successfully stubbed
29
+ assert(o.a) == :b
30
+ end
31
+
32
+ it 'calls given block' do
33
+ stub(o, :a) {:x}
34
+ does(o).respond_to?(:a)
35
+ is(o.a) == :x
36
+ end
37
+
38
+ it 'calls the block associated with given args' do
39
+ stub(o, :a).with(1, 2) {:ot}
40
+ is(o.a(1, 2)) == :ot
41
+
42
+ stub(o, :a).with(4, 5) {:ff}
43
+ is(o.a(4, 5)) == :ff
44
+
45
+ stub(o, :a).with(:x) {:x}
46
+ is(o.a(:x)) == :x
47
+ end
48
+
49
+ it 'calls the main block if no block associated with given args' do
50
+ stub(o, :a) {:main}
51
+ stub(o, :a).with(1) {1}
52
+ is(o.a) == :main
53
+ is(o.a(1)) == 1
54
+ is(o.a(2)) == :main
55
+ end
56
+
57
+ it 'returns nil if no main block nor block associated with given args' do
58
+ o = Class.new do
59
+ def a; :a; end
60
+ end.new
61
+ stub(o, :a).with(1) {1}
62
+ is(o.a(1)) == 1
63
+ is(o.a).nil?
64
+ end
65
+
66
+ it 'returns nil if no main block nor block associated with given args nor original defined' do
67
+ stub(o, :a)
68
+ is(o.a).nil?
69
+ end
70
+
71
+ it 'pass original as first argument' do
72
+ o = Class.new do
73
+ attr_reader :original_called
74
+ def a; @original_called = true; end
75
+ end.new
76
+ stub(o, :a) do |original|
77
+ is(o.original_called).nil?
78
+ original.call
79
+ is(o.original_called).true?
80
+ end
81
+ o.a
82
+ end
83
+
84
+ it 'pass args alongside original' do
85
+ o = Class.new do
86
+ attr_reader :original_called
87
+ def a; @original_called = true; end
88
+ end.new
89
+ stub(o, :a).with(1, 2) do |original, *args|
90
+ is(o.original_called).nil?
91
+ assert(args) == [1, 2]
92
+ original.call
93
+ is(o.original_called).true?
94
+ end
95
+ o.a(1, 2)
96
+ end
97
+
98
+ it 'pass given block alongside original and args' do
99
+ args = nil
100
+ o = Class.new do
101
+ def a(*a); yield(*a); end
102
+ end.new
103
+ stub(o, :a).with(1, 2) do |original, *a, &p|
104
+ original.call(*a, &p)
105
+ end
106
+ o.a(1, 2) {|*a| args = a}
107
+ assert(args) == [1, 2]
108
+ end
109
+
110
+ it 'creates public stubs' do
111
+ stub(o, :a)
112
+ does(o.public_methods).include?(:a)
113
+ end
114
+
115
+ it 'creates private stubs' do
116
+ private_stub(o, :a)
117
+ does(o.private_methods).include?(:a)
118
+ does { o.a }.raise? NoMethodError, /private method\W+a/
119
+ end
120
+
121
+ it 'creates private stubs with a Hash' do
122
+ private_stub(o, :a => :b)
123
+ assert(o.send(:a)) == :b
124
+ end
125
+
126
+ it 'creates private stubs with a block' do
127
+ private_stub(o, :a) {:b}
128
+ assert(o.send(:a)) == :b
129
+ end
130
+
131
+ it 'adds arguments constraints on private stubs' do
132
+ private_stub(o, :a).
133
+ with(1) {:one}.
134
+ with_any(:any)
135
+ assert(o.send(:a)) == :any
136
+ assert(o.send(:a, :blah)) == :any
137
+ assert(o.send(:a, 1)) == :one
138
+ end
139
+
140
+ it 'creates protected stubs' do
141
+ protected_stub(o, :a)
142
+ does(o.protected_methods).include?(:a)
143
+ does { o.a }.raise? NoMethodError, /protected method\W+a/
144
+ end
145
+
146
+ it 'creates protected stubs with a Hash' do
147
+ protected_stub(o, :a => :b)
148
+ assert(o.send(:a)) == :b
149
+ end
150
+
151
+ it 'creates protected stubs with a block' do
152
+ protected_stub(o, :a) {:b}
153
+ assert(o.send(:a)) == :b
154
+ end
155
+
156
+ it 'adds arguments constraints on protected stubs' do
157
+ protected_stub(o, :a).
158
+ with(1) {:one}.
159
+ with_any(:any)
160
+ assert(o.send(:a)) == :any
161
+ assert(o.send(:a, :blah)) == :any
162
+ assert(o.send(:a, 1)) == :one
163
+ end
164
+
165
+ it 'keeps the visibility of existing methods' do
166
+ o = Class.new do
167
+ def a; end
168
+ protected
169
+ def b; end
170
+ private
171
+ def c; end
172
+ end.new
173
+
174
+ stub(o, :a)
175
+ does(o.public_methods).include?(:a)
176
+
177
+ stub(o, :b)
178
+ does(o.protected_methods).include?(:b)
179
+
180
+ stub(o, :c)
181
+ does(o.private_methods).include?(:c)
182
+ end
183
+
184
+ it 'enforces public visibility on protected methods' do
185
+ o = Class.new do
186
+ protected
187
+ def a; end
188
+ end.new
189
+ does { o.a }.raise? NoMethodError, /protected method\W+a/
190
+ public_stub(o, :a) { :a }
191
+ assert(o.a) == :a
192
+ end
193
+
194
+ it 'enforces public visibility on private methods' do
195
+ o = Class.new do
196
+ private
197
+ def a; end
198
+ end.new
199
+ does { o.a }.raise? NoMethodError, /private method\W+a/
200
+ public_stub(o, :a) { :a }
201
+ assert(o.a) == :a
202
+ end
203
+
204
+ it 'stub :nil? method' do
205
+ o = nil
206
+ is(o.nil?) == true
207
+ stub(o, :nil?) { :blah }
208
+ is(o.nil?) == :blah
209
+ end
210
+
211
+ it 'defines chained stubs' do
212
+ @a = nil
213
+ stub(o, 'a.b.c') {|*a| @a = true; a}
214
+
215
+ does(o).respond_to?(:a)
216
+ o.a
217
+ is(@a).nil?
218
+
219
+ does(o.a).respond_to?(:b)
220
+ o.a.b
221
+ is(@a).nil?
222
+
223
+ does(o.a.b).respond_to?(:c)
224
+ expect(o.a.b.c(:x, :y)).to_contain :x, :y
225
+ is(@a).true?
226
+ end
227
+
228
+ it 'defines chained stubs with a Hash' do
229
+ stub(o, 'a.b.c' => 1, 'x.y.z' => 2)
230
+
231
+ does(o).respond_to?(:a)
232
+ does(o.a).respond_to?(:b)
233
+ does(o.a.b).respond_to?(:c)
234
+ assert(o.a.b.c) == 1
235
+
236
+ does(o).respond_to?(:x)
237
+ does(o.x).respond_to?(:y)
238
+ does(o.x.y).respond_to?(:z)
239
+ assert(o.x.y.z) == 2
240
+ end
241
+
242
+ test 'chained stubs works with arguments filters' do
243
+ stub(o, 'a.b').
244
+ with(1) {:one}.
245
+ with(2) {:two}.
246
+ with_any(:any)
247
+ assert(o.a.b) == :any
248
+ assert(o.a.b(:bl, :ah)) == :any
249
+ assert(o.a.b(1)) == :one
250
+ assert(o.a.b(2)) == :two
251
+ end
252
+
253
+ it 'passes the given block with last method in the chain' do
254
+ stub(o, 'b.c') {|&b| b.call(2)}
255
+ assert(o.b.c {|y| y ** 2}) == 4
256
+ end
257
+
258
+ it 'adds expectations on chained stubs' do
259
+ stub(o, 'a.b.c')
260
+ expect(o).to_receive(:a)
261
+ expect(o.a).to_receive(:b)
262
+ expect(o.a.b).to_receive(:c)
263
+ o.a.b.c
264
+ end
265
+
266
+ it 'restore stubbed singleton methods' do
267
+ o.define_singleton_method(:a) {:a}
268
+ stub(o, :a) {:b}
269
+ is(o.a) == :b
270
+ restore_originals
271
+ is(o.a) == :a
272
+ end
273
+
274
+ it 'restore stubbed public methods' do
275
+ o = Class.new do
276
+ def a; :a; end
277
+ end.new
278
+ stub(o, :a) {:b}
279
+ is(o.a) == :b
280
+ restore_originals
281
+ is(o.a) == :a
282
+ end
283
+
284
+ it 'restore stubbed protected methods' do
285
+ o = Class.new do
286
+ protected
287
+ def a; :a; end
288
+ end.new
289
+ stub(o, :a) {:b}
290
+ is(o.__send__(:a)) == :b
291
+ restore_originals
292
+ is(o.__send__(:a)) == :a
293
+ end
294
+
295
+ it 'restore stubbed private methods' do
296
+ o = Class.new do
297
+ private
298
+ def a; :a; end
299
+ end.new
300
+ stub(o, :a) {:b}
301
+ is(o.__send__(:a)) == :b
302
+ restore_originals
303
+ is(o.__send__(:a)) == :a
304
+ end
305
+
306
+ it 'restore stubbed chained methods' do
307
+ o.define_singleton_method(:a) {:a}
308
+ stub(o, 'a.b.c') {:b}
309
+ assert(o.a) != :a
310
+ restore_originals
311
+ is(o.a) == :a
312
+ end
313
+
314
+ it 'restore :nil? method' do
315
+ o = nil
316
+ is(o.nil?) == true
317
+ stub(o, :nil?) { :blah }
318
+ is(o.nil?) == :blah
319
+ restore_originals
320
+ is(o.nil?) == true
321
+ end
322
+
323
+ it 'undefines early unexisting public methods' do
324
+ assure(o).does_not.respond_to? :a
325
+ assert { o.a }.raise NoMethodError
326
+
327
+ stub(o, :a) {:a}
328
+ does(o).respond_to? :a
329
+ is(o.a) == :a
330
+
331
+ restore_originals
332
+
333
+ assure(o).does_not.respond_to? :a
334
+ assert { o.a }.raise NoMethodError
335
+ end
336
+
337
+ it 'undefines early unexisting protected methods' do
338
+ assert(o.protected_methods).does_not.include? :a
339
+
340
+ protected_stub(o, :a) {:a}
341
+ does(o.protected_methods).include? :a
342
+
343
+ restore_originals
344
+
345
+ assert(o.protected_methods).does_not.include? :a
346
+ end
347
+
348
+ it 'undefines early unexisting private methods' do
349
+ assert(o.private_methods).does_not.include? :a
350
+
351
+ private_stub(o, :a) {:a}
352
+ does(o.private_methods).include? :a
353
+
354
+ restore_originals
355
+
356
+ assert(o.private_methods).does_not.include? :a
357
+ end
358
+
359
+ it 'uses `returns` with a block to define a catchall return' do
360
+ stub(o, :a).
361
+ with_any { :A }.
362
+ with(1) { :one }
363
+ assert(o.a) == :A
364
+ assert(o.a(:blah)) == :A
365
+ assert(o.a(1)) == :one
366
+ end
367
+
368
+ it 'uses `returns` with a value to define a catchall return' do
369
+ stub(o, :a).
370
+ with_any(:A).
371
+ with(1) { :one }
372
+ assert(o.a) == :A
373
+ assert(o.a(:blah)) == :A
374
+ assert(o.a(1)) == :one
375
+ end
376
+
377
+ it 'defines multiple stubs at once' do
378
+ stubs(o, :a, :b)
379
+ does(o).respond_to?(:a)
380
+ does(o).respond_to?(:b)
381
+ end
382
+
383
+ it 'uses the given block for all stubs' do
384
+ stubs(o, :a, :b) {:x}
385
+ assert(o.a) == :x
386
+ assert(o.b) == :x
387
+ end
388
+
389
+ it 'uses same constraints for all stubs' do
390
+ stubs(o, :a, :b).
391
+ with(1) {:one}.
392
+ with(2) {:two}.
393
+ with_any(:any)
394
+
395
+ assert(o.a) == :any
396
+ assert(o.a(:what, :ever)) == :any
397
+
398
+ assert(o.b) == :any
399
+ assert(o.b(:blah)) == :any
400
+
401
+ assert(o.a(1)) == :one
402
+ assert(o.b(1)) == :one
403
+
404
+ assert(o.a(2)) == :two
405
+ assert(o.b(2)) == :two
406
+ end
407
+
408
+ it 'defines multiple private stubs' do
409
+ private_stubs(o, :a, :b)
410
+ does(o.private_methods).include?(:a)
411
+ does(o.private_methods).include?(:b)
412
+ does { o.a }.raise? NoMethodError, /private method\W+a/
413
+ does { o.b }.raise? NoMethodError, /private method\W+b/
414
+ end
415
+
416
+ it 'defines multiple protected stubs' do
417
+ protected_stubs(o, :a, :b)
418
+ does(o.protected_methods).include?(:a)
419
+ does(o.protected_methods).include?(:b)
420
+ does { o.a }.raise? NoMethodError, /protected method\W+a/
421
+ does { o.b }.raise? NoMethodError, /protected method\W+b/
422
+ end
423
+ end
424
+
425
+ define_tests(Unit)
426
+ end
427
+ end