muack 1.1.1 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 46ee22af9472ac4c12baeb58afee2b979d6b80d0
4
- data.tar.gz: f155f3f23684f6fdceb3a6e5bc922cebbd151d0b
3
+ metadata.gz: fa29c09257f78580be72e3872fc7d3ef05650e02
4
+ data.tar.gz: 222e4d730c838c6f76d701c0505b41f7b3476d1e
5
5
  SHA512:
6
- metadata.gz: d27fc18f9ef192c19167432c73ca93191af1f747bfe59731eb8621709925da4ae3f33549ad9b493e0627f4d061581cd7fc1b6d818af6f4c93cd09bcd9bf60267
7
- data.tar.gz: 161f8b4a87addc0d0841fcfe6e3a6ad71becb17ff0b2f2e535e0c7e856051225e71f363950c81bae9ee78f9de8a4baa38150312b4ac15ceb23aa60c231bcbff8
6
+ metadata.gz: 3e539ea17a87076e48f85d980ad7e2c58afb91c8c627af09f05266a2811ecf2d22efb7adbc49f117c240ffca3c34a5e95229457ab2d82a7e8174a132aa17798e
7
+ data.tar.gz: 3b2de41a40ab1134c0952ec763423a0a07b0967ce180b076e129ecde0063ddc05853e278cf6b5fb2d0bb36ecb7ac6d612f3471bd3abefa0ff69a8b79fe0660e4
@@ -2,8 +2,8 @@ before_install: 'git submodule update --init'
2
2
  script: 'ruby -r bundler/setup -S rake test'
3
3
 
4
4
  rvm:
5
- - 1.9.3
6
- - 2.0.0
7
- - ruby
5
+ - 1.9
6
+ - 2.0
7
+ - 2.1
8
8
  - rbx-2
9
9
  - jruby
data/CHANGES.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # CHANGES
2
2
 
3
+ ## Muack 1.1.2 -- 2014-11-07
4
+
5
+ * Introduced `Muack::API.coat`.
6
+ See [README.md](README.md#coats) for explanation.
7
+
8
+ * `Muack::Session` is no longer a hash. Hope no one is trying to store
9
+ anything into it so this change would break nothing.
10
+
11
+ * `Muack::Failure` is no longer an Exception, but a StandardError.
12
+
3
13
  ## Muack 1.1.1 -- 2014-05-21
4
14
 
5
15
  It's no longer necessary to make spy the last call. Below now works:
data/Gemfile CHANGED
@@ -4,7 +4,7 @@ source 'https://rubygems.org'
4
4
  gemspec
5
5
 
6
6
  gem 'rake'
7
- gem 'bacon'
7
+ gem 'pork'
8
8
 
9
9
  platform :rbx do
10
10
  gem 'rubysl-singleton' # used in rake
data/README.md CHANGED
@@ -33,27 +33,27 @@ Muack is much simpler and thus much faster and much more consistent.
33
33
 
34
34
  ## SYNOPSIS:
35
35
 
36
- Here's a quick example using [Bacon][].
36
+ Here's a quick example using [Pork][].
37
37
 
38
38
  ``` ruby
39
- require 'bacon'
39
+ require 'pork/auto'
40
40
  require 'muack'
41
41
 
42
- Bacon::Context.__send__(:include, Muack::API)
42
+ include Muack::API
43
43
 
44
44
  describe 'Hello' do
45
45
  before{ Muack.reset }
46
46
  after { Muack.verify }
47
47
 
48
- should 'say world!' do
48
+ would 'say world!' do
49
49
  str = 'Hello'
50
50
  mock(str).say('!'){ |arg| "World#{arg}" }
51
- str.say('!').should.equal 'World!'
51
+ str.say('!').should.eq 'World!'
52
52
  end
53
53
  end
54
54
  ```
55
55
 
56
- [Bacon]: https://github.com/chneukirchen/bacon
56
+ [Pork]: https://github.com/godfat/pork
57
57
 
58
58
  ### Overview
59
59
 
@@ -71,14 +71,15 @@ Let's explain them one by one.
71
71
 
72
72
  ### Mocks
73
73
 
74
- There are also 3 different kinds of mocks in Muack, which are:
74
+ There are also 4 different kinds of mocks in Muack, which are:
75
75
 
76
76
  * Mocks
77
77
  * Stubs
78
78
  * Spies
79
+ * Coats
79
80
 
80
- You could think of _mocks_ are sort of _stubs_ combined with _spies_. Here's
81
- the inequation:
81
+ You could think of _mocks_ are sort of _stubs_ combined with _spies_.
82
+ Here's the inequation: (we'll talk about _coats_ later)
82
83
 
