kathy_lee 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -1,150 +1 @@
1
- =Kathy Lee
2
-
3
- An easy to use factory framework for generating test data for ActiveRecord models.
4
-
5
- ==Setup Examples
6
-
7
- KathyLee::User.define do
8
- username(fake(:user_name))
9
- email(fake(:email))
10
- home_page_url(fake(:url))
11
- fullname(fake(:full_name))
12
- login_count(0)
13
-
14
- has_many :posts, :size => 2
15
- has_many :comments, :size => 1
16
- end
17
-
18
- KathyLee::User::Marge.define do
19
- fullname('Marge Simpson')
20
- login_count(1000)
21
- end
22
-
23
- KathyLee::User::Marge::Other.define do
24
- home_page_url('http://www.simpsons.com')
25
-
26
- has_many :posts, :size => 5
27
- has_many :comments, :size => 1
28
- end
29
-
30
- KathyLee::Post.define do
31
- title(fake(:title))
32
- body(fake(:body))
33
-
34
- belongs_to :user
35
- has_many :comments, :size => 1
36
- end
37
-
38
- KathyLee::Comment.define do
39
- body(fake(:body))
40
-
41
- belongs_to :user
42
- belongs_to :post
43
- end
44
-
45
- KathyLee::Movie.define(:title => 'Rocky II', :director => 'Sly Stallone')
46
-
47
-
48
- # Build a new unsaved model:
49
- user = KathyLee::User.new
50
- user.username.should == 'bill.smith'
51
- user.email.should == 'bill.smith@example.org'
52
- user.home_page_url.should == 'http://www.example.com'
53
- user.fullname.should == 'Bill Smith'
54
- user.login_count.should == 0
55
- user.new_record?.should be_true
56
-
57
- # Build a new unsaved model with a few overrides:
58
- user = KathyLee::User.new(:username => 'mark.bates', :login_count => 5)
59
- user.username.should == 'mark.bates'
60
- user.email.should == 'bill.smith@example.org'
61
- user.home_page_url.should == 'http://www.example.com'
62
- user.fullname.should == 'Bill Smith'
63
- user.login_count.should == 5
64
- user.new_record?.should be_true
65
-
66
- # Build and save a new model:
67
- user = KathyLee::User.create
68
- user.username.should == 'bill.smith'
69
- user.email.should == 'bill.smith@example.org'
70
- user.home_page_url.should == 'http://www.example.com'
71
- user.fullname.should == 'Bill Smith'
72
- user.login_count.should == 0
73
- user.new_record?.should be_false
74
-
75
- # Build and save a new model with a few overrides:
76
- user = KathyLee::User.create(:username => 'mark.bates')
77
- user.username.should == 'mark.bates'
78
- user.email.should == 'bill.smith@example.org'
79
- user.home_page_url.should == 'http://www.example.com'
80
- user.fullname.should == 'Bill Smith'
81
- user.login_count.should == 0
82
- user.new_record?.should be_false
83
-
84
- # Build many unsaved models (can be used with/without block):
85
- users = KathyLee::User.sweatshop(10) do |user, index|
86
- user.login_count = index
87
- end
88
- users.size.should == 10
89
- users.each_with_index do |user, index|
90
- user.login_count.should == index
91
- user.new_record?.should be_true
92
- end
93
-
94
- # Build and save many models (can be used with/without block):
95
- users = KathyLee::User.sweatshop!(10) do |user, index|
96
- user.login_count = index
97
- end
98
- users.size.should == 10
99
- users.each_with_index do |user, index|
100
- user.login_count.should == index
101
- user.new_record?.should be_false
102
- end
103
-
104
- # Build belongs_to associations (change KathyLee::Post.new to KathyLee::Post.create to save the whole thing):
105
- post = KathyLee::Post.new
106
- post.title.should_not be_nil
107
- post.user.should_not be_nil
108
- post.user.should be_kind_of(User)
109
- post.user.email.should == 'bill.smith@example.org'
110
-
111
- # Build has_many associations (change KathyLee::User.new to KathyLee::User.create to save the whole thing):
112
- user = KathyLee::User.new
113
- user.should_not be_nil
114
- user.posts.should_not be_nil
115
- user.posts.size.should == 2
116
- user.posts.each do |post|
117
- post.should be_kind_of(Post)
118
- post.title.should_not be_nil
119
- end
120
- user.comments.should_not be_nil
121
- user.comments.size.should == 1
122
- user.comments.each do |comment|
123
- comment.should be_kind_of(Comment)
124
- end
125
-
126
- # Build a variant of a model using subclasses:
127
- user = KathyLee::User::Marge.new
128
- user.username.should == 'bill.smith'
129
- user.email.should == 'bill.smith@example.org'
130
- user.home_page_url.should == 'http://www.example.com'
131
- user.fullname.should == 'Marge Simpson'
132
- user.login_count.should == 1000
133
- user.new_record?.should be_true
134
- user.posts.size.should == 2
135
-
136
- # Subclass your subclass for further customization:
137
- user = KathyLee::User::Marge::Other.new
138
- user.username.should == 'bill.smith'
139
- user.email.should == 'bill.smith@example.org'
140
- user.home_page_url.should == 'http://www.simpsons.com'
141
- user.fullname.should == 'Marge Simpson'
142
- user.login_count.should == 1000
143
- user.new_record?.should be_true
144
- user.posts.size.should == 5
145
-
146
- ==Contact
147
-
148
- Please mail bugs, suggestions and patches to "development@metabates.com":mailto:development@metabates.com
149
-
150
- On the web at: "http://www.metabates.com":http://www.metabates.
1
+ =KathyLee - An easy to use factory framework for generating test data for objects.
@@ -0,0 +1,14 @@
1
+ require 'generators/kathy_lee'
2
+
3
+ class KathyLee
4
+ module Generators
5
+ class ModelGenerator < Base
6
+ argument :attributes, :type => :array, :default => [], :banner => "field:type field:type"
7
+ class_option :dir, :type => :string, :default => "spec/factories", :desc => "The directory where the factories should go"
8
+
9
+ def create_fixture_file
10
+ template 'fixtures.rb', File.join(options[:dir], "#{singular_name}_factories.rb")
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,11 @@
1
+ # Define attributes for <%= class_name %>:
2
+ KathyLee.attributes(:<%= singular_name %>) do
3
+ <% for attribute in attributes -%>
4
+ <%= attribute.name %> <%= attribute.default.inspect %>
5
+ <% end -%>
6
+ end
7
+
8
+ KathyLee.define(:<%= singular_name %>) do
9
+ <%= singular_name %> = <%= class_name %>.new(options)
10
+ <%= singular_name %>
11
+ end
@@ -0,0 +1,11 @@
1
+ require 'rails/generators/named_base'
2
+
3
+ class KathyLee
4
+ module Generators
5
+ class Base < Rails::Generators::NamedBase #:nodoc:
6
+ def self.source_root
7
+ @_kathy_lee_source_root ||= File.expand_path(File.join(File.dirname(__FILE__), 'kathy_lee', 'model', 'templates'))
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,31 @@
1
+ class KathyLee::Attributes::Binding
2
+
3
+ attr_accessor :results
4
+ attr_accessor :attributes
5
+ attr_accessor :code_block
6
+
7
+ def initialize(attributes = {}, &block)
8
+ self.results = {}
9
+ self.attributes = attributes
10
+ self.code_block = block
11
+ end
12
+
13
+ def process!
14
+ if self.code_block
15
+ instance_eval(&self.code_block)
16
+ end
17
+ self.results.merge!(self.attributes)
18
+ end
19
+
20
+ def fake(name)
21
+ KathyLee::Fakes.execute(name)
22
+ end
23
+
24
+ def method_missing(sym, args = nil, &block)
25
+ self.results[sym] = args unless args.nil?
26
+ if block_given?
27
+ self.results[sym] = block.call
28
+ end
29
+ end
30
+
31
+ end
@@ -0,0 +1,18 @@
1
+ class KathyLee::Attributes
2
+
3
+ attr_accessor :attributes
4
+ attr_accessor :code_block
5
+
6
+ def initialize(attributes = {}, &block)
7
+ self.attributes = attributes
8
+ self.code_block = block
9
+ end
10
+
11
+ def process(attribs = {})
12
+ b = KathyLee::Attributes::Binding.new(self.attributes.merge(attribs), &self.code_block)
13
+ b.process!
14
+ return b.results
15
+ end
16
+
17
+
18
+ end
@@ -0,0 +1,72 @@
1
+ # Used to evaluate a KathyLee::Definition in it's own 'space' (binding)
2
+ class KathyLee::Definition::Binding
3
+
4
+ attr_accessor :factory_name
5
+ attr_accessor :options
6
+ attr_accessor :code_block
7
+ attr_accessor :result
8
+ attr_accessor :has_ones
9
+ attr_accessor :has_manys
10
+ attr_accessor :parent
11
+
12
+ def initialize(factory_name, attributes = {}, &block)
13
+ self.factory_name = factory_name
14
+ attrib_name = attributes.delete(:attributes_for) || factory_name.to_sym
15
+ self.options = (KathyLee.attributes(attrib_name) || {}).merge(attributes)
16
+ self.code_block = block
17
+ self.has_ones = {}
18
+ self.has_manys = {}
19
+ end
20
+
21
+ def has_one(factory, options = {}, &block)
22
+ self.has_ones[factory.to_sym] = {:options => options, :code_block => block,
23
+ :klass => self.options.delete(factory.to_sym)}
24
+ end
25
+
26
+ def has_many(factory, options = {}, &block)
27
+ options = {:size => 2}.merge(options)
28
+ self.has_manys[factory.to_sym] = KathyLee::Definition::HasMany.new(factory.to_sym, {:options => options, :code_block => block, :klass => self.options.delete(factory.to_sym)})
29
+ end
30
+
31
+ def process!
32
+ self.result = instance_eval(&self.code_block)
33
+ handle_has_ones
34
+ handle_has_manys
35
+ end
36
+
37
+ protected
38
+ def handle_has_ones
39
+ self.has_ones.each do |factory, h|
40
+ if h[:klass]
41
+ self.result.send("#{factory}=", h[:klass])
42
+ else
43
+ if h[:code_block]
44
+ b = KathyLee::Definition::Binding.new(factory, h[:options], &h[:code_block])
45
+ # b.send(:eval, %{
46
+ # def #{self.factory_name}=(x)
47
+ # @__#{self.factory_name} = x
48
+ # end
49
+ # def #{self.factory_name}
50
+ # @__#{self.factory_name}
51
+ # end
52
+ # })
53
+ # b.send("#{self.factory_name}=", self.result)
54
+ b.parent = self.result
55
+ b.process!
56
+ self.result.send("#{factory}=", b.result)
57
+ else
58
+ self.result.send("#{factory}=", KathyLee.build(factory, h[:options]))
59
+ end
60
+ end
61
+ end
62
+ end
63
+
64
+ def handle_has_manys
65
+ self.has_manys.each do |factory, h|
66
+ h.build.each do |obj|
67
+ self.result.send("#{factory}") << obj
68
+ end
69
+ end
70
+ end
71
+
72
+ end
@@ -0,0 +1,27 @@
1
+ class KathyLee::Definition::HasMany < KathyLee::Definition::Relationship
2
+ attr_accessor :size
3
+
4
+ def initialize(factory, options = {})
5
+ super(factory, options)
6
+ self.size = (self.options.delete(:size) || 2)
7
+ end
8
+
9
+ def build
10
+ results = []
11
+ self.size.times do
12
+ if self.klass
13
+ results << self.klass
14
+ else
15
+ if self.code_block
16
+ b = KathyLee::Definition::Binding.new(self.factory, self.options, self.code_block)
17
+ b.process!
18
+ results << b.result
19
+ else
20
+ results << KathyLee.build(self.factory, self.options)
21
+ end
22
+ end
23
+ end
24
+ [results].flatten
25
+ end
26
+
27
+ end
@@ -0,0 +1,3 @@
1
+ class KathyLee::Definition::HasOne < KathyLee::Definition::Relationship
2
+
3
+ end
@@ -0,0 +1,14 @@
1
+ class KathyLee::Definition::Relationship
2
+ attr_accessor :options
3
+ attr_accessor :code_block
4
+ attr_accessor :klass
5
+ attr_accessor :factory
6
+
7
+ def initialize(factory, options = {})
8
+ self.factory = factory
9
+ self.options = options
10
+ self.klass = self.options.delete(:klass)
11
+ self.code_block = self.options.delete(:code_block)
12
+ end
13
+
14
+ end
@@ -0,0 +1,38 @@
1
+ # Houses the definition of a factory.
2
+ #
3
+ # Examples:
4
+ # KathyLee.define(:user) do
5
+ # user = User.new(options)
6
+ # ... # do some more work
7
+ # user
8
+ # end
9
+ #
10
+ # KathyLee.define(:user) do
11
+ # has_one :blog # will call the :blog factory and assign it to the
12
+ # # user object when it's returned from the block.
13
+ #
14
+ # user = User.new(options)
15
+ # ... # do some more work
16
+ # user
17
+ # end
18
+ class KathyLee::Definition
19
+
20
+ attr_accessor :factory_name
21
+ attr_accessor :attributes
22
+ attr_accessor :code_block
23
+
24
+ def initialize(factory_name, attributes = {}, &block)
25
+ self.attributes = attributes
26
+ self.factory_name = factory_name
27
+ self.code_block = block
28
+ end
29
+
30
+ # Execute the code block in it's own building, with it's own attributes
31
+ # and return the result.
32
+ def build(attribs = {})
33
+ b = KathyLee::Definition::Binding.new(self.factory_name, self.attributes.merge(attribs), &self.code_block)
34
+ b.process!
35
+ return b.result
36
+ end
37
+
38
+ end
@@ -1,25 +1,41 @@
1
- module KathyLee
1
+ class KathyLee
2
+ # A registry for procs that can be called to generate random, or fake, data.
2
3
  class Fakes
