snowblink-factory_girl 1.1.5
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/CONTRIBUTION_GUIDELINES.rdoc +10 -0
- data/Changelog +29 -0
- data/LICENSE +19 -0
- data/README.textile +154 -0
- data/Rakefile +76 -0
- data/lib/factory_girl.rb +33 -0
- data/lib/factory_girl/aliases.rb +39 -0
- data/lib/factory_girl/attribute.rb +24 -0
- data/lib/factory_girl/factory.rb +258 -0
- data/lib/factory_girl/sequence.rb +58 -0
- data/test/aliases_test.rb +29 -0
- data/test/attribute_test.rb +32 -0
- data/test/factory_test.rb +410 -0
- data/test/integration_test.rb +147 -0
- data/test/models.rb +42 -0
- data/test/sequence_test.rb +76 -0
- data/test/test_helper.rb +11 -0
- metadata +79 -0
| @@ -0,0 +1,58 @@ | |
| 1 | 
            +
            class Factory
         | 
| 2 | 
            +
             | 
| 3 | 
            +
              class Sequence
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                def initialize (&proc) #:nodoc:
         | 
| 6 | 
            +
                  @proc  = proc
         | 
| 7 | 
            +
                  @value = 0
         | 
| 8 | 
            +
                end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                # Returns the next value for this sequence
         | 
| 11 | 
            +
                def next
         | 
| 12 | 
            +
                  @value += 1
         | 
| 13 | 
            +
                  @proc.call(@value)
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
              class << self
         | 
| 19 | 
            +
                attr_accessor :sequences #:nodoc:
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
              self.sequences = {}
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              # Defines a new sequence that can be used to generate unique values in a specific format.
         | 
| 24 | 
            +
              #
         | 
| 25 | 
            +
              # Arguments:
         | 
| 26 | 
            +
              #   name: (Symbol)
         | 
| 27 | 
            +
              #     A unique name for this sequence. This name will be referenced when
         | 
| 28 | 
            +
              #     calling next to generate new values from this sequence.
         | 
| 29 | 
            +
              #   block: (Proc)
         | 
| 30 | 
            +
              #     The code to generate each value in the sequence. This block will be
         | 
| 31 | 
            +
              #     called with a unique number each time a value in the sequence is to be
         | 
| 32 | 
            +
              #     generated. The block should return the generated value for the
         | 
| 33 | 
            +
              #     sequence.
         | 
| 34 | 
            +
              #
         | 
| 35 | 
            +
              # Example:
         | 
| 36 | 
            +
              #   
         | 
| 37 | 
            +
              #   Factory.sequence(:email) {|n| "somebody_#{n}@example.com" }
         | 
| 38 | 
            +
              def self.sequence (name, &block)
         | 
| 39 | 
            +
                self.sequences[name] = Sequence.new(&block)
         | 
| 40 | 
            +
              end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
              # Generates and returns the next value in a sequence.
         | 
| 43 | 
            +
              #
         | 
| 44 | 
            +
              # Arguments:
         | 
| 45 | 
            +
              #   name: (Symbol)
         | 
| 46 | 
            +
              #     The name of the sequence that a value should be generated for.
         | 
| 47 | 
            +
              #
         | 
| 48 | 
            +
              # Returns:
         | 
| 49 | 
            +
              #   The next value in the sequence. (Object)
         | 
| 50 | 
            +
              def self.next (sequence)
         | 
| 51 | 
            +
                unless self.sequences.key?(sequence)
         | 
| 52 | 
            +
                  raise "No such sequence: #{sequence}"
         | 
| 53 | 
            +
                end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                self.sequences[sequence].next
         | 
| 56 | 
            +
              end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
            end
         | 
| @@ -0,0 +1,29 @@ | |
| 1 | 
            +
            require(File.join(File.dirname(__FILE__), 'test_helper'))
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            class AliasesTest < Test::Unit::TestCase
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              should "include an attribute as an alias for itself by default" do
         | 
