cranky 1.0.0 → 1.1.0
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.
- 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.
|