muack 1.2.0 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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 [![Build Status](https://secure.travis-ci.org/godfat/muack.png?branch=master)](http://travis-ci.org/godfat/muack) [![Coverage Status](https://coveralls.io/repos/godfat/muack/badge.png
|
1
|
+
# Muack [![Build Status](https://secure.travis-ci.org/godfat/muack.png?branch=master)](http://travis-ci.org/godfat/muack) [![Coverage Status](https://coveralls.io/repos/github/godfat/muack/badge.png)](https://coveralls.io/github/godfat/muack) [![Join the chat at https://gitter.im/godfat/muack](https://badges.gitter.im/Join%20Chat.svg)](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.
|