| 6 | 
            +
                assert Factory.aliases_for(:test).include?(:test)
         | 
| 7 | 
            +
              end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              should "include the root of a foreign key as an alias by default" do
         | 
| 10 | 
            +
                assert Factory.aliases_for(:test_id).include?(:test)
         | 
| 11 | 
            +
              end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
              should "include an attribute's foreign key as an alias by default" do
         | 
| 14 | 
            +
                assert Factory.aliases_for(:test).include?(:test_id)
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              context "after adding an alias" do
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                setup do
         | 
| 20 | 
            +
                  Factory.alias(/(.*)_suffix/, '\1')
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                should "return the alias in the aliases list" do
         | 
| 24 | 
            +
                  assert Factory.aliases_for(:test_suffix).include?(:test)
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
            end
         | 
| @@ -0,0 +1,32 @@ | |
| 1 | 
            +
            require(File.join(File.dirname(__FILE__), 'test_helper'))
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            class AttributeTest < Test::Unit::TestCase
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              context "an attribute" do
         | 
| 6 | 
            +
                setup do
         | 
| 7 | 
            +
                  @name  = :user
         | 
| 8 | 
            +
                  @attr  = Factory::Attribute.new(@name)
         | 
| 9 | 
            +
                end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                should "have a name" do
         | 
| 12 | 
            +
                  assert_equal @name, @attr.name
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                should "do nothing when being added to a proxy" do
         | 
| 16 | 
            +
                  @proxy = mock('proxy')
         | 
| 17 | 
            +
                  @proxy.expects(:set).never
         | 
| 18 | 
            +
                  @attr.add_to(@proxy)
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
              should "raise an error when defining an attribute writer" do
         | 
| 23 | 
            +
                assert_raise Factory::AttributeDefinitionError do
         | 
| 24 | 
            +
                  Factory::Attribute.new('test=')
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
              end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
              should "convert names to symbols" do
         | 
| 29 | 
            +
                assert_equal :name, Factory::Attribute.new('name').name
         | 
| 30 | 
            +
              end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
            end
         | 
| @@ -0,0 +1,410 @@ | |
| 1 | 
            +
            require(File.join(File.dirname(__FILE__), 'test_helper'))
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            class FactoryTest < Test::Unit::TestCase
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              context "defining a factory" do
         | 
| 6 | 
            +
                setup do
         | 
| 7 | 
            +
                  @name    = :user
         | 
| 8 | 
            +
                  @factory = mock('factory')
         | 
| 9 | 
            +
                  @factory.stubs(:factory_name).returns(@name)
         | 
| 10 | 
            +
                  @options = { :class => 'magic' }
         | 
| 11 | 
            +
                  Factory.stubs(:new).returns(@factory)
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                should "create a new factory using the specified name and options" do
         | 
| 15 | 
            +
                  Factory.expects(:new).with(@name, @options).returns(@factory)
         | 
| 16 | 
            +
                  Factory.define(@name, @options) {|f| }
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                should "pass the factory do the block" do
         | 
| 20 | 
            +
                  yielded = nil
         | 
| 21 | 
            +
                  Factory.define(@name) do |y|
         | 
| 22 | 
            +
                    yielded = y
         | 
| 23 | 
            +
                  end
         | 
| 24 | 
            +
                  assert_equal @factory, yielded
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                should "add the factory to the list of factories" do
         | 
| 28 | 
            +
                  Factory.define(@name) {|f| }
         | 
| 29 | 
            +
                  assert_equal Factory.factories[@name], 
         | 
| 30 | 
            +
                               @factory,
         | 
| 31 | 
            +
                               "Factories: #{Factory.factories.inspect}"
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
              end
         | 
| 34 | 
            +
              
         | 
| 35 | 
            +
              context "a factory" do
         | 
| 36 | 
            +
                setup do
         | 
| 37 | 
            +
                  @name    = :user
         | 
| 38 | 
            +
                  @class   = User
         | 
