Permalink
Browse files

Add fabricator specific transforms overrides

  • Loading branch information...
1 parent 71f6406 commit 8a8d687995eb65020c783a92140de0f99b02d3ad Brandon Farmer and Shay Arnett committed with shayarnett Apr 20, 2012
@@ -12,7 +12,7 @@ def initialize(model_name, opts ={})
def from_table(table, extra={})
hashes = singular? ? [table.rows_hash] : table.hashes
hashes.map do |hash|
- transformed_hash = Fabrication::Transform.apply(parameterize_hash(hash))
+ transformed_hash = Fabrication::Transform.apply_to(@model, parameterize_hash(hash))
make(transformed_hash.merge(extra))
end.tap {|o| remember(o) }
end
@@ -2,21 +2,34 @@ class Fabrication::Transform
class << self
- def apply(attributes_hash)
+ def apply_to(schematic, attributes_hash)
Fabrication::Support.find_definitions if Fabrication::Fabricator.schematics.empty?
- attributes_hash.inject({}) {|h,(k,v)| h.update(k => transforms[k].call(v)) }
+ attributes_hash.inject({}) {|h,(k,v)| h.update(k => apply_transform(schematic, k, v)) }
end
def clear_all
@transforms = nil
+ @overrides = nil
end
def define(attribute, transform)
transforms[attribute] = transform
end
+ def only_for(schematic, attribute, transform)
+ overrides[schematic] = (overrides[schematic] || {}).merge!(attribute => transform)
+ end
+
private
+ def overrides
+ @overrides ||= {}
+ end
+
+ def apply_transform(schematic, attribute, value)
+ overrides.fetch(schematic, transforms)[attribute].call(value)
+ end
+
def transforms
@transforms ||= Hash.new(lambda {|value| value})
end
@@ -82,8 +82,8 @@
end
it 'applies transforms' do
- Fabrication::Transform.should_receive(:apply).
- with({:some => 'thing'}).and_return({})
+ Fabrication::Transform.should_receive(:apply_to).
+ with('bears', {:some => 'thing'}).and_return({})
Fabrication::Cucumber::StepFabricator.new('bears').from_table(table)
end
end
@@ -7,57 +7,73 @@
Fabrication::Transform.clear_all
end
- describe '.apply' do
+ describe '.apply_to' do
context 'find definitions' do
context 'transforms are empty' do
it 'loads the definitions' do
Fabrication::Support.should_receive(:find_definitions)
- Fabrication::Transform.apply(:name => 'Shay')
+ Fabrication::Transform.apply_to(nil, :name => 'Shay')
end
end
context 'transforms are not empty' do
it 'does not load the definitions' do
- Fabrication::Transform.apply(:name => 'Shay')
+ Fabrication::Transform.apply_to(nil, :name => 'Shay')
Fabrication::Support.should_not_receive(:find_definitions)
- Fabrication::Transform.apply(:name => 'Gabriel')
+ Fabrication::Transform.apply_to(nil, :name => 'Gabriel')
end
end
end
- context 'attributes include a key with transform defined' do
+ context 'when there is a generic transform for that column' do
before do
- Fabrication::Transform.define(:name, lambda {|value| value.reverse})
+ Fabrication::Transform.define(:city, lambda {|value| value.split.first})
end
- it 'transform is applied' do
- Fabrication::Transform.apply({:name => 'Shay'}).should == {:name => 'yahS'}
- end
- end
+ context 'fabricating an instance that is described by the per fabricator transform' do
+ before do
+ Fabrication::Transform.only_for(:address, :city, lambda {|value| value.upcase})
+ end
- context 'attributes do not include a key with transform defined' do
- before do
- Fabrication::Transform.define(:name, lambda {|value| value.reverse})
+ it 'applies the transform to the specified types' do
+ Fabrication::Transform.apply_to(:address, {:city => 'Jacksonville Beach'}).should == {:city => 'JACKSONVILLE BEACH'}
+ end
end
- it 'no transform is applied' do
- Fabrication::Transform.apply({:favorite_color => 'blue'}).should == {:favorite_color => 'blue'}
+ context 'no override has been defined' do
+ it 'applies the generic transform' do
+ Fabrication::Transform.apply_to(:address, {:city => 'Jacksonville Beach'}).should == {:city => 'Jacksonville'}
+ end
end
end
- context 'no transforms are defined' do
- it 'no transform is applied' do
- Fabrication::Transform.apply({:favorite_color => 'blue'}).should == {:favorite_color => 'blue'}
+ context 'when no generic transform has been defined' do
+ it 'does not change value' do
+ Fabrication::Transform.apply_to(:address, {:city => 'Jacksonville Beach'}).should == {:city => 'Jacksonville Beach'}
end
end
+ context 'ensuring precedence' do
+ context 'override is done before generic transform' do
+ before do
+ Fabrication::Transform.only_for(:address, :city, lambda {|value| value.upcase})
+ Fabrication::Transform.define(:city, lambda {|value| value.split.first})
+ end
+
+ it 'applies corretly' do
+ Fabrication::Transform.apply_to(:address, {:city => 'Jacksonville Beach'}).should == {:city => 'JACKSONVILLE BEACH'}
+ end
+ end
+ end
end
describe '.clear_all' do
it 'clears all transforms' do
Fabrication::Transform.define(:name, lambda {|value| value})
+ Fabrication::Transform.only_for(:address, :name, lambda {|value| value})
Fabrication::Transform.clear_all
Fabrication::Transform.send(:transforms).should be_empty
+ Fabrication::Transform.send(:overrides).should be_empty
end
end
@@ -69,4 +85,12 @@
end
end
+ describe '.only_for' do
+ it 'registers an override transform for provided model' do
+ lambda {
+ Fabrication::Transform.only_for(:address, :name, lambda {|value| value})
+ }.should change(Fabrication::Transform, :overrides)
+ end
+ end
+
end

0 comments on commit 8a8d687

Please sign in to comment.