Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Refactor schematic processing

  • Loading branch information...
commit 0f7fd63ec8f7be5cdf9b60262cc06410e6a3bcd1 1 parent 8a8d687
@paulelliott authored
View
2  features/step_definitions/object_verification_steps.rb
@@ -13,7 +13,7 @@ def generate_fabricator_name(model_name)
def get_class(model_name)
fabricator_name = generate_fabricator_name(model_name)
- Fabrication::Fabricator.schematics[fabricator_name].klass
+ Fabrication.schematics[fabricator_name].klass
end
View
14 lib/fabrication.rb
@@ -5,11 +5,15 @@ module Fabrication
autoload :UnknownFabricatorError, 'fabrication/errors/unknown_fabricator_error'
autoload :MisplacedFabricateError, 'fabrication/errors/misplaced_fabricate_error'
+ module Schematic
+ autoload :Definition, 'fabrication/schematic/definition'
+ autoload :Manager, 'fabrication/schematic/manager'
+ end
+
autoload :Attribute, 'fabrication/attribute'
autoload :Config, 'fabrication/config'
autoload :Fabricator, 'fabrication/fabricator'
autoload :Sequencer, 'fabrication/sequencer'
- autoload :Schematic, 'fabrication/schematic'
autoload :Support, 'fabrication/support'
autoload :Transform, 'fabrication/transform'
@@ -25,7 +29,7 @@ module Generator
end
def self.clear_definitions
- Fabricator.schematics.clear
+ @schematics = nil
Sequencer.sequences.clear
end
@@ -41,10 +45,14 @@ def self.initializing?
@initializing
end
+ def self.schematics
+ @schematics ||= Fabrication::Schematic::Manager.new
+ end
+
end
def Fabricator(name, options={}, &block)
- Fabrication::Fabricator.define(name, options, &block)
+ Fabrication.schematics.register(name, options, &block)
end
def Fabricate(name, overrides={}, &block)
View
2  lib/fabrication/cucumber/step_fabricator.rb
@@ -54,7 +54,7 @@ def singular?
end
def schematic
- Fabrication::Fabricator.schematics[@fabricator]
+ Fabrication.schematics[@fabricator]
end
def dehumanize(string)
View
42 lib/fabrication/fabricator.rb
@@ -1,44 +1,10 @@
class Fabrication::Fabricator
- def self.define(name, options={}, &block)
- raise Fabrication::DuplicateFabricatorError, "'#{name}' is already defined" if schematics.include?(name)
- aliases = Array(options.delete(:aliases))
- schematic = schematics[name] = schematic_for(name, options, &block)
- Array(aliases).each do |as|
- schematics[as.to_sym] = schematic
- end
- schematic
- end
-
def self.generate(name, options={}, overrides={}, &block)
- Fabrication::Support.find_definitions if schematics.empty?
- raise Fabrication::UnknownFabricatorError, "No Fabricator defined for '#{name}'" unless schematics.has_key?(name)
- schematics[name].generate(options, overrides, &block)
- end
-
- def self.schematics
- @schematics ||= defined?(HashWithIndifferentAccess) ? {}.with_indifferent_access : {}
- end
-
- private
-
- def self.class_name_for(name, parent, options)
- options[:class_name] ||
- (parent && parent.klass.name) ||
- options[:from] ||
- name
- end
-
- def self.schematic_for(name, options, &block)
- parent = schematics[options[:from]]
- class_name = class_name_for(name, parent, options)
- klass = Fabrication::Support.class_for(class_name)
- raise Fabrication::UnfabricatableError, "No class found for '#{name}'" unless klass
- if parent
- parent.merge(&block).tap { |s| s.klass = klass }
- else
- Fabrication::Schematic.new(klass, &block)
- end
+ Fabrication::Support.find_definitions if Fabrication.schematics.empty?
+ schematic = Fabrication.schematics[name]
+ raise Fabrication::UnknownFabricatorError, "No Fabricator defined for '#{name}'" unless schematic
+ schematic.generate(options, overrides, &block)
end
end
View
2  lib/fabrication/schematic.rb → lib/fabrication/schematic/definition.rb
@@ -1,4 +1,4 @@
-class Fabrication::Schematic
+class Fabrication::Schematic::Definition
GENERATORS = [
Fabrication::Generator::ActiveRecord,
View
59 lib/fabrication/schematic/manager.rb
@@ -0,0 +1,59 @@
+class Fabrication::Schematic::Manager
+
+ def clear
+ schematics.clear
+ end
+
+ def empty?
+ schematics.empty?
+ end
+
+ def register(name, options, &block)
+ name = name.to_sym
+ raise_if_registered(name)
+ store(name, Array(options.delete(:aliases)), options, &block)
+ end
+
+ def [](name)
+ schematics[name.to_sym]
+ end
+
+ def schematics
+ @schematics ||= {}
+ end
+
+ protected
+
+ def raise_if_registered(name)
+ if self[name]
+ raise Fabrication::DuplicateFabricatorError, "'#{name}' is already defined"
+ end
+ end
+
+ def store(name, aliases, options, &block)
+ schematic = schematics[name] = schematic_for(name, options, &block)
+ aliases.each { |as| schematics[as.to_sym] = schematic }
+ end
+
+ def resolve_class(name, parent, options)
+ Fabrication::Support.class_for(
+ options[:class_name] ||
+ (parent && parent.klass.name) ||
+ options[:from] ||
+ name
+ ).tap do |klass|
+ raise Fabrication::UnfabricatableError, "No class found for '#{name}'" unless klass
+ end
+ end
+
+ def schematic_for(name, options, &block)
+ parent = schematics[options[:from]]
+ klass = resolve_class(name, parent, options)
+
+ if parent
+ parent.merge(&block).tap { |s| s.klass = klass }
+ else
+ Fabrication::Schematic::Definition.new(klass, &block)
+ end
+ end
+end
View
2  lib/fabrication/support.rb
@@ -3,7 +3,7 @@ class Fabrication::Support
class << self
def fabricatable?(name)
- Fabrication::Fabricator.schematics.include?(name) || class_for(name)
+ Fabrication.schematics[name] || class_for(name)
end
def class_for(class_or_to_s)
View
2  lib/fabrication/transform.rb
@@ -3,7 +3,7 @@ class Fabrication::Transform
class << self
def apply_to(schematic, attributes_hash)
- Fabrication::Support.find_definitions if Fabrication::Fabricator.schematics.empty?
+ Fabrication::Support.find_definitions if Fabrication.schematics.empty?
attributes_hash.inject({}) {|h,(k,v)| h.update(k => apply_transform(schematic, k, v)) }
end
View
2  spec/fabrication/cucumber_spec.rb
@@ -11,7 +11,7 @@
let(:fabricator_name) { :dog }
before do
- Fabrication::Fabricator.schematics.stub(:[]).
+ Fabrication.schematics.stub(:[]).
with(fabricator_name).and_return(stub(:klass => "Boom"))
end
View
44 spec/fabrication/fabricator_spec.rb
@@ -4,49 +4,11 @@
subject { Fabrication::Fabricator }
- describe ".define" do
-
- let(:options) { { aliases: ["thing_one", :thing_two] } }
-
- before(:all) do
- subject.define(:open_struct, options) do
- first_name "Joe"
- last_name { "Schmoe" }
- end
- end
-
- it "returns the schematic" do
- subject.define(:something, :class_name => :open_struct) do
- name "Paul"
- end.class.should == Fabrication::Schematic
- end
-
- it "creates a schematic" do
- subject.schematics[:open_struct].should be
- end
-
- it "has the correct class" do
- subject.schematics[:open_struct].klass.should == OpenStruct
- end
-
- it "has the attributes" do
- subject.schematics[:open_struct].attributes.size.should == 2
- end
-
- context "with an alias" do
-
- it "recognizes the aliases" do
- subject.schematics[:thing_one].should == subject.schematics[:open_struct]
- subject.schematics[:thing_two].should == subject.schematics[:open_struct]
- end
- end
- end
-
describe ".generate" do
context 'without definitions' do
- before { subject.schematics.clear }
+ before { Fabrication.schematics.clear }
it "finds definitions if none exist" do
Fabrication::Support.should_receive(:find_definitions)
@@ -57,10 +19,6 @@
context 'with definitions' do
- it "raises an error if the class cannot be located" do
- lambda { subject.define(:somenonexistantclass) }.should raise_error(Fabrication::UnfabricatableError)
- end
-
it "raises an error if the fabricator cannot be located" do
lambda { subject.generate(:object) }.should raise_error(Fabrication::UnknownFabricatorError)
end
View
2  spec/fabrication/generator/active_record_spec.rb
@@ -32,7 +32,7 @@
describe "#generate" do
let(:attributes) do
- Fabrication::Schematic.new(Company) do
+ Fabrication::Schematic::Definition.new(Company) do
name 'Company Name'
city { |c| c.name.downcase }
divisions(:count => 2) { |c, i| Division.create(:company => c, :name => "Division #{i}") }
View
8 spec/fabrication/generator/base_spec.rb
@@ -14,7 +14,7 @@
let(:generator) { Fabrication::Generator::Base.new(Person) }
let(:attributes) do
- Fabrication::Schematic.new(Person) do
+ Fabrication::Schematic::Definition.new(Person) do
first_name 'Guy'
shoes(:count => 4) do |person, index|
"#{person.first_name}'s shoe #{index}"
@@ -43,7 +43,7 @@
context "using init_with" do
let(:schematic) do
- Fabrication::Schematic.new(klass) do
+ Fabrication::Schematic::Definition.new(klass) do
on_init { init_with(:a, :b) }
end
end
@@ -56,7 +56,7 @@
context "not using init_with" do
let(:schematic) do
- Fabrication::Schematic.new(klass) do
+ Fabrication::Schematic::Definition.new(klass) do
on_init { [ :a, :b ] }
end
end
@@ -71,7 +71,7 @@
context "using an after_create hook" do
let(:schematic) do
- Fabrication::Schematic.new(Person) do
+ Fabrication::Schematic::Definition.new(Person) do
first_name "Guy"
after_create { |k| k.first_name.upcase! }
end
View
12 spec/fabrication/schematic_spec.rb → spec/fabrication/schematic/definition_spec.rb
@@ -1,9 +1,9 @@
require 'spec_helper'
-describe Fabrication::Schematic do
+describe Fabrication::Schematic::Definition do
let(:schematic) do
- Fabrication::Schematic.new(OpenStruct) do
+ Fabrication::Schematic::Definition.new(OpenStruct) do
name "Orgasmo"
something(:param => 2) { "hi!" }
another_thing { 25 }
@@ -13,17 +13,17 @@
describe "generator selection" do
context "for an activerecord object" do
it "uses the activerecord generator" do
- Fabrication::Schematic.new(Division).generator.should == Fabrication::Generator::ActiveRecord
+ Fabrication::Schematic::Definition.new(Division).generator.should == Fabrication::Generator::ActiveRecord
end
end
context "for a mongoid object" do
it "uses the base generator" do
- Fabrication::Schematic.new(Author).generator.should == Fabrication::Generator::Mongoid
+ Fabrication::Schematic::Definition.new(Author).generator.should == Fabrication::Generator::Mongoid
end
end
context "for a sequel object" do
it "uses the base generator" do
- Fabrication::Schematic.new(ParentSequelModel).generator.should == Fabrication::Generator::Sequel
+ Fabrication::Schematic::Definition.new(ParentSequelModel).generator.should == Fabrication::Generator::Sequel
end
end
end
@@ -157,7 +157,7 @@
let(:init_block) { lambda {} }
let(:init_schematic) do
block = init_block
- Fabrication::Schematic.new(OpenStruct) do
+ Fabrication::Schematic::Definition.new(OpenStruct) do
on_init &block
end
end
View
39 spec/fabrication/schematic/manager_spec.rb
@@ -0,0 +1,39 @@
+require 'spec_helper'
+
+describe Fabrication::Schematic::Manager do
+
+ subject { Fabrication::Schematic::Manager.new }
+
+ describe "#register" do
+
+ let(:options) { { aliases: ["thing_one", :thing_two] } }
+
+ before(:all) do
+ subject.register(:open_struct, options) do
+ first_name "Joe"
+ last_name { "Schmoe" }
+ end
+ end
+
+ it "creates a schematic" do
+ subject.schematics[:open_struct].should be
+ end
+
+ it "has the correct class" do
+ subject.schematics[:open_struct].klass.should == OpenStruct
+ end
+
+ it "has the attributes" do
+ subject.schematics[:open_struct].attributes.size.should == 2
+ end
+
+ context "with an alias" do
+ it "recognizes the aliases" do
+ subject.schematics[:thing_one].should == subject.schematics[:open_struct]
+ subject.schematics[:thing_two].should == subject.schematics[:open_struct]
+ end
+ end
+
+ end
+
+end
View
4 spec/fabrication/support_spec.rb
@@ -42,11 +42,11 @@
end
it "has an awesome object" do
- Fabrication::Fabricator.schematics[:awesome_object].should be
+ Fabrication.schematics[:awesome_object].should be
end
it "has a cool object" do
- Fabrication::Fabricator.schematics[:cool_object].should be
+ Fabrication.schematics[:cool_object].should be
end
end
View
22 spec/fabrication_spec.rb
@@ -306,7 +306,7 @@
after { Fabrication::Support.find_definitions }
it 'should not generate authors' do
- Fabrication::Fabricator.schematics.has_key?(:author).should be_false
+ Fabrication.schematics[:author].should be_nil
end
end
@@ -328,17 +328,23 @@
end
end
- context 'defining a fabricator without a block' do
+ context 'defining a fabricator' do
+ context 'without a block' do
+ before(:all) do
+ class Widget; end
+ Fabricator(:widget)
+ end
- before(:all) do
- class Widget; end
- Fabricator(:widget)
+ it 'works fine' do
+ Fabricate(:widget).should be
+ end
end
- it 'works fine' do
- Fabricate(:widget).should be
+ context 'for a non-existant class' do
+ it "raises an error if the class cannot be located" do
+ lambda { Fabricator(:somenonexistantclass) }.should raise_error(Fabrication::UnfabricatableError)
+ end
end
-
end
describe "Fabricate with a sequence" do
View
2  turnip/object_verification_steps.rb
@@ -14,7 +14,7 @@ def generate_fabricator_name(model_name)
def get_class(model_name)
fabricator_name = generate_fabricator_name(model_name)
- Fabrication::Fabricator.schematics[fabricator_name].klass
+ Fabrication.schematics[fabricator_name].klass
end
Please sign in to comment.
Something went wrong with that request. Please try again.