| 39 | 
            +
                  @factory = Factory.new(@name)
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                should "have a factory name" do
         | 
| 43 | 
            +
                  assert_equal @name, @factory.factory_name
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                should "have a build class" do
         | 
| 47 | 
            +
                  assert_equal @class, @factory.build_class
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                should "not allow the same attribute to be added twice" do
         | 
| 51 | 
            +
                  assert_raise(Factory::AttributeDefinitionError) do
         | 
| 52 | 
            +
                    2.times { @factory.add_attribute :first_name }
         | 
| 53 | 
            +
                  end
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                should "add a static attribute when an attribute is defined with a value" do
         | 
| 57 | 
            +
                  attribute = mock('attribute', :name => :name)
         | 
| 58 | 
            +
                  Factory::Attribute::Static.
         | 
| 59 | 
            +
                    expects(:new).
         | 
| 60 | 
            +
                    with(:name, 'value').
         | 
| 61 | 
            +
                    returns(attribute)
         | 
| 62 | 
            +
                  @factory.add_attribute(:name, 'value')
         | 
| 63 | 
            +
                end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                should "add a dynamic attribute when an attribute is defined with a block" do
         | 
| 66 | 
            +
                  attribute = mock('attribute', :name => :name)
         | 
| 67 | 
            +
                  block     = lambda {}
         | 
| 68 | 
            +
                  Factory::Attribute::Dynamic.
         | 
| 69 | 
            +
                    expects(:new).
         | 
| 70 | 
            +
                    with(:name, block).
         | 
| 71 | 
            +
                    returns(attribute)
         | 
| 72 | 
            +
                  @factory.add_attribute(:name, &block)
         | 
| 73 | 
            +
                end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                should "raise for an attribute with a value and a block" do
         | 
| 76 | 
            +
                  assert_raise(Factory::AttributeDefinitionError) do
         | 
| 77 | 
            +
                    @factory.add_attribute(:name, 'value') {}
         | 
| 78 | 
            +
                  end
         | 
| 79 | 
            +
                end
         | 
| 80 | 
            +
             | 
| 81 | 
            +
                context "after adding an attribute" do
         | 
| 82 | 
            +
                  setup do
         | 
| 83 | 
            +
                    @attribute = mock('attribute')
         | 
| 84 | 
            +
                    @proxy     = mock('proxy')
         | 
| 85 | 
            +
             | 
| 86 | 
            +
                    @attribute.                stubs(:name).  returns(:name)
         | 
| 87 | 
            +
                    @attribute.                stubs(:add_to)
         | 
| 88 | 
            +
                    @proxy.                    stubs(:set)
         | 
| 89 | 
            +
                    @proxy.                    stubs(:result).returns('result')
         | 
| 90 | 
            +
                    Factory::Attribute::Static.stubs(:new).   returns(@attribute)
         | 
| 91 | 
            +
                    Factory::Proxy::Build.     stubs(:new).   returns(@proxy)
         | 
| 92 | 
            +
             | 
| 93 | 
            +
                    @factory.add_attribute(:name, 'value')
         | 
| 94 | 
            +
                  end
         | 
| 95 | 
            +
             | 
| 96 | 
            +
                  should "create the right proxy using the build class when running" do
         | 
| 97 | 
            +
                    Factory::Proxy::Build.
         | 
| 98 | 
            +
                      expects(:new).
         | 
| 99 | 
            +
                      with(@factory.build_class).
         | 
| 100 | 
            +
                      returns(@proxy)
         | 
| 101 | 
            +
                    @factory.run(Factory::Proxy::Build, {})
         | 
| 102 | 
            +
                  end
         | 
| 103 | 
            +
             | 
| 104 | 
            +
                  should "add the attribute to the proxy when running" do
         | 
| 105 | 
            +
                    @attribute.expects(:add_to).with(@proxy)
         | 
| 106 | 
            +
                    @factory.run(Factory::Proxy::Build, {})
         | 
