From 49f9a05f894b66671219bb3537b7b94b3cce79af Mon Sep 17 00:00:00 2001 From: Ginty Date: Sun, 16 Oct 2011 20:17:13 +0100 Subject: [PATCH] More updates for 0.3.0, see changelog --- CHANGELOG.md | 12 +++++++++ Gemfile | 1 + Gemfile.lock | 15 +++++++++++ lib/cranky/factory.rb | 6 ++++- lib/cranky/job.rb | 41 +++++++++++++++++++++-------- spec/cranky_spec.rb | 60 ++++++++++++++++++++++++++++++------------- spec/spec_helper.rb | 5 ++++ 7 files changed, 110 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6010a4f..12ca877 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/Gemfile b/Gemfile index b30125d..52bd02c 100644 --- a/Gemfile +++ b/Gemfile @@ -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 diff --git a/Gemfile.lock b/Gemfile.lock index 42370d3..f8034a6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -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) @@ -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 @@ -22,3 +36,4 @@ DEPENDENCIES rake rcov rspec + ruby-debug19 diff --git a/lib/cranky/factory.rb b/lib/cranky/factory.rb index f324272..56cb345 100644 --- a/lib/cranky/factory.rb +++ b/lib/cranky/factory.rb @@ -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 @@ -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 diff --git a/lib/cranky/job.rb b/lib/cranky/job.rb index 802f4ed..2194e94 100644 --- a/lib/cranky/job.rb +++ b/lib/cranky/job.rb @@ -8,6 +8,7 @@ def initialize(target, overrides={}) @defaults = {} @target = target @overrides = overrides + @return_attributes = overrides.delete(:_return_attributes) end def attributes @@ -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 diff --git a/spec/cranky_spec.rb b/spec/cranky_spec.rb index 088ab22..46bee30 100644 --- a/spec/cranky_spec.rb +++ b/spec/cranky_spec.rb @@ -5,19 +5,21 @@ 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 => "indy@home.com", :role => :dog, :unique => :yep) u.name.should == "Indy" u.email.should == "indy@home.com" @@ -25,19 +27,18 @@ 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 @@ -45,7 +46,7 @@ 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 @@ -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) @@ -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) @@ -82,7 +83,7 @@ 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 @@ -90,12 +91,12 @@ 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 == "jenny@home.com" 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 == "jenny@home.com" @@ -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 diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 16b32e6..c575bd0 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -86,6 +86,11 @@ def address :valid => true end + def user_hash + define :class => Hash, + :name => "Fred", + :role => :user + end end