bogus 0.0.2 → 0.0.3.rc.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/Gemfile.lock +14 -2
- data/Guardfile +5 -0
- data/README.md +7 -249
- data/bogus.gemspec +3 -1
- data/features/.nav +21 -0
- data/features/authors.md +42 -0
- data/{CHANGELOG.md → features/changelog.md} +9 -2
- data/features/configuration_options.feature +1 -2
- data/features/{contract_tests_mocks.feature → contract_tests/contract_tests_mocks.feature} +4 -1
- data/features/{contract_tests_spies.feature → contract_tests/contract_tests_spies.feature} +2 -0
- data/features/{contract_tests_stubs.feature → contract_tests/contract_tests_stubs.feature} +14 -0
- data/features/contract_tests/readme.md +26 -0
- data/features/{return_value_contracts.feature → contract_tests/return_value_contracts.feature} +6 -2
- data/features/{anonymous_doubles.feature → fakes/anonymous_doubles.feature} +24 -8
- data/features/{fake_objects.feature → fakes/fake_objects.feature} +39 -4
- data/features/fakes/global_fake_configuration.feature +88 -0
- data/features/fakes/readme.md +11 -0
- data/features/fakes/replacing_classes.feature +148 -0
- data/features/getting_started.md +36 -0
- data/features/license.md +9 -0
- data/features/readme.md +173 -0
- data/features/safe_stubbing/argument_matchers.feature +30 -0
- data/features/safe_stubbing/readme.md +35 -0
- data/features/{safe_mocking.feature → safe_stubbing/safe_mocking.feature} +14 -0
- data/features/{safe_stubbing.feature → safe_stubbing/safe_stubbing.feature} +18 -4
- data/features/{spies.feature → safe_stubbing/spies.feature} +19 -4
- data/features/step_definitions/rspec_steps.rb +14 -5
- data/features/support/env.rb +4 -0
- data/lib/bogus.rb +2 -0
- data/lib/bogus/adds_recording.rb +11 -7
- data/lib/bogus/any_args.rb +7 -0
- data/lib/bogus/anything.rb +11 -0
- data/lib/bogus/contract_not_fulfilled.rb +17 -10
- data/lib/bogus/copies_classes.rb +2 -6
- data/lib/bogus/creates_fakes_with_stubbed_methods.rb +40 -0
- data/lib/bogus/double.rb +28 -8
- data/lib/bogus/ensures_all_interactions_satisfied.rb +36 -0
- data/lib/bogus/fake.rb +6 -0
- data/lib/bogus/fake_configuration.rb +69 -0
- data/lib/bogus/fakes_classes.rb +21 -0
- data/lib/bogus/has_overwritten_methods.rb +24 -0
- data/lib/bogus/have_received_matcher.rb +63 -0
- data/lib/bogus/injector.rb +36 -14
- data/lib/bogus/interaction.rb +33 -17
- data/lib/bogus/makes_substitute_methods.rb +15 -0
- data/lib/bogus/mocking_dsl.rb +31 -0
- data/lib/bogus/multi_stubber.rb +15 -0
- data/lib/bogus/not_all_expectations_satisfied.rb +27 -0
- data/lib/bogus/overwriten_classes.rb +15 -0
- data/lib/bogus/overwrites_classes.rb +2 -2
- data/lib/bogus/overwrites_methods.rb +42 -0
- data/lib/bogus/proxies_method_calls.rb +23 -0
- data/lib/bogus/proxy_class.rb +25 -16
- data/lib/bogus/public_methods.rb +36 -11
- data/lib/bogus/record_interactions.rb +3 -9
- data/lib/bogus/recording_proxy.rb +5 -0
- data/lib/bogus/registers_created_fakes.rb +2 -1
- data/lib/bogus/resets_overwritten_classes.rb +14 -0
- data/lib/bogus/resets_stubbed_methods.rb +12 -0
- data/lib/bogus/responds_to_everything.rb +11 -0
- data/lib/bogus/rspec.rb +7 -0
- data/lib/bogus/rspec_adapter.rb +17 -0
- data/lib/bogus/rspec_extensions.rb +8 -20
- data/lib/bogus/shadow.rb +60 -0
- data/lib/bogus/verifies_contracts.rb +5 -1
- data/lib/bogus/verifies_stub_definition.rb +5 -0
- data/lib/bogus/version.rb +1 -1
- data/lib/tracks_existence_of_test_doubles.rb +11 -0
- data/spec/bogus/adds_recording_spec.rb +46 -10
- data/spec/bogus/anything_spec.rb +13 -0
- data/spec/bogus/copies_classes_spec.rb +4 -3
- data/spec/bogus/creates_fakes_with_stubbed_methods_spec.rb +121 -0
- data/spec/bogus/double_spec.rb +63 -20
- data/spec/bogus/ensures_all_interactions_satisfied_spec.rb +43 -0
- data/spec/bogus/fake_configuration_spec.rb +99 -0
- data/spec/bogus/fakes_classes_spec.rb +46 -0
- data/spec/bogus/have_received_matcher_spec.rb +56 -0
- data/spec/bogus/interaction_spec.rb +18 -7
- data/spec/bogus/interactions_repository_spec.rb +42 -0
- data/spec/bogus/makes_substitute_methods_spec.rb +24 -0
- data/spec/bogus/mocking_dsl_spec.rb +234 -7
- data/spec/bogus/multi_stubber_spec.rb +31 -0
- data/spec/bogus/overwriten_classes_spec.rb +27 -0
- data/spec/bogus/overwrites_classes_spec.rb +2 -2
- data/spec/bogus/overwrites_methods_spec.rb +107 -0
- data/spec/bogus/proxy_class_spec.rb +6 -0
- data/spec/bogus/record_interactions_spec.rb +3 -4
- data/spec/bogus/registers_created_fakes_spec.rb +8 -0
- data/spec/bogus/resets_overwritten_classes_spec.rb +26 -0
- data/spec/bogus/resets_stubbed_methods_spec.rb +16 -0
- data/spec/bogus/shadow_spec.rb +182 -0
- data/spec/bogus/verifies_contracts_spec.rb +9 -3
- data/spec/bogus/verifies_stub_definition_spec.rb +4 -0
- data/spec/spec_helper.rb +3 -0
- data/spec/support/fake_creator_of_fakes.rb +15 -0
- data/spec/support/sample_fake.rb +13 -0
- data/spec/tracks_existence_of_test_doubles_spec.rb +26 -0
- metadata +105 -32
- data/lib/bogus/creates_anonymous_stubs.rb +0 -27
- data/lib/bogus/invocation_matcher.rb +0 -27
- data/lib/bogus/rr_proxy.rb +0 -5
- data/spec/bogus/invocation_matcher_spec.rb +0 -26
data/Gemfile.lock
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
bogus (0.0.
|
4
|
+
bogus (0.0.3.rc.1)
|
5
5
|
dependor (>= 0.0.4)
|
6
|
-
rr
|
7
6
|
|
8
7
|
GEM
|
9
8
|
remote: http://rubygems.org/
|
10
9
|
specs:
|
10
|
+
archive-tar-minitar (0.5.2)
|
11
11
|
aruba (0.4.11)
|
12
12
|
childprocess (>= 0.2.3)
|
13
13
|
cucumber (>= 1.1.1)
|
@@ -30,6 +30,8 @@ GEM
|
|
30
30
|
guard (1.1.1)
|
31
31
|
listen (>= 0.4.2)
|
32
32
|
thor (>= 0.14.6)
|
33
|
+
guard-ctags-bundler (0.1.6)
|
34
|
+
guard (>= 1.1)
|
33
35
|
guard-cucumber (1.1.0)
|
34
36
|
cucumber (>= 1.2.0)
|
35
37
|
guard (>= 1.1.0)
|
@@ -42,12 +44,19 @@ GEM
|
|
42
44
|
rb-fchange (~> 0.0.5)
|
43
45
|
rb-fsevent (~> 0.9.1)
|
44
46
|
rb-inotify (~> 0.8.8)
|
47
|
+
mime-types (1.19)
|
45
48
|
rake (0.9.2.2)
|
46
49
|
rb-fchange (0.0.5)
|
47
50
|
ffi
|
48
51
|
rb-fsevent (0.9.1)
|
49
52
|
rb-inotify (0.8.8)
|
50
53
|
ffi (>= 0.5.0)
|
54
|
+
relish (0.6)
|
55
|
+
archive-tar-minitar (>= 0.5.2)
|
56
|
+
json (>= 1.4.6)
|
57
|
+
rest-client (>= 1.6.1)
|
58
|
+
rest-client (1.6.7)
|
59
|
+
mime-types (>= 1.16)
|
51
60
|
rr (1.0.4)
|
52
61
|
rspec (2.10.0)
|
53
62
|
rspec-core (~> 2.10.0)
|
@@ -68,8 +77,11 @@ DEPENDENCIES
|
|
68
77
|
cucumber
|
69
78
|
growl
|
70
79
|
guard
|
80
|
+
guard-ctags-bundler
|
71
81
|
guard-cucumber
|
72
82
|
guard-rspec
|
73
83
|
libnotify
|
74
84
|
rake
|
85
|
+
relish
|
86
|
+
rr
|
75
87
|
rspec
|
data/Guardfile
CHANGED
@@ -13,3 +13,8 @@ guard 'rspec', :version => 2 do
|
|
13
13
|
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
14
14
|
watch('spec/spec_helper.rb') { "spec" }
|
15
15
|
end
|
16
|
+
|
17
|
+
guard 'ctags-bundler', :src_path => ["lib", "spec"] do
|
18
|
+
watch(/^(lib|spec)\/.*\.rb$/)
|
19
|
+
watch('Gemfile.lock')
|
20
|
+
end
|
data/README.md
CHANGED
@@ -7,266 +7,24 @@
|
|
7
7
|
|
8
8
|
Bogus aims to make your unit tests more reliable by ensuring that you don't stub or mock methods that don't actually exist in the mocked objects.
|
9
9
|
|
10
|
-
|
10
|
+
Bogus provides facilities to create *fakes* - test doubles that have the same interface as the doubled class.
|
11
11
|
|
12
|
-
|
13
|
-
In most cases, fakes are just named stubs: they don't implement the logic (otherwise they should be tested too), but they have the same interface as the real object and they make it easier to remove duplication in your stubs.
|
12
|
+
Another feature of Bogus is *safe stubbing*, which does not allow you to stub methods that don't exist or don't match the signature specified when stubbing.
|
14
13
|
|
15
|
-
|
14
|
+
A unique feature of Bogus are the *contract tests*, which reduce the need for integrated tests to a minimum by ensuring that the things you stub match how the object really behaves.
|
16
15
|
|
17
|
-
|
16
|
+
## Documentation
|
18
17
|
|
19
|
-
|
20
|
-
class FindsUsers
|
21
|
-
takes :users_repository
|
22
|
-
|
23
|
-
def near_point(location, distance_in_km);
|
24
|
-
# do something with users_repository and return a list of users
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
class Geocoder
|
29
|
-
takes :http_client
|
30
|
-
|
31
|
-
def location_for(address)
|
32
|
-
# do something to http_client and return location
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
class SuggestsFollowings
|
37
|
-
takes :finds_users
|
38
|
-
|
39
|
-
def suggestions_for(user)
|
40
|
-
finds_users.near_point(user.location, 50).select{|user| user.followers_count > 10}
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
class ListsUsersNearCity
|
45
|
-
takes :finds_users, :geocoder
|
46
|
-
|
47
|
-
def users(city)
|
48
|
-
city_location = geocoder.location_for(city.name)
|
49
|
-
finds_users.near_point(city_location, 10)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
```
|
53
|
-
|
54
|
-
Typically, when testing SuggestsFollowings and ListsUsersNearCity you'd have code like this in your specs:
|
55
|
-
|
56
|
-
```ruby
|
57
|
-
describe SuggestsFollowings
|
58
|
-
let(:finds_users) { stub(:finds_users) }
|
59
|
-
let(:user) { new_user }
|
60
|
-
|
61
|
-
subject { SuggestsFollowings.new(finds_users) }
|
62
|
-
|
63
|
-
it "returns users with follower count of 10 or more" do
|
64
|
-
user_with_followers = new_user(followers_count: 10)
|
65
|
-
users = [new_user(followers_count: 5), user_with_followers]
|
66
|
-
|
67
|
-
finds_users.should_receive(:near_point).with(user.location, 50).and_return(users)
|
68
|
-
|
69
|
-
subject.suggestions_for(user).should == [user_with_followers]
|
70
|
-
end
|
71
|
-
|
72
|
-
# ...
|
73
|
-
end
|
74
|
-
|
75
|
-
describe ListsUsersNearCity
|
76
|
-
let(:finds_users) { stub(:finds_users) }
|
77
|
-
let(:geocoder) { stub(:geocoder) }
|
78
|
-
let(:city) { new_city(name: "New York") }
|
79
|
-
|
80
|
-
subject { ListsUsersNearCity.new(finds_users, geocoder) }
|
81
|
-
|
82
|
-
it "returns users near center of the city" do
|
83
|
-
location = Location.new(1, 2)
|
84
|
-
users = [new_user, new_user]
|
85
|
-
|
86
|
-
geocoder.should_receive(:location_for).with("New York").and_return(location)
|
87
|
-
finds_users.should_receive(:near_point).with(location, 10).and_return(users)
|
88
|
-
|
89
|
-
subject.users(city).should == users
|
90
|
-
end
|
91
|
-
|
92
|
-
# ...
|
93
|
-
end
|
94
|
-
```
|
95
|
-
|
96
|
-
Notice how the stubbing/mocking code is duplicated between both specs.
|
97
|
-
This might not be a huge problem in a small project, but as your codebase grows, there might be more and more objects that interact with finds_users, and the more objects interact with finds_users, the more places it's interface is specified in using stubbing or mock expectations.
|
98
|
-
|
99
|
-
## Bogus to the rescue!
|
100
|
-
|
101
|
-
Bogus is aimed to help you remove duplication in specifying interfaces from your specs.
|
102
|
-
It will reduce the need for integration testing, because with Bogus, you make sure that the test doubles you use have the same interface as the real object, while still allowing you to test in isolation and benefit from that.
|
103
|
-
|
104
|
-
So how would your tests look like if you used Bogus?
|
105
|
-
|
106
|
-
```ruby
|
107
|
-
require 'bogus/rspec'
|
108
|
-
|
109
|
-
Bogus.configure do |config|
|
110
|
-
config.spy_by_default = true
|
111
|
-
config.stub_dsl = :rr # only :rr available for now
|
112
|
-
end
|
113
|
-
|
114
|
-
shared_context 'fakes' do
|
115
|
-
fake(:geocoder) # same as let(:geocoder) { Bogus.fake_for(:geocoder) }
|
116
|
-
fake(:finds_users)
|
117
|
-
end
|
118
|
-
|
119
|
-
describe SuggestsFollowings
|
120
|
-
include_context "fakes"
|
121
|
-
|
122
|
-
let(:user) { new_user }
|
123
|
-
|
124
|
-
subject { SuggestsFollowings.new(finds_users) }
|
125
|
-
|
126
|
-
it "returns users with follower count of 10 or more" do
|
127
|
-
user_with_followers = new_user(followers_count: 10)
|
128
|
-
users = [new_user(followers_count: 5), user_with_followers]
|
129
|
-
|
130
|
-
# this will actually fail if FindsUsers does not have a near_point method
|
131
|
-
# that takes 2 arguments
|
132
|
-
mock(finds_users).near_point(user.location, 50) { users }
|
133
|
-
|
134
|
-
subject.suggestions_for(user).should == [user_with_followers]
|
135
|
-
end
|
136
|
-
|
137
|
-
# ...
|
138
|
-
end
|
139
|
-
|
140
|
-
describe ListsUsersNearCity
|
141
|
-
include_context "fakes"
|
142
|
-
|
143
|
-
let(:city) { new_city(name: "New York") }
|
144
|
-
|
145
|
-
subject { ListsUsersNearCity.new(finds_users, geocoder) }
|
146
|
-
|
147
|
-
it "returns users near center of the city" do
|
148
|
-
location = Location.new(1, 2)
|
149
|
-
users = [new_user, new_user]
|
150
|
-
|
151
|
-
mock(geocoder).location_for("New York") { location }
|
152
|
-
mock(finds_users).near_point(location, 10) { users }
|
153
|
-
|
154
|
-
subject.users(city).should == users
|
155
|
-
end
|
156
|
-
|
157
|
-
# ...
|
158
|
-
end
|
159
|
-
```
|
160
|
-
|
161
|
-
As you can see, by using Bogus you can keep writing truly isolated unit tests just like you are used to, but with higher degree of security, because Bogus makes sure, that the methods you are stubbing actually exist and take same arguments.
|
162
|
-
|
163
|
-
## Bogus and commands
|
164
|
-
|
165
|
-
By default, fakes created by Bogus are nil-objects.
|
166
|
-
This is particularly useful when dealing with "command" methods or if you follow the "tell, don't ask" principle.
|
167
|
-
|
168
|
-
```ruby
|
169
|
-
class SendsEmailNotifications
|
170
|
-
def notify_password_changed(user)
|
171
|
-
# do something
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
class Logger
|
176
|
-
def info(*message)
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
class ChangesPassword
|
181
|
-
takes :sends_email_notifications, :logger
|
182
|
-
|
183
|
-
def change_password(user, old_pass, new_pass)
|
184
|
-
# change user password
|
185
|
-
user.password = new_pass if user.password == old_pass
|
186
|
-
|
187
|
-
# notify by email
|
188
|
-
sends_email_notifications.notify_password_changed(user)
|
189
|
-
|
190
|
-
# and log
|
191
|
-
logger.info("User", user.name, "changed password")
|
192
|
-
end
|
193
|
-
end
|
194
|
-
|
195
|
-
describe ChangesPassword do
|
196
|
-
fake(:sends_email_notifications)
|
197
|
-
fake(:logger)
|
198
|
-
|
199
|
-
let(:user) { new_user }
|
200
|
-
|
201
|
-
subject{ ChangesPassword.new(sends_email_notifications, logger) }
|
202
|
-
|
203
|
-
it "sends the email notification" do
|
204
|
-
subject.change_password(user, 'old', 'new')
|
205
|
-
|
206
|
-
# no need to set up the stub on sends_email_notifications for this to work
|
207
|
-
sends_email_notifications.should have_received.notify_password_changed(user)
|
208
|
-
end
|
209
|
-
end
|
210
|
-
```
|
211
|
-
|
212
|
-
The beautiful thing is, that even if you don't care about testing something (like logging in this example), you still get the benefit of ensuring that the interface matches, even in a fully isolated test.
|
213
|
-
|
214
|
-
## Contract tests
|
215
|
-
|
216
|
-
Knowing that a method exists and takes the right number of parameters is great, but why stop there?
|
217
|
-
Bogus can also make sure that the interface you stub is actually tested somewhere with the correct arguments and return value.
|
218
|
-
|
219
|
-
```ruby
|
220
|
-
describe ChangesPassword do
|
221
|
-
fake(:sends_email_notifications)
|
222
|
-
fake(:logger)
|
223
|
-
|
224
|
-
let(:user) { new_user }
|
225
|
-
|
226
|
-
subject{ ChangesPassword.new(sends_email_notifications, logger) }
|
227
|
-
|
228
|
-
it "sends the email notification" do
|
229
|
-
subject.change_password(user, 'old', 'new')
|
230
|
-
|
231
|
-
sends_email_notifications.should have_received.notify_password_changed(user)
|
232
|
-
end
|
233
|
-
end
|
234
|
-
```
|
235
|
-
|
236
|
-
In the above spec, SendsEmailNotifications#notify_password_changed is specified as a method that takes a user as an argument.
|
237
|
-
Thanks to Bogus, we already know that there is a class named SendsEmailNotifications and it has a #notify_password_changed method that takes one argument.
|
238
|
-
But how can we be sure that this argument is a User, and not a String for example?
|
239
|
-
|
240
|
-
Here's how Bogus can help with this problem:
|
241
|
-
|
242
|
-
```ruby
|
243
|
-
describe SendsEmailNotifications do
|
244
|
-
verify_contract(:sends_email_notifications)
|
245
|
-
|
246
|
-
let(:sends_email_notifications) { SendsEmailNotifications.new }
|
247
|
-
|
248
|
-
it "send email notifications" do
|
249
|
-
user = new_user
|
250
|
-
|
251
|
-
sends_email_notifications.notify_password_changed(user)
|
252
|
-
|
253
|
-
# ...
|
254
|
-
end
|
255
|
-
end
|
256
|
-
```
|
18
|
+
[You can find our (executable) documentation on Relish.][docs]
|
257
19
|
|
258
20
|
## License
|
259
21
|
|
260
22
|
MIT. See the LICENSE file.
|
261
23
|
|
262
|
-
## TODO:
|
263
|
-
|
264
|
-
This is a README driven project, so don't expect stuff in the README to be implemented ;P
|
265
|
-
|
266
|
-
See the features directory for the completed functionality.
|
267
|
-
|
268
24
|
## Authors
|
269
25
|
|
270
26
|
* [Adam Pohorecki](http://github.com/psyho)
|
271
27
|
* [Paweł Pierzchała](http://github.com/wrozka)
|
272
28
|
* [Marek Nowak](https://github.com/yundt)
|
29
|
+
|
30
|
+
[docs]: http://www.relishapp.com/bogus/bogus/docs
|
data/bogus.gemspec
CHANGED
@@ -19,7 +19,6 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.require_paths = ["lib"]
|
20
20
|
|
21
21
|
s.add_dependency 'dependor', '>= 0.0.4'
|
22
|
-
s.add_dependency 'rr'
|
23
22
|
|
24
23
|
s.add_development_dependency 'rake'
|
25
24
|
s.add_development_dependency 'rspec'
|
@@ -29,6 +28,9 @@ Gem::Specification.new do |s|
|
|
29
28
|
s.add_development_dependency 'guard'
|
30
29
|
s.add_development_dependency 'guard-rspec'
|
31
30
|
s.add_development_dependency 'guard-cucumber'
|
31
|
+
s.add_development_dependency 'guard-ctags-bundler'
|
32
32
|
s.add_development_dependency 'growl'
|
33
33
|
s.add_development_dependency 'libnotify'
|
34
|
+
s.add_development_dependency 'rr'
|
35
|
+
s.add_development_dependency 'relish'
|
34
36
|
end
|
data/features/.nav
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
- getting_started.md (Getting Started)
|
2
|
+
- readme.md (Introduction to Bogus)
|
3
|
+
- changelog.md
|
4
|
+
- fakes (Fakes):
|
5
|
+
- fake_objects.feature
|
6
|
+
- global_fake_configuration.feature
|
7
|
+
- anonymous_doubles.feature
|
8
|
+
- replacing_classes.feature
|
9
|
+
- safe_stubbing (Safe Stubbing):
|
10
|
+
- safe_mocking.feature
|
11
|
+
- safe_stubbing.feature
|
12
|
+
- spies.feature
|
13
|
+
- argument_matchers.feature
|
14
|
+
- contract_tests (Contract Tests):
|
15
|
+
- contract_tests_mocks.feature
|
16
|
+
- contract_tests_stubs.feature
|
17
|
+
- contract_tests_spies.feature
|
18
|
+
- return_value_contracts.feature
|
19
|
+
- configuration_options.feature
|
20
|
+
- license.md
|
21
|
+
- authors.md
|
data/features/authors.md
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
## Adam Pohorecki
|
2
|
+
|
3
|
+
github: [psyho][psyho]
|
4
|
+
twitter: [@apohorecki][apohorecki]
|
5
|
+
blog: [adam.pohorecki.pl][blog]
|
6
|
+
|
7
|
+
## Paweł Pierzchała
|
8
|
+
|
9
|
+
github: [wrozka][wrozka]
|
10
|
+
twitter: [@zwrozka][zwrozka]
|
11
|
+
|
12
|
+
## Marek Nowak
|
13
|
+
|
14
|
+
github: [yundt][yundt]
|
15
|
+
twitter: [@yundt][yundt]
|
16
|
+
|
17
|
+
## Contract tests
|
18
|
+
|
19
|
+
The contract tests feature was inspired by [J. B. Rainsberger's talk: "Integration Tests are a Scam"][scam].
|
20
|
+
|
21
|
+
## Mocking DSL syntax
|
22
|
+
|
23
|
+
The mocking DSL syntax was inspired by the [RR framework][rr].
|
24
|
+
|
25
|
+
## Sponsor
|
26
|
+
|
27
|
+
The development of Bogus was partially sponsored by [Lunar Logic][llp].
|
28
|
+
|
29
|
+
[llp]: http://www.lunarlogicpolska.com
|
30
|
+
|
31
|
+
[psyho]: https://github.com/psyho
|
32
|
+
[apohorecki]: http://twitter.com/apohorecki
|
33
|
+
[blog]: http://adam.pohorecki.pl
|
34
|
+
|
35
|
+
[wrozka]: https://github.com/wrozka
|
36
|
+
[zwrozka]: http://twitter.com/zwrozka
|
37
|
+
|
38
|
+
[yundt]: https://github.com/yundt
|
39
|
+
[yundt]: http://twitter.com/yundt
|
40
|
+
|
41
|
+
[scam]: http://www.infoq.com/presentations/integration-tests-scam
|
42
|
+
[rr]: https://github.com/btakita/rr
|
@@ -1,5 +1,3 @@
|
|
1
|
-
# Changelog
|
2
|
-
|
3
1
|
## 0.0.1
|
4
2
|
|
5
3
|
Initial version.
|
@@ -15,3 +13,12 @@ Initial version.
|
|
15
13
|
- Implemented anonymous fakes.
|
16
14
|
- Fixed a bug in copying ActiveRecord classes.
|
17
15
|
- (internal) Replaced autoloads with require.
|
16
|
+
|
17
|
+
## 0.0.3 (not released yet)
|
18
|
+
|
19
|
+
- Global fake configuration
|
20
|
+
- Inline method stubbing syntax
|
21
|
+
- Removed dependency on RR
|
22
|
+
- verifies_contracts records on described_class instead of class based on fake name
|
23
|
+
- Replacing classes with fakes
|
24
|
+
|