bogus 0.0.4 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile.lock +19 -1
  3. data/Guardfile +0 -7
  4. data/Guardfile.cucumber +9 -0
  5. data/README.md +42 -6
  6. data/bogus.gemspec +3 -0
  7. data/features/.nav +5 -2
  8. data/features/authors.md +10 -2
  9. data/features/changelog.md +11 -0
  10. data/features/configuration/fake_ar_attributes.feature +51 -0
  11. data/features/configuration/readme.md +7 -0
  12. data/features/{configuration_options.feature → configuration/search_modules.feature} +2 -2
  13. data/features/fakes/anonymous_doubles.feature +11 -7
  14. data/features/fakes/fake_objects.feature +0 -16
  15. data/lib/bogus/active_record_accessors.rb +41 -0
  16. data/lib/bogus/class_methods.rb +1 -1
  17. data/lib/bogus/configuration.rb +1 -0
  18. data/lib/bogus/constructor_methods.rb +18 -0
  19. data/lib/bogus/copies_methods.rb +7 -5
  20. data/lib/bogus/creates_fakes.rb +1 -1
  21. data/lib/bogus/creates_fakes_with_stubbed_methods.rb +1 -1
  22. data/lib/bogus/ensures_all_interactions_satisfied.rb +0 -2
  23. data/lib/bogus/fake.rb +8 -0
  24. data/lib/bogus/injector.rb +10 -0
  25. data/lib/bogus/instance_methods.rb +1 -1
  26. data/lib/bogus/interaction.rb +22 -3
  27. data/lib/bogus/interaction_presenter.rb +1 -1
  28. data/lib/bogus/makes_ducks.rb +5 -6
  29. data/lib/bogus/makes_subtypes.rb +1 -1
  30. data/lib/bogus/method_stringifier.rb +16 -8
  31. data/lib/bogus/record_interactions.rb +1 -1
  32. data/lib/bogus/records_double_interactions.rb +8 -7
  33. data/lib/bogus/registers_created_fakes.rb +10 -8
  34. data/lib/bogus/responds_to_everything.rb +8 -1
  35. data/lib/bogus/shadow.rb +3 -2
  36. data/lib/bogus/undefined_return_value.rb +11 -0
  37. data/lib/bogus/verifies_contracts.rb +12 -10
  38. data/lib/bogus/verifies_stub_definition.rb +37 -41
  39. data/lib/bogus/version.rb +1 -1
  40. data/spec/bogus/copies_classes_spec.rb +13 -6
  41. data/spec/bogus/creates_fakes_spec.rb +1 -1
  42. data/spec/bogus/fake_ar_attributes_spec.rb +72 -0
  43. data/spec/bogus/faking_factories_spec.rb +83 -0
  44. data/spec/bogus/frozen_fakes_spec.rb +59 -0
  45. data/spec/bogus/interaction_spec.rb +4 -0
  46. data/spec/bogus/method_copiers_spec.rb +26 -0
  47. data/spec/bogus/mocking_dsl_spec.rb +7 -3
  48. data/spec/bogus/overwrites_methods_spec.rb +2 -2
  49. data/spec/bogus/record_interactions_spec.rb +1 -1
  50. data/spec/bogus/ruby_2_support_spec.rb +96 -0
  51. data/spec/bogus/shadow_spec.rb +10 -8
  52. data/spec/bogus/verifies_stub_definition_spec.rb +1 -1
  53. data/spec/spec_helper.rb +1 -1
  54. data/spec/support/matchers.rb +3 -0
  55. metadata +76 -66
data/lib/bogus/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Bogus
2
- VERSION = "0.0.4"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -51,10 +51,6 @@ describe Bogus::CopiesClasses do
51
51
  subject.baa('hello')
52
52
  subject.baa('hello') {}
53
53
  end
54
-
55
- it "makes the methods chainable" do
56
- subject.foo.bar('hello').baz('hello', 'world', 'foo').bam.baa('foo')
57
- end
58
54
  end
59
55
 
60
56
  let(:copies_classes) { Bogus.inject.copies_classes }
@@ -77,11 +73,22 @@ describe Bogus::CopiesClasses do
77
73
  Class.new do
78
74
  def initialize(hello)
79
75
  end
76
+
77
+ def foo
78
+ end
80
79
  end
81
80
  }
82
81
 
83
- it "adds a constructor that allows passing any number of arguments" do
84
- fake_class.new('hello', 'w', 'o', 'r', 'l', 'd') { test }
82
+ it "adds a no-arg constructor" do
83
+ instance = fake_class.__create__
84
+
85
+ instance.should respond_to(:foo)
86
+ end
87
+
88
+ it "adds a constructor that allows passing the correct number of arguments" do
89
+ instance = fake_class.new('hello')
90
+
91
+ instance.should respond_to(:foo)
85
92
  end
