cranky 0.5.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +101 -38
- data/lib/cranky.rb +1 -0
- data/lib/cranky/factory.rb +40 -3
- data/lib/cranky/linter.rb +101 -0
- data/lib/cranky/version.rb +1 -1
- data/spec/cranky_spec.rb +43 -6
- data/spec/linter_spec.rb +38 -0
- data/spec/spec_helper.rb +28 -13
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fbcde86a6a73ee0148b12ed591e978d21521f5ba
|
4
|
+
data.tar.gz: 61a43c0743b8b333f85e3ec26f6604197086741b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bf660e5eb16c325dc12f2c6f52839f6b2c5268a0d647729d5cb7b11f5bd9dcd55eb464609d57ffc3ef671b0def15abba10571c141e383e30029d59bd4696e5b6
|
7
|
+
data.tar.gz: ce11711bca5aa5de02f02d33305074e025147727ef13f425837e0182522cf119330bd38d19eb2e8bd5b46e3a23e44fd1d3a136e9a9b2486fc63bbfcd25848a70
|
data/README.md
CHANGED
@@ -70,7 +70,7 @@ Cranky allows you to build factories via std Ruby methods, like this...
|
|
70
70
|
# factories/my_factories.rb
|
71
71
|
class Cranky::Factory # Your factory must reopen Cranky::Factory
|
72
72
|
|
73
|
-
# Simple factory method to create a user instance, you would call this via
|
73
|
+
# Simple factory method to create a user instance, you would call this via crank(:user)
|
74
74
|
def user
|
75
75
|
# Define attributes via a hash, generate the values any way you want
|
76
76
|
define :name => "Jimmy",
|
@@ -79,7 +79,7 @@ class Cranky::Factory # Your factory must reopen Cranky::Factory
|
|
79
79
|
:address => default_address # Call your own helper methods to wire up your associations
|
80
80
|
end
|
81
81
|
|
82
|
-
# Easily create variations via the inherit helper, callable via
|
82
|
+
# Easily create variations via the inherit helper, callable via crank(:admin)
|
83
83
|
def admin
|
84
84
|
inherit(:user, :role => "admin")
|
85
85
|
end
|
@@ -89,12 +89,12 @@ class Cranky::Factory # Your factory must reopen Cranky::Factory
|
|
89
89
|
@default_address ||= create(:address)
|
90
90
|
end
|
91
91
|
|
92
|
-
# Alternatively loose the DSL altogether and define the factory yourself, still callable via
|
92
|
+
# Alternatively loose the DSL altogether and define the factory yourself, still callable via crank(:address)
|
93
93
|
def address
|
94
94
|
a = Address.new
|
95
95
|
a.street = "192 Broadway"
|
96
96
|
a.city = options[:city] || "New York" # You can get any caller overrides via the options hash
|
97
|
-
a # Only rule is the method must return the generated object
|
97
|
+
a # Only rule is that the method must return the generated object
|
98
98
|
end
|
99
99
|
|
100
100
|
end
|
@@ -109,8 +109,8 @@ This is where Cranky really shines, if you can create Ruby methods you can prett
|
|
109
109
|
The only rules are:
|
110
110
|
|
111
111
|
1. Your factory must reopen the Cranky::Factory class
|
112
|
-
2. Your factory method must return the object you wanted to create
|
113
|
-
3. You can access the overrides passed in via options[:key]
|
112
|
+
2. Your factory method must return the object you wanted to create (or an array containing a collection of them)
|
113
|
+
3. You can access the overrides passed in via `options[:key]` or `fetch(:key)`. (not really a rule!)
|
114
114
|
|
115
115
|
So for example to create a simple user factory...
|
116
116
|
|
@@ -118,13 +118,16 @@ So for example to create a simple user factory...
|
|
118
118
|
# factories/my_factories.rb
|
119
119
|
class Cranky::Factory
|
120
120
|
|
121
|
-
# Simple factory method to create a user instance, you would call this via
|
121
|
+
# Simple factory method to create a user instance, you would call this via crank(:user)
|
122
122
|
def user
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
123
|
+
User.new do |u|
|
124
|
+
u.name = options[:name] || "Jimmy" # Use the passed in name if present, or the default
|
125
|
+
u.nickname = fetch(:nickname, 'Silencer') # Use the passed in nickname if present, or the default
|
126
|
+
u.phone = fetch(:phone, 'phoneless') # Use the passed in phone if present, or the default
|
127
|
+
|
128
|
+
u.email = fetch(:email) { "jimmy#{n}@home.com" } # Give each user a unique email address
|
129
|
+
u.role = fetch(:role, 'pleb')
|
130
|
+
end
|
128
131
|
end
|
129
132
|
|
130
133
|
end
|
@@ -144,12 +147,12 @@ class Cranky::Factory
|
|
144
147
|
end
|
145
148
|
|
146
149
|
def user
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
150
|
+
User.new do |u|
|
151
|
+
u.name = fetch(:name, "Jimmy")
|
152
|
+
u.email = fetch(:email) { "jimmy#{n}@home.com" }
|
153
|
+
u.role = fetch(:role, "pleb")
|
154
|
+
u.address = fetch(:address) { default_address }
|
155
|
+
end
|
153
156
|
end
|
154
157
|
|
155
158
|
# Create the address factory in the same way
|
@@ -172,30 +175,30 @@ end
|
|
172
175
|
You can pass additional arguments to your factories via the overrides hash...
|
173
176
|
|
174
177
|
~~~ruby
|
175
|
-
|
178
|
+
crank(:user, :new_address => true)
|
176
179
|
|
177
180
|
def user
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
181
|
+
User.new do |u|
|
182
|
+
u.name = fetch(:name, "Jimmy")
|
183
|
+
u.email = fetch(:email) { "jimmy#{n}@home.com" }
|
184
|
+
u.role = fetch(:role, "pleb")
|
185
|
+
u.address = options[:new_address] ? create(:address) : default_address
|
186
|
+
end
|
184
187
|
end
|
185
188
|
~~~
|
186
189
|
|
187
190
|
You can use traits...
|
188
191
|
|
189
192
|
~~~ruby
|
190
|
-
|
193
|
+
crank(:user, traits: [:admin, :manager])
|
191
194
|
|
192
195
|
def user
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
196
|
+
User.new do |u|
|
197
|
+
u.name = fetch(:name, "Jimmy")
|
198
|
+
u.email = fetch(:email) { "jimmy#{n}@home.com" }
|
199
|
+
u.role = fetch(:role, "pleb")
|
200
|
+
u.address = options[:new_address] ? create(:address) : default_address
|
201
|
+
end
|
199
202
|
end
|
200
203
|
|
201
204
|
def apply_trait_admin_to_user(user)
|
@@ -210,13 +213,73 @@ end
|
|
210
213
|
You can create collections...
|
211
214
|
|
212
215
|
~~~ruby
|
213
|
-
|
216
|
+
crank(:users_collection)
|
214
217
|
|
215
218
|
def users_collection
|
216
219
|
3.time.map { build(:user) }
|
217
220
|
end
|
218
221
|
~~~
|
219
222
|
|
223
|
+
## Linting Factories
|
224
|
+
|
225
|
+
Cranky allows for linting known factories:
|
226
|
+
|
227
|
+
~~~ruby
|
228
|
+
Factory.lint!
|
229
|
+
~~~
|
230
|
+
|
231
|
+
`Factory.lint!` creates each factory and catches any exceptions raised during the creation process. `Cranky::Linter::InvalidFactoryError` is raised with a list of factories (and corresponding exceptions) for factories which could not be created.
|
232
|
+
|
233
|
+
Recommended usage of `Factory.lint!` is to run this in a task before your test suite is executed. Running it in a `before(:suite)`, will negatively impact the performance of your tests when running single tests.
|
234
|
+
|
235
|
+
Example Rake task:
|
236
|
+
|
237
|
+
~~~ruby
|
238
|
+
# lib/tasks/factory_girl.rake
|
239
|
+
namespace :cranky do
|
240
|
+
desc "Verify that all factories are valid"
|
241
|
+
task lint: :environment do
|
242
|
+
if Rails.env.test?
|
243
|
+
begin
|
244
|
+
DatabaseCleaner.start
|
245
|
+
Factory.lint!
|
246
|
+
ensure
|
247
|
+
DatabaseCleaner.clean
|
248
|
+
end
|
249
|
+
else
|
250
|
+
system("bundle exec rake cranky:lint RAILS_ENV='test'")
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
~~~
|
255
|
+
|
256
|
+
After calling `Factory.lint!`, you'll likely want to clear out the database, as records will most likely be created. The provided example above uses the database_cleaner gem to clear out the database; be sure to add the gem to your Gemfile under the appropriate groups.
|
257
|
+
|
258
|
+
You can lint factories selectively by passing only factories you want linted:
|
259
|
+
|
260
|
+
~~~ruby
|
261
|
+
factories_to_lint = Factory.factory_names.reject do |name|
|
262
|
+
name =~ /^old_/
|
263
|
+
end
|
264
|
+
|
265
|
+
Factory.lint! factories_to_lint
|
266
|
+
~~~
|
267
|
+
|
268
|
+
This would lint all factories that aren't prefixed with `old_`.
|
269
|
+
|
270
|
+
Traits can also be linted. This option verifies that each
|
271
|
+
and every trait of a factory generates a valid object on its own. This is turned on by passing traits: true to the lint method:
|
272
|
+
|
273
|
+
~~~ruby
|
274
|
+
Factory.lint! traits: true
|
275
|
+
~~~
|
276
|
+
|
277
|
+
This can also be combined with other arguments:
|
278
|
+
|
279
|
+
~~~ruby
|
280
|
+
Factory.lint! factories_to_lint, traits: true
|
281
|
+
~~~
|
282
|
+
|
220
283
|
## Helpers
|
221
284
|
|
222
285
|
Of course its nice to get some help...
|
@@ -244,7 +307,7 @@ If you like you can generate attributes with a block:
|
|
244
307
|
~~~ruby
|
245
308
|
def user
|
246
309
|
define :name => "Jimmy",
|
247
|
-
:email =>
|
310
|
+
:email => -> { |u| "#{u.name.downcase}@home.com" },
|
248
311
|
:role => "pleb",
|
249
312
|
:address => default_address
|
250
313
|
end
|
@@ -266,7 +329,7 @@ end
|
|
266
329
|
If for any reason you want to have your factory method named differently from the model it instantiates you can pass in a :class attribute to the define method...
|
267
330
|
|
268
331
|
~~~ruby
|
269
|
-
# Called via
|
332
|
+
# Called via crank(:jimmy)
|
270
333
|
def jimmy
|
271
334
|
u = define :class => :user,
|
272
335
|
:name => "Jimmy",
|
@@ -281,7 +344,7 @@ end
|
|
281
344
|
You can inherit from other factories via the inherit method. So for example to create an admin user you might do...
|
282
345
|
|
283
346
|
~~~ruby
|
284
|
-
# Called via
|
347
|
+
# Called via crank(:admin)
|
285
348
|
def admin
|
286
349
|
inherit(:user, :role => "admin") # Pass in any attribute overrides you want
|
287
350
|
end
|
@@ -308,11 +371,11 @@ end
|
|
308
371
|
Sometimes it is useful to be warned that your factory is generating invalid instances (although quite often your tests may intentionally generate invalid instances, so use this with care). By turning on debug the Factory will raise an error if the generated instance is invalid...
|
309
372
|
|
310
373
|
~~~ruby
|
311
|
-
Factory.debug(:user) # A replacement for Factory.build, with validation
|
374
|
+
Factory.debug(:user) # A replacement for Factory.build, with validation errors enabled
|
312
375
|
Factory.debug!(:user) # Likewise for Factory.create
|
313
376
|
~~~
|
314
377
|
|
315
|
-
Note that this relies on the instance having a valid? method, so in practice this may only work with
|
378
|
+
Note that this relies on the instance having a valid? method, so in practice this may only work with models that include ActiveModel::Validations.
|
316
379
|
|
317
380
|
### Attributes For
|
318
381
|
|
data/lib/cranky.rb
CHANGED
data/lib/cranky/factory.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Cranky
|
2
|
-
class
|
2
|
+
class FactoryBase
|
3
3
|
|
4
|
-
|
4
|
+
TRAIT_METHOD_REGEXP = /apply_trait_(\w+)_to_(\w+)/.freeze
|
5
5
|
|
6
6
|
def initialize
|
7
7
|
# Factory jobs can be nested, i.e. a factory method can itself invoke another factory method to
|
@@ -22,6 +22,12 @@ module Cranky
|
|
22
22
|
item
|
23
23
|
end
|
24
24
|
|
25
|
+
def create!(what, overrides={})
|
26
|
+
item = build(what, overrides)
|
27
|
+
Array(item).each(&:save!)
|
28
|
+
item
|
29
|
+
end
|
30
|
+
|
25
31
|
# Reset the factory instance, clear all instance variables
|
26
32
|
def reset
|
27
33
|
self.instance_variables.each do |var|
|
@@ -57,6 +63,35 @@ module Cranky
|
|
57
63
|
item
|
58
64
|
end
|
59
65
|
|
66
|
+
# Look for errors in factories and (optionally) their traits.
|
67
|
+
# Parameters:
|
68
|
+
# factory_names - which factories to lint; omit for all factories
|
69
|
+
# options:
|
70
|
+
# traits : true - to lint traits as well as factories
|
71
|
+
def lint!(factory_names: nil, traits: false)
|
72
|
+
factories_to_lint = Array(factory_names || self.factory_names)
|
73
|
+
strategy = traits ? :factory_and_traits : :factory
|
74
|
+
Linter.new(self, factories_to_lint, strategy).lint!
|
75
|
+
end
|
76
|
+
|
77
|
+
def factory_names
|
78
|
+
public_methods(false).reject {|m| TRAIT_METHOD_REGEXP === m }
|
79
|
+
end
|
80
|
+
|
81
|
+
def traits_for(factory_name)
|
82
|
+
regexp = /^apply_trait_(\w+)_to_#{factory_name}$/.freeze
|
83
|
+
trait_methods = public_methods(false).select {|m| regexp === m }
|
84
|
+
trait_methods.map {|m| regexp.match(m)[1] }
|
85
|
+
end
|
86
|
+
|
87
|
+
def fetch(*args)
|
88
|
+
if block_given?
|
89
|
+
options.fetch(*args, &Proc.new)
|
90
|
+
else
|
91
|
+
options.fetch(*args)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
60
95
|
private
|
61
96
|
|
62
97
|
def apply_traits(what, item)
|
@@ -118,5 +153,7 @@ module Cranky
|
|
118
153
|
|
119
154
|
end
|
120
155
|
|
121
|
-
|
156
|
+
class Factory < FactoryBase
|
157
|
+
end
|
122
158
|
|
159
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
module Cranky
|
2
|
+
class Linter
|
3
|
+
|
4
|
+
def initialize(factory, factories_to_lint, linting_strategy)
|
5
|
+
@factory = factory
|
6
|
+
@factories_to_lint = factories_to_lint
|
7
|
+
@linting_method = "lint_#{linting_strategy}"
|
8
|
+
@invalid_factories = calculate_invalid_factories
|
9
|
+
end
|
10
|
+
|
11
|
+
def lint!
|
12
|
+
if invalid_factories.any?
|
13
|
+
raise InvalidFactoryError, error_message
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
attr_reader :factories_to_lint, :invalid_factories
|
18
|
+
private :factories_to_lint, :invalid_factories
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def calculate_invalid_factories
|
23
|
+
factories_to_lint.reduce(Hash.new([])) do |result, factory|
|
24
|
+
errors = send(@linting_method, factory)
|
25
|
+
result[factory] |= errors unless errors.empty?
|
26
|
+
result
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Raised when any factory is considered invalid
|
31
|
+
class InvalidFactoryError < RuntimeError; end
|
32
|
+
|
33
|
+
class FactoryError
|
34
|
+
def initialize(wrapped_error, factory_name)
|
35
|
+
@wrapped_error = wrapped_error
|
36
|
+
@factory_name = factory_name
|
37
|
+
end
|
38
|
+
|
39
|
+
def message
|
40
|
+
message = @wrapped_error.message
|
41
|
+
"* #{location} - #{message} (#{@wrapped_error.class.name})"
|
42
|
+
end
|
43
|
+
|
44
|
+
def location
|
45
|
+
@factory_name
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
class FactoryTraitError < FactoryError
|
50
|
+
def initialize(wrapped_error, factory_name, trait_name)
|
51
|
+
super(wrapped_error, factory_name)
|
52
|
+
@trait_name = trait_name
|
53
|
+
end
|
54
|
+
|
55
|
+
def location
|
56
|
+
"#{@factory_name}+#{@trait_name}"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def lint_factory(factory_name)
|
61
|
+
result = []
|
62
|
+
begin
|
63
|
+
@factory.create!(factory_name)
|
64
|
+
rescue => error
|
65
|
+
result |= [FactoryError.new(error, factory_name)]
|
66
|
+
end
|
67
|
+
result
|
68
|
+
end
|
69
|
+
|
70
|
+
def lint_traits(factory_name)
|
71
|
+
result = []
|
72
|
+
@factory.traits_for(factory_name).each do |trait_name|
|
73
|
+
begin
|
74
|
+
@factory.create!(factory_name, traits: trait_name)
|
75
|
+
rescue => error
|
76
|
+
result |=
|
77
|
+
[FactoryTraitError.new(error, factory_name, trait_name)]
|
78
|
+
end
|
79
|
+
end
|
80
|
+
result
|
81
|
+
end
|
82
|
+
|
83
|
+
def lint_factory_and_traits(factory_name)
|
84
|
+
errors = lint_factory(factory_name)
|
85
|
+
errors |= lint_traits(factory_name)
|
86
|
+
errors
|
87
|
+
end
|
88
|
+
|
89
|
+
def error_message
|
90
|
+
lines = invalid_factories.map do |_factory, exceptions|
|
91
|
+
exceptions.map(&:message)
|
92
|
+
end.flatten
|
93
|
+
|
94
|
+
<<-ERROR_MESSAGE.strip
|
95
|
+
The following factories are invalid:
|
96
|
+
|
97
|
+
#{lines.join("\n")}
|
98
|
+
ERROR_MESSAGE
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
data/lib/cranky/version.rb
CHANGED
data/spec/cranky_spec.rb
CHANGED
@@ -2,7 +2,44 @@ require "spec_helper"
|
|
2
2
|
|
3
3
|
describe "The Cranky factory" do
|
4
4
|
|
5
|
-
|
5
|
+
describe '#factory_names' do
|
6
|
+
it 'returns an array of names of defined factories' do
|
7
|
+
Factory.factory_names.should eq [:user,
|
8
|
+
:address,
|
9
|
+
:users_collection,
|
10
|
+
:user_manually,
|
11
|
+
:user_by_define,
|
12
|
+
:admin_manually,
|
13
|
+
:admin_by_define,
|
14
|
+
:user_hash,
|
15
|
+
:invalid_user]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '#traits_for' do
|
20
|
+
it 'returns an array of trait names defined for the given factory' do
|
21
|
+
Factory.traits_for(:user_manually).should eq ['manager']
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '#create!' do
|
26
|
+
context 'given invalid record' do
|
27
|
+
let(:factory_name) { :invalid_user }
|
28
|
+
|
29
|
+
it 'raises an error if validation failed' do
|
30
|
+
expect { Factory.create!(factory_name) }.to raise_error('Validation failed: {:required_attr=>["can\'t be blank"]}')
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'given valid record' do
|
35
|
+
let(:factory_name) { :user }
|
36
|
+
|
37
|
+
it 'creates object' do
|
38
|
+
result = nil
|
39
|
+
expect { result = Factory.create!(factory_name) }.to_not raise_error
|
40
|
+
result.should be_saved
|
41
|
+
end
|
42
|
+
end
|
6
43
|
end
|
7
44
|
|
8
45
|
it "is alive" do
|
@@ -37,10 +74,10 @@ describe "The Cranky factory" do
|
|
37
74
|
end
|
38
75
|
|
39
76
|
it "clears all instance variables when reset" do
|
40
|
-
Factory.some_instance_variable
|
41
|
-
Factory.some_instance_variable.should
|
77
|
+
Factory.instance_variable_set('@some_instance_variable', true)
|
78
|
+
Factory.instance_variable_get('@some_instance_variable').should be_true
|
42
79
|
Factory.reset
|
43
|
-
Factory.some_instance_variable.should
|
80
|
+
Factory.instance_variable_get('@some_instance_variable').should be_nil
|
44
81
|
end
|
45
82
|
|
46
83
|
it "can create items using the define helper or manually" do
|
@@ -79,7 +116,7 @@ describe "The Cranky factory" do
|
|
79
116
|
describe "debugger" do
|
80
117
|
|
81
118
|
it "raises an error if the factory produces an invalid object when enabled (rails only)" do
|
82
|
-
expect { Factory.debug(:user) }.to raise_error(
|
119
|
+
expect { Factory.debug(:user, required_attr: nil) }.to raise_error(
|
83
120
|
'Oops, the User created by the Factory has the following errors: {:required_attr=>["can\'t be blank"]}'
|
84
121
|
)
|
85
122
|
end
|
@@ -147,7 +184,7 @@ describe "The Cranky factory" do
|
|
147
184
|
end
|
148
185
|
|
149
186
|
it "returns nothing extra in the attributes" do
|
150
|
-
crank(:user_attrs).size.should ==
|
187
|
+
crank(:user_attrs).size.should == 6
|
151
188
|
end
|
152
189
|
|
153
190
|
specify "attributes for works with factory methods using inherit" do
|
data/spec/linter_spec.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Factory.lint' do
|
4
|
+
it 'raises when a factory is invalid' do
|
5
|
+
error_message = <<-ERROR_MESSAGE.strip
|
6
|
+
The following factories are invalid:
|
7
|
+
|
8
|
+
* user_hash - undefined method `save!' for [:name, "Fred"]:Array (NoMethodError)
|
9
|
+
* invalid_user - Validation failed: {:required_attr=>["can't be blank"]} (RuntimeError)
|
10
|
+
ERROR_MESSAGE
|
11
|
+
|
12
|
+
expect do
|
13
|
+
Factory.lint!
|
14
|
+
end.to raise_error Cranky::Linter::InvalidFactoryError, error_message
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'does not raise when all factories are valid' do
|
18
|
+
expect { Factory.lint!(factory_names: [:admin_manually, :address]) }.not_to raise_error
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "trait validation" do
|
22
|
+
context "enabled" do
|
23
|
+
it "raises if a trait produces an invalid object" do
|
24
|
+
error_message = <<-ERROR_MESSAGE.strip
|
25
|
+
The following factories are invalid:
|
26
|
+
|
27
|
+
* user+invalid - Validation failed: {:required_attr=>["can't be blank"]} (RuntimeError)
|
28
|
+
* user_hash - undefined method `save!' for [:name, "Fred"]:Array (NoMethodError)
|
29
|
+
* invalid_user - Validation failed: {:required_attr=>["can't be blank"]} (RuntimeError)
|
30
|
+
ERROR_MESSAGE
|
31
|
+
|
32
|
+
expect do
|
33
|
+
Factory.lint!(traits: true)
|
34
|
+
end.to raise_error Cranky::Linter::InvalidFactoryError, error_message
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -19,6 +19,13 @@ class TestClass
|
|
19
19
|
@saved = true
|
20
20
|
end
|
21
21
|
|
22
|
+
def save!
|
23
|
+
if invalid?
|
24
|
+
raise "Validation failed: #{errors.messages}"
|
25
|
+
end
|
26
|
+
save
|
27
|
+
end
|
28
|
+
|
22
29
|
def saved?
|
23
30
|
!!@saved
|
24
31
|
end
|
@@ -38,7 +45,6 @@ class User < TestClass
|
|
38
45
|
attr_accessor :address
|
39
46
|
end
|
40
47
|
|
41
|
-
|
42
48
|
class Address < TestClass
|
43
49
|
attr_accessor :address
|
44
50
|
attr_accessor :city
|
@@ -47,32 +53,32 @@ end
|
|
47
53
|
# Some basic factory methods
|
48
54
|
class Cranky::Factory
|
49
55
|
|
50
|
-
attr_accessor :some_instance_variable
|
51
|
-
|
52
56
|
def user_manually
|
53
|
-
u = User.new
|
54
|
-
u.name =
|
55
|
-
u.role =
|
56
|
-
u.unique = "value#{n}"
|
57
|
-
u.email = "fred@home.com"
|
58
|
-
u.address = Factory.build(:address)
|
57
|
+
u = User.new
|
58
|
+
u.name = fetch(:name, 'Fred')
|
59
|
+
u.role = fetch(:role) { :user }
|
60
|
+
u.unique = fetch(:unique) { "value#{n}" }
|
61
|
+
u.email = fetch(:email) { "fred@home.com" }
|
62
|
+
u.address = fetch(:address) { Factory.build(:address) }
|
63
|
+
u.required_attr = true
|
59
64
|
u
|
60
65
|
end
|
61
66
|
|
62
67
|
def user_by_define
|
63
|
-
u = define :class => :user,
|
68
|
+
u = define :class => :user,
|
64
69
|
:name => "Fred",
|
65
70
|
:role => :user,
|
66
71
|
:unique => "value#{n}",
|
67
72
|
:email => "fred@home.com",
|
68
|
-
:address => Factory.create(:address)
|
73
|
+
:address => Factory.create(:address),
|
74
|
+
:required_attr => true
|
69
75
|
u.argument_received = true if options[:argument_supplied]
|
70
76
|
u
|
71
77
|
end
|
72
78
|
alias :user :user_by_define
|
73
79
|
|
74
80
|
def admin_manually
|
75
|
-
inherit(:user_manually, :
|
81
|
+
inherit(:user_manually, role: :admin, required_attr: true)
|
76
82
|
end
|
77
83
|
|
78
84
|
def admin_by_define
|
@@ -81,7 +87,8 @@ class Cranky::Factory
|
|
81
87
|
|
82
88
|
def address
|
83
89
|
define :address => "25 Wisteria Lane",
|
84
|
-
:city => "New York"
|
90
|
+
:city => "New York",
|
91
|
+
:required_attr => true
|
85
92
|
end
|
86
93
|
|
87
94
|
def user_hash
|
@@ -97,4 +104,12 @@ class Cranky::Factory
|
|
97
104
|
def apply_trait_manager_to_user_manually(user)
|
98
105
|
user.role = :manager
|
99
106
|
end
|
107
|
+
|
108
|
+
def apply_trait_invalid_to_user(user)
|
109
|
+
user.required_attr = nil
|
110
|
+
end
|
111
|
+
|
112
|
+
def invalid_user
|
113
|
+
inherit(:user, required_attr: false)
|
114
|
+
end
|
100
115
|
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: 0.
|
4
|
+
version: 1.0.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-11-06 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.
|
@@ -27,8 +27,10 @@ files:
|
|
27
27
|
- lib/cranky.rb
|
28
28
|
- lib/cranky/factory.rb
|
29
29
|
- lib/cranky/job.rb
|
30
|
+
- lib/cranky/linter.rb
|
30
31
|
- lib/cranky/version.rb
|
31
32
|
- spec/cranky_spec.rb
|
33
|
+
- spec/linter_spec.rb
|
32
34
|
- spec/spec_helper.rb
|
33
35
|
homepage: http://github.com/ginty/cranky
|
34
36
|
licenses: []
|
@@ -49,7 +51,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
49
51
|
version: 1.3.4
|
50
52
|
requirements: []
|
51
53
|
rubyforge_project:
|
52
|
-
rubygems_version: 2.6.
|
54
|
+
rubygems_version: 2.6.7
|
53
55
|
signing_key:
|
54
56
|
specification_version: 4
|
55
57
|
summary: A very light yet powerful test factory framework.
|