mack-data_factory 0.7.1 → 0.7.1.1

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.
Files changed (38) hide show
  1. data/lib/mack-data_factory/content_generator.rb +1 -1
  2. data/lib/mack-data_factory/core_extensions/kernel.rb +13 -17
  3. data/lib/mack-data_factory/data_factory.rb +128 -19
  4. data/lib/mack-data_factory/field.rb +1 -1
  5. data/lib/mack-data_factory/field_manager.rb +1 -1
  6. data/lib/mack-data_factory/orm_api_bridge/bridge.rb +69 -1
  7. data/lib/mack-data_factory/orm_api_bridge/orm/active_record.rb +2 -2
  8. data/lib/mack-data_factory/orm_api_bridge/orm/data_mapper.rb +2 -2
  9. data/lib/mack-data_factory/orm_api_bridge/orm/default.rb +1 -1
  10. metadata +2 -30
  11. data/doc/classes/Kernel.html +0 -207
  12. data/doc/classes/Mack.html +0 -137
  13. data/doc/classes/Mack/Data/Bridge.html +0 -269
  14. data/doc/classes/Mack/Data/Factory.html +0 -171
  15. data/doc/classes/Mack/Data/Factory/ClassMethods.html +0 -290
  16. data/doc/classes/Mack/Data/Factory/FieldContentGenerator.html +0 -685
  17. data/doc/classes/Mack/Data/Field.html +0 -271
  18. data/doc/classes/Mack/Data/FieldMgr.html +0 -217
  19. data/doc/classes/Mack/Data/OrmBridge/ActiveRecord.html +0 -267
  20. data/doc/classes/Mack/Data/OrmBridge/DataMapper.html +0 -267
  21. data/doc/classes/Mack/Data/OrmBridge/Default.html +0 -266
  22. data/doc/created.rid +0 -1
  23. data/doc/files/README.html +0 -107
  24. data/doc/files/lib/mack-data_factory/content_generator_rb.html +0 -108
  25. data/doc/files/lib/mack-data_factory/core_extensions/kernel_rb.html +0 -101
  26. data/doc/files/lib/mack-data_factory/data_factory_rb.html +0 -101
  27. data/doc/files/lib/mack-data_factory/field_manager_rb.html +0 -101
  28. data/doc/files/lib/mack-data_factory/field_rb.html +0 -101
  29. data/doc/files/lib/mack-data_factory/orm_api_bridge/bridge_rb.html +0 -101
  30. data/doc/files/lib/mack-data_factory/orm_api_bridge/orm/active_record_rb.html +0 -101
  31. data/doc/files/lib/mack-data_factory/orm_api_bridge/orm/data_mapper_rb.html +0 -101
  32. data/doc/files/lib/mack-data_factory/orm_api_bridge/orm/default_rb.html +0 -101
  33. data/doc/files/lib/mack-data_factory_rb.html +0 -108
  34. data/doc/fr_class_index.html +0 -37
  35. data/doc/fr_file_index.html +0 -37
  36. data/doc/fr_method_index.html +0 -79
  37. data/doc/index.html +0 -24
  38. data/doc/rdoc-style.css +0 -208
@@ -4,7 +4,7 @@ module Mack
4
4
  module Data
5
5
  module Factory
6
6
 
7
- class FieldContentGenerator
7
+ class FieldContentGenerator # :nodoc:
8
8
  class << self
9
9
  def alpha_generator
10
10
  @alpha_gen = Proc.new do |def_value, rules, index|
@@ -11,19 +11,19 @@ module Kernel
11
11
  # Convenient routine to create an execution chain of factories
12
12
  #
13
13
  # Example:
14
- # factories(:foo) do
15
- # UserFactory.create(1)
16
- # UserFactory.create(2, :diff_firstname)
17
- # end
14
+ # factories(:foo) do
15
+ # UserFactory.create(1)
16
+ # UserFactory.create(2, :diff_firstname)
17
+ # end
18
18
  #
19
19
  # Then to execute the chains, you'll need to call run_factories, and
20
20
  # pass in the name of the chain you want to execute.
21
21
  #
22
- # Example:
23
- # run_factories(:foo)
22
+ # run_factories(:foo)
24
23
  #
25
- # @tag -- the name of the factory chain
26
- # @block -- the proc to be executed later
24
+ # <i>Parameters:</i>
25
+ # tag: the name of the factory chain
26
+ # block: the proc to be executed later
27
27
  #