3
4
  include Singleton
4
-
5
+
6
+ # List of all the fake procs in the system.
5
7
  attr_accessor :list
6
-
7
- def initialize
8
+
9
+ def initialize # :nodoc:
8
10
  self.reset!
9
11
  end
10
-
11
- def reset!
12
+
13
+ def reset! # :nodoc:
12
14
  self.list = {}
13
15
  end
14
-
16
+
17
+ # Add a new proc to the system.
18
+ #
19
+ # Example:
20
+ # KathyLee::Fakes.add(:birth_date) {(rand(80) + 13).years.ago}
15
21
  def add(name, &block)
16
22
  self.list[name.to_sym] = block
17
23
  end
18
24
 
25
+ # Create an alias from one fake proc to another.
26
+ #
27
+ # Example:
28
+ # KathyLee::Fakes.add(:birth_date) {(rand(80) + 13).years.ago}
29
+ # KathyLee::Fakes.alias(:birthday, :birth_date)
19
30
  def alias(from, to)
20
31
  self.list[from.to_sym] = KathyLee::Fakes::Alias.new(to)
21
32
  end
22
-
33
+
34
+ # Executes the specified fake proc. Raise KathyLee::Errors::NoFakeRegistered
35
+ # if the fake proc is not registered with the system.
36
+ #
37
+ # Example:
38
+ # KathyLee::Fakes.execute(:email) # => 'bob@example.com'
23
39
  def execute(name, *args)
