Skip to content

Commit

Permalink
More updates for 0.3.0, see changelog
Browse files Browse the repository at this point in the history
  • Loading branch information
Ginty committed Oct 16, 2011
1 parent 37fe0c9 commit 49f9a05
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 30 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,18 @@

## 0.3.0

* Updated README to present the crank syntax as the default

* Appending the first argument with _attrs will return a hash of attributes rather than
the object, i.e. crank(:user) returns a User instance, and crank(:user_attrs) returns
a hash of valid attributes

* Factory.attributes_for now returns a hash of attributes rather than an array, this
method is no longer dependent on rails

* \#3 Factory methods can generate attribute hashes by default by setting :class => Hash in
the define declaration (leemhenson)

* Factory.debug was broken on ActiveModel based classes, now works with them

* Attributes can be skipped by setting the value to :skip. e.g. crank(:user, :name => :skip) will
Expand Down
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ source "http://gemcutter.org"
group :development do
gem "rake"
gem "gemcutter"
gem "ruby-debug19", :require => 'ruby-debug'
end

group :test do
Expand Down
15 changes: 15 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
GEM
remote: http://gemcutter.org/
specs:
archive-tar-minitar (0.5.2)
columnize (0.3.4)
diff-lcs (1.1.2)
gemcutter (0.7.0)
linecache19 (0.5.12)
ruby_core_source (>= 0.1.4)
rake (0.9.2)
rcov (0.9.9)
rspec (2.6.0)
Expand All @@ -13,6 +17,16 @@ GEM
rspec-expectations (2.6.0)
diff-lcs (~> 1.1.2)
rspec-mocks (2.6.0)
ruby-debug-base19 (0.11.25)
columnize (>= 0.3.1)
linecache19 (>= 0.5.11)
ruby_core_source (>= 0.1.4)
ruby-debug19 (0.11.6)
columnize (>= 0.3.1)
linecache19 (>= 0.5.11)
ruby-debug-base19 (>= 0.11.19)
ruby_core_source (0.1.5)
archive-tar-minitar (>= 0.5.2)

PLATFORMS
ruby
Expand All @@ -22,3 +36,4 @@ DEPENDENCIES
rake
rcov
rspec
ruby-debug19
6 changes: 5 additions & 1 deletion lib/cranky/factory.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def reset
end

def attributes_for(what, attrs={})
build(what, attrs).attributes
build(what, attrs.merge(:_return_attributes => true))
end

# Can be left in your tests as an alternative to build and to warn if your factory method
Expand Down Expand Up @@ -68,6 +68,10 @@ def inherit(what, overrides={})

# Execute the requested factory method, crank out the target object!
def crank_it(what, overrides)
if what.to_s =~ /(.*)_attrs$/
what = $1
overrides = overrides.merge(:_return_attributes => true)
end
item = "TBD"
new_job(what, overrides) do
item = self.send(what) # Invoke the factory method
Expand Down
41 changes: 30 additions & 11 deletions lib/cranky/job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ def initialize(target, overrides={})
@defaults = {}
@target = target
@overrides = overrides
@return_attributes = overrides.delete(:_return_attributes)
end

def attributes
Expand All @@ -19,25 +20,43 @@ def defaults=(defs)
@defaults = defs
end

def execute
item = get_constant(attributes[:class] ? attributes[:class] : @target).new
# Assign all explicit attributes first
attributes.each do |attribute, value|
unless value == :skip
item.send("#{attribute}=", value) if item.respond_to?("#{attribute}=") && !value.respond_to?("call")
end
# Returns the created item
def item
return @item if @item
if @return_attributes
@item = Hash.new
else
@item = get_constant(attributes[:class] ? attributes.delete(:class) : @target).new
end
# Then call any blocks
attributes.each do |attribute, value|
item.send("#{attribute}=", value.call(item)) if item.respond_to?("#{attribute}=") && value.respond_to?("call")
end

# Assign the value to the given attribute of the item
def assign(attribute, value)
unless value == :skip || attribute == :class
if item.respond_to?("#{attribute}=")
item.send("#{attribute}=", value)
elsif item.is_a?(Hash)
item[attribute] = value
end
end
end

def execute
values = attributes.reject { |attribute, value| value.respond_to?("call") }
blocks = attributes.select { |attribute, value| value.respond_to?("call") }

values.each { |attribute, value| assign(attribute, value) }
blocks.each { |attribute, value| assign(attribute, value.call(*(value.arity > 0 ? [item] : []))) }

item
end

private

# Nicked from here: http://gist.github.com/301173
# Nicked from here: http://gist.github.com/301173
def get_constant(name_sym)
return name_sym if name_sym.is_a? Class

name = name_sym.to_s.split('_').collect {|s| s.capitalize }.join('')
Object.const_defined?(name) ? Object.const_get(name) : Object.const_missing(name)
end
Expand Down
60 changes: 42 additions & 18 deletions spec/cranky_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,47 +5,48 @@
before(:each) do
end