28
28
  def factories(tag, &block)
29
29
  raise "factories: block needed" if !block_given?
@@ -31,19 +31,15 @@ module Kernel
31
31
  end
32
32
 
33
33
  #
34
- # Run defined factory chain
34
+ # Run defined factory chain defined using factories method.
35
+ #
36
+ # <i>Parameters:</i>
37
+ # tag: the name of the factory chain to be run
35
38
  #
36
- # @see factories
37
- # @tag -- the name of the factory chain to be run
38
- # @return true if successful, false otherwise
39
39
  def run_factories(tag)
40
40
  runners = fact_registry.registered_items[tag]
41
41
  return false if runners == nil
42
-
43
- runners.each do |r|
44
- r.call
45
- end
46
-
42
+ runners.each { |r| r.call }
47
43
  return true
48
44
  end
49
45
 
@@ -1,4 +1,4 @@
1
- module Mack
1
+ module Mack # :nodoc:
2
2
  module Data # :nodoc:
3
3
  #
4
4
  # Add factory capability to a class.
@@ -7,15 +7,26 @@ module Mack
7
7
  # define a scope for different situation, and set a custom content generator
8
8
  # for field that doesn't want to use the default content generator.
9
9
  #
10
- # For more information and usage, please read README file
10
+ # You must add this module when creating a factory class; and the name
11
+ # of the factory class should be following this format:
12
+ # #{model_name_camelcase}Factory
13
+ #
14
+ # <i>Example:</i>
15
+ # If there's a model class named "Item", then its factory must be:
16
+ #
17
+ # class ItemFactory
18
+ # include Mack::Data::Factory
19
+ # ...
20
+ # end
21
+ #
22
+ # See Mack::Data::Factory::ClassMethods for the factory API and examples.
11
23
  #
12
- # author: Darsono Sutedja
13
- # July 2008
24
+ # Author:: Darsono Sutedja
25
+ # Date:: July 2008
14
26
  #
15
27
  module Factory
16
28
 
17
- # make sure the data factory API is available to the class that includes it
18
- def self.included(base)
29
+ def self.included(base) # :nodoc:
19
30
  base.extend ClassMethods
20
31
  end
21
32
 
@@ -24,17 +35,42 @@ module Mack
24
35
  #
25
36
  # Run the factory to produce n number of objects.
26
37
  #
27
- # Example:
28
- # class CarFactory
29
- # include Mack::Data::Factory
30
- # field :name, :default => "honda" { |def_value, rules, index| "#{def_value} #{['civic', 'accord', 'pilot'].randomize[0]}"}
31
- # end
38
+ # <i>Example:</i>
39
+ #
40
+ # class CarFactory
41
+ # include Mack::Data::Factory
42
+ # field(:name, :default => "honda") do |def_value, rules, index|
43
+ # "#{def_value} #{['civic', 'accord', 'pilot'].randomize[0]}"
44
+ # end
45
+ # end
46
+ #
47
+ # CarFactory.create(100) #=> will produce 100 cars whose name is "honda xxx" where xxx is a random item from ['civic', 'accord', 'pilot']
48
+ #
49
+ # <i>Scoping:</i>
32
50
  #
33
- # CarFactory.create(100) #=> will produce 100 cars whose name is "honda xxx" where xxx is a random item from ['civic', 'accord', 'pilot']
51
+ # In some instances, you may want different settings in the factory for different test scope.
52
+ # You can achieve this by doing the following:
53
+ #
54
+ # class UserFactory
55
+ # include Mack::Data::Factory
56
+ #
57
+ # field :username, :default => "planters", :length => 25, :content => :alpha
58
+ # field :password, :default => "roastedPeanuts", :immutable => true
59
+ #
60
+ # scope_for(:long_username) do
61
+ # field :username, :default => "planters", :length => 128, :content => :alpha
62
+ # end
63
+ # end
64
+ #
65
+ # The above example defined a scoping for "long_username", which you can use by calling:
66
+ # UserFactory.create(100, :long_username)
67
+ #
68
+ # When a scope is defined and called, the field defined in the block will overwrite the default field listing
69
+ # in that class. Scopes in the factory is independent to each other, so one scope cannot affect the others.
34
70
  #