24
40
  block = self.list[name.to_sym]
25
41
  if block.is_a?(KathyLee::Fakes::Alias)
@@ -28,17 +44,17 @@ module KathyLee
28
44
  if block
29
45
  return block.call(*args)
30
46
  end
31
- raise KathyLee::Errors::NoFakeRegistered.new(name)
47
+ raise "No fake has been registered for '#{name}'!"
32
48
  end
33
-
49
+
34
50
  class << self
35
- def method_missing(sym, *args, &block)
51
+ def method_missing(sym, *args, &block) # :nodoc:
36
52
  KathyLee::Fakes.instance.send(sym, *args, &block)
37
53
  end
38
54
  end # class << self
39
-
55
+
40
56
  private
41
- class Alias
57
+ class Alias # :nodoc:
42
58
  attr_accessor :to
43
59
  def initialize(to)
44
60
  self.to = to
@@ -48,34 +64,80 @@ module KathyLee
48
64
  end # Fakes
49
65
  end # KathyLee
50
66
 
51
- %w{first_name last_name name prefix suffix}.each do |m|
52
- eval("KathyLee::Fakes.add(:#{m}) {|*args| Faker::Name.#{m}(*args)}")
67
+ %w{zip_code us_state us_state_short city street_name street_address neighborhood}.each do |m|
68
+ eval("KathyLee::Fakes.add(:#{m}) {|*args| Dummy::Address.#{m}}")
53
69
  end