| 107 | 
            +
                  end
         | 
| 108 | 
            +
             | 
| 109 | 
            +
                  should "return the result from the proxy when running" do
         | 
| 110 | 
            +
                    @proxy.expects(:result).with().returns('result')
         | 
| 111 | 
            +
                    assert_equal 'result',
         | 
| 112 | 
            +
                                 @factory.run(Factory::Proxy::Build, {})
         | 
| 113 | 
            +
                  end
         | 
| 114 | 
            +
                end
         | 
| 115 | 
            +
             | 
| 116 | 
            +
                should "add an association without a factory name or overrides" do
         | 
| 117 | 
            +
                  factory = Factory.new(:post)
         | 
| 118 | 
            +
                  name    = :user
         | 
| 119 | 
            +
                  attr    = 'attribute'
         | 
| 120 | 
            +
                  Factory::Attribute::Association.
         | 
| 121 | 
            +
                    expects(:new).
         | 
| 122 | 
            +
                    with(name, name, {}).
         | 
| 123 | 
            +
                    returns(attr)
         | 
| 124 | 
            +
                  factory.association(name)
         | 
| 125 | 
            +
                  assert factory.attributes.include?(attr)
         | 
| 126 | 
            +
                end
         | 
| 127 | 
            +
             | 
| 128 | 
            +
                should "add an association with overrides" do
         | 
| 129 | 
            +
                  factory   = Factory.new(:post)
         | 
| 130 | 
            +
                  name      = :user
         | 
| 131 | 
            +
                  attr      = 'attribute'
         | 
| 132 | 
            +
                  overrides = { :first_name => 'Ben' }
         | 
| 133 | 
            +
                  Factory::Attribute::Association.
         | 
| 134 | 
            +
                    expects(:new).
         | 
| 135 | 
            +
                    with(name, name, overrides).
         | 
| 136 | 
            +
                    returns(attr)
         | 
| 137 | 
            +
                  factory.association(name, overrides)
         | 
| 138 | 
            +
                  assert factory.attributes.include?(attr)
         | 
| 139 | 
            +
                end
         | 
| 140 | 
            +
             | 
| 141 | 
            +
                should "add an association with a factory name" do
         | 
| 142 | 
            +
                  factory = Factory.new(:post)
         | 
| 143 | 
            +
                  attr = 'attribute'
         | 
| 144 | 
            +
                  Factory::Attribute::Association.
         | 
| 145 | 
            +
                    expects(:new).
         | 
| 146 | 
            +
                    with(:author, :user, {}).
         | 
| 147 | 
            +
                    returns(attr)
         | 
| 148 | 
            +
                  factory.association(:author, :factory => :user)
         | 
| 149 | 
            +
                  assert factory.attributes.include?(attr)
         | 
| 150 | 
            +
                end
         | 
| 151 | 
            +
             | 
| 152 | 
            +
                should "add an association with a factory name and overrides" do
         | 
| 153 | 
            +
                  factory = Factory.new(:post)
         | 
| 154 | 
            +
                  attr = 'attribute'
         | 
| 155 | 
            +
                  Factory::Attribute::Association.
         | 
| 156 | 
            +
                    expects(:new).
         | 
| 157 | 
            +
                    with(:author, :user, :first_name => 'Ben').
         | 
| 158 | 
            +
                    returns(attr)
         | 
| 159 | 
            +
                  factory.association(:author, :factory => :user, :first_name => 'Ben')
         | 
| 160 | 
            +
                  assert factory.attributes.include?(attr)
         | 
| 161 | 
            +
                end
         | 
| 162 | 
            +
             | 
| 163 | 
            +
                should "add an attribute using the method name when passed an undefined method" do
         | 
| 164 | 
            +
                  attr  = mock('attribute', :name => :name)
         | 
| 165 | 
            +
                  block = lambda {}
         | 
| 166 | 
            +
                  Factory::Attribute::Static.
         | 
| 167 | 
            +
                    expects(:new).
         | 