it "should be alive" do
it "is alive" do
Factory.build(:user).class.should == User
end

it "should not save the item when generated via build" do
it "does not save the item when generated via build or crank" do
Factory.build(:user).saved?.should == false
crank(:user).saved?.should == false
end

it "should save the item when generated via create" do
it "does save the item when generated via create or crank!" do
Factory.create(:user).saved?.should == true
crank!(:user).saved?.should == true
end

it "should allow all attributes to be overriden in the call" do
it "allows all attributes to be overriden in the call" do
u = Factory.build(:user, :name => "Indy", :email => "[email protected]", :role => :dog, :unique => :yep)
u.name.should == "Indy"
u.email.should == "[email protected]"
u.role.should == :dog
u.unique.should == :yep
end

it "should return valid attributes rather than the model (rails only)" do
attrs = Factory.attributes_for(:user)
attrs.class.should == Array
it "returns valid attributes rather than the model" do
Factory.attributes_for(:user).class.should == Hash
end

it "should clear all instance variables when reset" do
it "clears all instance variables when reset" do
Factory.some_instance_variable = true
Factory.some_instance_variable.should == true
Factory.reset
Factory.some_instance_variable.should == nil
end

it "should be able to create items using the define helper or manually" do
it "can create items using the define helper or manually" do
m = Factory.build(:user_manually)
d = Factory.build(:user_by_define)
m.name.should == d.name
m.email.should == d.email
m.role.should == d.role
end

it "should be able to build by inheriting and overriding from other methods" do
it "can build by inheriting and overriding from other methods" do
a = Factory.build(:admin_manually)
a.name.should == "Fred"
a.role.should == :admin
Expand All @@ -54,14 +55,14 @@
b.role.should == :admin
end

it "should give top priority to attributes defined at the top level, even when inheriting" do
it "gives top priority to attributes defined at the top level, even when inheriting" do
a = Factory.build(:admin_manually, :role => :something_else)
a.role.should == :something_else
b = Factory.build(:admin_by_define, :role => :something_else)
b.role.should == :something_else
end

it "should create unique values using the n method" do
it "creates unique values using the n method" do
a = Factory.build(:user)
b = Factory.build(:user)
c = Factory.build(:user)
Expand All @@ -72,7 +73,7 @@

describe "debugger" do

it "should raise an error if the factory produces an invalid object when enabled (rails only)" do
it "raises an error if the factory produces an invalid object when enabled (rails only)" do
error = false
begin
Factory.debug(:user, :valid => false)
Expand All @@ -82,20 +83,20 @@
error.should == true
end

it "should have debug work like build and create when there are no errors" do
it "debug works like build and create when there are no errors" do
Factory.debug(:user).class.should == User
Factory.debug(:user).saved?.should == false
Factory.debug!(:user).saved?.should == true
end

end

it "should allow arguments to be passed in the overrides hash" do
it "allows arguments to be passed in the overrides hash" do
Factory.build(:user).argument_received.should == nil
Factory.build(:user, :argument_supplied => true).argument_received.should == true
end

it "should allow blocks to be passed into the define method" do
it "allows blocks to be passed into the define method" do
Factory.build(:user, :name => "jenny", :email => lambda{ |u| "#{u.name}@home.com" }).email.should == "[email protected]"
Factory.build(:user, :name => lambda { |u| "jimmy" + " cranky" }).name.should == "jimmy cranky"
Factory.build(:user, :name => "jenny", :email => Proc.new{ |u| "#{u.name}@home.com" }).email.should == "[email protected]"
Expand All @@ -111,10 +112,33 @@
Factory.create(:user_by_define).address.saved?.should == true
end

it "should also have its own syntax" do
it "has its own syntax" do
crank(:user).saved?.should == false
crank!(:address).saved?.should == true
end


it "is capable of creating user hashes" do
Factory.build(:user_hash)[:name].should == "Fred"
Factory.build(:user_hash)[:role].should == :user
Factory.build(:user_hash)[:class].should be_nil
end

it "is capable of overriding user hashes" do
Factory.build(:user_hash, :role => :admin)[:role].should == :admin
end

specify "attributes are not assigned when they have the value :skip" do
crank(:user, :name => :skip).name.should_not be
end

it "returns an hash of attributes when the 1st argument is appended with _attrs" do
crank(:user_attrs).class.should == Hash
crank(:user_attrs, :name => "Yo")[:name].should == "Yo"
end

it "returns nothing extra in the attributes" do
crank(:user_attrs).size.should == 6
end

end

5 changes: 5 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@ def address
:valid => true
end

def user_hash
define :class => Hash,
:name => "Fred",
:role => :user
end
end


Expand Down

0 comments on commit 49f9a05

Please sign in to comment.