54
70
 
55
- %w{city city_prefix city_suffix secondary_address street_address street_name
56
- street_suffix uk_country uk_county uk_postcode us_state us_state_abbr zip_code}.each do |m|
57
- eval("KathyLee::Fakes.add(:#{m}) {|*args| Faker::Address.#{m}(*args)}")
71
+ %w{name catch_phrase bs}.each do |m|
72
+ eval("KathyLee::Fakes.add(:#{m}) {|*args| Dummy::Company.#{m}}")
58
73
  end
59
74
 
60
- %w{bs catch_phrase name suffix}.each do |m|
61
- eval("KathyLee::Fakes.add(:#{m}) {|*args| Faker::Company.#{m}(*args)}")
75
+ KathyLee::Fakes.add(:company_name) {|*args| Dummy::Company.name}
76
+
77
+ %w{lat lng}.each do |m|
78
+ eval("KathyLee::Fakes.add(:#{m}) {|*args| Dummy::Geolocation.#{m}}")
62
79
  end
63
80
 
64
- %w{domain_name domain_suffix domain_word email free_email user_name}.each do |m|
65
- eval("KathyLee::Fakes.add(:#{m}) {|*args| Faker::Internet.#{m}(*args)}")
81
+ %w{email username password url}.each do |m|
82
+ eval("KathyLee::Fakes.add(:#{m}) {|*args| Dummy::Internet.#{m}}")
66
83
  end