35
- # params:
36
- # * num - how many objects to produce
37
- # * scope - run the factory in a named scope
71
+ # <i>Parameters:</i>
72
+ # num: how many objects to produce
73
+ # scope: run the factory in a named scope. By default the factory will be run in _default_ scope
38
74
  #
39
75
  def create(num, scope = :default)
40
76
  factory_name = self.name.underscore
@@ -75,15 +111,85 @@ module Mack
75
111
  end
76
112
 
77
113
  #
78
- # Define a field with its default value and rules and an optional content generator
79
- # for this factory
114
+ # Define a field for the factory class, and set the name of the field,
115
+ # any options for the field, and optionally specify a block that serves as the custom
116
+ # content generator.
117
+ #
118
+ # The options can be categorized into the following:
119
+ # * default value (e.g. :default_value => "foo")
120
+ # * whether it's immutable or not (e.g. :immutable => true, and by default it's false)
121
+ # * the field's content type (e.g. :content => :alpha)
122
+ # * and the rules on how to generate the content (rules are contextually dependent on the content type).
123
+ #
124
+ # <i>Example:</i>
125
+ # class UserFactory
126
+ # include Mack::Data::Factory
127
+ # field :full_name, :content => :name
128
+ # field :created_at, :content => :time, :start_time => 2.days.ago, :end_time => 1.day.from_now
129
+ # end
130
+ #
131
+ # The following are all the supported content types and its rules:
132
+ #
133
+ # <i>Strings and Numbers</i>
134
+ # * :alpha --> alphabets. rules: [:length, :min_length, :max_length]
135
+ # * :alphanumeric --> alphabets and number. rules: same as :alpha
136
+ # * :numeric --> numbers [optional, because if the field's default value is number, its content type will automatically set to numeric)
137
+ # <i>Time and Money</i>
138
+ # * :time --> generate random time object. rules: [:start_time, :end_time]. It will generate random time between the given start and end time if available, otherwise it'll generate random time between 'now' and 1 day from 'now'
139
+ # * :money --> generate random amount of money. rules: [:min, :max]. It will generate random money amount (of BigDecimal type) between the given min and max amount.
140
+ # <i>Internet related content</i>
141
+ # * :email --> generate random email address
142
+ # * :username --> generate random username
143
+ # * :domain --> generate random domain name
144
+ # <i>Name related info</i>
145
+ # * :firstname --> generate first name
146
+ # * :lastname --> generate last name
147
+ # * :name --> generate full name
148
+ # <i>Address related info</i>
149
+ # * :city --> generate city name
150
+ # * :streetname --> generate street name
151
+ # * :state --> generate state. rules: [:country --> :us or :uk, :abbr --> true if you want a abbreviated state name (us only)]
152
+ # * :zipcode --> generate zipcode. rules: [:country --> :us or :uk]
153
+ # * :phone --> generate phone number
154
+ # <i>Company info</i>
155
+ # * :company --> generate company name. rules: [:include_bs --> include sales tag line]
156
+ # example: field, :content => :company, :include_bs => true
157
+ # could generate something like:
158
+ # Fadel-Larkin
159
+ # monetize cross-media experiences
160
+ #
161
+ # <i>Parameters:</i>
162
+ # model_attrib_sym: the name of the field
163
+ # options: the options for the field.
164
+ # block: the optional custom content generator
80
165
  #
81
166
  def field(model_attrib_sym, options = {}, &block)
82
167
  field_manager.add(scope, model_attrib_sym, options, &block)
83
168
  end
84
169
 
85
170
  #
86
- # Define an association rule for this field
171
+ # Define an association rule for this field.
172
+ #
173
+ # <i>Example:</i>
174
+ # class ItemFactory
175
+ # include Mack::Data::Factory
176
+ # ...
177
+ # association :owner_id, {:user => 'id'}, :random
178
+ # end
179
+ #
180
+ # The above example states that for each item generated, its owner_id will
181
+ # come from user's id field. But which user? since the association rule
182
+ # is set to random, then the generator will pick random user.
183
+ #
184
+ # <i>Supported association rules: </i>
185
+ # :first:: If there are 10 users, then the item will get associated with user #0.
186
+ # :last:: If there are 10 users, then the item will get associated with user #10.
187
+ # :random:: If there are 10 users, then the item will get associated with user #rand(10)
188
+ # :spread:: If there are 3 users, then the items' association will be spread out (i.e. 6 items will have id, sequentially, [0, 1, 2, 0, 1, 2])
189
+ #
190
+ # <i>Parameters:</i>
191
+ # model_attrib_sym: the name of the field
192
+ # assoc_map: the association map
87
193
  #