| 168 | 
            +
                    with(:name, 'value').
         | 
| 169 | 
            +
                    returns(attr)
         | 
| 170 | 
            +
                  @factory.send(:name, 'value')
         | 
| 171 | 
            +
                  assert @factory.attributes.include?(attr)
         | 
| 172 | 
            +
                end
         | 
| 173 | 
            +
             | 
| 174 | 
            +
                context "when overriding generated attributes with a hash" do
         | 
| 175 | 
            +
                  setup do
         | 
| 176 | 
            +
                    @attr  = :name
         | 
| 177 | 
            +
                    @value = 'The price is right!'
         | 
| 178 | 
            +
                    @hash  = { @attr => @value }
         | 
| 179 | 
            +
                  end
         | 
| 180 | 
            +
             | 
| 181 | 
            +
                  should "return the overridden value in the generated attributes" do
         | 
| 182 | 
            +
                    @factory.add_attribute(@attr, 'The price is wrong, Bob!')
         | 
| 183 | 
            +
                    result = @factory.run(Factory::Proxy::AttributesFor, @hash)
         | 
| 184 | 
            +
                    assert_equal @value, result[@attr]
         | 
| 185 | 
            +
                  end
         | 
| 186 | 
            +
             | 
| 187 | 
            +
                  should "not call a lazy attribute block for an overridden attribute" do
         | 
| 188 | 
            +
                    @factory.add_attribute(@attr) { flunk }
         | 
| 189 | 
            +
                    result = @factory.run(Factory::Proxy::AttributesFor, @hash)
         | 
| 190 | 
            +
                  end
         | 
| 191 | 
            +
             | 
| 192 | 
            +
                  should "override a symbol parameter with a string parameter" do
         | 
| 193 | 
            +
                    @factory.add_attribute(@attr, 'The price is wrong, Bob!')
         | 
| 194 | 
            +
                    @hash = { @attr.to_s => @value }
         | 
| 195 | 
            +
                    result = @factory.run(Factory::Proxy::AttributesFor, @hash)
         | 
| 196 | 
            +
                    assert_equal @value, result[@attr]
         | 
| 197 | 
            +
                  end
         | 
| 198 | 
            +
                end
         | 
| 199 | 
            +
             | 
| 200 | 
            +
                context "overriding an attribute with an alias" do
         | 
| 201 | 
            +
                  setup do
         | 
| 202 | 
            +
                    @factory.add_attribute(:test, 'original')
         | 
| 203 | 
            +
                    Factory.alias(/(.*)_alias/, '\1')
         | 
| 204 | 
            +
                    @result = @factory.run(Factory::Proxy::AttributesFor, 
         | 
| 205 | 
            +
                                           :test_alias => 'new')
         | 
| 206 | 
            +
                  end
         | 
| 207 | 
            +
             | 
| 208 | 
            +
                  should "use the passed in value for the alias" do
         | 
| 209 | 
            +
                    assert_equal 'new', @result[:test_alias]
         | 
| 210 | 
            +
                  end
         | 
| 211 | 
            +
             | 
| 212 | 
            +
                  should "discard the predefined value for the attribute" do
         | 
| 213 | 
            +
                    assert_nil @result[:test]
         | 
| 214 | 
            +
                  end
         | 
| 215 | 
            +
                end
         | 
| 216 | 
            +
             | 
| 217 | 
            +
                should "guess the build class from the factory name" do
         | 
| 218 | 
            +
                  assert_equal User, @factory.build_class
         | 
| 219 | 
            +
                end
         | 
| 220 | 
            +
             | 
| 221 | 
            +
                context "when defined with a custom class" do
         | 
| 222 | 
            +
                  setup do
         | 
| 223 | 
            +
                    @class   = User
         | 
| 224 | 
            +
                    @factory = Factory.new(:author, :class => @class)
         | 
| 225 | 
            +
                  end
         | 
| 226 | 
            +
             | 
