mack-data_factory 0.7.1 → 0.7.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/mack-data_factory/content_generator.rb +1 -1
- data/lib/mack-data_factory/core_extensions/kernel.rb +13 -17
- data/lib/mack-data_factory/data_factory.rb +128 -19
- data/lib/mack-data_factory/field.rb +1 -1
- data/lib/mack-data_factory/field_manager.rb +1 -1
- data/lib/mack-data_factory/orm_api_bridge/bridge.rb +69 -1
- data/lib/mack-data_factory/orm_api_bridge/orm/active_record.rb +2 -2
- data/lib/mack-data_factory/orm_api_bridge/orm/data_mapper.rb +2 -2
- data/lib/mack-data_factory/orm_api_bridge/orm/default.rb +1 -1
- metadata +2 -30
- data/doc/classes/Kernel.html +0 -207
- data/doc/classes/Mack.html +0 -137
- data/doc/classes/Mack/Data/Bridge.html +0 -269
- data/doc/classes/Mack/Data/Factory.html +0 -171
- data/doc/classes/Mack/Data/Factory/ClassMethods.html +0 -290
- data/doc/classes/Mack/Data/Factory/FieldContentGenerator.html +0 -685
- data/doc/classes/Mack/Data/Field.html +0 -271
- data/doc/classes/Mack/Data/FieldMgr.html +0 -217
- data/doc/classes/Mack/Data/OrmBridge/ActiveRecord.html +0 -267
- data/doc/classes/Mack/Data/OrmBridge/DataMapper.html +0 -267
- data/doc/classes/Mack/Data/OrmBridge/Default.html +0 -266
- data/doc/created.rid +0 -1
- data/doc/files/README.html +0 -107
- data/doc/files/lib/mack-data_factory/content_generator_rb.html +0 -108
- data/doc/files/lib/mack-data_factory/core_extensions/kernel_rb.html +0 -101
- data/doc/files/lib/mack-data_factory/data_factory_rb.html +0 -101
- data/doc/files/lib/mack-data_factory/field_manager_rb.html +0 -101
- data/doc/files/lib/mack-data_factory/field_rb.html +0 -101
- data/doc/files/lib/mack-data_factory/orm_api_bridge/bridge_rb.html +0 -101
- data/doc/files/lib/mack-data_factory/orm_api_bridge/orm/active_record_rb.html +0 -101
- data/doc/files/lib/mack-data_factory/orm_api_bridge/orm/data_mapper_rb.html +0 -101
- data/doc/files/lib/mack-data_factory/orm_api_bridge/orm/default_rb.html +0 -101
- data/doc/files/lib/mack-data_factory_rb.html +0 -108
- data/doc/fr_class_index.html +0 -37
- data/doc/fr_file_index.html +0 -37
- data/doc/fr_method_index.html +0 -79
- data/doc/index.html +0 -24
- data/doc/rdoc-style.css +0 -208
@@ -11,19 +11,19 @@ module Kernel
|
|
11
11
|
# Convenient routine to create an execution chain of factories
|
12
12
|
#
|
13
13
|
# Example:
|
14
|
-
#
|
15
|
-
#
|
16
|
-
#
|
17
|
-
#
|
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
|
-
#
|
23
|
-
# run_factories(:foo)
|
22
|
+
# run_factories(:foo)
|
24
23
|
#
|
25
|
-
#
|
26
|
-
#
|
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
|
-
#
|
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
|
-
#
|
13
|
-
# July 2008
|
24
|
+
# Author:: Darsono Sutedja
|
25
|
+
# Date:: July 2008
|
14
26
|
#
|
15
27
|
module Factory
|
16
28
|
|
17
|
-
|
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
|
-
#
|
29
|
-
#
|
30
|
-
#
|
31
|
-
#
|
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
|
-
#
|
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
|
-
#
|
36
|
-
#
|
37
|
-
#
|
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
|
79
|
-
# for
|
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
|
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
|
@@ -1,9 +1,41 @@
|
|
1
1
|
module Mack
|
2
2
|
module Data
|
3
3
|
|
4
|
-
|
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
|
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-
|
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:
|