muack 1.2.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.travis.yml +19 -9
- data/CHANGES.md +47 -0
- data/Gemfile +0 -4
- data/README.md +162 -65
- data/Rakefile +3 -4
- data/lib/muack.rb +43 -11
- data/lib/muack/block.rb +4 -15
- data/lib/muack/block_26.rb +16 -0
- data/lib/muack/block_27.rb +16 -0
- data/lib/muack/coat.rb +1 -1
- data/lib/muack/definition.rb +4 -3
- data/lib/muack/error.rb +6 -0
- data/lib/muack/failure.rb +5 -4
- data/lib/muack/mock.rb +134 -68
- data/lib/muack/satisfying.rb +195 -0
- data/lib/muack/spy.rb +18 -4
- data/lib/muack/stub.rb +7 -6
- data/lib/muack/test.rb +42 -11
- data/lib/muack/version.rb +1 -1
- data/muack.gemspec +65 -55
- data/task/README.md +8 -8
- data/task/gemgem.rb +34 -7
- data/test/test_any_instance_of.rb +16 -2
- data/test/test_from_readme.rb +6 -8
- data/test/test_keyargs.rb +111 -0
- data/test/test_modifier.rb +6 -6
- data/test/test_prepend.rb +121 -0
- data/test/test_proxy.rb +19 -4
- data/test/{test_satisfy.rb → test_satisfying.rb} +216 -80
- data/test/test_spy.rb +149 -0
- data/test/test_stub.rb +0 -95
- data/test/test_visibility.rb +120 -0
- metadata +20 -11
- data/lib/muack/satisfy.rb +0 -100
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e65f1260993f94d96899086e3975500583ec077bfae332a8fd4cefc5a2c7da49
|
4
|
+
data.tar.gz: 736468eb986e1925f8f83973fec00c2142df16ca80aee9ce051bbdc255cbbfc8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d3bb1281eab20185484890205696cbed1d3996ed6392b76e08297af8e742bd76a80f2e3a26fffec265848d18a5373dffd517db6d2127b4e511dfdc5a2b475937
|
7
|
+
data.tar.gz: 2c148e33b0dce444708d09a58f6364e160a926f73e5432120fa8668c7ee0dd65c83128e69723673fd6c95bb62db879b8ff3636af29c93e783954f8409a882ebd
|
data/.travis.yml
CHANGED
@@ -1,11 +1,21 @@
|
|
1
|
-
|
1
|
+
sudo: false
|
2
2
|
language: ruby
|
3
|
-
rvm:
|
4
|
-
- 2.0
|
5
|
-
- 2.1
|
6
|
-
- 2.2
|
7
|
-
- rbx-2
|
8
|
-
- jruby
|
9
3
|
|
10
|
-
install: 'bundle install --retry=3'
|
11
|
-
|
4
|
+
install: 'gem update --system; gem install bundler; bundle install --retry=3'
|
5
|
+
before_script: unset CI
|
6
|
+
script: 'ruby -vwr bundler/setup -S rake test'
|
7
|
+
|
8
|
+
matrix:
|
9
|
+
include:
|
10
|
+
- rvm: 2.4
|
11
|
+
env: RUBYOPT=--enable-frozen-string-literal
|
12
|
+
- rvm: 2.5
|
13
|
+
env: RUBYOPT=--enable-frozen-string-literal
|
14
|
+
- rvm: 2.6
|
15
|
+
env: RUBYOPT=--enable-frozen-string-literal
|
16
|
+
- rvm: 2.7
|
17
|
+
env: RUBYOPT=--enable-frozen-string-literal
|
18
|
+
- rvm: ruby-head
|
19
|
+
env: RUBYOPT=--enable-frozen-string-literal
|
20
|
+
- rvm: jruby
|
21
|
+
env: RUBYOPT=--enable-frozen-string-literal
|
data/CHANGES.md
CHANGED
@@ -1,5 +1,52 @@
|
|
1
1
|
# CHANGES
|
2
2
|
|
3
|
+
## Muack 1.5.0 -- 2020-11-28
|
4
|
+
|
5
|
+
### Bugs fixed
|
6
|
+
|
7
|
+
* Properly handle prepended objects
|
8
|
+
* Properly restore method visibilities for singleton methods
|
9
|
+
|
10
|
+
### Enhancement
|
11
|
+
|
12
|
+
* Eliminated any potential keyword arguments warnings to be future proof
|
13
|
+
* Some major internal restructure
|
14
|
+
|
15
|
+
## Muack 1.4.0 -- 2015-11-21
|
16
|
+
|
17
|
+
### Incompatible changes / Enhancement
|
18
|
+
|
19
|
+
* Spies would now do pattern matching like stubs for matching
|
20
|
+
method arguments. This could be an incompatible change if you're
|
21
|
+
relying on spies checking the order for the same method calls.
|
22
|
+
This change would make spies and stubs more similar. If you are
|
23
|
+
really into a specific order, use mocks instead.
|
24
|
+
|
25
|
+
## Muack 1.3.2 -- 2015-06-11
|
26
|
+
|
27
|
+
* Fixed a bug for `where`, `having`, and `allowing` which should distinguish
|
28
|
+
between `nil` and `undefined` (which does not have a key in a hash)
|
29
|
+
|
30
|
+
## Muack 1.3.1 -- 2015-05-27
|
31
|
+
|
32
|
+
* Fixed a bug for `where`, `having`, and `allowing` which would raise an
|
33
|
+
exception whenever the actual value is not a hash or array.
|
34
|
+
|
35
|
+
## Muack 1.3.0 -- 2015-05-24
|
36
|
+
|
37
|
+
### Incompatible changes
|
38
|
+
|
39
|
+
* `Muack::API.match` is renamed to `Muack::API.matching`
|
40
|
+
* `Muack::API.respond_to` is renamed to `Muack::API.responding_to`
|
41
|
+
* `Muack::API.hash_including` is renamed to `Muack::API.having`
|
42
|
+
* `Muack::API.satisfy` is renamed to `Muack::API.satisfying`
|
43
|
+
* `Muack::Satisy` is renamed to `Muack::Satisying`
|
44
|
+
|
45
|
+
### Enhancement
|
46
|
+
|
47
|
+
* `Muack::API.where` is added
|
48
|
+
* `Muack::API.allowing` is added
|
49
|
+
|
3
50
|
## Muack 1.2.0 -- 2015-03-10
|
4
51
|
|
5
52
|
* Now stubs could be overwritten. Input from @mz026
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Muack [](http://travis-ci.org/godfat/muack) [](http://travis-ci.org/godfat/muack) [](https://coveralls.io/github/godfat/muack) [](https://gitter.im/godfat/muack)
|
2
2
|
|
3
3
|
by Lin Jen-Shin ([godfat](http://godfat.org))
|
4
4
|
|
@@ -7,6 +7,7 @@ by Lin Jen-Shin ([godfat](http://godfat.org))
|
|
7
7
|
* [github](https://github.com/godfat/muack)
|
8
8
|
* [rubygems](https://rubygems.org/gems/muack)
|
9
9
|
* [rdoc](http://rdoc.info/github/godfat/muack)
|
10
|
+
* [issues](https://github.com/godfat/muack/issues) (feel free to ask for support)
|
10
11
|
|
11
12
|
## DESCRIPTION:
|
12
13
|
|
@@ -25,7 +26,7 @@ Muack is much simpler and thus much faster and much more consistent.
|
|
25
26
|
|
26
27
|
## REQUIREMENTS:
|
27
28
|
|
28
|
-
* Tested with MRI (official CRuby)
|
29
|
+
* Tested with MRI (official CRuby) and JRuby.
|
29
30
|
|
30
31
|
## INSTALLATION:
|
31
32
|
|
@@ -39,14 +40,14 @@ Here's a quick example using [Pork][].
|
|
39
40
|
require 'pork/auto'
|
40
41
|
require 'muack'
|
41
42
|
|
42
|
-
include Muack::API
|
43
|
-
|
44
43
|
describe 'Hello' do
|
44
|
+
include Muack::API
|
45
|
+
|
45
46
|
before{ Muack.reset }
|
46
47
|
after { Muack.verify }
|
47
48
|
|
48
49
|
would 'say world!' do
|
49
|
-
str = 'Hello'
|
50
|
+
str = 'Hello'.dup
|
50
51
|
mock(str).say('!'){ |arg| "World#{arg}" }
|
51
52
|
str.say('!').should.eq 'World!'
|
52
53
|
end
|
@@ -59,9 +60,9 @@ end
|
|
59
60
|
|
60
61
|
There are 3 parts in Muack, which are:
|
61
62
|
|
62
|
-
* Mocks
|
63
|
-
* Mocks Modifiers
|
64
|
-
* Arguments Verifiers (
|
63
|
+
* [Mocks](#mocks)
|
64
|
+
* [Mocks Modifiers](#mocks-modifiers)
|
65
|
+
* [Arguments Verifiers (Satisfying)](#arguments-verifiers-satisfying)
|
65
66
|
|
66
67
|
Mocks are objects with injected methods which we could observe, and mocks
|
67
68
|
modifiers are telling how we want to observe the mocks, and finally argument
|
@@ -98,7 +99,7 @@ p obj.name # 'obj'
|
|
98
99
|
p Muack.verify # true
|
99
100
|
```
|
100
101
|
|
101
|
-
Which is
|
102
|
+
Which is similar to using a stub with a spy:
|
102
103
|
|
103
104
|
``` ruby
|
104
105
|
obj = Object.new
|
@@ -143,6 +144,11 @@ p Muack.verify # true
|
|
143
144
|
However you should not mix mocks and stubs with the same method, or you
|
144
145
|
might encounter some unexpected result. Jump to _Caveat_ for more detail.
|
145
146
|
|
147
|
+
The other differences for stubs and spies, please check
|
148
|
+
[Pattern Matching for stubs and spies][pattern-matching].
|
149
|
+
In short, stubs and spies would do some kind of pattern matching,
|
150
|
+
making the order of the same method irrelevant.
|
151
|
+
|
146
152
|
On the other hand, stubs aren't limited to testing. If we want to monkey
|
147
153
|
patching something, stubs could be useful as we don't care how many times
|
148
154
|
the injected methods are called. Jump to _Muack as a mocky patching library_
|
@@ -167,7 +173,7 @@ affecting the others. This is helpful in the cases of mocking some very
|
|
167
173
|
basic objects like Time, without causing too much side effect.
|
168
174
|
|
169
175
|
``` ruby
|
170
|
-
name = 'str'
|
176
|
+
name = 'str'.dup
|
171
177
|
stub(name).to_s{ 'hi' }
|
172
178
|
stub(Time).new { Time.at(0) }
|
173
179
|
mock(Time).now { Time.new }
|
@@ -269,7 +275,7 @@ into proxy mode we simply do not provide any block to the injected method,
|
|
269
275
|
but just name it. Here's an example:
|
270
276
|
|
271
277
|
``` ruby
|
272
|
-
str = 'str'
|
278
|
+
str = 'str'.dup
|
273
279
|
mock(str).reverse
|
274
280
|
p str.reverse # 'rts'
|
275
281
|
p Muack.verify # true
|
@@ -279,7 +285,7 @@ Note that if reverse was not called exactly once, the mock would complain.
|
|
279
285
|
We could also use stub + spy to do the same thing as well:
|
280
286
|
|
281
287
|
``` ruby
|
282
|
-
str = 'str'
|
288
|
+
str = 'str'.dup
|
283
289
|
stub(str).reverse
|
284
290
|
p str.reverse # 'rts'
|
285
291
|
spy(str).reverse
|
@@ -290,6 +296,44 @@ You might also want to use `peek_args` and `peek_return` modifier along with
|
|
290
296
|
proxies in order to slightly tweak the original implementation. Jump to
|
291
297
|
_Muack as a mocky patching library_ section for more detail.
|
292
298
|
|
299
|
+
#### Partial mode
|
300
|
+
|
301
|
+
Occasionally we would want to fake some of the values inside a hash, but
|
302
|
+
we don't want to interfere with the other values in that hash, and we also
|
303
|
+
don't want to modify it directly, or we'll need to make sure to restore it
|
304
|
+
after the tests.
|
305
|
+
|
306
|
+
Partial mode is not really a mode, but a combination of using proxy mode and
|
307
|
+
the [pattern matching mechanism specialized in stubs][pattern-matching].
|
308
|
+
Suppose we want to stub `ENV` (which is not a hash but you get the idea),
|
309
|
+
enabling some of the flags inside tests without really setting it, we'll do:
|
310
|
+
|
311
|
+
``` ruby
|
312
|
+
@user = ENV['USER']
|
313
|
+
p ENV['NDEBUG'] # nil
|
314
|
+
|
315
|
+
stub(ENV)[is_a(String)] #- NOTE: NEED TO DEFINE THIS PROXY FIRST
|
316
|
+
stub(ENV)['NDEBUG'].returns{ '1' } #- `returns` workaround Ruby syntax
|
317
|
+
|
318
|
+
p ENV['NDEBUG'] # '1'
|
319
|
+
p ENV['USER'] # @user
|
320
|
+
p Muack.verify # true
|
321
|
+
p ENV['NDEBUG'] # nil
|
322
|
+
```
|
323
|
+
|
324
|
+
Note that in order to make this work, proxy should be defined first. Because
|
325
|
+
stubs are searched in Last In First Out (LIFO) order, it would first check
|
326
|
+
if the key is matching `'NDEBUG'` in this case. If it's not matched, then
|
327
|
+
search the next one. Eventually it would reach to the first stub, which
|
328
|
+
we put `is_a(String)` there so it must match, and return the original value
|
329
|
+
inside `ENV`.
|
330
|
+
|
331
|
+
If the order is reversed, then it would always return the original value,
|
332
|
+
because the proxy would always match, and Muack would stop searching the
|
333
|
+
next stub.
|
334
|
+
|
335
|
+
[pattern-matching]: #pattern-matching-for-stubs-and-spies
|
336
|
+
|
293
337
|
#### any_instance_of mode
|
294
338
|
|
295
339
|
We only talked about mocking a specific object, but never mentioned what if
|
@@ -408,7 +452,7 @@ p Muack.verify # true
|
|
408
452
|
|
409
453
|
Note that it does not make sense to specify `times` for stubs, because
|
410
454
|
stubs don't care about times. Spies do, though. So this is also
|
411
|
-
|
455
|
+
similar to below:
|
412
456
|
|
413
457
|
``` ruby
|
414
458
|
obj = Object.new
|
@@ -580,7 +624,7 @@ our own behaviour, then we already have full control of the arguments.
|
|
580
624
|
There's no points to use both. This also applies to `peek_return`.
|
581
625
|
|
582
626
|
``` ruby
|
583
|
-
str = 'ff'
|
627
|
+
str = 'ff'.dup
|
584
628
|
mock(str).to_i.with_any_args.peek_args{ |radix| radix * 2 }
|
585
629
|
p str.to_i(8) # 255
|
586
630
|
p Muack.verify # true
|
@@ -611,7 +655,7 @@ might just want to take a look at the return? Here's an example using
|
|
611
655
|
`peek_return` to modify the original return value.
|
612
656
|
|
613
657
|
``` ruby
|
614
|
-
str = 'ff'
|
658
|
+
str = 'ff'.dup
|
615
659
|
mock(str).to_i.with_any_args.peek_return{ |int| int * 2 }
|
616
660
|
p str.to_i(16) # 510
|
617
661
|
p Muack.verify # true
|
@@ -635,7 +679,7 @@ p Muack.verify # true
|
|
635
679
|
We could also omit `|_|` if we don't care about the original return value
|
636
680
|
in the above example.
|
637
681
|
|
638
|
-
### Arguments Verifiers (
|
682
|
+
### Arguments Verifiers (Satisfying)
|
639
683
|
|
640
684
|
If we're not passing any arguments to the injected method we define, then
|
641
685
|
basically we're saying that there's no arguments should be passed to the
|
@@ -670,6 +714,8 @@ obj.say{ |msg| p msg } # 'Hi'
|
|
670
714
|
p Muack.verify # true
|
671
715
|
```
|
672
716
|
|
717
|
+
#### Pattern Matching for stubs and spies
|
718
|
+
|
673
719
|
Moreover, we could also have stubs on the same method for different
|
674
720
|
arguments. We could think of this as a sort of pattern matching, and Muack
|
675
721
|
would try to find the best matched stub for us.
|
@@ -684,29 +730,18 @@ p Muack.verify # true
|
|
684
730
|
```
|
685
731
|
|
686
732
|
If `obj.find(2)` is called and Muack cannot find a matched stub, it would
|
687
|
-
raise a `Muack::Unexpected` and list the candidates for us.
|
733
|
+
raise a `Muack::Unexpected` and list the candidates for us. This also
|
734
|
+
applies to spies.
|
688
735
|
|
689
736
|
However, What if we don't want to be so exact? Then we should use verifiers.
|
690
737
|
We'll introduce each of them in next section. Note that verifiers
|
691
|
-
are not recursive though. If you need complex
|
738
|
+
are not recursive though. If you need complex arguments verification,
|
692
739
|
you'll need to use `satisfy` verifier which you could give an arbitrary
|
693
740
|
block to verify anything.
|
694
741
|
|
695
|
-
#### is_a
|
696
|
-
|
697
|
-
`is_a` would check if the argument is a kind of the given class.
|
698
|
-
Actually, it's calling `kind_of?` underneath.
|
699
|
-
|
700
|
-
``` ruby
|
701
|
-
obj = Object.new
|
702
|
-
mock(obj).say(is_a(String)){ |arg| arg }
|
703
|
-
p obj.say('something') # 'something'
|
704
|
-
p Muack.verify # true
|
705
|
-
```
|
706
|
-
|
707
742
|
#### anything
|
708
743
|
|
709
|
-
`anything` is a wildcard
|
744
|
+
`anything` is a wildcard arguments verifier. It matches anything.
|
710
745
|
Although this actually verifies nothing, we could still think of
|
711
746
|
this as an arity verifier. Since one anything is not two anythings.
|
712
747
|
|
@@ -718,15 +753,27 @@ p obj.say(true) # true
|
|
718
753
|
p Muack.verify # true
|
719
754
|
```
|
720
755
|
|
721
|
-
####
|
756
|
+
#### is_a
|
757
|
+
|
758
|
+
`is_a` would check if the argument is a kind of the given class.
|
759
|
+
Actually, it's calling `kind_of?` underneath.
|
760
|
+
|
761
|
+
``` ruby
|
762
|
+
obj = Object.new
|
763
|
+
mock(obj).say(is_a(String)){ |arg| arg }
|
764
|
+
p obj.say('something') # 'something'
|
765
|
+
p Muack.verify # true
|
766
|
+
```
|
767
|
+
|
768
|
+
#### matching
|
722
769
|
|
723
|
-
`
|
770
|
+
`matching` would check the argument with `match` method. Usually this is
|
724
771
|
used with regular expression, but anything which responds to `match`
|
725
772
|
should work.
|
726
773
|
|
727
774
|
``` ruby
|
728
775
|
obj = Object.new
|
729
|
-
mock(obj).say(
|
776
|
+
mock(obj).say(matching(/\w+/)){ |arg| arg }
|
730
777
|
p obj.say('Hi') # 'Hi'
|
731
778
|
p Muack.verify # true
|
732
779
|
```
|
@@ -735,18 +782,6 @@ Note that please don't pass the regular expression directly without
|
|
735
782
|
wrapping it with a match verifier, or how do we distinguish if we
|
736
783
|
really want to make sure the argument is exactly the regular expression?
|
737
784
|
|
738
|
-
#### hash_including
|
739
|
-
|
740
|
-
`hash_including` would check if the given hash is the actual
|
741
|
-
argument's subset.
|
742
|
-
|
743
|
-
``` ruby
|
744
|
-
obj = Object.new
|
745
|
-
mock(obj).say(hash_including(:a => 0)){ |arg| arg }
|
746
|
-
p obj.say(:a => 0, :b => 1) # {:a => 0, :b => 1}
|
747
|
-
p Muack.verify # true
|
748
|
-
```
|
749
|
-
|
750
785
|
#### including
|
751
786
|
|
752
787
|
`including` would check if the actual argument includes the given value
|
@@ -771,36 +806,98 @@ p obj.say(0) # 0
|
|
771
806
|
p Muack.verify # true
|
772
807
|
```
|
773
808
|
|
774
|
-
####
|
809
|
+
#### responding_to
|
775
810
|
|
776
|
-
`
|
811
|
+
`responding_to` would check if the actual argument would be responding to
|
777
812
|
the given message, checked via `respond_to?`, also known as duck typing.
|
778
813
|
|
779
814
|
``` ruby
|
780
815
|
obj = Object.new
|
781
|
-
mock(obj).say(
|
816
|
+
mock(obj).say(responding_to(:size)){ |arg| arg }
|
782
817
|
p obj.say([]) # []
|
783
818
|
p Muack.verify # true
|
784
819
|
```
|
785
820
|
|
786
|
-
Note that you could give multiple messages to `
|
821
|
+
Note that you could give multiple messages to `responding_to`.
|
787
822
|
|
788
823
|
``` ruby
|
789
824
|
obj = Object.new
|
790
|
-
mock(obj).say(
|
825
|
+
mock(obj).say(responding_to(:size, :reverse)){ |arg| arg }
|
791
826
|
p obj.say([]) # []
|
792
827
|
p Muack.verify # true
|
793
828
|
```
|
794
829
|
|
795
|
-
####
|
830
|
+
#### where
|
831
|
+
|
832
|
+
`where` would check if the actual argument matches given specification.
|
833
|
+
|
834
|
+
``` ruby
|
835
|
+
obj = Object.new
|
836
|
+
mock(obj).say(where(:a => is_a(Integer))){ |arg| arg }
|
837
|
+
p obj.say(:a => 0) # {:a => 0}
|
838
|
+
p Muack.verify # true
|
839
|
+
```
|
840
|
+
|
841
|
+
Note that this could be recursive.
|
842
|
+
|
843
|
+
``` ruby
|
844
|
+
obj = Object.new
|
845
|
+
mock(obj).say(where(:a => {:b => [is_a(Integer)]})){ |arg| arg[:a] }
|
846
|
+
p obj.say(:a => {:b => [0]}) # {:b => [0]}
|
847
|
+
p Muack.verify # true
|
848
|
+
```
|
849
|
+
|
850
|
+
#### having
|
851
|
+
|
852
|
+
`having` would check if the actual argument is a superset of given
|
853
|
+
specification.
|
854
|
+
|
855
|
+
``` ruby
|
856
|
+
obj = Object.new
|
857
|
+
mock(obj).say(having(:a => 0)){ |arg| arg }
|
858
|
+
p obj.say(:a => 0, :b => 1) # {:a => 0, :b => 1}
|
859
|
+
p Muack.verify # true
|
860
|
+
```
|
861
|
+
|
862
|
+
Note that this could be recursive.
|
863
|
+
|
864
|
+
``` ruby
|
865
|
+
obj = Object.new
|
866
|
+
mock(obj).say(having(:a => {:b => [is_a(Integer)]})){ |arg| arg[:c] }
|
867
|
+
p obj.say(:a => {:b => [1]}, :c => 2) # 2
|
868
|
+
p Muack.verify # true
|
869
|
+
```
|
870
|
+
|
871
|
+
#### allowing
|
872
|
+
|
873
|
+
`allowing` would check if the actual argument is a subset of given
|
874
|
+
specification.
|
875
|
+
|
876
|
+
``` ruby
|
877
|
+
obj = Object.new
|
878
|
+
mock(obj).say(allowing(:a => 0, :b => [1])){ |arg| arg }
|
879
|
+
p obj.say(:a => 0) # {:a => 0}
|
880
|
+
p Muack.verify # true
|
881
|
+
```
|
882
|
+
|
883
|
+
Note that this could be recursive.
|
884
|
+
|
885
|
+
``` ruby
|
886
|
+
obj = Object.new
|
887
|
+
mock(obj).say(allowing(:a => {:b => is_a(Integer), :c => 1})){ |arg| arg[:a] }
|
888
|
+
p obj.say(:a => {:b => 2}) # {:b => 2}
|
889
|
+
p Muack.verify # true
|
890
|
+
```
|
891
|
+
|
892
|
+
#### satisfying
|
796
893
|
|
797
|
-
`
|
894
|
+
`satisfying` accepts a block to let you do arbitrary verification.
|
798
895
|
nil and false are considered false, otherwise true, just like in
|
799
896
|
regular if expression.
|
800
897
|
|
801
898
|
``` ruby
|
802
899
|
obj = Object.new
|
803
|
-
mock(obj).say(
|
900
|
+
mock(obj).say(satisfying{ |arg| arg % 2 == 0 }){ |arg| arg }
|
804
901
|
p obj.say(0) # 0
|
805
902
|
p Muack.verify # true
|
806
903
|
```
|
@@ -837,7 +934,7 @@ class implements each method. We could use conjunction for this.
|
|
837
934
|
|
838
935
|
``` ruby
|
839
936
|
obj = Object.new
|
840
|
-
mock(obj).say(is_a(Enumerable) &
|
937
|
+
mock(obj).say(is_a(Enumerable) & responding_to(:each)){}.times(3)
|
841
938
|
p obj.say( [] ) # nil
|
842
939
|
p obj.say( {} ) # nil
|
843
940
|
p obj.say(0..1) # nil
|
@@ -1026,7 +1123,7 @@ Consider we have two classes:
|
|
1026
1123
|
|
1027
1124
|
``` ruby
|
1028
1125
|
Food = Class.new
|
1029
|
-
User = Class.new
|
1126
|
+
User = Class.new(Struct.new(:food))
|
1030
1127
|
```
|
1031
1128
|
|
1032
1129
|
And we could make sure User#food is always a kind of `Food` by putting this
|
@@ -1053,11 +1150,11 @@ verifiers. For example, we could do this to check if the food is frozen:
|
|
1053
1150
|
|
1054
1151
|
``` ruby
|
1055
1152
|
Food = Class.new
|
1056
|
-
User = Class.new
|
1153
|
+
User = Class.new(Struct.new(:food))
|
1057
1154
|
|
1058
|
-
FoodFrozen = Class.new(Muack::
|
1059
|
-
def
|
1060
|
-
|
1155
|
+
FoodFrozen = Class.new(Muack::Satisfying) do
|
1156
|
+
def match actual_arg
|
1157
|
+
actual_arg.frozen?
|
1061
1158
|
end
|
1062
1159
|
end
|
1063
1160
|
|
@@ -1072,7 +1169,7 @@ p u.food = Food.new.freeze # ok
|
|
1072
1169
|
p u.food = Food.new # raise Muack::Unexpected
|
1073
1170
|
```
|
1074
1171
|
|
1075
|
-
Please check _Arguments Verifiers (
|
1172
|
+
Please check _Arguments Verifiers (Satisfying)_ section for more argument
|
1076
1173
|
verifiers details.
|
1077
1174
|
|
1078
1175
|
[dm-core]: https://github.com/datamapper/dm-core
|
@@ -1113,8 +1210,8 @@ Or, I am happy to break legacy.
|
|
1113
1210
|
## USERS:
|
1114
1211
|
|
1115
1212
|
* [Rib][]
|
1116
|
-
* [rest-core](https://github.com/
|
1117
|
-
* [rest-more](https://github.com/
|
1213
|
+
* [rest-core](https://github.com/godfat/rest-core)
|
1214
|
+
* [rest-more](https://github.com/godfat/rest-more)
|
1118
1215
|
|
1119
1216
|
## CONTRIBUTORS:
|
1120
1217
|
|
@@ -1122,9 +1219,9 @@ Or, I am happy to break legacy.
|
|
1122
1219
|
|
1123
1220
|
## LICENSE:
|
1124
1221
|
|
1125
|
-
Apache License 2.0
|
1222
|
+
Apache License 2.0 (Apache-2.0)
|
1126
1223
|
|
1127
|
-
Copyright (c) 2013-
|
1224
|
+
Copyright (c) 2013-2020, Lin Jen-Shin (godfat)
|
1128
1225
|
|
1129
1226
|
Licensed under the Apache License, Version 2.0 (the "License");
|
1130
1227
|
you may not use this file except in compliance with the License.
|