67
84
 
68
- %w{paragraph paragraphs sentence sentences words}.each do |m|
69
- eval("KathyLee::Fakes.add(:#{m}) {|*args| Faker::Lorem.#{m}(*args)}")
85
+ KathyLee::Fakes.alias(:login, :username)
86
+
87
+ %w{sentence sentences paragraph paragraphs}.each do |m|
88
+ eval("KathyLee::Fakes.add(:#{m}) {|*args| Dummy::Lorem.#{m}}")
70
89
  end
71
90
 
72
- %w{phone_number}.each do |m|
73
- eval("KathyLee::Fakes.add(:#{m}) {|*args| Faker::PhoneNumber.#{m}(*args)}")
91
+ KathyLee::Fakes.add(:lorem) do |*args|
92
+ lorem = []
93
+ 3.times {lorem << Dummy::Lorem.paragraph}
94
+ lorem.join("\n")
74
95
  end
75
96
 
76
- KathyLee::Fakes.add(:url) {|*args| 'http://' + Faker::Internet.domain_name(*args)}
77
- KathyLee::Fakes.add(:lorem) {|*args| Faker::Lorem.paragraphs(*args).join("\n")}
78
- KathyLee::Fakes.add(:name) {|*args| Faker::Name.first_name + ' ' + Faker::Name.last_name}
79
97
  KathyLee::Fakes.alias(:body, :lorem)
98
+
99
+ %w{name first_name last_name}.each do |m|
100
+ eval("KathyLee::Fakes.add(:#{m}) {|*args| Dummy::Name.#{m}}")
101
+ end
102
+
80
103
  KathyLee::Fakes.alias(:full_name, :name)
81
- KathyLee::Fakes.alias(:title, :sentence)
104
+
105
+ %w{phone_number phone_number_short}.each do |m|
106
+ eval("KathyLee::Fakes.add(:#{m}) {|*args| Dummy::PhoneNumber.#{m}}")
107
+ end
108
+
109
+ # %w{first_name last_name name prefix suffix}.each do |m|
110
+ # eval("KathyLee::Fakes.add(:#{m}) {|*args| Faker::Name.#{m}(*args)}")
111
+ # end
112
+ #
113
+ # %w{city city_prefix city_suffix secondary_address street_address street_name
114
+ # street_suffix uk_country uk_county uk_postcode us_state us_state_abbr zip_code}.each do |m|
115
+ # eval("KathyLee::Fakes.add(:#{m}) {|*args| Faker::Address.#{m}(*args)}")
116
+ # end
117
+ #
118
+ # %w{bs catch_phrase name suffix}.each do |m|
119
+ # eval("KathyLee::Fakes.add(:#{m}) {|*args| Faker::Company.#{m}(*args)}")
120
+ # end
121
+ #
122
+ # %w{domain_name domain_suffix domain_word email free_email user_name}.each do |m|
123
+ # eval("KathyLee::Fakes.add(:#{m}) {|*args| Faker::Internet.#{m}(*args)}")
124
+ # end
125
+ #
126
+ # %w{paragraph paragraphs sentence sentences words}.each do |m|
127
+ # eval("KathyLee::Fakes.add(:#{m}) {|*args| Faker::Lorem.#{m}(*args)}")
128
+ # end
129
+ #
130
+ # %w{phone_number}.each do |m|
131
+ # eval("KathyLee::Fakes.add(:#{m}) {|*args| Faker::PhoneNumber.#{m}(*args)}")
132
+ # end
133
+ #
134
+ # KathyLee::Fakes.add(:url) {|*args| 'http://' + Faker::Internet.domain_name(*args)}
135
+ # KathyLee::Fakes.add(:lorem) {|*args| Faker::Lorem.paragraphs(*args).join("\n")}
136
+ # KathyLee::Fakes.add(:name) {|*args| Faker::Name.first_name + ' ' + Faker::Name.last_name}
137
+ # KathyLee::Fakes.add(:birth_date) {|*args| (rand(80) + 13).years.ago}
138
+ # KathyLee::Fakes.add(:title) {|*args| Faker::Company.catch_phrase.slice(0..250)}
139
+ # KathyLee::Fakes.add(:username) {|*args| Faker::Internet.user_name}
140
+ # KathyLee::Fakes.add(:company_name) {|*args| Faker::Company.name}
141
+ # KathyLee::Fakes.alias(:login, :username)
142
+ # KathyLee::Fakes.alias(:body, :lorem)
143
+ # KathyLee::Fakes.alias(:full_name, :name)
@@ -1,15 +1,68 @@
1
- module KathyLee
1
+ # Put your gem code here:
2
+
3
+ class KathyLee
4
+ include Singleton
5
+
6
+ attr_accessor :factories
7
+ attr_accessor :factory_attributes
8
+
9
+ def initialize
10
+ self.factories = {}
11
+ self.factory_attributes = {}
12
+ end
13
+
14
+ def build(factory_name, attributes = {})
15
+ if self.factories[factory_name.to_sym]
16
+ return self.factories[factory_name.to_sym].build(attributes)
17
+ else
18
+ self.define(factory_name, attributes) do
19
+ object = factory_name.to_s.classify.constantize.new(options)
20
+ object
21
+ end
22
+ self.build(factory_name, attributes)
23
+ end
24
+ end
25
+
26
+ def create(factory_name, attributes = {})
27
+ object = self.build(factory_name, attributes)
28
+ object.save!
29
+ return object
30
+ end
31
+
32
+ def attributes(factory_name, attributes = {}, &block)
33
+ if block_given?
34
+ self.factory_attributes[factory_name] = KathyLee::Attributes.new(attributes, &block)
35
+ end
36
+ if self.factory_attributes.has_key?(factory_name)
37
+ return self.factory_attributes[factory_name].process(attributes)
38
+ end
39
+ return nil
40
+ end
41
+
42
+ def define(factory_name, attributes = {}, &block)
43
+ self.factories[factory_name.to_sym] = KathyLee::Definition.new(factory_name, attributes, &block)
44
+ end
45
+
46
+ def sweatshop(factory_name, *options, count)
47
+ results = []
48
+ count.times do
49
+ results << self.build(factory_name, (options.first || {}))
50
+ end
51
+ return results
52
+ end
53
+
54
+ def sweatshop!(factory_name, *options, count)
55
+ results = self.sweatshop(factory_name, *options, count)
56
+ results.each {|x| x.save!}
57
+ return results
58
+ end
2
59
 
