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 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