| 227 | 
            +
                  should "use the specified class as the build class" do
         | 
| 228 | 
            +
                    assert_equal @class, @factory.build_class
         | 
| 229 | 
            +
                  end
         | 
| 230 | 
            +
                end
         | 
| 231 | 
            +
             | 
| 232 | 
            +
                context "when defined with a class instead of a name" do
         | 
| 233 | 
            +
                  setup do
         | 
| 234 | 
            +
                    @class   = ArgumentError
         | 
| 235 | 
            +
                    @name    = :argument_error
         | 
| 236 | 
            +
                    @factory = Factory.new(@class)
         | 
| 237 | 
            +
                  end
         | 
| 238 | 
            +
             | 
| 239 | 
            +
                  should "guess the name from the class" do
         | 
| 240 | 
            +
                    assert_equal @name, @factory.factory_name
         | 
| 241 | 
            +
                  end
         | 
| 242 | 
            +
             | 
| 243 | 
            +
                  should "use the class as the build class" do
         | 
| 244 | 
            +
                    assert_equal @class, @factory.build_class
         | 
| 245 | 
            +
                  end
         | 
| 246 | 
            +
                end
         | 
| 247 | 
            +
             | 
| 248 | 
            +
                context "when defined with a custom class name" do
         | 
| 249 | 
            +
                  setup do
         | 
| 250 | 
            +
                    @class   = ArgumentError
         | 
| 251 | 
            +
                    @factory = Factory.new(:author, :class => :argument_error)
         | 
| 252 | 
            +
                  end
         | 
| 253 | 
            +
             | 
| 254 | 
            +
                  should "use the specified class as the build class" do
         | 
| 255 | 
            +
                    assert_equal @class, @factory.build_class
         | 
| 256 | 
            +
                  end
         | 
| 257 | 
            +
                end
         | 
| 258 | 
            +
              end
         | 
| 259 | 
            +
              
         | 
| 260 | 
            +
              context "a factory with a name ending in s" do
         | 
| 261 | 
            +
                setup do
         | 
| 262 | 
            +
                  @name    = :business
         | 
| 263 | 
            +
                  @class   = Business
         | 
| 264 | 
            +
                  @factory = Factory.new(@name)
         | 
| 265 | 
            +
                end
         | 
| 266 | 
            +
                
         | 
| 267 | 
            +
                should "have a factory name" do
         | 
| 268 | 
            +
                  assert_equal @name, @factory.factory_name
         | 
| 269 | 
            +
                end
         | 
| 270 | 
            +
             | 
| 271 | 
            +
                should "have a build class" do
         | 
| 272 | 
            +
                  assert_equal @class, @factory.build_class
         | 
| 273 | 
            +
                end
         | 
| 274 | 
            +
              end
         | 
| 275 | 
            +
             | 
| 276 | 
            +
              context "a factory with a string for a name" do
         | 
| 277 | 
            +
                setup do
         | 
| 278 | 
            +
                  @name    = :user
         | 
| 279 | 
            +
                  @factory = Factory.new(@name.to_s) {}
         | 
| 280 | 
            +
                end
         | 
| 281 | 
            +
             | 
| 282 | 
            +
                should "convert the string to a symbol" do
         | 
| 283 | 
            +
                  assert_equal @name, @factory.factory_name
         | 
| 284 | 
            +
                end
         | 
| 285 | 
            +
              end
         | 
| 286 | 
            +
             | 
| 287 | 
            +
              context "a factory defined with a string name" do
         | 
| 288 | 
            +
                setup do
         | 
| 289 | 
            +
                  Factory.factories = {}
         | 
| 290 | 
            +
                  @name    = :user
         | 
| 291 | 
            +
                  @factory = Factory.define(@name.to_s) {}
         | 
| 292 | 
            +
                end
         | 
| 293 | 
            +
             | 
| 294 | 
            +
                should "store the factory using a symbol" do
         | 
| 295 | 
            +
                  assert_equal @factory, Factory.factories[@name]
         | 
