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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fbcde86a6a73ee0148b12ed591e978d21521f5ba
4
- data.tar.gz: 61a43c0743b8b333f85e3ec26f6604197086741b
3
+ metadata.gz: 42aebc7927e7fc1f29417cb638be0bee94190521
4
+ data.tar.gz: dd1710da521efa26a01615646b5daaa4e98980b7
5
5
  SHA512:
6
- metadata.gz: bf660e5eb16c325dc12f2c6f52839f6b2c5268a0d647729d5cb7b11f5bd9dcd55eb464609d57ffc3ef671b0def15abba10571c141e383e30029d59bd4696e5b6
7
- data.tar.gz: ce11711bca5aa5de02f02d33305074e025147727ef13f425837e0182522cf119330bd38d19eb2e8bd5b46e3a23e44fd1d3a136e9a9b2486fc63bbfcd25848a70
6
+ metadata.gz: e5234e23763c245d614d50dfe44d4e862ad4e236f16fb4eb9f71d5e98bf1899c4b55c4edaec3632b7bd8ea20e16965f0877e6d6e499e8ca3fe5654e3c6ec64e1
7
+ data.tar.gz: 621dcfd64bbdfefddd9e484a3c10e96dbd0f5ebdfe11ba537d7b674973a5ca4b5a77f29eca5416a48e5cab040c4d339213b82b44fd10faa44d4dbfc1a4a5abe3
@@ -1,31 +1,9 @@
1
1
  # Overview of Changes
2
2
 
3
- ## 0.3.1
3
+ ## 1.1.0
4
4
 
5
- * Bugfix, generating a hash of attributes via _attrs did not work with factory methods
6
- that used the inherit method
5
+ * Added before_create, after_build, after_create callbacks (@beorc)
7
6
 
8
- ## 0.3.0
7
+ ## 1.0.0
9
8
 
10
- * Updated README to present the crank syntax as the default
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/factory_girl.rake
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
@@ -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(&:save)
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(&:save!)
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
- trait_methods = public_methods(false).select {|m| regexp === m }
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.") unless respond_to?(trait_method_name)
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
 
@@ -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
- <<-ERROR_MESSAGE.strip
95
- The following factories are invalid:
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
- #{lines.join("\n")}
98
- ERROR_MESSAGE
129
+ "The following callbacks are invalid:\n\n#{invalid_callbacks.join("\n")}"
99
130
  end
100
131
  end
101
132
  end
@@ -1,3 +1,3 @@
1
1
  module Cranky
2
- VERSION = "1.0.0"
2
+ VERSION = "1.1.0"
3
3
  end
@@ -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 [: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]
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 == 6
191
+ crank(:user_attrs).size.should == 4
188
192
  end
189
193
 
190
194
  specify "attributes for works with factory methods using inherit" do
@@ -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
- expect { Factory.lint!(factory_names: [:admin_manually, :address]) }.not_to raise_error
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
- * invalid_user - Validation failed: {:required_attr=>["can't be blank"]} (RuntimeError)
41
+
42
+ The following callbacks are invalid:
43
+
44
+ after_create_not_existing_factory
30
45
  ERROR_MESSAGE
31
46
 
32
47
  expect do
@@ -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 invalid_user
113
- inherit(:user, required_attr: false)
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.0.0
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-06 00:00:00.000000000 Z
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.6.7
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.