3
60
  class << self
4
61
 
5
- def const_missing(klass, for_klass = klass)
6
- @klass = klass
7
- @for_klass = for_klass
8
- result = ERB.new(File.read(File.join(File.dirname(__FILE__), 'templates', 'proxy.html.erb'))).result(binding)
9
- eval(result)
10
- return "KathyLee::#{klass}".constantize
62
+ def method_missing(sym, *args, &block)
63
+ KathyLee.instance.send(sym, *args, &block)
11
64
  end
12
65
 
13
- end # class << self
66
+ end
14
67
 
15
- end
68
+ end
data/lib/kathy_lee.rb CHANGED
@@ -1,16 +1,20 @@
1
1
  require 'singleton'
2
- require 'faker'
3
- require 'benchmark'
4
- require 'erb'
2
+ require 'active_support'
3
+ require 'dummy'
5
4
 
6
- class Symbol
7
-
8
- def classify
9
- self.to_s.classify
5
+ # A monkey patch for dummy:
6
+ class Array
7
+ def rand
8
+ self[Kernel.rand(self.length)]
10
9
  end
11
-
12
10
  end
13
11
 
14
- Dir.glob(File.join(File.dirname(__FILE__), 'kathy_lee', '**/*.rb')).each do |f|
15
- require File.expand_path(f)
12
+
13
+ path = File.join(File.dirname(__FILE__), 'kathy_lee')
14
+
15
+ %w{kathy_lee definition definition/binding definition/relationship
16
+ definition/has_one definition/has_many attributes attributes/binding fakes}.each do |file|
17
+ require File.expand_path(File.join(path, file))
16
18
  end
19
+
20
+ # require File.join(File.dirname(__FILE__), 'generators', 'kathy_lee')
metadata CHANGED
@@ -1,7 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kathy_lee
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 2
8
+ - 0
9
+ version: 0.2.0
5
10
  platform: ruby
6
11
  authors:
7
12
  - markbates
@@ -9,21 +14,37 @@ autorequire:
9
14
  bindir: bin
10
15
  cert_chain: []
11
16
 
12
- date: 2010-01-04 00:00:00 -05:00
17
+ date: 2010-08-25 00:00:00 -04:00
13
18
  default_executable:
14
19
  dependencies:
15
20
  - !ruby/object:Gem::Dependency
16
- name: faker
21
+ name: activesupport
22
+ requirement: &id001 !ruby/object:Gem::Requirement
23
+ none: false
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ version: "0"
17
30
  type: :runtime
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
31
+ prerelease: false
32
+ version_requirements: *id001
33
+ - !ruby/object:Gem::Dependency
34
+ name: dummy
35
+ requirement: &id002 !ruby/object:Gem::Requirement
36
+ none: false
20
37
  requirements:
21
38
  - - ">="
22
39
  - !ruby/object:Gem::Version
23
- version: 0.3.1
24
- version:
40
+ segments:
41
+ - 0
42
+ version: "0"
43
+ type: :runtime
44
+ prerelease: false
45
+ version_requirements: *id002
25
46
  description: "kathy_lee was developed by: markbates"
26
- email: ""
47
+ email: mark+kathylee@markbates.com
27
48
  executables: []
28
49
 
29
50
  extensions: []
@@ -32,18 +53,23 @@ extra_rdoc_files:
32
53
  - README
33
54
  - LICENSE
34
55
  files:
35
- - lib/kathy_lee/errors/no_fake_registered.rb
56
+ - lib/generators/kathy_lee/model/model_generator.rb
57
+ - lib/generators/kathy_lee/model/templates/fixtures.rb
58
+ - lib/generators/kathy_lee.rb
59
+ - lib/kathy_lee/attributes/binding.rb
60
+ - lib/kathy_lee/attributes.rb
61
+ - lib/kathy_lee/definition/binding.rb
62
+ - lib/kathy_lee/definition/has_many.rb
63
+ - lib/kathy_lee/definition/has_one.rb
64
+ - lib/kathy_lee/definition/relationship.rb
65
+ - lib/kathy_lee/definition.rb
36
66
  - lib/kathy_lee/fakes.rb
37
67
  - lib/kathy_lee/kathy_lee.rb
38
- - lib/kathy_lee/proxy.rb
39
- - lib/kathy_lee/proxy_manager.rb
40
- - lib/kathy_lee/templates/proxy.html.erb
41
- - lib/kathy_lee/transaction.rb
42
68
  - lib/kathy_lee.rb
43
69
  - README
44
70
  - LICENSE
45
71
  has_rdoc: true
46
- homepage: ""
72
+ homepage: http://www.metabates.com
47
73
  licenses: []
48
74
 
49
75
  post_install_message:
@@ -52,21 +78,26 @@ rdoc_options: []
52
78
  require_paths:
53
79
  - lib
54
80
  required_ruby_version: !ruby/object:Gem::Requirement
81
+ none: false
55
82
  requirements:
56
83
  - - ">="
57
84
  - !ruby/object:Gem::Version
85
+ hash: -2942405895079934725
86
+ segments:
87
+ - 0
58
88
  version: "0"
59
- version:
60
89
  required_rubygems_version: !ruby/object:Gem::Requirement
90
+ none: false
61
91
  requirements:
62
92
  - - ">="
63
93
  - !ruby/object:Gem::Version
94
+ segments:
95
+ - 0
64
96
  version: "0"
65
- version:
66
97
  requirements: []
67
98
 
68
99
  rubyforge_project: magrathea
69
- rubygems_version: 1.3.5
100
+ rubygems_version: 1.3.7
70
101
  signing_key:
71
102
  specification_version: 3
72
103
  summary: kathy_lee
