bogus 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +0 -1
- data/CHANGELOG.md +17 -0
- data/Gemfile.lock +1 -1
- data/features/anonymous_doubles.feature +129 -0
- data/features/step_definitions/rspec_steps.rb +0 -2
- data/lib/bogus.rb +8 -30
- data/lib/bogus/creates_anonymous_stubs.rb +27 -0
- data/lib/bogus/method_stringifier.rb +12 -0
- data/lib/bogus/public_methods.rb +10 -6
- data/lib/bogus/rspec.rb +2 -0
- data/lib/bogus/rspec_extensions.rb +10 -6
- data/lib/bogus/verifies_stub_definition.rb +1 -0
- data/lib/bogus/version.rb +1 -1
- data/spec/bogus/copies_classes_spec.rb +14 -0
- data/spec/bogus/mocking_dsl_spec.rb +40 -0
- data/spec/bogus/verifies_stub_definition_spec.rb +23 -0
- metadata +7 -4
data/.travis.yml
CHANGED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
## 0.0.1
|
4
|
+
|
5
|
+
Initial version.
|
6
|
+
|
7
|
+
- Fakes.
|
8
|
+
- Safe spying, stubbing, mocking.
|
9
|
+
- Veryfying contracts defined by test doubles.
|
10
|
+
|
11
|
+
## 0.0.2
|
12
|
+
|
13
|
+
- Makes it possible to stub method calls on objects that utilize method missing.
|
14
|
+
- Removed the need to require both bogus and bogus/rspec.
|
15
|
+
- Implemented anonymous fakes.
|
16
|
+
- Fixed a bug in copying ActiveRecord classes.
|
17
|
+
- (internal) Replaced autoloads with require.
|
data/Gemfile.lock
CHANGED
@@ -0,0 +1,129 @@
|
|
1
|
+
Feature: Anonymous test doubles
|
2
|
+
|
3
|
+
Anonymous test doubles can be useful as a stepping stone towards
|
4
|
+
actual fakes and when migrating from another testing library.
|
5
|
+
|
6
|
+
In contrast with other testing libraries, Bogus makes it's fakes
|
7
|
+
respond to all methods by default and makes those calls chainable.
|
8
|
+
This way you can spy on methods without stubbing them first.
|
9
|
+
|
10
|
+
It is not advisable to use those for anything else than an intermediate step.
|
11
|
+
Fakes that mimic an actual class have many more benefits.
|
12
|
+
|
13
|
+
Background:
|
14
|
+
Given a file named "foo.rb" with:
|
15
|
+
"""ruby
|
16
|
+
class Student
|
17
|
+
attr_reader :library_card
|
18
|
+
|
19
|
+
def initialize(name)
|
20
|
+
@name = name
|
21
|
+
end
|
22
|
+
|
23
|
+
def sign_up(library)
|
24
|
+
@library_card = library.register_junior(@name)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
"""
|
28
|
+
|
29
|
+
Scenario: Stubbing any method with any parameters
|
30
|
+
Then spec file with following content should pass:
|
31
|
+
"""ruby
|
32
|
+
describe Student do
|
33
|
+
let(:library) { fake }
|
34
|
+
let(:jake) { Student.new("Jake") }
|
35
|
+
|
36
|
+
it "allows stubbing any method with any parameters" do
|
37
|
+
stub(library).register_junior { "the card" }
|
38
|
+
|
39
|
+
jake.sign_up(library)
|
40
|
+
|
41
|
+
jake.library_card.should == "the card"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
"""
|
45
|
+
|
46
|
+
Scenario: Stubbing methods in initializer
|
47
|
+
Then spec file with following content should pass:
|
48
|
+
"""ruby
|
49
|
+
describe Student do
|
50
|
+
let(:library) { fake(register_junior: "the card") }
|
51
|
+
let(:jake) { Student.new("Jake") }
|
52
|
+
|
53
|
+
it "allows stubbing any method with any parameters" do
|
54
|
+
jake.sign_up(library)
|
55
|
+
|
56
|
+
jake.library_card.should == "the card"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
"""
|
60
|
+
|
61
|
+
Scenario: Mocking any method with any parameters
|
62
|
+
Then spec file with following content should pass:
|
63
|
+
"""ruby
|
64
|
+
describe Student do
|
65
|
+
let(:library) { fake }
|
66
|
+
let(:jake) { Student.new("Jake") }
|
67
|
+
|
68
|
+
it "allows stubbing any method with any parameters" do
|
69
|
+
mock(library).register_junior("Jake") { "the card" }
|
70
|
+
|
71
|
+
jake.sign_up(library)
|
72
|
+
|
73
|
+
jake.library_card.should == "the card"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
"""
|
77
|
+
|
78
|
+
Scenario: Mocking any method with any parameters
|
79
|
+
Then spec file with following content should fail:
|
80
|
+
"""ruby
|
81
|
+
describe Student do
|
82
|
+
it "allows stubbing any method with any parameters" do
|
83
|
+
library = fake
|
84
|
+
mock(library).register_junior { "the card" }
|
85
|
+
end
|
86
|
+
end
|
87
|
+
"""
|
88
|
+
|
89
|
+
Scenario: Stubbing methods in initializer
|
90
|
+
Then spec file with following content should pass:
|
91
|
+
"""ruby
|
92
|
+
describe Student do
|
93
|
+
let(:library) { fake(register_junior: "the card") }
|
94
|
+
let(:jake) { Student.new("Jake") }
|
95
|
+
|
96
|
+
it "allows stubbing any method with any parameters" do
|
97
|
+
jake.sign_up(library)
|
98
|
+
|
99
|
+
jake.library_card.should == "the card"
|
100
|
+
end
|
101
|
+
end
|
102
|
+
"""
|
103
|
+
|
104
|
+
Scenario: Spying on method calls
|
105
|
+
Then spec file with following content should pass:
|
106
|
+
"""ruby
|
107
|
+
describe Student do
|
108
|
+
let(:library) { fake }
|
109
|
+
let(:jake) { Student.new("Jake") }
|
110
|
+
|
111
|
+
it "allows stubbing any method with any parameters" do
|
112
|
+
jake.sign_up(library)
|
113
|
+
|
114
|
+
library.should have_received.register_junior("Jake")
|
115
|
+
end
|
116
|
+
end
|
117
|
+
"""
|
118
|
+
|
119
|
+
Scenario: Invoking arbitrary methods
|
120
|
+
Then spec file with following content should pass:
|
121
|
+
"""ruby
|
122
|
+
describe Student do
|
123
|
+
let(:library) { fake }
|
124
|
+
|
125
|
+
it "allows stubbing any method with any parameters" do
|
126
|
+
library.foo.bar("hello").baz.should == library
|
127
|
+
end
|
128
|
+
end
|
129
|
+
"""
|
data/lib/bogus.rb
CHANGED
@@ -1,35 +1,13 @@
|
|
1
1
|
require 'dependor'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
autoload :Double, 'bogus/double'
|
11
|
-
autoload :Fake, 'bogus/fake'
|
12
|
-
autoload :FakeRegistry, 'bogus/fake_registry'
|
13
|
-
autoload :Injector, 'bogus/injector'
|
14
|
-
autoload :Interaction, 'bogus/interaction'
|
15
|
-
autoload :InteractionPresenter, 'bogus/interaction_presenter'
|
16
|
-
autoload :InteractionsRepository, 'bogus/interactions_repository'
|
17
|
-
autoload :InvocationMatcher, 'bogus/invocation_matcher'
|
18
|
-
autoload :MethodStringifier, 'bogus/method_stringifier'
|
19
|
-
autoload :MockingDSL, 'bogus/rspec_extensions'
|
20
|
-
autoload :OverwritesClasses, 'bogus/overwrites_classes'
|
21
|
-
autoload :ProxyClass, 'bogus/proxy_class'
|
22
|
-
autoload :PublicMethods, 'bogus/public_methods'
|
23
|
-
autoload :RRProxy, 'bogus/rr_proxy'
|
24
|
-
autoload :RSpecExtensions, 'bogus/rspec_extensions'
|
25
|
-
autoload :RecordInteractions, 'bogus/record_interactions'
|
26
|
-
autoload :RecordingProxy, 'bogus/recording_proxy'
|
27
|
-
autoload :RecordsDoubleInteractions, 'bogus/records_double_interactions'
|
28
|
-
autoload :RegistersCreatedFakes, 'bogus/registers_created_fakes'
|
29
|
-
autoload :Takes, 'bogus/takes'
|
30
|
-
autoload :VERSION, 'bogus/version'
|
31
|
-
autoload :VerifiesContracts, 'bogus/verifies_contracts'
|
32
|
-
autoload :VerifiesStubDefinition, 'bogus/verifies_stub_definition'
|
3
|
+
require_relative 'bogus/takes'
|
4
|
+
require_relative 'bogus/record_interactions'
|
5
|
+
require_relative 'bogus/rspec_extensions'
|
6
|
+
|
7
|
+
all_files = Dir[File.expand_path('../**/*.rb', __FILE__)]
|
8
|
+
all_files = all_files.reject{|f| f.include?('bogus/rspec') }.sort
|
9
|
+
all_files.each { |f| require f }
|
33
10
|
|
11
|
+
module Bogus
|
34
12
|
extend PublicMethods
|
35
13
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Bogus
|
2
|
+
class CreatesAnonymousStubs
|
3
|
+
extend Bogus::Takes
|
4
|
+
|
5
|
+
takes :creates_fakes, :create_stub
|
6
|
+
|
7
|
+
def create(methods = {})
|
8
|
+
object = RespondsToEverything.new
|
9
|
+
methods.each do |name, result|
|
10
|
+
create_stub.call(object).__send__(name) { result }
|
11
|
+
end
|
12
|
+
object
|
13
|
+
end
|
14
|
+
|
15
|
+
class RespondsToEverything
|
16
|
+
include RecordInteractions
|
17
|
+
|
18
|
+
def respond_to?(method)
|
19
|
+
true
|
20
|
+
end
|
21
|
+
|
22
|
+
def method_missing(name, *args, &block)
|
23
|
+
__record__(name, *args, &block)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -10,6 +10,7 @@ module Bogus
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def arguments_as_string(arguments)
|
13
|
+
arguments = fill_in_missing_names(arguments)
|
13
14
|
arguments.map{|type, name| argument_to_string(name, type) }.compact.join(', ')
|
14
15
|
end
|
15
16
|
|
@@ -27,5 +28,16 @@ module Bogus
|
|
27
28
|
end
|
28
29
|
end
|
29
30
|
|
31
|
+
def fill_in_missing_names(arguments)
|
32
|
+
noname_count = 0
|
33
|
+
arguments.map do |type, name|
|
34
|
+
unless name
|
35
|
+
name = "_noname_#{noname_count}"
|
36
|
+
noname_count += 1
|
37
|
+
end
|
38
|
+
[type, name]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
30
42
|
end
|
31
43
|
end
|
data/lib/bogus/public_methods.rb
CHANGED
@@ -25,16 +25,20 @@ module Bogus
|
|
25
25
|
@injector = Bogus::Injector.new
|
26
26
|
end
|
27
27
|
|
28
|
-
def create_stub(
|
29
|
-
inject.create_stub(
|
28
|
+
def create_stub(*args)
|
29
|
+
inject.create_stub(*args)
|
30
30
|
end
|
31
31
|
|
32
|
-
def create_mock(
|
33
|
-
inject.create_mock(
|
32
|
+
def create_mock(*args)
|
33
|
+
inject.create_mock(*args)
|
34
34
|
end
|
35
35
|
|
36
|
-
def have_received(
|
37
|
-
inject.invocation_matcher(
|
36
|
+
def have_received(*args)
|
37
|
+
inject.invocation_matcher(*args)
|
38
|
+
end
|
39
|
+
|
40
|
+
def create_anonymous_stub(*args)
|
41
|
+
inject.creates_anonymous_stubs.create(*args)
|
38
42
|
end
|
39
43
|
|
40
44
|
private
|
data/lib/bogus/rspec.rb
CHANGED
@@ -16,16 +16,20 @@ module Bogus
|
|
16
16
|
end
|
17
17
|
|
18
18
|
module MockingDSL
|
19
|
-
def
|
20
|
-
Bogus.
|
19
|
+
def fake(*args)
|
20
|
+
Bogus.create_anonymous_stub(*args)
|
21
21
|
end
|
22
22
|
|
23
|
-
def
|
24
|
-
Bogus.
|
23
|
+
def stub(*args)
|
24
|
+
Bogus.create_stub(*args)
|
25
25
|
end
|
26
26
|
|
27
|
-
def
|
28
|
-
Bogus.
|
27
|
+
def have_received(*args)
|
28
|
+
Bogus.have_received(*args)
|
29
|
+
end
|
30
|
+
|
31
|
+
def mock(*args)
|
32
|
+
Bogus.create_mock(*args)
|
29
33
|
end
|
30
34
|
end
|
31
35
|
end
|
@@ -5,6 +5,7 @@ class Bogus::VerifiesStubDefinition
|
|
5
5
|
|
6
6
|
def verify!(object, method_name, args)
|
7
7
|
stubbing_non_existent_method!(object, method_name) unless object.respond_to?(method_name)
|
8
|
+
return unless object.methods.include?(method_name)
|
8
9
|
method = object.method(method_name)
|
9
10
|
wrong_number_of_arguments!(method, args) if under_number_of_required_arguments?(method, args.size)
|
10
11
|
wrong_number_of_arguments!(method, args) if over_number_of_allowed_arguments?(method, args.size)
|
data/lib/bogus/version.rb
CHANGED
@@ -171,5 +171,19 @@ describe Bogus::CopiesClasses do
|
|
171
171
|
|
172
172
|
include_examples 'spying'
|
173
173
|
end
|
174
|
+
|
175
|
+
class SomeModel
|
176
|
+
def save(*)
|
177
|
+
# ignores arguments
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
context "copying classes with methods with nameless parameters" do
|
182
|
+
let(:klass) { SomeModel }
|
183
|
+
|
184
|
+
it "copies those methods" do
|
185
|
+
fake.should respond_to(:save)
|
186
|
+
end
|
187
|
+
end
|
174
188
|
end
|
175
189
|
|
@@ -73,4 +73,44 @@ describe Bogus::MockingDSL do
|
|
73
73
|
baz.foo("bar").should == :return_value
|
74
74
|
end
|
75
75
|
end
|
76
|
+
|
77
|
+
describe "#fake" do
|
78
|
+
include Bogus::MockingDSL
|
79
|
+
|
80
|
+
it "creates objects that can be stubbed" do
|
81
|
+
greeter = fake
|
82
|
+
|
83
|
+
stub(greeter).greet("Jake") { "Hello Jake" }
|
84
|
+
|
85
|
+
greeter.greet("Jake").should == "Hello Jake"
|
86
|
+
end
|
87
|
+
|
88
|
+
it "creates objects that can be mocked" do
|
89
|
+
greeter = fake
|
90
|
+
|
91
|
+
mock(greeter).greet("Jake") { "Hello Jake" }
|
92
|
+
|
93
|
+
greeter.greet("Jake").should == "Hello Jake"
|
94
|
+
end
|
95
|
+
|
96
|
+
it "creates objects with some methods stubbed by default" do
|
97
|
+
greeter = fake(greet: "Hello Jake")
|
98
|
+
|
99
|
+
greeter.greet("Jake").should == "Hello Jake"
|
100
|
+
end
|
101
|
+
|
102
|
+
it "creates objects that can be spied upon" do
|
103
|
+
greeter = fake
|
104
|
+
|
105
|
+
greeter.greet("Jake")
|
106
|
+
|
107
|
+
greeter.should have_received.greet("Jake")
|
108
|
+
end
|
109
|
+
|
110
|
+
it "allows chaining interactions" do
|
111
|
+
greeter = fake(foo: "bar")
|
112
|
+
|
113
|
+
greeter.baz.foo.should == "bar"
|
114
|
+
end
|
115
|
+
end
|
76
116
|
end
|
@@ -67,5 +67,28 @@ describe Bogus::VerifiesStubDefinition do
|
|
67
67
|
it_disallows_argument_numbers :var_args, 0
|
68
68
|
end
|
69
69
|
end
|
70
|
+
|
71
|
+
class UsesMethodMissing
|
72
|
+
def respond_to?(method)
|
73
|
+
method == :foo
|
74
|
+
end
|
75
|
+
|
76
|
+
def method_missing(name, *args, &block)
|
77
|
+
return super unless name == :foo
|
78
|
+
:bar
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
context "with objects that use method missing" do
|
83
|
+
let(:object) { UsesMethodMissing.new }
|
84
|
+
|
85
|
+
it "allows stubbing methods that the object responds to" do
|
86
|
+
it_allows(:foo, [])
|
87
|
+
end
|
88
|
+
|
89
|
+
it "disallows stubbing methods that the object does not respond to" do
|
90
|
+
it_disallows(:bar, [], NameError)
|
91
|
+
end
|
92
|
+
end
|
70
93
|
end
|
71
94
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bogus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-11-01 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: dependor
|
@@ -198,12 +198,14 @@ files:
|
|
198
198
|
- .gitignore
|
199
199
|
- .pelusa.yml
|
200
200
|
- .travis.yml
|
201
|
+
- CHANGELOG.md
|
201
202
|
- Gemfile
|
202
203
|
- Gemfile.lock
|
203
204
|
- Guardfile
|
204
205
|
- README.md
|
205
206
|
- Rakefile
|
206
207
|
- bogus.gemspec
|
208
|
+
- features/anonymous_doubles.feature
|
207
209
|
- features/configuration_options.feature
|
208
210
|
- features/contract_tests_mocks.feature
|
209
211
|
- features/contract_tests_spies.feature
|
@@ -221,6 +223,7 @@ files:
|
|
221
223
|
- lib/bogus/contract_not_fulfilled.rb
|
222
224
|
- lib/bogus/converts_name_to_class.rb
|
223
225
|
- lib/bogus/copies_classes.rb
|
226
|
+
- lib/bogus/creates_anonymous_stubs.rb
|
224
227
|
- lib/bogus/creates_fakes.rb
|
225
228
|
- lib/bogus/double.rb
|
226
229
|
- lib/bogus/fake.rb
|
@@ -280,7 +283,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
280
283
|
version: '0'
|
281
284
|
segments:
|
282
285
|
- 0
|
283
|
-
hash: -
|
286
|
+
hash: -343777807
|
284
287
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
285
288
|
none: false
|
286
289
|
requirements:
|
@@ -289,7 +292,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
289
292
|
version: '0'
|
290
293
|
segments:
|
291
294
|
- 0
|
292
|
-
hash: -
|
295
|
+
hash: -343777807
|
293
296
|
requirements: []
|
294
297
|
rubyforge_project: bogus
|
295
298
|
rubygems_version: 1.8.24
|