| 296 | 
            +
                end
         | 
| 297 | 
            +
              end
         | 
| 298 | 
            +
             | 
| 299 | 
            +
              context "after defining a factory" do
         | 
| 300 | 
            +
                setup do
         | 
| 301 | 
            +
                  @name    = :user
         | 
| 302 | 
            +
                  @factory = mock('factory')
         | 
| 303 | 
            +
             | 
| 304 | 
            +
                  Factory.factories[@name] = @factory
         | 
| 305 | 
            +
                end
         | 
| 306 | 
            +
             | 
| 307 | 
            +
                teardown { Factory.factories.clear }
         | 
| 308 | 
            +
             | 
| 309 | 
            +
                should "use Proxy::AttributesFor for Factory.attributes_for" do
         | 
| 310 | 
            +
                  @factory.
         | 
| 311 | 
            +
                    expects(:run).
         | 
| 312 | 
            +
                    with(Factory::Proxy::AttributesFor, :attr => 'value').
         | 
| 313 | 
            +
                    returns('result')
         | 
| 314 | 
            +
                  assert_equal 'result', Factory.attributes_for(@name, :attr => 'value')
         | 
| 315 | 
            +
                end
         | 
| 316 | 
            +
             | 
| 317 | 
            +
                should "use Proxy::Build for Factory.build" do
         | 
| 318 | 
            +
                  @factory.
         | 
| 319 | 
            +
                    expects(:run).
         | 
| 320 | 
            +
                    with(Factory::Proxy::Build, :attr => 'value').
         | 
| 321 | 
            +
                    returns('result')
         | 
| 322 | 
            +
                  assert_equal 'result', Factory.build(@name, :attr => 'value')
         | 
| 323 | 
            +
                end
         | 
| 324 | 
            +
             | 
| 325 | 
            +
                should "use Proxy::Create for Factory.create" do
         | 
| 326 | 
            +
                  @factory.
         | 
| 327 | 
            +
                    expects(:run).
         | 
| 328 | 
            +
                    with(Factory::Proxy::Create, :attr => 'value').
         | 
| 329 | 
            +
                    returns('result')
         | 
| 330 | 
            +
                  assert_equal 'result', Factory.create(@name, :attr => 'value')
         | 
| 331 | 
            +
                end
         | 
| 332 | 
            +
             | 
| 333 | 
            +
                should "use Proxy::Create for the global Factory method" do
         | 
| 334 | 
            +
                  @factory.
         | 
| 335 | 
            +
                    expects(:run).
         | 
| 336 | 
            +
                    with(Factory::Proxy::Create, :attr => 'value').
         | 
| 337 | 
            +
                    returns('result')
         | 
| 338 | 
            +
                  assert_equal 'result', Factory(@name, :attr => 'value')
         | 
| 339 | 
            +
                end
         | 
| 340 | 
            +
             | 
| 341 | 
            +
                [:build, :create, :attributes_for].each do |method|
         | 
| 342 | 
            +
                  should "raise an ArgumentError on #{method} with a nonexistant factory" do
         | 
| 343 | 
            +
                    assert_raise(ArgumentError) { Factory.send(method, :bogus) }
         | 
| 344 | 
            +
                  end
         | 
| 345 | 
            +
             | 
| 346 | 
            +
                  should "recognize either 'name' or :name for Factory.#{method}" do
         | 
| 347 | 
            +
                    @factory.stubs(:run)
         | 
| 348 | 
            +
                    assert_nothing_raised { Factory.send(method, @name.to_s) }
         | 
| 349 | 
            +
                    assert_nothing_raised { Factory.send(method, @name.to_sym) }
         | 
| 350 | 
            +
                  end
         | 
| 351 | 
            +
                end
         | 
| 352 | 
            +
              end
         | 
| 353 | 
            +
              
         | 
| 354 | 
            +
              def self.context_in_directory_with_files(*files)
         | 
| 355 | 
            +
                context "in a directory with #{files.to_sentence}" do
         | 
| 356 | 
            +
                  setup do
         | 
| 357 | 
            +
                    @pwd = Dir.pwd
         | 
| 358 | 
            +
                    @tmp_dir = File.join(File.dirname(__FILE__), 'tmp')
         | 
| 359 | 
            +
                    FileUtils.mkdir_p @tmp_dir
         | 
| 360 | 
            +
                    Dir.chdir(@tmp_dir)
         | 
| 361 | 
            +
                    
         | 
| 362 | 
            +
                    files.each do |file|
         | 
| 363 | 
            +
                      FileUtils.mkdir_p File.dirname(file)
         | 
| 364 | 
            +
                      FileUtils.touch file
         | 
| 365 | 
            +
                      Factory.stubs(:require).with(file)
         | 
| 366 | 
            +
                    end
         | 
| 367 | 
            +
                  end
         | 
| 368 | 
            +
                  
         | 
| 369 | 
            +
                  teardown do
         | 
| 370 | 
            +
                    Dir.chdir(@pwd)
         | 
| 371 | 
            +
                    FileUtils.rm_rf(@tmp_dir)
         | 
| 372 | 
            +
                  end
         | 
| 373 | 
            +
             | 
| 374 | 
            +
                  yield
         | 
| 375 | 
            +
                end
         | 
| 376 | 
            +
              end
         | 
| 377 | 
            +
              
         | 
| 378 | 
            +
              def self.should_require_definitions_from(file)
         | 
| 379 | 
            +
                should "load definitions from #{file}" do
         | 
| 380 | 
            +
                  Factory.expects(:require).with(file)
         | 
| 381 | 
            +
                  Factory.find_definitions
         | 
| 382 | 
            +
                end    
         | 
| 383 | 
            +
              end
         | 
| 384 | 
            +
              
         | 
| 385 | 
            +
              context_in_directory_with_files 'factories.rb' do
         | 
| 386 | 
            +
                should_require_definitions_from 'factories.rb'
         | 
| 387 | 
            +
              end
         | 
| 388 | 
            +
              
         | 
| 389 | 
            +
              %w(spec test).each do |dir|
         | 
| 390 | 
            +
                context_in_directory_with_files File.join(dir, 'factories.rb') do
         | 
| 391 | 
            +
                  should_require_definitions_from "#{dir}/factories.rb"
         | 
| 392 | 
            +
                end
         | 
| 393 | 
            +
             | 
| 394 | 
            +
                context_in_directory_with_files File.join(dir, 'factories', 'post_factory.rb') do
         | 
| 395 | 
            +
                  should_require_definitions_from "#{dir}/factories/post_factory.rb"
         | 
| 396 | 
            +
                end
         | 
| 397 | 
            +
             | 
| 398 | 
            +
                context_in_directory_with_files File.join(dir, 'factories', 'post_factory.rb'), File.join(dir, 'factories', 'person_factory.rb') do
         | 
| 399 | 
            +
                  should_require_definitions_from "#{dir}/factories/post_factory.rb"
         | 
| 400 | 
            +
                  should_require_definitions_from "#{dir}/factories/person_factory.rb"
         | 
| 401 | 
            +
                end
         | 
| 402 | 
            +
             | 
| 403 | 
            +
                context_in_directory_with_files File.join(dir, 'factories.rb'), File.join(dir, 'factories', 'post_factory.rb'), File.join(dir, 'factories', 'person_factory.rb') do
         | 
| 404 | 
            +
                  should_require_definitions_from "#{dir}/factories.rb"
         | 
| 405 | 
            +
                  should_require_definitions_from "#{dir}/factories/post_factory.rb"
         | 
| 406 | 
            +
                  should_require_definitions_from "#{dir}/factories/person_factory.rb"
         | 
| 407 | 
            +
                end
         | 
| 408 | 
            +
              end
         | 
| 409 | 
            +
             | 
| 410 | 
            +
            end
         |