86
93
  end
87
94
 
@@ -14,7 +14,7 @@ describe Bogus::CreatesFakes do
14
14
  module Bar
15
15
  end
16
16
 
17
- before { stub(fake_class).new{fake_instance} }
17
+ before { stub(fake_class).__create__{fake_instance} }
18
18
 
19
19
  context "without block" do
20
20
  before do
@@ -0,0 +1,72 @@
1
+ require 'spec_helper'
2
+ require 'active_record'
3
+ require 'nulldb'
4
+
5
+ describe "Stubbing ActiveRecord::Base subclasses" do
6
+ ActiveRecord::Schema.verbose = false
7
+ ActiveRecord::Base.establish_connection :adapter => :nulldb
8
+
9
+ ActiveRecord::Schema.define do
10
+ create_table :blog_posts do |t|
11
+ t.string :name
12
+ t.string :author
13
+ end
14
+ end
15
+
16
+ class BlogPost < ActiveRecord::Base
17
+ def author(x)
18
+ "#{x} #{self[:author]}!"
19
+ end
20
+ end
21
+
22
+ include Bogus::MockingDSL
23
+
24
+ before do
25
+ Bogus.configure do |c|
26
+ c.fake_ar_attributes = true
27
+ end
28
+ end
29
+
30
+ it "makes it possible to stub active record fields" do
31
+ post = fake(:blog_post, name: "hello")
32
+
33
+ post.name.should == "hello"
34
+ end
35
+
36
+ it "works only when enabled in configuration" do
37
+ Bogus.configure do |c|
38
+ c.fake_ar_attributes = false
39
+ end
40
+
41
+ expect {
42
+ fake(:blog_post, name: "hello")
43
+ }.to raise_error(NameError)
44
+ end
45
+
46
+ it "does not overwrite existing method signatures" do
47
+ post = fake(:blog_post)
48
+
49
+ post.author("hello")
50
+
51
+ post.should have_received.author("hello")
52
+ end
53
+
54
+ class ExampleForActiveRecordAttributes
55
+ def foo(x)
56
+ end
57
+ end
58
+
59
+ it "does not interfere with non-ar classes" do
60
+ fake = fake(:example_for_active_record_attributes)
61
+
62
+ fake.foo(1)
63
+
64
+ fake.should have_received.foo(1)
65
+ end
66
+
67
+ after do
68
+ Bogus.configure do |c|
69
+ c.fake_ar_attributes = false
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,83 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Faking Factories" do
4
+ include Bogus::MockingDSL
5
+
6
+ class ExampleFactory
7
+ def initialize(model_class)
8
+ @model_class = model_class
9
+ end
10
+
11
+ def create(y)
12
+ @model_class.new(1, y)
13
+ end
14
+ end
15
+
16
+ class ExampleModel1
17
+ def initialize(x, y)
18
+ end
19
+ end
20
+
21
+ it "allows spying on factory classes" do
22
+ model_class = fake(:example_model, as: :class) { ExampleModel1 }
23
+ factory = ExampleFactory.new(model_class)
24
+
25
+ factory.create(2)
26
+
27
+ model_class.should have_received.new(1, 2)
28
+ end
29
+
30
+ class ExampleModel2
31
+ def initialize(x, y, z)
32
+ end
33
+ end
34
+
35
+ it "retains the arity safety" do
36
+ model_class = fake(:example_model, as: :class) { ExampleModel2 }
37
+ factory = ExampleFactory.new(model_class)
38
+
39
+ expect {
40
+ factory.create(2)
41
+ }.to raise_error(ArgumentError)
42
+ end
43
+
44
+ class ExampleModel3
45
+ end
46
+
47
+ it "works with classes with no explicit constructor" do
48
+ model_class = fake(:example_model, as: :class) { ExampleModel3 }
49
+
50
+ model = model_class.new
51
+
52
+ model_class.should have_received.new
53
+ end
54
+
55
+ class ExampleModel4
56
+ def initialize(y)
57
+ end
58
+
59
+ def foo(x)
60
+ end
61
+ end
62
+
63
+ it "allows creating the model instances as usual" do
64
+ model = fake(:example_model) { ExampleModel4 }
65
+
66
+ model.foo(1)
67
+
68
+ model.should have_received.foo(1)
69
+ end
70
+
71
+ module ExampleModel5
72
+ def self.foo(x)
73
+ end
74
+ end
75
+
76
+ it "allows creating fakes of modules as usual" do
77
+ model = fake(:example_model, as: :class) { ExampleModel5 }
78
+
79
+ model.foo(1)
80
+
81
+ model.should have_received.foo(1)
82
+ end
83
+ end
@@ -0,0 +1,59 @@
1
+ require "spec_helper"
2
+
3
+ describe "Frozen Fakes" do
4
+ include Bogus::MockingDSL
5
+
6
+ class ExampleForFreezing
7
+ def foo(x)
8
+ end
9
+ end
10
+
11
+ shared_examples_for "frozen fakes" do
12
+ before { object.freeze }
13
+
14
+ describe "stubbing" do
15
+ it "allows stubbing" do
16
+ stub(object).foo(1) { 123 }
17
+
18
+ object.foo(1).should == 123
19
+ end
20
+ end
21
+
22
+ describe "mocking" do
23
+ it "allows mocking" do
24
+ mock(object).foo(1) { 123 }
25
+
26
+ object.foo(1).should == 123
27
+ end
28
+
29
+ it "allows verifying expectations" do
30
+ mock(object).foo(1) { 123 }
31
+
32
+ expect {
33
+ Bogus.after_each_test
34
+ }.to raise_error(Bogus::NotAllExpectationsSatisfied)
35
+ end
36
+ end
37
+
38
+ describe "spying" do
39
+ it "allows spying" do
40
+ object.foo(1)
41
+
42
+ object.should have_received.foo(1)
43
+ object.should_not have_received.foo(2)
44
+ end
45
+ end
46
+ end
47
+
48
+ context "anonymous fakes" do
49
+ let(:object) { fake }
50
+
51
+ include_examples "frozen fakes"
52
+ end
53
+
54
+ context "named fakes" do
55
+ let(:object) { fake(:example_for_freezing) }
56
+
57
+ include_examples "frozen fakes"
58
+ end
59
+ end
@@ -6,6 +6,9 @@ describe Bogus::Interaction do
6
6
  same = [
7
7
  [[:foo, [:bar], "value"], [:foo, [:bar], "value"]],
8
8
  [[:foo, [:bar, Bogus::DefaultValue], "value"], [:foo, [:bar], "value"]],
9
+ [[:foo, [:bar, {foo: Bogus::DefaultValue}], "value"], [:foo, [:bar], "value"]],
10
+ [[:foo, [:bar, {foo: Bogus::DefaultValue}], "value"], [:foo, [:bar, {}], "value"]],
11
+ [[:foo, [:bar, {foo: Bogus::DefaultValue, bar: 1}], "value"], [:foo, [:bar, {bar: 1}], "value"]],
9
12
  [[:foo, [:bar]], [:foo, [:bar], "value"]],
10
13
  [[:foo, [:bar], "value"], [:foo, [:bar]]],
11
14
  [[:foo, [:bar]], [:foo, [:bar]]],
@@ -23,6 +26,7 @@ describe Bogus::Interaction do
23
26
  [[:foo, [:bar], "value"], [:baz, [:bar], "value"]],
24
27
  [[:foo, [:baz], "value"], [:foo, [:bar], "value"]],
25
28
  [[:foo, [Bogus::DefaultValue, :baz], "value"], [:foo, [:bar, :bar], "value"]],
29
+ [[:foo, [:bar, {foo: Bogus::DefaultValue, bar: 1}], "value"], [:foo, [:bar, {bar: 2}], "value"]],
26
30
  [[:foo, [Bogus::AnyArgs]], [:bar, [:bar]]],
27
31
  [[:foo, [:bar]], [:bar, [Bogus::AnyArgs]]],
28
32
  [[:foo, [Bogus::AnyArgs], "some value"], [:foo, [:bar], "other value"]],
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Method Copiers" do
4
+ shared_examples_for "method copier" do
5
+ let(:klass) { Class.new }
6
+ subject { isolate(described_class) }
7
+
8
+ it { should respond_to(:all) }
9
+ it { should respond_to(:get) }
10
+ it { should respond_to(:remove) }
11
+ it { should respond_to(:define) }
12
+ end
13
+
14
+ describe Bogus::InstanceMethods do
15
+ it_behaves_like "method copier"
16
+ end
17
+
18
+ describe Bogus::ClassMethods do
19
+ it_behaves_like "method copier"
20
+ end
21
+
22
+ describe Bogus::ActiveRecordAccessors do
23
+ let(:instance_methods) { nil }
24
+ it_behaves_like "method copier"
25
+ end
26
+ end
@@ -269,12 +269,16 @@ describe Bogus::MockingDSL do
269
269
  greeter.greet("Jake")
270
270
 
271
271
  greeter.should have_received.greet("Jake")
272
+ greeter.should_not have_received.greet("Bob")
272
273
  end
273
274
 
274
- it "allows chaining interactions" do
275
- greeter = fake(foo: "bar")
275
+ it "verifies mock expectations set on anonymous fakes" do
276
+ greeter = fake
277
+ mock(greeter).greet("Jake") { "Hello Jake" }
276
278
 
277
- greeter.baz.foo.should == "bar"
279
+ expect {
280
+ Bogus.after_each_test
281
+ }.to raise_error(Bogus::NotAllExpectationsSatisfied)
278
282
  end
279
283
  end
280
284
 
@@ -24,7 +24,7 @@ module Bogus
24
24
  end
25
25
 
26
26
  it "does not change the method signature" do
27
- object.greet("John").should == object
27
+ object.method(:greet).arity.should == 1
28
28
  end
29
29
 
30
30
  it "does not change the method signature" do
@@ -75,7 +75,7 @@ module Bogus
75
75
  end
76
76
 
77
77
  it "can overwrite the non-existent methods" do
78
- object.greet.should equal(object)
78
+ object.methods.should include(:greet)
79
79
  end
80
80
 
81
81
  it "can be reset back to the original state" do
@@ -21,6 +21,6 @@ describe Bogus::RecordInteractions do
21
21
  end
22
22
 
23
23
  it "returns self from record by default" do
24
- sample.__record__(:foo).should == sample
24
+ sample.__record__(:foo).should be_a_default_return_value
25
25
  end
26
26
  end
@@ -0,0 +1,96 @@
1
+ require 'spec_helper'
2
+
3
+ if RUBY_VERSION >= '2.0'
4
+ describe "Ruby 2.0 keyword arguments" do
5
+ class ExampleForKeywordArgs
6
+ eval "def foo(x: raise, y: 1); end"
7
+ eval "def bar(x: 1, **rest); end"
8
+ end
9
+
10
+ include Bogus::MockingDSL
11
+
12
+ shared_examples_for "stubbing methods with keyword arguments" do
13
+ it "can spy on stubbed methods" do
14
+ stub(subject).foo(any_args)
15
+
16
+ subject.foo(x: "test")
17
+
18
+ subject.should have_received.foo(x: "test")
19
+ subject.should_not have_received.foo(x: "baz")
20
+ end
21
+
22
+ it "can mock methods with keyword arguments" do
23
+ mock(subject).foo(x: 1) { :return }
24
+
25
+ subject.foo(x: 1).should == :return
26
+
27
+ expect { Bogus.after_each_test }.not_to raise_error
28
+ end
29
+
30
+ it "can stub methods with keyword arguments" do
31
+ stub(subject).foo(x: "bar") { :return_value }
32
+
33
+ subject.foo(x: "bar").should == :return_value
34
+ end
35
+
36
+ it "raises on error on unknown keyword" do
37
+ expect {
38
+ stub(subject).foo(x: "bar", baz: "baz")
39
+ }.to raise_error(ArgumentError)
40
+ end
41
+
42
+ it "does not overwrite the method signature" do
43
+ stub(subject).foo(x: 1)
44
+
45
+ expect {
46
+ subject.foo(bar: 1)
47
+ }.to raise_error(ArgumentError)
48
+ end
49
+ end
50
+
51
+ shared_examples_for "stubbing methods with double splat" do
52
+ it "can spy on stubbed methods" do
53
+ stub(subject).bar(any_args)
54
+
55
+ subject.bar(x: "test", z: "spec")
56
+
57
+ subject.should have_received.bar(x: "test", z: "spec")
58
+ subject.should_not have_received.bar(y: "baz")
59
+ end
60
+
61
+ it "can mock methods with keyword arguments" do
62
+ mock(subject).bar(x: 1, z: 2) { :return }
63
+
64
+ subject.bar(x: 1, z: 2).should == :return
65
+
66
+ expect { Bogus.after_each_test }.not_to raise_error
67
+ end
68
+
69
+ it "can stub methods with keyword arguments" do
70
+ stub(subject).bar(x: "bar", z: "bar") { :return_value }
71
+
72
+ subject.bar(x: "bar", z: "bar").should == :return_value
73
+ end
74
+ end
75
+
76
+ context "with regular objects" do
77
+ subject { ExampleForKeywordArgs.new }
78
+
79
+ include_examples "stubbing methods with keyword arguments"
80
+ include_examples "stubbing methods with double splat"
81
+ end
82
+
83
+ context "with fakes" do
84
+ subject { fake(:example_for_keyword_args) }
85
+
86
+ it "allows spying without stubbing" do
87
+ subject.foo(x: "test")
88
+
89
+ subject.should have_received.foo(x: "test")
90
+ end
91
+
92
+ include_examples "stubbing methods with keyword arguments"
93
+ include_examples "stubbing methods with double splat"
94
+ end
95
+ end
96
+ end