bogus 0.0.1 → 0.0.2

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.
@@ -2,5 +2,4 @@ language: ruby
2
2
  rvm:
3
3
  - 1.9.2
4
4
  - 1.9.3
5
- - rbx-19mode
6
5
  script: bundle exec rspec spec && bundle exec cucumber --tag ~@wip
@@ -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.
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- bogus (0.0.1)
4
+ bogus (0.0.2)
5
5
  dependor (>= 0.0.4)
6
6
  rr
7
7
 
@@ -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
+ """
@@ -5,9 +5,7 @@ Given /^a spec file named "([^"]*)" with:$/ do |file_name, string|
5
5
  steps %Q{
6
6
  Given a file named "#{file_name}" with:
7
7
  """ruby
8
- require 'bogus'
9
8
  require 'bogus/rspec'
10
- require 'rr'
11
9
 
12
10
  require_relative 'foo'
13
11
 
@@ -1,35 +1,13 @@
1
1
  require 'dependor'
2
2
 
3
- module Bogus
4
- autoload :AddsRecording, 'bogus/adds_recording'
5
- autoload :Configuration, 'bogus/configuration'
6
- autoload :ContractNotFulfilled, 'bogus/contract_not_fulfilled'
7
- autoload :ConvertsNameToClass, 'bogus/converts_name_to_class'
8
- autoload :CopiesClasses, 'bogus/copies_classes'
9
- autoload :CreatesFakes, 'bogus/creates_fakes'
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
@@ -25,16 +25,20 @@ module Bogus
25
25
  @injector = Bogus::Injector.new
26
26
  end
27
27
 
28
- def create_stub(object)
29
- inject.create_stub(object)
28
+ def create_stub(*args)
29
+ inject.create_stub(*args)
30
30
  end
31
31
 
32
- def create_mock(object)
33
- inject.create_mock(object)
32
+ def create_mock(*args)
33
+ inject.create_mock(*args)
34
34
  end
35
35
 
36
- def have_received(method = nil)
37
- inject.invocation_matcher(method)
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
@@ -1,3 +1,5 @@
1
+ require 'bogus'
2
+
1
3
  RSpec.configure do |config|
2
4
  config.extend Bogus::RSpecExtensions
3
5
  config.include Bogus::MockingDSL
@@ -16,16 +16,20 @@ module Bogus
16
16
  end
17
17
 
18
18
  module MockingDSL
19
- def stub(object)
20
- Bogus.create_stub(object)
19
+ def fake(*args)
20
+ Bogus.create_anonymous_stub(*args)
21
21
  end
22
22
 
23
- def have_received(method = nil)
24
- Bogus.have_received(method)
23
+ def stub(*args)
24
+ Bogus.create_stub(*args)
25
25
  end
26
26
 
27
- def mock(object)
28
- Bogus.create_mock(object)
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)
@@ -1,3 +1,3 @@
1
1
  module Bogus
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -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.1
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-07-30 00:00:00.000000000 Z
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: -1064750600305128815
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: -1064750600305128815
295
+ hash: -343777807
293
296
  requirements: []
294
297
  rubyforge_project: bogus
295
298
  rubygems_version: 1.8.24