88
194
  def association(model_attrib_sym, assoc_map, assoc_rule = :spread)
89
195
  field(model_attrib_sym, {:default => {:df_assoc_map => assoc_map}, :assoc => assoc_rule})
@@ -91,8 +197,11 @@ module Mack
91
197
 
92
198
  #
93
199
  # Define a scope in the factory.
94
- # Any field defined in a scope will overwrite its cousin in the default scope.
200
+ # Any field defined in a scope will overwrite its sibling in the default scope.
95
201
  #
202
+ # <i>Parameters:</i>
203
+ # tag: name of the scope
204
+ #
96
205
  def scope_for(tag)
97
206
  set_scope(tag)
98
207
  yield
@@ -4,7 +4,7 @@ module Mack
4
4
  class RegistryMap < Mack::Utils::RegistryMap # :nodoc:
5
5
  end
6
6
 
7
- class Field
7
+ class Field # :nodoc:
8
8
  attr_accessor :field_name
9
9
  attr_accessor :field_value
10
10
  attr_accessor :field_value_producer
@@ -1,6 +1,6 @@
1
1
  module Mack
2
2
  module Data
3
- class FieldMgr
3
+ class FieldMgr # :nodoc:
4
4
  attr_reader :scopes
5
5
 
6
6
  def initialize
@@ -1,9 +1,41 @@
1
1
  module Mack
2
2
  module Data
3
3
 
4
- class OrmRegistry < Mack::Utils::RegistryList # :nodoc:
4
+ #
5
+ # Registry list (LIFO) for all valid handlers.
6
+ #
7
+ # <i>Example:</i>
8
+ # OrmRegistry.add(Mack::Data::OrmBridge::ActiveRecord.new)
9
+ #
10
+ class OrmRegistry < Mack::Utils::RegistryList
5
11
  end
6
12
 
13
+ #
14
+ # Different ORMs have different API at getting object from the store.
15
+ # The ORM bridge is an attempt to have a common API that the data_factory
16
+ # can use to get at the objects it needed.
17
+ #
18
+ # Currently there are 2 orm bridges implemented: DataMapper and ActiveRecord.
19
+ # But developers are free to develop another adapter.
20
+ #
21
+ # Although this feature is called an "ORM" bridge, the API that it's trying
22
+ # to bridge doesn't necessarily have to be of an ORM. As long as the module
23
+ # you're bridging can respond to these API, you can use it as a valid adapter.
24
+ #
25
+ # This feature is an advanced feature of the Data Factory, and it's very useful
26
+ # in a case where you have some legacy data sitting somewhere, or you may have
27
+ # a collection of data that is obtained through a very costly sql query (so doing
28
+ # it many times is obviously not acceptable). So you may want to build a class
29
+ # that can preload all the data, then register itself to the OrmRegistry.
30
+ #
31
+ # The most important method that a "handler" must implement is the can_handle
32
+ # method. When the DataFactory is handling a certain object, it will attempt
33
+ # to find the appropriate API module that can handle that object, so it will
34
+ # ask all the registered handlers of the OrmRegistry, and the first one to
35
+ # answer yes to the question will be the handler of the object.
36
+ # When a handler say yes to the question, it's expected that the handler
37
+ # implement all the methods defined in the Bridge class.
38
+ #
7
39
  class Bridge
8
40
 
9
41
  def initialize
@@ -11,22 +43,58 @@ module Mack
11
43
  OrmRegistry.add(Mack::Data::OrmBridge::DataMapper.new)
12
44
  end
13
45
 
46
+ #
47
+ # Get a record from the given _obj_ model.
48
+ # In active record implementation: this will get translated to
49
+ # obj.find(*args)
50
+ #
51
+ # <i>Parameters:</i>
52
+ # obj: the object model class
53
+ # args: the list of arguments
54
+ #
14
55
  def get(obj, *args)
15
56
  handler(obj).get(obj, *args)
16
57
  end
17
58
 
59
+ #
60
+ # Get all records from the given _obj_ model
61
+ #
62
+ # <i>Parameters:</i>
63
+ # obj: the object model class
64
+ # args: the list of arguments
65
+ #
18
66
  def get_all(obj, *args)
