fabrication 0.2.4 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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 fabricators.has_key?(name)
32
- fabricators[name].fabricate(options)
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 clone
12
- Fabrication::Schematic.new.tap do |dup|
13
- dup.attributes = attributes.map do |a|
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
- schematic = clone
21
- options.each do |name, value|
22
- if attribute = schematic.attribute(name)
23
- attribute.params = nil
24
- attribute.value = value
25
- else
26
- schematic.attributes << Attribute.new(name, nil, value)
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
@@ -1,3 +1,3 @@
1
1
  module Fabrication
2
- VERSION = '0.2.4'
2
+ VERSION = '0.3.0'
3
3
  end
@@ -242,7 +242,7 @@ describe Fabrication do
242
242
  end
243
243
 
244
244
  it 'should not generate authors' do
245
- lambda { Fabricate(:author) }.should raise_error(Fabrication::UnknownFabricatorError)
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(:author) }.should raise_error(Fabrication::UnknownFabricatorError)
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
@@ -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: 31
4
+ hash: 19
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 2
9
- - 4
10
- version: 0.2.4
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 00:00:00 -04:00
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: 13
29
+ hash: 27
30
30
  segments:
31
31
  - 1
32
- - 2
33
- - 9
34
- version: 1.2.9
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 that lazily generated attributes as they are used
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 aims to provide a fast and simple solution for test object generation
165
+ summary: Fabrication provides a robust solution for test object generation.
165
166
  test_files: []
166
167