cranky 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -26
- data/README.md +33 -1
- data/lib/cranky/factory.rb +32 -6
- data/lib/cranky/linter.rb +38 -7
- data/lib/cranky/version.rb +1 -1
- data/spec/cranky_spec.rb +15 -11
- data/spec/linter_spec.rb +18 -3
- data/spec/spec_helper.rb +24 -4
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 42aebc7927e7fc1f29417cb638be0bee94190521
|
4
|
+
data.tar.gz: dd1710da521efa26a01615646b5daaa4e98980b7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e5234e23763c245d614d50dfe44d4e862ad4e236f16fb4eb9f71d5e98bf1899c4b55c4edaec3632b7bd8ea20e16965f0877e6d6e499e8ca3fe5654e3c6ec64e1
|
7
|
+
data.tar.gz: 621dcfd64bbdfefddd9e484a3c10e96dbd0f5ebdfe11ba537d7b674973a5ca4b5a77f29eca5416a48e5cab040c4d339213b82b44fd10faa44d4dbfc1a4a5abe3
|
data/CHANGELOG.md
CHANGED
@@ -1,31 +1,9 @@
|
|
1
1
|
# Overview of Changes
|
2
2
|
|
3
|
-
##
|
3
|
+
## 1.1.0
|
4
4
|
|
5
|
-
*
|
6
|
-
that used the inherit method
|
5
|
+
* Added before_create, after_build, after_create callbacks (@beorc)
|
7
6
|
|
8
|
-
## 0.
|
7
|
+
## 1.0.0
|
9
8
|
|
10
|
-
*
|
11
|
-
|
12
|
-
* Appending the first argument with _attrs will return a hash of attributes rather than
|
13
|
-
the object, i.e. crank(:user) returns a User instance, and crank(:user_attrs) returns
|
14
|
-
a hash of valid attributes
|
15
|
-
|
16
|
-
* Factory.attributes_for now returns a hash of attributes rather than an array, this
|
17
|
-
method is no longer dependent on rails
|
18
|
-
|
19
|
-
* \#3 Factory methods can generate attribute hashes by default by setting :class => Hash in
|
20
|
-
the define declaration (leemhenson)
|
21
|
-
|
22
|
-
* Factory.debug was broken on ActiveModel based classes, now works with them
|
23
|
-
|
24
|
-
* Attributes can be skipped by setting the value to :skip. e.g. crank(:user, :name => :skip) will
|
25
|
-
generate a User instance without calling or assigning anything to the name attribute
|
26
|
-
|
27
|
-
* Updated dev environment for latest rspec compatibility (2.6.0)
|
28
|
-
|
29
|
-
## 0.2.0
|
30
|
-
|
31
|
-
Changes between version prior to this were not tracked here
|
9
|
+
* Initial baseline for future change tracking
|
data/README.md
CHANGED
@@ -202,10 +202,12 @@ def user
|
|
202
202
|
end
|
203
203
|
|
204
204
|
def apply_trait_admin_to_user(user)
|
205
|
+
# the 'options' method is available here
|
205
206
|
user.roles << :admin
|
206
207
|
end
|
207
208
|
|
208
209
|
def apply_trait_manager_to_user(user)
|
210
|
+
# the 'options' method is available here
|
209
211
|
user.roles << :manager
|
210
212
|
end
|
211
213
|
~~~
|
@@ -220,6 +222,36 @@ def users_collection
|
|
220
222
|
end
|
221
223
|
~~~
|
222
224
|
|
225
|
+
You can inject code using callbacks...
|
226
|
+
|
227
|
+
~~~ruby
|
228
|
+
# factories/my_factories.rb
|
229
|
+
class Cranky::Factory
|
230
|
+
|
231
|
+
def user
|
232
|
+
define name: 'Jimmy'
|
233
|
+
end
|
234
|
+
|
235
|
+
private
|
236
|
+
|
237
|
+
def after_build_user(user)
|
238
|
+
# the 'options' method is available here
|
239
|
+
do_something_to(user)
|
240
|
+
end
|
241
|
+
|
242
|
+
def before_create_user(user)
|
243
|
+
# the 'options' method is available here
|
244
|
+
do_something_to(user)
|
245
|
+
end
|
246
|
+
|
247
|
+
def after_create_user(user)
|
248
|
+
# the 'options' method is available here
|
249
|
+
do_something_to(user)
|
250
|
+
end
|
251
|
+
|
252
|
+
end
|
253
|
+
~~~
|
254
|
+
|
223
255
|
## Linting Factories
|
224
256
|
|
225
257
|
Cranky allows for linting known factories:
|
@@ -235,7 +267,7 @@ Recommended usage of `Factory.lint!` is to run this in a task before your test s
|
|
235
267
|
Example Rake task:
|
236
268
|
|
237
269
|
~~~ruby
|
238
|
-
# lib/tasks/
|
270
|
+
# lib/tasks/cranky.rake
|
239
271
|
namespace :cranky do
|
240
272
|
desc "Verify that all factories are valid"
|
241
273
|
task lint: :environment do
|
data/lib/cranky/factory.rb
CHANGED
@@ -13,18 +13,28 @@ module Cranky
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def build(what, overrides={})
|
16
|
-
crank_it(what, overrides)
|
16
|
+
item = crank_it(what, overrides)
|
17
|
+
call_after_build(what, item)
|
18
|
+
|
19
|
+
item
|
17
20
|
end
|
18
21
|
|
19
22
|
def create(what, overrides={})
|
20
23
|
item = build(what, overrides)
|
21
|
-
Array(item).each
|
24
|
+
Array(item).each do |i|
|
25
|
+
call_before_create(what, i)
|
26
|
+
i.save && call_after_create(what, i)
|
27
|
+
end
|
22
28
|
item
|
23
29
|
end
|
24
30
|
|
25
31
|
def create!(what, overrides={})
|
26
32
|
item = build(what, overrides)
|
27
|
-
Array(item).each
|
33
|
+
Array(item).each do |i|
|
34
|
+
call_before_create(what, i)
|
35
|
+
i.save!
|
36
|
+
call_after_create(what, i)
|
37
|
+
end
|
28
38
|
item
|
29
39
|
end
|
30
40
|
|
@@ -75,12 +85,13 @@ module Cranky
|
|
75
85
|
end
|
76
86
|
|
77
87
|
def factory_names
|
78
|
-
public_methods(false).reject {|m| TRAIT_METHOD_REGEXP === m }
|
88
|
+
public_methods(false).reject {|m| TRAIT_METHOD_REGEXP === m }.sort
|
79
89
|
end
|
80
90
|
|
81
91
|
def traits_for(factory_name)
|
82
92
|
regexp = /^apply_trait_(\w+)_to_#{factory_name}$/.freeze
|
83
|
-
|
93
|
+
available_methods = private_methods(false) + public_methods(false)
|
94
|
+
trait_methods = available_methods.select {|m| regexp === m }
|
84
95
|
trait_methods.map {|m| regexp.match(m)[1] }
|
85
96
|
end
|
86
97
|
|
@@ -94,10 +105,25 @@ module Cranky
|
|
94
105
|
|
95
106
|
private
|
96
107
|
|
108
|
+
def call_after_build(what, item)
|
109
|
+
method_name = "after_build_#{what}"
|
110
|
+
respond_to?(method_name, true) && send(method_name, item)
|
111
|
+
end
|
112
|
+
|
113
|
+
def call_before_create(what, item)
|
114
|
+
method_name = "before_create_#{what}"
|
115
|
+
respond_to?(method_name, true) && send(method_name, item)
|
116
|
+
end
|
117
|
+
|
118
|
+
def call_after_create(what, item)
|
119
|
+
method_name = "after_create_#{what}"
|
120
|
+
respond_to?(method_name, true) && send(method_name, item)
|
121
|
+
end
|
122
|
+
|
97
123
|
def apply_traits(what, item)
|
98
124
|
Array(options[:traits]).each do |t|
|
99
125
|
trait_method_name = "apply_trait_#{t}_to_#{what}"
|
100
|
-
fail("Invalid trait '#{t}'! No method '#{trait_method_name}' is defined.")
|
126
|
+
respond_to?(trait_method_name, true) || fail("Invalid trait '#{t}'! No method '#{trait_method_name}' is defined.")
|
101
127
|
send(trait_method_name, item)
|
102
128
|
end
|
103
129
|
|
data/lib/cranky/linter.rb
CHANGED
@@ -6,16 +6,17 @@ module Cranky
|
|
6
6
|
@factories_to_lint = factories_to_lint
|
7
7
|
@linting_method = "lint_#{linting_strategy}"
|
8
8
|
@invalid_factories = calculate_invalid_factories
|
9
|
+
@invalid_callbacks = calculate_invalid_callbacks
|
9
10
|
end
|
10
11
|
|
11
12
|
def lint!
|
12
|
-
if invalid_factories.any?
|
13
|
+
if invalid_factories.any? || invalid_callbacks.any?
|
13
14
|
raise InvalidFactoryError, error_message
|
14
15
|
end
|
15
16
|
end
|
16
17
|
|
17
|
-
attr_reader :factories_to_lint, :invalid_factories
|
18
|
-
private :factories_to_lint, :invalid_factories
|
18
|
+
attr_reader :factories_to_lint, :invalid_factories, :invalid_callbacks
|
19
|
+
private :factories_to_lint, :invalid_factories, :invalid_callbacks
|
19
20
|
|
20
21
|
private
|
21
22
|
|
@@ -27,6 +28,25 @@ module Cranky
|
|
27
28
|
end
|
28
29
|
end
|
29
30
|
|
31
|
+
def calculate_invalid_callbacks
|
32
|
+
result = []
|
33
|
+
|
34
|
+
regexp = /^(after_build|before_create|after_create)_(\w+)$/.freeze
|
35
|
+
available_methods = @factory.private_methods(false) + @factory.public_methods(false)
|
36
|
+
available_methods.select do |m|
|
37
|
+
match = regexp.match(m)
|
38
|
+
if match
|
39
|
+
factory_name = match[2]
|
40
|
+
|
41
|
+
unless @factory.respond_to?(factory_name)
|
42
|
+
result << m
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
result
|
48
|
+
end
|
49
|
+
|
30
50
|
# Raised when any factory is considered invalid
|
31
51
|
class InvalidFactoryError < RuntimeError; end
|
32
52
|
|
@@ -87,15 +107,26 @@ module Cranky
|
|
87
107
|
end
|
88
108
|
|
89
109
|
def error_message
|
110
|
+
[
|
111
|
+
factories_error_message,
|
112
|
+
callbacks_error_message
|
113
|
+
].compact.join("\n\n".freeze)
|
114
|
+
end
|
115
|
+
|
116
|
+
def factories_error_message
|
90
117
|
lines = invalid_factories.map do |_factory, exceptions|
|
91
118
|
exceptions.map(&:message)
|
92
119
|
end.flatten
|
93
120
|
|
94
|
-
|
95
|
-
|
121
|
+
return if lines.empty?
|
122
|
+
|
123
|
+
"The following factories are invalid:\n\n#{lines.join("\n")}"
|
124
|
+
end
|
125
|
+
|
126
|
+
def callbacks_error_message
|
127
|
+
return if invalid_callbacks.empty?
|
96
128
|
|
97
|
-
#{
|
98
|
-
ERROR_MESSAGE
|
129
|
+
"The following callbacks are invalid:\n\n#{invalid_callbacks.join("\n")}"
|
99
130
|
end
|
100
131
|
end
|
101
132
|
end
|
data/lib/cranky/version.rb
CHANGED
data/spec/cranky_spec.rb
CHANGED
@@ -4,15 +4,17 @@ describe "The Cranky factory" do
|
|
4
4
|
|
5
5
|
describe '#factory_names' do
|
6
6
|
it 'returns an array of names of defined factories' do
|
7
|
-
Factory.factory_names.should eq
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
7
|
+
Factory.factory_names.should eq %i(
|
8
|
+
address
|
9
|
+
admin_by_define
|
10
|
+
admin_manually
|
11
|
+
invalid_user
|
12
|
+
user
|
13
|
+
user_by_define
|
14
|
+
user_hash
|
15
|
+
user_manually
|
16
|
+
users_collection
|
17
|
+
)
|
16
18
|
end
|
17
19
|
end
|
18
20
|
|
@@ -144,10 +146,12 @@ describe "The Cranky factory" do
|
|
144
146
|
it "allows factories to call other factories" do
|
145
147
|
Factory.build(:user_manually).address.city.should == "New York"
|
146
148
|
Factory.create(:user_manually).address.city.should == "New York"
|
149
|
+
Factory.create!(:user_manually).address.city.should == "New York"
|
147
150
|
Factory.create(:user_manually).address.saved?.should == false
|
148
|
-
Factory.build(:user_by_define).address.city.should == "New York"
|
149
151
|
Factory.create(:user_by_define).address.city.should == "New York"
|
150
152
|
Factory.create(:user_by_define).address.saved?.should == true
|
153
|
+
Factory.create(:user_by_define).email.should == 'max@home.com'
|
154
|
+
Factory.create!(:user_by_define).email.should == 'max@home.com'
|
151
155
|
end
|
152
156
|
|
153
157
|
it "has its own syntax" do
|
@@ -184,7 +188,7 @@ describe "The Cranky factory" do
|
|
184
188
|
end
|
185
189
|
|
186
190
|
it "returns nothing extra in the attributes" do
|
187
|
-
crank(:user_attrs).size.should ==
|
191
|
+
crank(:user_attrs).size.should == 4
|
188
192
|
end
|
189
193
|
|
190
194
|
specify "attributes for works with factory methods using inherit" do
|
data/spec/linter_spec.rb
CHANGED
@@ -5,8 +5,12 @@ describe 'Factory.lint' do
|
|
5
5
|
error_message = <<-ERROR_MESSAGE.strip
|
6
6
|
The following factories are invalid:
|
7
7
|
|
8
|
-
* user_hash - undefined method `save!' for [:name, "Fred"]:Array (NoMethodError)
|
9
8
|
* invalid_user - Validation failed: {:required_attr=>["can't be blank"]} (RuntimeError)
|
9
|
+
* user_hash - undefined method `save!' for [:name, "Fred"]:Array (NoMethodError)
|
10
|
+
|
11
|
+
The following callbacks are invalid:
|
12
|
+
|
13
|
+
after_create_not_existing_factory
|
10
14
|
ERROR_MESSAGE
|
11
15
|
|
12
16
|
expect do
|
@@ -15,7 +19,14 @@ The following factories are invalid:
|
|
15
19
|
end
|
16
20
|
|
17
21
|
it 'does not raise when all factories are valid' do
|
18
|
-
|
22
|
+
error_message = <<-ERROR_MESSAGE.strip
|
23
|
+
The following callbacks are invalid:
|
24
|
+
|
25
|
+
after_create_not_existing_factory
|
26
|
+
ERROR_MESSAGE
|
27
|
+
expect do
|
28
|
+
Factory.lint!(factory_names: [:admin_manually, :address])
|
29
|
+
end.to raise_error Cranky::Linter::InvalidFactoryError, error_message
|
19
30
|
end
|
20
31
|
|
21
32
|
describe "trait validation" do
|
@@ -24,9 +35,13 @@ The following factories are invalid:
|
|
24
35
|
error_message = <<-ERROR_MESSAGE.strip
|
25
36
|
The following factories are invalid:
|
26
37
|
|
38
|
+
* invalid_user - Validation failed: {:required_attr=>["can't be blank"]} (RuntimeError)
|
27
39
|
* user+invalid - Validation failed: {:required_attr=>["can't be blank"]} (RuntimeError)
|
28
40
|
* user_hash - undefined method `save!' for [:name, "Fred"]:Array (NoMethodError)
|
29
|
-
|
41
|
+
|
42
|
+
The following callbacks are invalid:
|
43
|
+
|
44
|
+
after_create_not_existing_factory
|
30
45
|
ERROR_MESSAGE
|
31
46
|
|
32
47
|
expect do
|
data/spec/spec_helper.rb
CHANGED
@@ -69,8 +69,6 @@ class Cranky::Factory
|
|
69
69
|
:name => "Fred",
|
70
70
|
:role => :user,
|
71
71
|
:unique => "value#{n}",
|
72
|
-
:email => "fred@home.com",
|
73
|
-
:address => Factory.create(:address),
|
74
72
|
:required_attr => true
|
75
73
|
u.argument_received = true if options[:argument_supplied]
|
76
74
|
u
|
@@ -101,6 +99,12 @@ class Cranky::Factory
|
|
101
99
|
3.times.map { build(:user) }
|
102
100
|
end
|
103
101
|
|
102
|
+
def invalid_user
|
103
|
+
inherit(:user, required_attr: false)
|
104
|
+
end
|
105
|
+
|
106
|
+
private
|
107
|
+
|
104
108
|
def apply_trait_manager_to_user_manually(user)
|
105
109
|
user.role = :manager
|
106
110
|
end
|
@@ -109,7 +113,23 @@ class Cranky::Factory
|
|
109
113
|
user.required_attr = nil
|
110
114
|
end
|
111
115
|
|
112
|
-
def
|
113
|
-
|
116
|
+
def after_build_user_by_define(user)
|
117
|
+
if user.respond_to?('[]')
|
118
|
+
user[:email] = 'fred@home.com'
|
119
|
+
else
|
120
|
+
user.email = 'fred@home.com'
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def before_create_user_by_define(user)
|
125
|
+
user.address = create!(:address)
|
126
|
+
end
|
127
|
+
|
128
|
+
def after_create_user_by_define(user)
|
129
|
+
user.email = 'max@home.com'
|
130
|
+
end
|
131
|
+
|
132
|
+
def after_create_not_existing_factory(user)
|
133
|
+
user.address = create!(:address)
|
114
134
|
end
|
115
135
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cranky
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stephen McGinty
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-12-28 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: A very light yet powerful test factory framework with an extremely clean
|
14
14
|
syntax that makes it very easy to define your factories.
|
@@ -51,7 +51,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
51
51
|
version: 1.3.4
|
52
52
|
requirements: []
|
53
53
|
rubyforge_project:
|
54
|
-
rubygems_version: 2.
|
54
|
+
rubygems_version: 2.2.5
|
55
55
|
signing_key:
|
56
56
|
specification_version: 4
|
57
57
|
summary: A very light yet powerful test factory framework.
|