@@ -1,11 +0,0 @@
1
- module KathyLee
2
- module Errors
3
- class NoFakeRegistered < StandardError
4
-
5
- def initialize(name)
6
- super("No fake has been registered for '#{name}'!")
7
- end
8
-
9
- end # NoFakeRegistered
10
- end # Errors
11
- end # KathyLee
@@ -1,113 +0,0 @@
1
- module KathyLee
2
- class Proxy
3
- attr_accessor :for
4
- attr_accessor :attributes
5
- attr_accessor :belongs_tos
6
- attr_accessor :has_manys
7
-
8
- class << self
9
-
10
- def define(options = {}, &block)
11
- KathyLee::ProxyManager.set_attributes(self, options, &block)
12
- end
13
-
14
- def create(options = {})
15
- model = self.new(options)
16
- model.save!
17
- return model
18
- end
19
-
20
- def new(options = {})
21
- proxy = super(options)
22
- KathyLee::Transaction.execute do
23
- proxy.build_new
24
- end
25
- end
26
-
27
- def sweatshop(count, options = {}, &block)
28
- models = []
29
- count.times do |i|
30
- model = self.new(options)
31
- yield model, i if block_given?
32
- models << model
33
- end
34
- return models
35
- end
36
-
37
- def sweatshop!(count, &block)
38
- nmodels = []
39
- models = self.sweatshop(count, &block)
40
- models.each do |m|
41
- m.save!
42
- nmodels << m
43
- end
44
- return models
45
- end
46
-
47
- end # class << self
48
-
49
- def initialize(options = {})
50
- self.for = self.class.for
51
- self.belongs_tos = {}
52
- self.has_manys = {}
53
-
54
- opts = KathyLee::ProxyManager.get_attributes(self.class)
55
- self.attributes = opts[:attributes]
56
- instance_eval(&opts[:definition_block]) if opts[:definition_block]
57
- self.attributes.merge!(options) if options.is_a?(Hash)
58
- end
59
-
60
- def build_new
61
- model = self.for.send(:new, self.attributes)
62
- KathyLee::Transaction.register(model)
63
- model = build_has_manys(model)
64
- model = build_belongs_to(model)
65
- return model
66
- end
67
-
68
- def method_missing(sym, *args)
69
- self.attributes[sym] = *args
70
- end
71
-
72
- def belongs_to(owner, options = {})
73
- self.belongs_tos[owner.to_sym] = options
74
- end
75
-
76
- def has_many(things, options = {})
77
- self.has_manys[things.to_sym] = options
78
- end
79
-
80
- def fake(sym, *args)
81
- KathyLee::Fakes.execute(sym, *args)
82
- end
83
-
84
- protected
85
- def build_has_manys(model)
86
- hm = self.has_manys.dup
87
- hm.each do |things, opts|
88
- options = opts.dup
89
- size = options.delete(:size) || 2
90
- thing_klass = "::KathyLee::#{things.classify}".constantize
91
- model.send("#{things}=", []) # clear out any parents versions of this
92
- model.send(things) << thing_klass.sweatshop(size)
93
- end
94
-
95
- return model
96
- end
97
-
98
- def build_belongs_to(model)
99
- bt = self.belongs_tos.dup
100
-
101
- bt.each do |owner, opts|
102
- thing_klass = "::KathyLee::#{owner.classify}".constantize
103
- thing = KathyLee::Transaction.get_model(thing_klass.for) do
104
- thing_klass.new(opts)
105
- end
106
- model.send("#{owner}=", thing)
107
- end
108
-
109
- return model
110
- end
111
-
112
- end # Proxy
113
- end # KathyLee
@@ -1,34 +0,0 @@
1
- module KathyLee
2
- class ProxyManager
3
- include Singleton
4
-
5
- attr_accessor :proxies
6
-
7
- def initialize
8
- self.reset!
9
- end
10
-
11
- def reset!
12
- self.proxies = {}
13
- end
14
-
15
- def get_attributes(klass)
16
- proxy = self.proxies[klass]
17
- return proxy if proxy
18
- return {:attributes => {}}
19
- end
20
-
21
- def set_attributes(klass, attributes = {}, &block)
22
- options = {:attributes => attributes}
23
- options[:definition_block] = block if block_given?
24
- self.proxies[klass] = options
25
- end
26
-
27
- class << self
28
- def method_missing(sym, *args, &block)
29
- KathyLee::ProxyManager.instance.send(sym, *args, &block)
30
- end
31
- end # class << self
32
-
33
- end # ProxyManager
34
- end # KathyLee
@@ -1,15 +0,0 @@
1
- class KathyLee::<%= @klass %> < KathyLee::Proxy
2
-
3
- class << self
4
-
5
- def for
6
- ::<%= @for_klass %>
7
- end
8
-
9
- def const_missing(klass, for_klass = <%= @klass %>)
10
- KathyLee.const_missing(klass, for_klass)
11
- end
12
-
13
- end
14
-
15
- end
@@ -1,51 +0,0 @@
1
- module KathyLee
2
- class Transaction
3
- include Singleton
4
-
5
- attr_accessor :started
6
- attr_accessor :models
7
- attr_accessor :transaction_id
8
-
9
- class << self
10
- def method_missing(sym, *args, &block)
11
- KathyLee::Transaction.instance.send(sym, *args, &block)
12
- end
13
- end
14
-
15
- def initialize
16
- self.reset!
17
- end
18
-
19
- def reset!
20
- self.started = false
21
- self.models = {}
22
- end
23
-
24
- def register(model)
25
- self.models[model.class.name.to_sym] = model
26
- end
27
-
28
- def get_model(klass, &block)
29
- model = self.models[klass.name.to_sym]
30
- if block_given? && model.nil?
31
- model = yield
32
- self.register(model)
33
- end
34
- return model
35
- end
36
-
37
- def execute(&block)
38
- unless self.started
39
- self.transaction_id = rand.to_s.gsub('0.', '')
40
- self.started = true
41
- results = yield if block_given?
42
- self.reset!
43
- return results
44
- else
45
- results = yield if block_given?
46
- return results
47
- end
48
- end
49
-
50
- end # Transaction
51
- end # KathyLee