fabrication 0.2.4 → 0.3.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.
- data/README.markdown +32 -2
- data/lib/fabrication.rb +11 -8
- data/lib/fabrication/fabricator.rb +3 -18
- data/lib/fabrication/generator/base.rb +4 -4
- data/lib/fabrication/schematic.rb +13 -14
- data/lib/fabrication/support.rb +27 -0
- data/lib/fabrication/version.rb +1 -1
- data/spec/fabrication_spec.rb +42 -2
- data/spec/schematic_spec.rb +23 -0
- metadata +12 -11
data/README.markdown
CHANGED
@@ -44,6 +44,8 @@ Breaking down the above, we are defining a "company" fabricator, which will gene
|
|
44
44
|
* It has a belongs_to association to location and this will be generated immediately with the company object. This is because of the :force => true parameter being passed in.
|
45
45
|
* After the object is created, it will update the "ceo" association with a new "drone" record.
|
46
46
|
|
47
|
+
Alternatively, you can Fabricate(:company) without first defining the Fabricator. Doing so will create an empty Fabricator called ":company" and prevent you from defining the Fabricator explicitly later.
|
48
|
+
|
47
49
|
### Inheritance ###
|
48
50
|
|
49
51
|
So you already have a company fabricator, but you need one that specifically generates an LLC. No problem!
|
@@ -54,15 +56,43 @@ So you already have a company fabricator, but you need one that specifically gen
|
|
54
56
|
|
55
57
|
Setting the :from option will inherit the class and all the attributes from the named Fabricator. Even if you haven't defined a :company Fabricator yet, it will still work as long as it references an actual class name.
|
56
58
|
|
59
|
+
### Fabricating ###
|
60
|
+
|
61
|
+
Now that your Fabricators are defined, you can start generating some objects! To generate the LLC from the previous example, just do this:
|
62
|
+
|
63
|
+
llc = Fabricate(:llc, :name => "Awesome Labs", :location => "Earth")
|
64
|
+
|
65
|
+
That will return an instance of the LLC using the fields defined in the Fabricators and overriding with anything passed into Fabricate.
|
66
|
+
|
67
|
+
If you need to do something more complex, you can also pass a block to Fabricate. You can use all the features available to you when defining Fabricators, but they only apply to the object generated by this Fabricate call.
|
68
|
+
|
69
|
+
llc = Fabricate(:llc, :name => "Awesome, Inc.") do
|
70
|
+
location(:force => true, :count => 2) { Faker::Address.city }
|
71
|
+
end
|
72
|
+
|
73
|
+
### Contributing ###
|
74
|
+
|
75
|
+
I (paulelliott) am actively maintaining this project. If you would like contribute, please fork the project, make your changes on a feature branch, and submit a pull request.
|
76
|
+
|
77
|
+
To run rake successfully:
|
78
|
+
|
79
|
+
1. Clone the project
|
80
|
+
2. Install mongodb and sqlite3
|
81
|
+
3. Install bundler
|
82
|
+
4. Run `bundle install` from the project root
|
83
|
+
5. Run `rake` and the test suite should be all green!
|
84
|
+
|
57
85
|
|
86
|
+
build without create...
|
58
87
|
|
88
|
+
look into: Object.reflect_on_associations
|
59
89
|
|
60
90
|
Fabricator(:atlanta_hub, :from => :hub) do
|
61
91
|
city "Atlanta"
|
62
92
|
state "GA"
|
63
93
|
location [33.755, -84.39]
|
64
|
-
hardwares(:hardware, :as => :headend, :count => 4)
|
94
|
+
hardwares(:hardware, :as => :headend, :count => 4) do |hub, index|
|
65
95
|
name 'something'
|
66
|
-
|
96
|
+
end
|
67
97
|
end
|
68
98
|
|
data/lib/fabrication.rb
CHANGED
@@ -4,6 +4,7 @@ module Fabrication
|
|
4
4
|
|
5
5
|
autoload :Fabricator, 'fabrication/fabricator'
|
6
6
|
autoload :Schematic, 'fabrication/schematic'
|
7
|
+
autoload :Support, 'fabrication/support'
|
7
8
|
|
8
9
|
module Generator
|
9
10
|
autoload :ActiveRecord, 'fabrication/generator/active_record'
|
@@ -26,10 +27,11 @@ module Fabrication
|
|
26
27
|
fabricators[name] = Fabricator.new(class_name, parent, &block)
|
27
28
|
end
|
28
29
|
|
29
|
-
def generate(name, options)
|
30
|
+
def generate(name, options, &block)
|
30
31
|
find_definitions if @@fabricators.nil?
|
31
|
-
raise UnknownFabricatorError unless
|
32
|
-
fabricators
|
32
|
+
raise UnknownFabricatorError unless Fabrication::Support.fabricatable?(name)
|
33
|
+
schematic(name, {}) unless fabricators.has_key?(name)
|
34
|
+
fabricators[name].fabricate(options, &block)
|
33
35
|
end
|
34
36
|
|
35
37
|
def find_definitions
|
@@ -54,13 +56,14 @@ module Fabrication
|
|
54
56
|
fabricators.clear
|
55
57
|
end
|
56
58
|
|
57
|
-
private
|
58
|
-
|
59
|
-
@@fabricators = nil
|
60
59
|
def fabricators
|
61
60
|
@@fabricators ||= {}
|
62
61
|
end
|
63
62
|
|
63
|
+
private
|
64
|
+
|
65
|
+
@@fabricators = nil
|
66
|
+
|
64
67
|
end
|
65
68
|
|
66
69
|
end
|
@@ -69,6 +72,6 @@ def Fabricator(name, options={}, &block)
|
|
69
72
|
Fabrication.schematic(name, options, &block)
|
70
73
|
end
|
71
74
|
|
72
|
-
def Fabricate(name, options={})
|
73
|
-
Fabrication.generate(name, options)
|
75
|
+
def Fabricate(name, options={}, &block)
|
76
|
+
Fabrication.generate(name, options, &block)
|
74
77
|
end
|
@@ -10,34 +10,19 @@ class Fabrication::Fabricator
|
|
10
10
|
|
11
11
|
def initialize(class_name, parent=nil, &block)
|
12
12
|
self.class_name = class_name
|
13
|
-
klass = class_for(class_name)
|
13
|
+
klass = Fabrication::Support.class_for(class_name)
|
14
14
|
self.schematic = parent ? parent.schematic.clone.merge!(&block) : Fabrication::Schematic.new(&block)
|
15
15
|
self.generator = GENERATORS.detect do |gen|
|
16
16
|
gen.supports?(klass)
|
17
17
|
end.new(klass, schematic)
|
18
18
|
end
|
19
19
|
|
20
|
-
def fabricate(options={})
|
21
|
-
generator.generate(options)
|
20
|
+
def fabricate(options={}, &block)
|
21
|
+
generator.generate(options, &block)
|
22
22
|
end
|
23
23
|
|
24
24
|
private
|
25
25
|
|
26
26
|
attr_accessor :generator
|
27
27
|
|
28
|
-
def class_for(class_or_to_s)
|
29
|
-
if class_or_to_s.respond_to?(:to_sym)
|
30
|
-
class_name = variable_name_to_class_name(class_or_to_s)
|
31
|
-
class_name.split('::').inject(Object) do |object, string|
|
32
|
-
object.const_get(string)
|
33
|
-
end
|
34
|
-
else
|
35
|
-
class_or_to_s
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def variable_name_to_class_name(name)
|
40
|
-
name.to_s.gsub(/\/(.?)/){"::#{$1.upcase}"}.gsub(/(?:^|_)(.)/){$1.upcase}
|
41
|
-
end
|
42
|
-
|
43
28
|
end
|
@@ -6,9 +6,9 @@ class Fabrication::Generator::Base
|
|
6
6
|
self.after_create_block = block if block_given?
|
7
7
|
end
|
8
8
|
|
9
|
-
def generate(options={})
|
9
|
+
def generate(options={}, &block)
|
10
10
|
self.instance = klass.new
|
11
|
-
process_attributes(options)
|
11
|
+
process_attributes(options, &block)
|
12
12
|
after_generation
|
13
13
|
after_create_block.call(instance) if after_create_block
|
14
14
|
instance
|
@@ -43,8 +43,8 @@ class Fabrication::Generator::Base
|
|
43
43
|
instance.send("#{method_name.to_s}=", value)
|
44
44
|
end
|
45
45
|
|
46
|
-
def process_attributes(options)
|
47
|
-
schematic.merge(options).attributes.each do |attribute|
|
46
|
+
def process_attributes(options, &block)
|
47
|
+
schematic.merge(options, &block).attributes.each do |attribute|
|
48
48
|
if attribute.name == :after_create
|
49
49
|
after_create(&attribute.value)
|
50
50
|
else
|
@@ -8,25 +8,24 @@ class Fabrication::Schematic
|
|
8
8
|
attributes.select { |a| a.name == name }.first
|
9
9
|
end
|
10
10
|
|
11
|
-
def
|
12
|
-
|
13
|
-
|
14
|
-
Attribute.new(a.name, a.params, a.value)
|
15
|
-
end
|
11
|
+
def initialize_copy(original)
|
12
|
+
self.attributes = original.attributes.map do |a|
|
13
|
+
Attribute.new(a.name, a.params, a.value)
|
16
14
|
end
|
17
15
|
end
|
18
16
|
|
19
|
-
def merge(options)
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
attribute
|
24
|
-
|
25
|
-
|
26
|
-
|
17
|
+
def merge(options, &block)
|
18
|
+
clone.tap do |schematic|
|
19
|
+
schematic.instance_eval(&block) if block_given?
|
20
|
+
options.each do |name, value|
|
21
|
+
if attribute = schematic.attribute(name)
|
22
|
+
attribute.params = nil
|
23
|
+
attribute.value = value
|
24
|
+
else
|
25
|
+
schematic.attributes << Attribute.new(name, nil, value)
|
26
|
+
end
|
27
27
|
end
|
28
28
|
end
|
29
|
-
schematic
|
30
29
|
end
|
31
30
|
|
32
31
|
def merge!(&block)
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class Fabrication::Support
|
2
|
+
|
3
|
+
class << self
|
4
|
+
|
5
|
+
def fabricatable?(name)
|
6
|
+
Fabrication.fabricators.has_key?(name) || class_for(name).present?
|
7
|
+
end
|
8
|
+
|
9
|
+
def class_for(class_or_to_s)
|
10
|
+
if class_or_to_s.respond_to?(:to_sym)
|
11
|
+
class_name = variable_name_to_class_name(class_or_to_s)
|
12
|
+
class_name.split('::').inject(Object) do |object, string|
|
13
|
+
object.const_get(string)
|
14
|
+
end
|
15
|
+
else
|
16
|
+
class_or_to_s
|
17
|
+
end
|
18
|
+
rescue NameError
|
19
|
+
end
|
20
|
+
|
21
|
+
def variable_name_to_class_name(name)
|
22
|
+
name.to_s.gsub(/\/(.?)/){"::#{$1.upcase}"}.gsub(/(?:^|_)(.)/){$1.upcase}
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
data/lib/fabrication/version.rb
CHANGED
data/spec/fabrication_spec.rb
CHANGED
@@ -242,7 +242,7 @@ describe Fabrication do
|
|
242
242
|
end
|
243
243
|
|
244
244
|
it 'should not generate authors' do
|
245
|
-
|
245
|
+
Fabrication.fabricators.has_key?(:author).should be_false
|
246
246
|
end
|
247
247
|
|
248
248
|
end
|
@@ -262,7 +262,7 @@ describe Fabrication do
|
|
262
262
|
context 'when generating from a non-existant fabricator' do
|
263
263
|
|
264
264
|
it 'throws an error' do
|
265
|
-
lambda { Fabricate(:
|
265
|
+
lambda { Fabricate(:your_mom) }.should raise_error(Fabrication::UnknownFabricatorError)
|
266
266
|
end
|
267
267
|
|
268
268
|
end
|
@@ -277,4 +277,44 @@ describe Fabrication do
|
|
277
277
|
|
278
278
|
end
|
279
279
|
|
280
|
+
describe ".fabricators" do
|
281
|
+
|
282
|
+
let(:author) { Fabricator(:author) }
|
283
|
+
let(:book) { Fabricator(:book) }
|
284
|
+
|
285
|
+
before(:all) { author; book }
|
286
|
+
|
287
|
+
it "returns the two fabricators" do
|
288
|
+
Fabrication.fabricators.should == {:author => author, :book => book}
|
289
|
+
end
|
290
|
+
|
291
|
+
end
|
292
|
+
|
293
|
+
describe "Fabricate with a block" do
|
294
|
+
|
295
|
+
let(:person) do
|
296
|
+
Fabricate(:person) do
|
297
|
+
first_name "Paul"
|
298
|
+
last_name { "Elliott" }
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
it 'uses the class matching the passed-in symbol' do
|
303
|
+
person.kind_of?(Person).should be_true
|
304
|
+
end
|
305
|
+
|
306
|
+
it 'has the correct first_name' do
|
307
|
+
person.first_name.should == 'Paul'
|
308
|
+
end
|
309
|
+
|
310
|
+
it 'has the correct last_name' do
|
311
|
+
person.last_name.should == 'Elliott'
|
312
|
+
end
|
313
|
+
|
314
|
+
it 'has the correct age' do
|
315
|
+
person.age.should be_nil
|
316
|
+
end
|
317
|
+
|
318
|
+
end
|
319
|
+
|
280
320
|
end
|
data/spec/schematic_spec.rb
CHANGED
@@ -89,4 +89,27 @@ describe Fabrication::Schematic do
|
|
89
89
|
schematic2.attribute(:name).value.should == 'Henry'
|
90
90
|
end
|
91
91
|
|
92
|
+
describe ".merge" do
|
93
|
+
|
94
|
+
context "accepts options and a block parameter" do
|
95
|
+
|
96
|
+
let(:merged) do
|
97
|
+
schematic.merge(:name => "Paul") do
|
98
|
+
name "Barack"
|
99
|
+
something "else"
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
it "sets name to 'Paul'" do
|
104
|
+
merged.attribute(:name).value.should == 'Paul'
|
105
|
+
end
|
106
|
+
|
107
|
+
it "sets something to 'else'" do
|
108
|
+
merged.attribute(:something).value.should == 'else'
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
|
92
115
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fabrication
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 19
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 3
|
9
|
+
- 0
|
10
|
+
version: 0.3.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Paul Elliott
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-07-
|
18
|
+
date: 2010-07-20 00:00:00 -04:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -26,12 +26,12 @@ dependencies:
|
|
26
26
|
requirements:
|
27
27
|
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
hash:
|
29
|
+
hash: 27
|
30
30
|
segments:
|
31
31
|
- 1
|
32
|
-
-
|
33
|
-
-
|
34
|
-
version: 1.
|
32
|
+
- 3
|
33
|
+
- 0
|
34
|
+
version: 1.3.0
|
35
35
|
type: :development
|
36
36
|
version_requirements: *id001
|
37
37
|
- !ruby/object:Gem::Dependency
|
@@ -98,7 +98,7 @@ dependencies:
|
|
98
98
|
version: 1.9.1
|
99
99
|
type: :development
|
100
100
|
version_requirements: *id005
|
101
|
-
description: Fabrication is an object generation framework
|
101
|
+
description: Fabrication is an object generation framework for ActiveRecord and Mongoid. It has a flexible syntax and lazily generates ActiveRecord associations!
|
102
102
|
email:
|
103
103
|
- paul@hashrocket.com
|
104
104
|
executables: []
|
@@ -114,6 +114,7 @@ files:
|
|
114
114
|
- lib/fabrication/generator/base.rb
|
115
115
|
- lib/fabrication/generator/mongoid.rb
|
116
116
|
- lib/fabrication/schematic.rb
|
117
|
+
- lib/fabrication/support.rb
|
117
118
|
- lib/fabrication/version.rb
|
118
119
|
- lib/fabrication.rb
|
119
120
|
- spec/fabrication_spec.rb
|
@@ -161,6 +162,6 @@ rubyforge_project:
|
|
161
162
|
rubygems_version: 1.3.7
|
162
163
|
signing_key:
|
163
164
|
specification_version: 3
|
164
|
-
summary: Fabrication
|
165
|
+
summary: Fabrication provides a robust solution for test object generation.
|
165
166
|
test_files: []
|
166
167
|
|