83
84
  mock >= stub + spy
84
85
 
@@ -183,6 +184,39 @@ p name.to_s # 'str'
183
184
  p Muack.verify # true
184
185
  ```
185
186
 
187
+ ### Coats
188
+
189
+ Now we could talk about coats. It's a kind of mocks but it would wear out
190
+ instead of raising an exception when it's called more than expected times.
191
+ This is useful when we want to restore the original behaviour of a
192
+ particular method at some point. The problem is that we can't simply
193
+ call the original method because it's already mocked! We could workaround
194
+ this by using `Muack.verify` or `Muack.reset` at some point, or let _coats_
195
+ handle that.
196
+
197
+ Here's an example with _coats_:
198
+
199
+ ``` ruby
200
+ coat(Time).now{ Time.at(0) }.times(2)
201
+
202
+ p Time.now.to_i == 0 # true
203
+ p Time.now.to_i == 0 # true
204
+ p Time.now.to_i > 0 # true
205
+ p Muack.verify # true
206
+ ```
207
+
208
+ Without _coats_ we might end up with:
209
+
210
+ ``` ruby
211
+ mock(Time).now{ Time.at(0) }
212
+ mock(Time).now{ Muack.verify(Time); Time.at(0) }
213
+
214
+ p Time.now.to_i == 0 # true
215
+ p Time.now.to_i == 0 # true
216
+ p Time.now.to_i > 0 # true
217
+ p Muack.verify # true
218
+ ```
219
+
186
220
  #### Anonymous mode
187
221
 
188
222
  Sometimes we just want to stub something without a concrete object in mind.
@@ -31,6 +31,11 @@ module Muack
31
31
  if block_given? then yield(ret) else ret end
32
32
  end
33
33
 
34
+ def coat obj=Object.new
35
+ ret = Muack.session.coat(obj)
36
+ if block_given? then yield(ret) else ret end
37
+ end
38
+
34
39
  def spy obj
35
40
  ret = Muack.session.spy(obj)
36
41
  if block_given? then yield(ret) else ret end
@@ -4,5 +4,9 @@ module Muack
4
4
  def inspect
5
5
  "Muack::API.any_instance_of(#{singleton_class})"
6
6
  end
7
+
8
+ # dummies for Muack::Session
9
+ def __mock_verify; true; end
10
+ def __mock_reset ; ; end
7
11
  end
8
12
  end
@@ -0,0 +1,16 @@
1
+
2
+ require 'muack/mock'
3
+
4
+ module Muack
5
+ class Coat < Mock
6
+ # used for mocked object to dispatch mocked method
7
+ def __mock_dispatch msg, actual_args
8
+ defi = super
9
+ if __mock_defis[defi.msg].empty?
10
+ __mock_reset_method(defi)
11
+ __mock_injected.delete(defi.msg)
12
+ end
13
+ defi
14
+ end
15
+ end
16
+ end
@@ -1,6 +1,6 @@
1
1
 
2
2
  module Muack
3
- class Failure < Exception
3
+ class Failure < StandardError
4
4
  attr_reader :expected
5
5
  def build_expected obj, expected_defis
6
6
  @expected = expected_defis.uniq{ |d| [d.msg, d.args] }.map{ |defi|
@@ -112,17 +112,7 @@ module Muack
112
112
 
113
113
  # used for Muack::Session#reset
114
114
  def __mock_reset
115
- __mock_injected.each_value do |defi|
116
- object.singleton_class.module_eval do
117
- remove_method(defi.msg)
118
- # restore original method
119
- if instance_methods(false).include?(defi.original_method) ||
120
- private_instance_methods(false).include?(defi.original_method)
121
- alias_method(defi.msg, defi.original_method)
122
- remove_method(defi.original_method)
123
- end
124
- end
125
- end
115
+ __mock_injected.each_value{ |defi| __mock_reset_method(defi) }
126
116
  end
127
117
 
128
118
  protected # get warnings for private attributes
@@ -136,6 +126,18 @@ module Muack
136
126
  __mock_inject_mock_method(target, defi, privilege)
137
127
  end
138
128
 
129
+ def __mock_reset_method defi
130
+ object.singleton_class.module_eval do
131
+ remove_method(defi.msg)
132
+ # restore original method
133
+ if instance_methods(false).include?(defi.original_method) ||
134
+ private_instance_methods(false).include?(defi.original_method)
135
+ alias_method(defi.msg, defi.original_method)
136
+ remove_method(defi.original_method)
137
+ end
138
+ end
139
+ end
140
+
139
141
  def self.store_original_method klass, defi
140
142
  privilege = if klass.instance_methods(false).include?(defi.msg)
141
143
  :public # TODO: forget about protected methods?
@@ -1,24 +1,29 @@
1
1
 
2
2
  require 'muack/mock'
3
3
  require 'muack/stub'
4
+ require 'muack/coat'
4
5
  require 'muack/spy'
5
6
  require 'muack/any_instance_of'
6
7
 
7
8
  module Muack
8
- class Session < Hash
9
- def mock obj; self["mk #{obj.__id__}"] ||= Mock.new(obj) ; end
10
- def stub obj; self["sb #{obj.__id__}"] ||= Stub.new(obj) ; end
11
- def spy obj; self["sy #{obj.__id__}"] ||= Spy .new(stub(obj)); end
9
+ class Session
10
+ attr_reader :data
11
+ def initialize; @data = {}; end
12
+
13
+ def mock obj; data["mk #{obj.__id__}"] ||= Mock.new(obj) ; end
14
+ def stub obj; data["sb #{obj.__id__}"] ||= Stub.new(obj) ; end
15
+ def coat obj; data["co #{obj.__id__}"] ||= Coat.new(obj) ; end
16
+ def spy obj; data["sy #{obj.__id__}"] ||= Spy .new(stub(obj)); end
12
17
 
13
18
  def any_instance_of kls
14
- (@others ||= {})["ai #{kls.__id__}"] ||= AnyInstanceOf.new(kls)
19
+ data["ai #{kls.__id__}"] ||= AnyInstanceOf.new(kls)
15
20
  end
16
21
 
17
22
  def verify obj=nil
18
23
  if obj
19
24
  with(obj, :[]).all?(&:__mock_verify)
20
25
  else
21
- each_value.all?(&:__mock_verify)
26
+ data.each_value.all?(&:__mock_verify)
22
27
  end
23
28
  end
24
29
 
@@ -26,15 +31,16 @@ module Muack
26
31
  if obj
27
32
  with(obj, :delete).each(&:__mock_reset)
28
33
  else
29
- instance_variable_defined?(:@others) && @others.clear
30
- reverse_each{ |_, m| m.__mock_reset }
31
- clear
34
+ data.reverse_each{ |_, m| m.__mock_reset } # reverse_each_value?
35
+ data.clear
32
36
  end
33
37
  end
34
38
 
35
39
  private
36
40
  def with obj, meth
37
- %w[mk sb sy].map{ |k| __send__(meth, "#{k} #{obj.__id__}") }.compact
41
+ %w[mk sb co sy ai].map{ |k|
42
+ data.__send__(meth, "#{k} #{obj.__id__}")
43
+ }.compact
38
44
  end
39
45
  end
40
46
  end
@@ -1,9 +1,8 @@
1
1
 
2
- require 'bacon'
2
+ require 'pork/auto'
3
3
  require 'muack'
4
4
 
5
- Bacon.summary_on_exit
6
- Bacon::Context.__send__(:include, Muack::API)
5
+ Pork::Executor.__send__(:include, Muack::API)
7
6
 
8
7
  Obj = Object.new
9
8
  Str = 'Moo'
@@ -22,12 +21,6 @@ Muack::EnsureReset = lambda{
22
21
  [Obj, Str].each do |o|
23
22
  o.methods.select{ |m|
24
23
  m.to_s.start_with?('__muack_mock') || m.to_s.start_with?('say')
25
- }.should.empty
24
+ }.should.empty?
26
25
  end
27
26
  }
28
-
29
- module Kernel
30
- def eq? rhs
31
- self == rhs
32
- end
33
- end
@@ -1,4 +1,4 @@
1
1
 
2
2
  module Muack
3
- VERSION = '1.1.1'
3
+ VERSION = '1.1.2'
4
4
  end
@@ -1,14 +1,14 @@
1
1
  # -*- encoding: utf-8 -*-
2
- # stub: muack 1.1.1 ruby lib
2
+ # stub: muack 1.1.2 ruby lib
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "muack"
6
- s.version = "1.1.1"
6
+ s.version = "1.1.2"
7
7
 
8
8
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
9
9
  s.require_paths = ["lib"]
10
10
  s.authors = ["Lin Jen-Shin (godfat)"]
11
- s.date = "2014-05-21"
11
+ s.date = "2014-11-07"
12
12
  s.description = "Muack -- A fast, small, yet powerful mocking library.\n\nInspired by [RR][], and it's 32x times faster (750s vs 23s) than RR\nfor running [Rib][] tests.\n\n[RR]: https://github.com/rr/rr\n[Rib]: https://github.com/godfat/rib"
13
13
  s.email = ["godfat (XD) godfat.org"]
14
14
  s.files = [
@@ -23,6 +23,7 @@ Gem::Specification.new do |s|
23
23
  "lib/muack.rb",
24
24
  "lib/muack/any_instance_of.rb",
25
25
  "lib/muack/block.rb",
26
+ "lib/muack/coat.rb",
26
27
  "lib/muack/definition.rb",
27
28
  "lib/muack/error.rb",
28
29
  "lib/muack/failure.rb",
@@ -38,6 +39,7 @@ Gem::Specification.new do |s|
38
39
  "task/README.md",
39
40
  "task/gemgem.rb",
40
41
  "test/test_any_instance_of.rb",
42
+ "test/test_coat.rb",
41
43
  "test/test_from_readme.rb",
42
44
  "test/test_mock.rb",
43
45
  "test/test_modifier.rb",
@@ -46,10 +48,11 @@ Gem::Specification.new do |s|
46
48
  "test/test_stub.rb"]
47
49
  s.homepage = "https://github.com/godfat/muack"
48
50
  s.licenses = ["Apache License 2.0"]
49
- s.rubygems_version = "2.2.2"
51
+ s.rubygems_version = "2.4.2"
50
52
  s.summary = "Muack -- A fast, small, yet powerful mocking library."
51
53
  s.test_files = [
52
54
  "test/test_any_instance_of.rb",
55
+ "test/test_coat.rb",
53
56
  "test/test_from_readme.rb",
54
57
  "test/test_mock.rb",
55
58
  "test/test_modifier.rb",
@@ -34,7 +34,7 @@ module Gemgem
34
34
  s.executables = bin_files
35
35
  end
36
36
  spec_create.call(spec)
37
- spec.homepage = "https://github.com/godfat/#{spec.name}"
37
+ spec.homepage ||= "https://github.com/godfat/#{spec.name}"
38
38
  self.spec = spec
39
39
  end
40
40
 
@@ -227,10 +227,6 @@ end # of gem namespace
227
227
  desc 'Run tests'
228
228
  task :test do
229
229
  next if Gemgem.test_files.empty?
230
-
231
- require 'bacon'
232
- Bacon.extend(Bacon::TestUnitOutput)
233
- Bacon.summary_on_exit
234
230
  Gemgem.test_files.each{ |file| require "#{Gemgem.dir}/#{file[0..-4]}" }
235
231
  end
236
232
 
@@ -4,7 +4,7 @@ require 'muack/test'
4
4
  describe Muack::AnyInstanceOf do
5
5
  klass = Class.new{ def f; 0; end; private; def g; 1; end }
6
6
 
7
- should 'mock any_instance_of' do
7
+ would 'mock any_instance_of' do
8
8
  any_instance_of(klass){ |inst| mock(inst).say{ true } }
9
9
  obj = klass.new
10
10
  obj.say .should.eq true
@@ -13,7 +13,7 @@ describe Muack::AnyInstanceOf do
13
13
  obj.respond_to?(:say).should.eq false
14
14
  end
15
15
 
16
- should 'mock any_instance_of with instance_exec' do
16
+ would 'mock any_instance_of with instance_exec' do
17
17
  any_instance_of(klass){ |inst|
18
18
  mock(inst).say.returns(:instance_exec => true){ f } }
19
19
  obj = klass.new
@@ -22,7 +22,7 @@ describe Muack::AnyInstanceOf do
22
22
  obj.respond_to?(:say).should.eq false
23
23
  end
24
24
 
25
- should 'proxy any_instance_of' do
25
+ would 'proxy any_instance_of' do
26
26
  any_instance_of(klass){ |inst| mock(inst).f }
27
27
  obj = klass.new
28
28
  obj.f .should.eq 0
@@ -30,7 +30,7 @@ describe Muack::AnyInstanceOf do
30
30
  obj.f .should.eq 0
31
31
  end
32
32
 
33
- should 'proxy any_instance_of for private methods' do
33
+ would 'proxy any_instance_of for private methods' do
34
34
  any_instance_of(klass){ |inst| mock(inst).g.peek_return{|i|i+1} }
35
35
  obj = klass.new
36
36
  obj.__send__(:g).should.eq 2
@@ -38,7 +38,7 @@ describe Muack::AnyInstanceOf do
38
38
  obj.__send__(:g).should.eq 1
39
39
  end
40
40
 
41
- should 'proxy any_instance_of with peek_return' do
41
+ would 'proxy any_instance_of with peek_return' do
42
42
  any_instance_of(klass){ |inst| mock(inst).f.peek_return{|i|i+1} }
43
43
  obj = klass.new
44
44
  obj.f .should.eq 1
@@ -46,7 +46,7 @@ describe Muack::AnyInstanceOf do
46
46
  obj.f .should.eq 0
47
47
  end
48
48
 
49
- should 'proxy with multiple any_instance_of call' do
49
+ would 'proxy with multiple any_instance_of call' do
50
50
  any_instance_of(klass){ |inst| mock(inst).f.peek_return{ |i| i+1 } }
51
51
  any_instance_of(klass){ |inst| mock(inst).f.peek_return{ |i| i+2 } }
52
52
  obj = klass.new
@@ -56,7 +56,7 @@ describe Muack::AnyInstanceOf do
56
56
  obj.f.should.eq 0
57
57
  end
58
58
 
59
- should 'mock with multiple any_instance_of call' do
59
+ would 'mock with multiple any_instance_of call' do
60
60
  any_instance_of(klass){ |inst| mock(inst).f(is_a(Fixnum)){ |i| i+1 } }
61
61
  any_instance_of(klass){ |inst| mock(inst).f(is_a(Fixnum)){ |i| i+2 } }
62
62
  obj = klass.new
@@ -66,14 +66,14 @@ describe Muack::AnyInstanceOf do
66
66
  obj.f.should.eq 0
67
67
  end
68
68
 
69
- should 'share the same counts for different instances' do
69
+ would 'share the same counts for different instances' do
70
70
  times = 2
71
71
  any_instance_of(klass){ |inst| mock(inst).f{0}.times(times) }
72
72
  times.times{ klass.new.f.should.eq 0 }
73
73
  Muack.verify.should.eq true
74
74
  end
75
75
 
76
- should 'stub proxy with any_instance_of and spy' do
76
+ would 'stub proxy with any_instance_of and spy' do
77
77
  any_instance_of(klass){ |inst| stub(inst).f.peek_return{ |i| i+3 } }
78
78
  obj = klass.new
79
79
  obj.f.should.eq 3
@@ -83,35 +83,33 @@ describe Muack::AnyInstanceOf do
83
83
  obj.f.should.eq 0
84
84
  end
85
85
 
86
- should 'stub with any_instance_of and spy under satisfied' do
86
+ would 'stub with any_instance_of and spy under satisfied' do
87
87
  any_instance_of(klass){ |inst| stub(inst).f{ 5 } }
88
88
  obj = klass.new
89
89
  obj.f.should.eq 5
90
90
  spy(any_instance_of(klass)).f.times(2)
91
- begin
92
- Muack.verify
93
- rescue Muack::Expected => e
94
- expected = /Muack::API\.any_instance_of\(.+?\)\.f\(\)/
95
- e.expected .should =~ expected
96
- e.expected_times.should.eq 2
97
- e.actual_times .should.eq 1
98
- end
91
+
92
+ e = should.raise(Muack::Expected){ Muack.verify }
93
+ expected = /Muack::API\.any_instance_of\(.+?\)\.f\(\)/
94
+ e.expected .should =~ expected
95
+ e.expected_times.should.eq 2
96
+ e.actual_times .should.eq 1
97
+
99
98
  obj.f.should.eq 0
100
99
  end
101
100
 
102
- should 'stub with any_instance_of and spy over satisfied' do
101
+ would 'stub with any_instance_of and spy over satisfied' do
103
102
  any_instance_of(klass){ |inst| stub(inst).f{ 2 } }
104
103
  obj = klass.new
105
104
  2.times{ obj.f.should.eq 2 }
106
105
  spy(any_instance_of(klass)).f
107
- begin
108
- Muack.verify
109
- rescue Muack::Expected => e
110
- expected = /Muack::API\.any_instance_of\(.+?\)\.f\(\)/
111
- e.expected .should =~ expected
112
- e.expected_times.should.eq 1
113
- e.actual_times .should.eq 2
114
- end
106
+
107
+ e = should.raise(Muack::Expected){ Muack.verify }
108
+ expected = /Muack::API\.any_instance_of\(.+?\)\.f\(\)/
109
+ e.expected .should =~ expected
110
+ e.expected_times.should.eq 1
111
+ e.actual_times .should.eq 2
112
+
115
113
  obj.f.should.eq 0
116
114
  end
117
115
  end