19
67
  handler(obj).get_all(obj, *args)
20
68
  end
21
69
 
70
+ #
71
+ # Get the first record from the given _obj_ model
72
+ #
73
+ # <i>Parameters:</i>
74
+ # obj: the object model class
75
+ # args: the list of arguments
76
+ #
22
77
  def get_first(obj, *args)
23
78
  handler(obj).get_first(obj, *args)
24
79
  end
25
80
 
81
+ # Get the total number of records for the given _obj_ model
82
+ #
83
+ # <i>Parameters:</i>
84
+ # obj: the object model class
85
+ # args: the list of arguments
86
+ #
26
87
  def count(obj, *args)
27
88
  handler(obj).count(obj, *args)
28
89
  end
29
90
 
91
+ #
92
+ # Commit changes made to the _obj_ model
93
+ #
94
+ # <i>Parameters:</i>
95
+ # obj: the object model class
96
+ # args: the list of arguments
97
+ #
30
98
  def save(obj, *args)
31
99
  handler(obj).save(obj, *args)
32
100
  end
@@ -1,7 +1,7 @@
1
1
  module Mack
2
2
  module Data
3
- module OrmBridge
4
- class ActiveRecord
3
+ module OrmBridge # :nodoc:
4
+ class ActiveRecord # :nodoc:
5
5
 
6
6
  def can_handle(obj)
7
7
  return false if !Object.const_defined?('ActiveRecord')
@@ -1,7 +1,7 @@
1
1
  module Mack
2
2
  module Data
3
- module OrmBridge
4
- class DataMapper
3
+ module OrmBridge # :nodoc:
4
+ class DataMapper # :nodoc:
5
5
 
6
6
  def can_handle(obj)
7
7
  return false if !Object.const_defined?('DataMapper')
@@ -1,7 +1,7 @@
1
1
  module Mack
2
2
  module Data
3
3
  module OrmBridge # :nodoc:
4
- class Default
4
+ class Default # :nodoc:
5
5
 
6
6
  def can_handle(obj)
7
7
  return true
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mack-data_factory
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.1
4
+ version: 0.7.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Darsono Sutedja
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-09-08 00:00:00 -04:00
12
+ date: 2008-09-14 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -42,34 +42,6 @@ files:
42
42
  - lib/mack-data_factory/orm_api_bridge/orm/default.rb
43
43
  - lib/mack-data_factory.rb
44
44
  - README
45
- - doc/classes/Kernel.html
46
- - doc/classes/Mack/Data/Bridge.html
47
- - doc/classes/Mack/Data/Factory/ClassMethods.html
48
- - doc/classes/Mack/Data/Factory/FieldContentGenerator.html
49
- - doc/classes/Mack/Data/Factory.html
50
- - doc/classes/Mack/Data/Field.html
51
- - doc/classes/Mack/Data/FieldMgr.html
52
- - doc/classes/Mack/Data/OrmBridge/ActiveRecord.html
53
- - doc/classes/Mack/Data/OrmBridge/DataMapper.html
54
- - doc/classes/Mack/Data/OrmBridge/Default.html
55
- - doc/classes/Mack.html
56
- - doc/created.rid
57
- - doc/files/lib/mack-data_factory/content_generator_rb.html
58
- - doc/files/lib/mack-data_factory/core_extensions/kernel_rb.html
59
- - doc/files/lib/mack-data_factory/data_factory_rb.html
60
- - doc/files/lib/mack-data_factory/field_manager_rb.html
61
- - doc/files/lib/mack-data_factory/field_rb.html
62
- - doc/files/lib/mack-data_factory/orm_api_bridge/bridge_rb.html
63
- - doc/files/lib/mack-data_factory/orm_api_bridge/orm/active_record_rb.html
64
- - doc/files/lib/mack-data_factory/orm_api_bridge/orm/data_mapper_rb.html
65
- - doc/files/lib/mack-data_factory/orm_api_bridge/orm/default_rb.html
66
- - doc/files/lib/mack-data_factory_rb.html
67
- - doc/files/README.html
68
- - doc/fr_class_index.html
69
- - doc/fr_file_index.html
70
- - doc/fr_method_index.html
71
- - doc/index.html
72
- - doc/rdoc-style.css
73
45
  has_rdoc: true
74
46
  homepage: http://www.mackframework.com
75
47
  post_install_message: