jim-summon 0.0.0 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -3,3 +3,4 @@
3
3
  coverage
4
4
  rdoc
5
5
  pkg
6
+ test.log
data/README.rdoc CHANGED
@@ -2,7 +2,108 @@
2
2
 
3
3
  Provides a nice DSL for creating dummy data using Factory Girl factory definitions.
4
4
 
5
- Docs and examples coming soon.
5
+ == Why
6
+
7
+ Now that you've moved away from fixtures (well, you have, haven't you?) and started using factory_girl
8
+ in your tests and specs, it would be nice to have a succinct way to generate dummy data for use in development.
9
+
10
+ In the past I've just used a bunch of extra factories for this, but it's a lot nicer to be able to build an
11
+ arbitrary number of objects, each with its own set of associations.
12
+
13
+ == Example
14
+
15
+ Here is an example Rakefile from a project I'm working on:
16
+
17
+ namespace :summon do
18
+ desc "Builds a ton of dummy data"
19
+ task :build => ['environment', 'db:reset'] do
20
+
21
+ require 'spec/support/factories' # load factory definitions
22
+ require 'summon'
23
+
24
+ published_date = lambda {
25
+ method = %w(ago since)[rand(2)]
26
+ rand(100).days.send(method)
27
+ }
28
+
29
+ Summon(:label, 5)
30
+ Summon(:blog_topic, 10)
31
+
32
+ Summon(:user, 20) do |user|
33
+ user.blogs(3..8,
34
+ :topic => BlogTopic.all,
35
+ :published_at => published_date
36
+ ) do |blog|
37
+ blog.comments 0..4
38
+ end
39
+ end
40
+
41
+ Summon(:artist, 20) do |artist|
42
+ artist.events 4..6
43
+ artist.releases(0..5,
44
+ :label => Label.all
45
+ ) do |release|
46
+ release.tracks 8..12
47
+ end
48
+ end
49
+
50
+ puts "Your minions are ready!"
51
+
52
+ end
53
+ end
54
+
55
+ == Installation
56
+
57
+ I'd go for the gem.
58
+
59
+ sudo gem install jim-summon
60
+
61
+ == Usage
62
+
63
+ === Specifying how many objects to build
64
+
65
+ You can use an integer or range when specifying how many objects to build:
66
+
67
+ Summon(:monkey, 3) # build 3 monkeys
68
+ Summon(:monkey, 3..6) # build between 3 and 6 monkeys
69
+
70
+ === Object attributes
71
+
72
+ Other attributes to set on created objects (potentially overriding those defined by the factory)
73
+ are passed in as a hash:
74
+
75
+ Summon(:monkey, 42, :dangerous => true) # builds 42 dangerous monkeys
76
+
77
+ If you pass a proc in as an attribute, it will be evaluated for each object and the resulting
78
+ value used in its place.
79
+
80
+ If you pass an Array in as a value to an attribute, a value from the array will be selected at
81
+ random. This might seem odd, but I've found it's much more common to want to set an attribute
82
+ or association randomly from a set of options than set an attribute value to be an array. You
83
+ can always use a proc for this.
84
+
85
+ == Associated objects
86
+
87
+ This is where the magic really happens. Use a block to define an object's associations, and
88
+ potentially their attributes:
89
+
90
+ Summon(:car, 4) do |car| # Build 4 cars, and in each...
91
+ car.passengers 3 # Build 3 passengers
92
+ car.driver # Build one driver
93
+ end
94
+
95
+ Right now has_many and has_one associations are supported. has_many :through is not. Associations
96
+ can be nested as deep as you like:
97
+
98
+ Summon(:car, 4, :color => 'red') do |car|
99
+ car.passengers 3, :backseat_driver => true
100
+ car.driver do |driver|
101
+ driver.gloves 2
102
+ driver.jacket do |jacket|
103
+ jacket.pockets 2, :cents => [0,5,10,25,50]
104
+ end
105
+ end
106
+ end
6
107
 
7
108
  == Note on Patches/Pull Requests
8
109
 
data/Rakefile CHANGED
@@ -5,7 +5,7 @@ begin
5
5
  require 'jeweler'
6
6
  Jeweler::Tasks.new do |gem|
7
7
  gem.name = "summon"
8
- gem.summary = %Q{Provided a nice DSL for creating dummy data using Factory Girl factory definitions}
8
+ gem.summary = %Q{Provides a nice DSL for creating dummy data using Factory Girl factory definitions}
9
9
  gem.description = %Q{Allows for easily setting up deeply nested associations}
10
10
  gem.email = "jim@autonomousmachine.com"
11
11
  gem.homepage = "http://github.com/jim/summon"
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.0
1
+ 0.1.0
data/lib/summon.rb CHANGED
@@ -1,7 +1,12 @@
1
1
  require 'factory_girl'
2
2
 
3
3
  module Summon
4
-
4
+
5
+ (class << self; self; end).class_eval do
6
+ attr_accessor :noisy
7
+ end
8
+ self.noisy = false
9
+
5
10
  class Conjure
6
11
 
7
12
  attr :parent
@@ -11,7 +16,7 @@ module Summon
11
16
  end
12
17
 
13
18
  def log(string)
14
- if parent.nil?
19
+ if parent.nil? && Summon.noisy
15
20
  printf string; $stdout.flush
16
21
  end
17
22
  end
@@ -31,7 +36,7 @@ module Summon
31
36
  end
32
37
  end
33
38
 
34
- quantity = args.first
39
+ quantity = args.first || 1
35
40
  quantity = quantity.to_a[rand(quantity.to_a.size)] if quantity.is_a?(Range)
36
41
  options = args.extract_options!
37
42
 
@@ -46,7 +51,17 @@ module Summon
46
51
  if parent.nil?
47
52
  child = Factory(name, attributes)
48
53
  else
49
- child = parent.send(name).create(Factory.attributes_for(name.to_s.singularize, attributes))
54
+ association = @parent.class.reflect_on_association(name.to_sym)
55
+ raise "Association #{name} not found on #{@parent.class.to_s}" unless association
56
+
57
+ child = case association.macro
58
+ when :has_one:
59
+ parent.send("#{name}=", Factory(name.to_s.singularize, attributes))
60
+ when :has_many:
61
+ parent.send(name).create(Factory.attributes_for(name.to_s.singularize, attributes))
62
+ else
63
+ raise "#{association.macro} macros are not supported"
64
+ end
50
65
  end
51
66
  yield Conjure.new(child) if block_given?
52
67
  end
data/summon.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{summon}
8
- s.version = "0.0.0"
8
+ s.version = "0.1.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Jim Benton"]
12
- s.date = %q{2009-08-25}
12
+ s.date = %q{2009-08-26}
13
13
  s.description = %q{Allows for easily setting up deeply nested associations}
14
14
  s.email = %q{jim@autonomousmachine.com}
