bogus 0.0.4 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile.lock +19 -1
- data/Guardfile +0 -7
- data/Guardfile.cucumber +9 -0
- data/README.md +42 -6
- data/bogus.gemspec +3 -0
- data/features/.nav +5 -2
- data/features/authors.md +10 -2
- data/features/changelog.md +11 -0
- data/features/configuration/fake_ar_attributes.feature +51 -0
- data/features/configuration/readme.md +7 -0
- data/features/{configuration_options.feature → configuration/search_modules.feature} +2 -2
- data/features/fakes/anonymous_doubles.feature +11 -7
- data/features/fakes/fake_objects.feature +0 -16
- data/lib/bogus/active_record_accessors.rb +41 -0
- data/lib/bogus/class_methods.rb +1 -1
- data/lib/bogus/configuration.rb +1 -0
- data/lib/bogus/constructor_methods.rb +18 -0
- data/lib/bogus/copies_methods.rb +7 -5
- data/lib/bogus/creates_fakes.rb +1 -1
- data/lib/bogus/creates_fakes_with_stubbed_methods.rb +1 -1
- data/lib/bogus/ensures_all_interactions_satisfied.rb +0 -2
- data/lib/bogus/fake.rb +8 -0
- data/lib/bogus/injector.rb +10 -0
- data/lib/bogus/instance_methods.rb +1 -1
- data/lib/bogus/interaction.rb +22 -3
- data/lib/bogus/interaction_presenter.rb +1 -1
- data/lib/bogus/makes_ducks.rb +5 -6
- data/lib/bogus/makes_subtypes.rb +1 -1
- data/lib/bogus/method_stringifier.rb +16 -8
- data/lib/bogus/record_interactions.rb +1 -1
- data/lib/bogus/records_double_interactions.rb +8 -7
- data/lib/bogus/registers_created_fakes.rb +10 -8
- data/lib/bogus/responds_to_everything.rb +8 -1
- data/lib/bogus/shadow.rb +3 -2
- data/lib/bogus/undefined_return_value.rb +11 -0
- data/lib/bogus/verifies_contracts.rb +12 -10
- data/lib/bogus/verifies_stub_definition.rb +37 -41
- data/lib/bogus/version.rb +1 -1
- data/spec/bogus/copies_classes_spec.rb +13 -6
- data/spec/bogus/creates_fakes_spec.rb +1 -1
- data/spec/bogus/fake_ar_attributes_spec.rb +72 -0
- data/spec/bogus/faking_factories_spec.rb +83 -0
- data/spec/bogus/frozen_fakes_spec.rb +59 -0
- data/spec/bogus/interaction_spec.rb +4 -0
- data/spec/bogus/method_copiers_spec.rb +26 -0
- data/spec/bogus/mocking_dsl_spec.rb +7 -3
- data/spec/bogus/overwrites_methods_spec.rb +2 -2
- data/spec/bogus/record_interactions_spec.rb +1 -1
- data/spec/bogus/ruby_2_support_spec.rb +96 -0
- data/spec/bogus/shadow_spec.rb +10 -8
- data/spec/bogus/verifies_stub_definition_spec.rb +1 -1
- data/spec/spec_helper.rb +1 -1
- data/spec/support/matchers.rb +3 -0
- metadata +76 -66
data/lib/bogus/version.rb
CHANGED
@@ -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
|
84
|
-
fake_class.
|
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
|
|
@@ -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 "
|
275
|
-
greeter = fake
|
275
|
+
it "verifies mock expectations set on anonymous fakes" do
|
276
|
+
greeter = fake
|
277
|
+
mock(greeter).greet("Jake") { "Hello Jake" }
|
276
278
|
|
277
|
-
|
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
|
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.
|
78
|
+
object.methods.should include(:greet)
|
79
79
|
end
|
80
80
|
|
81
81
|
it "can be reset back to the original state" do
|
@@ -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
|