15
15
  s.extra_rdoc_files = [
@@ -32,7 +32,7 @@ Gem::Specification.new do |s|
32
32
  s.rdoc_options = ["--charset=UTF-8"]
33
33
  s.require_paths = ["lib"]
34
34
  s.rubygems_version = %q{1.3.3}
35
- s.summary = %q{Provided a nice DSL for creating dummy data using Factory Girl factory definitions}
35
+ s.summary = %q{Provides a nice DSL for creating dummy data using Factory Girl factory definitions}
36
36
  s.test_files = [
37
37
  "test/summon_test.rb",
38
38
  "test/test_helper.rb"
data/test/summon_test.rb CHANGED
@@ -1,7 +1,53 @@
1
1
  require 'test_helper'
2
2
 
3
- class SummonTest < Test::Unit::TestCase
4
- def test_pass
5
- assert true, 'had better pass'
3
+ class SummonTest < ActiveSupport::TestCase
4
+
5
+ def setup
6
+ Summon.noisy = false
7
+ Corner.delete_all
8
+ Compartment.delete_all
9
+ Handle.delete_all
10
+ Box.delete_all
11
+ Secret.delete_all
6
12
  end
7
- end
13
+
14
+ test "building a number of objects" do
15
+ Summon(:corner, 3)
16
+ assert_equal 3, Corner.count
17
+ end
18
+
19
+ test "building a variable number of objects" do
20
+ Summon(:corner, 3..5)
21
+ assert_operator 3..5, :===, Corner.count
22
+ end
23
+
24
+ test "overriding default factory attributes" do
25
+ Summon(:corner, 1, :sharp => false)
26
+ assert_equal false, Corner.first.sharp
27
+ end
28
+
29
+ test "building has_many associations" do
30
+ Summon(:box, 1) do |b|
31
+ b.corners 3
32
+ b.compartments 2 do |c|
33
+ c.secrets 4
34
+ end
35
+ end
36
+ assert_equal 3, Box.first.corners.count
37
+ assert_equal 3, Corner.count
38
+ assert_equal 2, Box.first.compartments.count
39
+ assert_equal 2, Compartment.count
40
+ assert_equal 8, Secret.count
41
+ end
42
+
43
+ test "building has_one associations" do
44
+ Summon(:box, 1) do |b|
45
+ b.compartments 2 do |c|
46
+ c.handle
47
+ end
48
+ end
49
+ assert_equal 2, Compartment.count
50
+ assert_equal 2, Handle.count
51
+ end
52
+
53
+ end
data/test/test_helper.rb CHANGED
@@ -1,9 +1,78 @@
1
1
  require 'rubygems'
2
+ gem 'test-unit'
2
3
  require 'test/unit'
4
+ require 'active_support'
5
+ require 'active_support/test_case'
6
+ require 'active_record'
7
+ require 'factory_girl'
3
8
 
4
9
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
5
10
  $LOAD_PATH.unshift(File.dirname(__FILE__))
6
11
  require 'summon'
7
12
 
8
- class Test::Unit::TestCase
13
+ ActiveRecord::Base.logger = Logger.new(File.open('test.log', 'a'))
14
+ ActiveRecord::Base.logger.level = Logger::DEBUG
15
+ ActiveRecord::Base.colorize_logging = false
16
+
17
+ ActiveRecord::Base.establish_connection(
18
+ :adapter => 'sqlite3',
19
+ :database => ":memory:"
20
+ )
21
+
22
+ ActiveRecord::Schema.define do
23
+ create_table :boxes, :force => true do |t|
24
+ t.string :name
25
+ t.integer :depth
26
+ end
27
+ create_table :corners, :force => true do |t|
28
+ t.integer :box_id
29
+ t.boolean :sharp
30
+ end
31
+ create_table :compartments, :force => true do |t|
32
+ t.integer :box_id
33
+ t.boolean :hidden
34
+ end
35
+ create_table :handles, :force => true do |h|
36
+ h.integer :compartment_id
37
+ h.boolean :metal
38
+ end
39
+ create_table :secrets, :force => true do |s|
40
+ s.integer :compartment_id
41
+ s.boolean :valuable
42
+ end
43
+ end
44
+
45
+ class Corner < ActiveRecord::Base; end
46
+ class Secret < ActiveRecord::Base; end
47
+ class Handle < ActiveRecord::Base; end
48
+
49
+ class Compartment < ActiveRecord::Base
50
+ has_many :secrets
51
+ has_one :handle
52
+ end
53
+
54
+ class Box < ActiveRecord::Base
55
+ has_many :compartments
56
+ has_many :corners
57
+ end
58
+
59
+ Factory.define(:box) do |b|
60
+ b.name 'A box'
61
+ b.depth 12
62
+ end
63
+
64
+ Factory.define(:corner) do |c|
65
+ c.sharp true
66
+ end
67
+
68
+ Factory.define(:compartment) do |c|
69
+ c.hidden true
70
+ end
71
+
72
+ Factory.define(:handle) do |h|
73
+ h.metal true
9
74
  end
75
+
76
+ Factory.define(:secret) do |c|
77
+ c.valuable true
78
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jim-summon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jim Benton
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-08-25 00:00:00 -07:00
12
+ date: 2009-08-26 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -67,7 +67,7 @@ rubyforge_project:
67
67
  rubygems_version: 1.2.0
68
68
  signing_key:
69
69
  specification_version: 3
70
- summary: Provided a nice DSL for creating dummy data using Factory Girl factory definitions
70
+ summary: Provides a nice DSL for creating dummy data using Factory Girl factory definitions
71
71
  test_files:
72
72
  - test/summon_test.rb
73
73
  - test/test_helper.rb