aub-machine 1.0.0
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/README.textile +158 -0
- data/Rakefile +61 -0
- data/TODO.textile +0 -0
- data/lib/machine/association_helper.rb +16 -0
- data/lib/machine/machine.rb +226 -0
- data/lib/machine/machine_group.rb +22 -0
- data/lib/machine/sequence.rb +12 -0
- data/lib/machine.rb +15 -0
- data/machine.gemspec +24 -0
- data/rails/init.rb +1 -0
- data/test/machine_group_test.rb +95 -0
- data/test/machine_test.rb +269 -0
- data/test/models.rb +43 -0
- data/test/sequence_test.rb +39 -0
- data/test/test.db +0 -0
- data/test/test_helper.rb +13 -0
- metadata +79 -0
data/README.textile
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
h1. machine
|
|
2
|
+
|
|
3
|
+
Machine is a factory tool designed for a fixture replacement in Rails applications. It borrows a few concepts
|
|
4
|
+
from "factory_girl":http://github.com/thoughtbot/factory_girl/tree/master but applies attributes to objects
|
|
5
|
+
differently and has a different concept for associations.
|
|
6
|
+
|
|
7
|
+
Written by "Aubrey Holland":mailto:aubreyholland@gmail.com.
|
|
8
|
+
|
|
9
|
+
h2. download
|
|
10
|
+
|
|
11
|
+
Github: "Page":http://github.com/aub/machine/tree/master
|
|
12
|
+
|
|
13
|
+
Gem: <pre>gem install aub-machine --source http://gems.github.com</pre>
|
|
14
|
+
|
|
15
|
+
Note: if you install using the gem from Github, you'll need this
|
|
16
|
+
in your environment.rb if you want to use Rails 2.1's dependency manager:
|
|
17
|
+
|
|
18
|
+
config.gem "aub-machine",
|
|
19
|
+
:lib => "machine",
|
|
20
|
+
:source => "http://gems.github.com"
|
|
21
|
+
|
|
22
|
+
h3. define a machine
|
|
23
|
+
|
|
24
|
+
<pre><code>
|
|
25
|
+
Machine.define :car do |car, machine|
|
|
26
|
+
car.make = 'Ford'
|
|
27
|
+
car.model = 'Taurus'
|
|
28
|
+
end
|
|
29
|
+
</code></pre>
|
|
30
|
+
|
|
31
|
+
This defines a factory for building Car objects. The block is yielded an instance of the Car class
|
|
32
|
+
along with a machine object that can be used for building associated objects. Optionally, a class
|
|
33
|
+
name can be provided in cases where the name of the machine is not the same as that of the class.
|
|
34
|
+
|
|
35
|
+
<pre><code>
|
|
36
|
+
Machine.define :auto, :class => Car do |auto, machine|
|
|
37
|
+
...
|
|
38
|
+
end
|
|
39
|
+
</code></pre>
|
|
40
|
+
|
|
41
|
+
Machines can also be extended to any number of levels. When an extended machine is executed, the
|
|
42
|
+
tree will be applied starting from the bottom. This is useful in cases where one machine is a
|
|
43
|
+
specialization of another one.
|
|
44
|
+
|
|
45
|
+
<pre><code>
|
|
46
|
+
Machine.define :car do |car, machine|
|
|
47
|
+
car.make = 'Ford'
|
|
48
|
+
car.type = 'Car'
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
Machine.define :station_wagon, :class => Car, :extends => :car do |car, machine|
|
|
52
|
+
car.type = 'Station Wagon'
|
|
53
|
+
end
|
|
54
|
+
</code></pre>
|
|
55
|
+
|
|
56
|
+
In addition, groups of machines can be defined that are built from a set of base attributes.
|
|
57
|
+
This is useful for namespacing similar types.
|
|
58
|
+
|
|
59
|
+
<pre><code>
|
|
60
|
+
Machine.define_group :user do |group|
|
|
61
|
+
group.base do |user, machine|
|
|
62
|
+
user.password = 'password'
|
|
63
|
+
user.password_confirmation = 'password'
|
|
64
|
+
user.status = 'active'
|
|
65
|
+
user.permissions = 'none'
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
group.define :super_user do |user, machine|
|
|
69
|
+
user.permissions = 'super'
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
</code></pre>
|
|
73
|
+
|
|
74
|
+
This defines two machines, user and super_user, where super_user has all of the attributes of
|
|
75
|
+
user but with a different permissions value.
|
|
76
|
+
|
|
77
|
+
h3. use a machine
|
|
78
|
+
|
|
79
|
+
Machines can be applied using one of three methods:
|
|
80
|
+
|
|
81
|
+
<pre><code>
|
|
82
|
+
Machine(:car) # creates an unsaved object using the machine 'car'.
|
|
83
|
+
Machine.build(:car) # same as above.
|
|
84
|
+
Machine.build!(:car) # creates an object using the 'car' machine and saves it.
|
|
85
|
+
</code></pre>
|
|
86
|
+
|
|
87
|
+
With each of these methods, a hash of replacement attributes can be passed, and those
|
|
88
|
+
attributes will be used in place of the default ones defined in the machine.
|
|
89
|
+
|
|
90
|
+
<pre><code>
|
|
91
|
+
Machine(:car, :make => 'Ferrari')
|
|
92
|
+
</code></pre>
|
|
93
|
+
|
|
94
|
+
h3. associations
|
|
95
|
+
|
|
96
|
+
Associations are filled using the machine object that is yielded in the block of the machine
|
|
97
|
+
definition. Instances of other machines can be created by calling the object with the name of
|
|
98
|
+
the machine.
|
|
99
|
+
|
|
100
|
+
<pre><code>
|
|
101
|
+
Machine.define :garage do |garage, machine|
|
|
102
|
+
garage.car = machine.car
|
|
103
|
+
end
|
|
104
|
+
</code></pre>
|
|
105
|
+
|
|
106
|
+
Replacement attributes can be passed to the machine in order to specialize the instance
|
|
107
|
+
for for a given association.
|
|
108
|
+
|
|
109
|
+
<pre><code>
|
|
110
|
+
Machine.define :garage do |garage, machine|
|
|
111
|
+
garage.cars = [machine.car(:model => 'Thunderbird'), machine.car(:model => 'Mustang')]
|
|
112
|
+
end
|
|
113
|
+
</code></pre>
|
|
114
|
+
|
|
115
|
+
h3. sequences
|
|
116
|
+
|
|
117
|
+
In cases where an attribute is required to be unique, sequences can be used. A sequence is
|
|
118
|
+
defined as a block that takes as its argument a unique integer and returns a result.
|
|
119
|
+
|
|
120
|
+
<pre><code>
|
|
121
|
+
Machine.sequence :vin do |n|
|
|
122
|
+
"abc123-#{n}"
|
|
123
|
+
end
|
|
124
|
+
</code></pre>
|
|
125
|
+
|
|
126
|
+
Sequences can then be used in machine definitions to set attribute values.
|
|
127
|
+
|
|
128
|
+
<pre><code>
|
|
129
|
+
Machine.define :car do |car, machine|
|
|
130
|
+
car.vin = machine.next(:vin)
|
|
131
|
+
car.make = 'Honda'
|
|
132
|
+
end
|
|
133
|
+
</code></pre>
|
|
134
|
+
|
|
135
|
+
h1. license
|
|
136
|
+
|
|
137
|
+
(The MIT License)
|
|
138
|
+
|
|
139
|
+
Copyright (c) 2008 Aubrey Holland and patch
|
|
140
|
+
|
|
141
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
142
|
+
a copy of this software and associated documentation files (the
|
|
143
|
+
'Software'), to deal in the Software without restriction, including
|
|
144
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
145
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
146
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
147
|
+
the following conditions:
|
|
148
|
+
|
|
149
|
+
The above copyright notice and this permission notice shall be
|
|
150
|
+
included in all copies or substantial portions of the Software.
|
|
151
|
+
|
|
152
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
|
153
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
154
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
155
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
156
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
157
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
158
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
require 'rake'
|
|
3
|
+
require 'rake/testtask'
|
|
4
|
+
require 'rake/rdoctask'
|
|
5
|
+
require 'rake/gempackagetask'
|
|
6
|
+
require 'date'
|
|
7
|
+
|
|
8
|
+
desc 'Default: run unit tests.'
|
|
9
|
+
task :default => :test
|
|
10
|
+
|
|
11
|
+
desc 'Test the machine.'
|
|
12
|
+
Rake::TestTask.new(:test) do |t|
|
|
13
|
+
t.libs << 'lib'
|
|
14
|
+
t.pattern = 'test/**/*_test.rb'
|
|
15
|
+
t.verbose = true
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
desc 'Generate documentation for the machine.'
|
|
19
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
|
20
|
+
rdoc.rdoc_dir = 'rdoc'
|
|
21
|
+
rdoc.title = 'Machine'
|
|
22
|
+
rdoc.options << '--line-numbers' << '--inline-source' << "--main" << "README.textile"
|
|
23
|
+
rdoc.rdoc_files.include('README.textile')
|
|
24
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
spec = Gem::Specification.new do |s|
|
|
28
|
+
s.name = %q{machine}
|
|
29
|
+
s.version = "1.0.0"
|
|
30
|
+
s.summary = %q{machine defines a factory system for creating model objects to replace fixtures in Ruby apps.}
|
|
31
|
+
s.description = %q{machine defines a factory system for creating model objects to replace fixtures in Ruby apps.}
|
|
32
|
+
|
|
33
|
+
s.files = FileList['[A-Z]*', 'lib/**/*.rb', 'test/**/*.rb']
|
|
34
|
+
s.require_path = 'lib'
|
|
35
|
+
s.test_files = Dir[*['test/**/*_test.rb']]
|
|
36
|
+
|
|
37
|
+
s.has_rdoc = true
|
|
38
|
+
s.extra_rdoc_files = ["README.textile"]
|
|
39
|
+
s.rdoc_options = ['--line-numbers', '--inline-source', "--main", "README.textile"]
|
|
40
|
+
|
|
41
|
+
s.authors = ["Aubrey Holland"]
|
|
42
|
+
s.email = %q{aubrey@patch.com}
|
|
43
|
+
|
|
44
|
+
s.platform = Gem::Platform::RUBY
|
|
45
|
+
s.add_dependency(%q<activesupport>, [">= 1.0"])
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
Rake::GemPackageTask.new spec do |pkg|
|
|
49
|
+
pkg.need_tar = true
|
|
50
|
+
pkg.need_zip = true
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
desc "Clean files generated by rake tasks"
|
|
54
|
+
task :clobber => [:clobber_rdoc, :clobber_package]
|
|
55
|
+
|
|
56
|
+
desc "Generate a gemspec file"
|
|
57
|
+
task :gemspec do
|
|
58
|
+
File.open("#{spec.name}.gemspec", 'w') do |f|
|
|
59
|
+
f.write spec.to_ruby
|
|
60
|
+
end
|
|
61
|
+
end
|
data/TODO.textile
ADDED
|
File without changes
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
class AssociationHelper
|
|
2
|
+
|
|
3
|
+
def initialize #:nodoc
|
|
4
|
+
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def next(sequence) #:nodoc
|
|
8
|
+
Machine.next(sequence)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def method_missing(name, *args) #:nodoc
|
|
12
|
+
if Machine.machines.has_key?(name)
|
|
13
|
+
Machine.machines[name].build(*args)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
class MachineNotFoundError < StandardError; end
|
|
2
|
+
|
|
3
|
+
class Machine
|
|
4
|
+
|
|
5
|
+
cattr_accessor :machines #:nodoc:
|
|
6
|
+
self.machines = {}
|
|
7
|
+
|
|
8
|
+
cattr_accessor :sequences #:nodoc:
|
|
9
|
+
self.sequences = {}
|
|
10
|
+
|
|
11
|
+
# An Array of strings specifying locations that should be searched for
|
|
12
|
+
# machine definitions. By default, machine will attempt to require
|
|
13
|
+
# "machines," "test/machines," and "spec/machines." Only the first
|
|
14
|
+
# existing file will be loaded.
|
|
15
|
+
cattr_accessor :definition_file_paths
|
|
16
|
+
self.definition_file_paths = %w(machines test/machines spec/machines)
|
|
17
|
+
|
|
18
|
+
def self.find_definitions #:nodoc:
|
|
19
|
+
definition_file_paths.each do |file_path|
|
|
20
|
+
begin
|
|
21
|
+
require(file_path)
|
|
22
|
+
break
|
|
23
|
+
rescue LoadError
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Defines a new machine that sets up the default attributes for new objects.
|
|
29
|
+
#
|
|
30
|
+
# Arguments:
|
|
31
|
+
# name: (Symbol)
|
|
32
|
+
# A unique name used to identify this machine.
|
|
33
|
+
# options: (Hash)
|
|
34
|
+
# class: (Class) the class that will be used when generating instances for this
|
|
35
|
+
# machine. If not specified, the class will be guessed from the
|
|
36
|
+
# machine name.
|
|
37
|
+
# extends: (Symbol) the name of a machine that will be extended by this one.
|
|
38
|
+
# If provided, the attributes of the extended machine will be applied
|
|
39
|
+
# to the object before the one being defined.
|
|
40
|
+
#
|
|
41
|
+
# Yields:
|
|
42
|
+
# The object being created and an association helper
|
|
43
|
+
#
|
|
44
|
+
# Example:
|
|
45
|
+
#
|
|
46
|
+
# Machine.define :car do |car, machine|
|
|
47
|
+
# car.make = 'GMC'
|
|
48
|
+
# car.model = 'S-15'
|
|
49
|
+
# end
|
|
50
|
+
def self.define(name, options={}, &block)
|
|
51
|
+
self.machines[name] = Machine.new(name, options, block)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Defines a group of machines with a base set of attributes and then a set of
|
|
55
|
+
# machines as children. This is useful as a namespacing technique or for any
|
|
56
|
+
# case where you wish to define a set of objects that share a set of base
|
|
57
|
+
# attributes.
|
|
58
|
+
#
|
|
59
|
+
# Arguments:
|
|
60
|
+
# name: (Symbol)
|
|
61
|
+
# A unique name to identify the group. This name will itself become a machine
|
|
62
|
+
# that will build from the base attributes.
|
|
63
|
+
# options: (Hash)
|
|
64
|
+
# class: (Class) the class that will be used when generating instances for this
|
|
65
|
+
# machine. If not specified, the class will be guessed from the
|
|
66
|
+
# machine name.
|
|
67
|
+
#
|
|
68
|
+
# Example
|
|
69
|
+
#
|
|
70
|
+
# Machine.define_group :user do |group|
|
|
71
|
+
# group.base do |user, machine|
|
|
72
|
+
# user.password = 'password'
|
|
73
|
+
# user.password_confirmation = 'password'
|
|
74
|
+
# user.login = Machine.next(:login)
|
|
75
|
+
# user.email = Machine.next(:email)
|
|
76
|
+
# end
|
|
77
|
+
#
|
|
78
|
+
# group.define :super_user do |user, machine|
|
|
79
|
+
# user.permissions = [machine.permission(:user => user)]
|
|
80
|
+
# end
|
|
81
|
+
# end
|
|
82
|
+
#
|
|
83
|
+
# Machine.build(:user)
|
|
84
|
+
# Machine.build(:super_user)
|
|
85
|
+
#
|
|
86
|
+
def self.define_group(name, options={}, &block)
|
|
87
|
+
group = MachineGroup.new(name, options)
|
|
88
|
+
yield group
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# Creates an unsaved object using the machine with the given name.
|
|
92
|
+
#
|
|
93
|
+
# Arguments:
|
|
94
|
+
# name: (Symbol)
|
|
95
|
+
# The name of the machine to apply.
|
|
96
|
+
# attributes: (Hash)
|
|
97
|
+
# A set of attributes to use as a replacement for the default ones provided by
|
|
98
|
+
# the machine.
|
|
99
|
+
#
|
|
100
|
+
# Example
|
|
101
|
+
#
|
|
102
|
+
# Machine.build(:car, :model => 'Civic', :make => 'Honda')
|
|
103
|
+
def self.build(name, attributes={})
|
|
104
|
+
machines = machines_for(name)
|
|
105
|
+
raise MachineNotFoundError if machines.empty?
|
|
106
|
+
object = machines.shift.build(attributes)
|
|
107
|
+
while machine = machines.shift
|
|
108
|
+
machine.apply_to(object, attributes)
|
|
109
|
+
end
|
|
110
|
+
object
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# Creates an saved object using the machine with the given name.
|
|
114
|
+
#
|
|
115
|
+
# Arguments:
|
|
116
|
+
# name: (Symbol)
|
|
117
|
+
# The name of the machine to apply.
|
|
118
|
+
# attributes: (Hash)
|
|
119
|
+
# A set of attributes to use as a replacement for the default ones provided by
|
|
120
|
+
# the machine.
|
|
121
|
+
#
|
|
122
|
+
# Example
|
|
123
|
+
#
|
|
124
|
+
# Machine.build!(:car, :model => 'Civic', :make => 'Honda')
|
|
125
|
+
def self.build!(name, attributes={})
|
|
126
|
+
result = build(name, attributes)
|
|
127
|
+
result.save! if result.respond_to?(:save!)
|
|
128
|
+
result
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# Apply the machine with the given name to the provided object. This can
|
|
132
|
+
# be used to load an existing object with the attributes defined in a machine.
|
|
133
|
+
#
|
|
134
|
+
# Arguments:
|
|
135
|
+
# name: (Symbol)
|
|
136
|
+
# The name of the machine to apply.
|
|
137
|
+
# object: (Object)
|
|
138
|
+
# The object whose attributes should be set.
|
|
139
|
+
# attributes: (Hash)
|
|
140
|
+
# A set of replacements attributes for those specified in the machine.
|
|
141
|
+
#
|
|
142
|
+
# Example
|
|
143
|
+
#
|
|
144
|
+
# car = Car.new
|
|
145
|
+
# Machine.apply_to(:car, car, :model => 'Jetta')
|
|
146
|
+
def self.apply_to(name, object, attributes={})
|
|
147
|
+
machines = machines_for(name)
|
|
148
|
+
return if machines.empty?
|
|
149
|
+
while machine = machines.shift
|
|
150
|
+
machine.apply_to(object, attributes)
|
|
151
|
+
end
|
|
152
|
+
object
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
# Defines a new named sequence. Sequences can be used to set attributes
|
|
156
|
+
# that must be unique. Once a sequence is created it can be applied by
|
|
157
|
+
# calling Machine.next, passing the sequence name.
|
|
158
|
+
#
|
|
159
|
+
# Arguments:
|
|
160
|
+
# name: (Symbol)
|
|
161
|
+
# A unique name used to identify this sequence.
|
|
162
|
+
# block: (Proc)
|
|
163
|
+
# The code to generate each value in the sequence. This block will be
|
|
164
|
+
# called with a unique number each time a value in the sequence is to be
|
|
165
|
+
# generated. The block should return the generated value for the
|
|
166
|
+
# sequence.
|
|
167
|
+
#
|
|
168
|
+
# Example
|
|
169
|
+
#
|
|
170
|
+
# Machine.sequence :street do |n|
|
|
171
|
+
# "#{n} Main St."
|
|
172
|
+
# end
|
|
173
|
+
def self.sequence(name, &block)
|
|
174
|
+
self.sequences[name] = Sequence.new(block)
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
# Get the next value produced by the sequence with the given name. This
|
|
178
|
+
# can be used in machine definitions to fill in attributes that must be
|
|
179
|
+
# unique.
|
|
180
|
+
#
|
|
181
|
+
# Arguments:
|
|
182
|
+
# sequence: (Symbol)
|
|
183
|
+
# The name of the sequence to use.
|
|
184
|
+
#
|
|
185
|
+
# Example
|
|
186
|
+
#
|
|
187
|
+
# Machine.define :address do |address, machine|
|
|
188
|
+
# address.street = machine.next(:street)
|
|
189
|
+
# end
|
|
190
|
+
def self.next(sequence)
|
|
191
|
+
sequences[sequence].next if sequences.has_key?(sequence)
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
def initialize(name, options, proc) #:nodoc
|
|
195
|
+
@name, @options, @proc = name, options, proc
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
def extends #:nodoc
|
|
199
|
+
@options[:extends] ? machines[@options[:extends]] : nil
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
def build(attributes={}) #:nodoc
|
|
203
|
+
object = build_class.new
|
|
204
|
+
apply_to(object, attributes)
|
|
205
|
+
object
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def apply_to(object, attributes={}) #:nodoc
|
|
209
|
+
@proc.call(object, AssociationHelper.new)
|
|
210
|
+
attributes.each { |key, value| object.send("#{key}=", value) }
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
protected
|
|
214
|
+
|
|
215
|
+
def build_class #:nodoc
|
|
216
|
+
@options[:class] || @name.to_s.camelize.constantize
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
def self.machines_for(name) #:nodoc
|
|
220
|
+
result = [machines[name]]
|
|
221
|
+
while result.last
|
|
222
|
+
result << result.last.extends
|
|
223
|
+
end
|
|
224
|
+
result.compact.reverse
|
|
225
|
+
end
|
|
226
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
class MachineGroup
|
|
2
|
+
|
|
3
|
+
def initialize(name, options={}) #:nodoc
|
|
4
|
+
@name = name
|
|
5
|
+
@options = options
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def base(&block) #:nodoc
|
|
9
|
+
@base_machine = Machine.new(@name, @options, block)
|
|
10
|
+
Machine.machines[@name] = @base_machine
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def define(name, &block) #:nodoc
|
|
14
|
+
if @base_machine
|
|
15
|
+
options = @options.merge(:extends => @name)
|
|
16
|
+
else
|
|
17
|
+
options = @options.merge(:class => (@options[:class] || @name.to_s.camelize.constantize))
|
|
18
|
+
end
|
|
19
|
+
machine = Machine.new(name, options, block)
|
|
20
|
+
Machine.machines[name] = machine
|
|
21
|
+
end
|
|
22
|
+
end
|
data/lib/machine.rb
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require 'machine/association_helper'
|
|
2
|
+
require 'machine/machine'
|
|
3
|
+
require 'machine/machine_group'
|
|
4
|
+
require 'machine/sequence'
|
|
5
|
+
|
|
6
|
+
# Find the definitions in the default locations:
|
|
7
|
+
# machines.rb
|
|
8
|
+
# test/machines.rb
|
|
9
|
+
# spec/machines.rb
|
|
10
|
+
Machine.find_definitions
|
|
11
|
+
|
|
12
|
+
# Shorthand method for building a machine, is an alias for Machine.build(name, attributes)
|
|
13
|
+
def Machine(name, attributes={})
|
|
14
|
+
Machine.build(name, attributes)
|
|
15
|
+
end
|
data/machine.gemspec
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
Gem::Specification.new do |s|
|
|
2
|
+
s.version = '1.0.0'
|
|
3
|
+
s.date = %q{2008-11-07}
|
|
4
|
+
|
|
5
|
+
s.name = %q{machine}
|
|
6
|
+
s.required_rubygems_version = Gem::Requirement.new('>= 0') if s.respond_to? :required_rubygems_version=
|
|
7
|
+
s.authors = ['Aubrey Holland', 'patch']
|
|
8
|
+
s.description = %q{machine defines a factory system for creating model objects to replace fixtures in Ruby apps.}
|
|
9
|
+
s.email = %q{aubrey@patch.com}
|
|
10
|
+
s.files = ['lib', 'lib/machine', 'lib/machine/association_helper.rb', 'lib/machine/machine.rb', 'lib/machine/machine_group.rb', 'lib/machine/sequence.rb', 'lib/machine.rb', 'machine-1.0.0.gem', 'machine.gemspec', 'rails', 'rails/init.rb', 'Rakefile', 'README.textile', 'test', 'test/machine_group_test.rb', 'test/machine_test.rb', 'test/models.rb', 'test/sequence_test.rb', 'test/test.db', 'test/test_helper.rb', 'TODO.textile']
|
|
11
|
+
s.homepage = %q{http://github.com/aub/machine/tree/master}
|
|
12
|
+
s.require_paths = ['lib']
|
|
13
|
+
s.rubygems_version = %q{1.2.0}
|
|
14
|
+
s.summary = %q{Machine crunches factories.}
|
|
15
|
+
s.has_rdoc = true
|
|
16
|
+
s.extra_rdoc_files = ['README.textile']
|
|
17
|
+
s.rdoc_options = ['--line-numbers', '--inline-source', '--main', 'README.textile']
|
|
18
|
+
s.test_files = ['test/machine_test.rb', 'test/machine_group_test.rb', 'test/sequence_test.rb']
|
|
19
|
+
|
|
20
|
+
if s.respond_to? :specification_version then
|
|
21
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
|
22
|
+
s.specification_version = 2
|
|
23
|
+
end
|
|
24
|
+
end
|
data/rails/init.rb
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require 'machine'
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper.rb'
|
|
2
|
+
|
|
3
|
+
class MachineGroupTest < Test::Unit::TestCase
|
|
4
|
+
|
|
5
|
+
def setup
|
|
6
|
+
Machine.machines.clear
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
context "defining the base machine" do
|
|
10
|
+
setup do
|
|
11
|
+
@group = MachineGroup.new(:article)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
should "create a machine from the name of the group" do
|
|
15
|
+
@group.base do |article, machine|
|
|
16
|
+
article.title = 'ooooh'
|
|
17
|
+
end
|
|
18
|
+
a = Machine(:article)
|
|
19
|
+
assert_equal 'ooooh', a.title
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
context "creating a group with a specified class" do
|
|
24
|
+
setup do
|
|
25
|
+
@group = MachineGroup.new(:whoosit, :class => Article)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
should "create the correct type of object and set its attributes" do
|
|
29
|
+
@group.base do |article, machine|
|
|
30
|
+
article.title = 'ooooh'
|
|
31
|
+
end
|
|
32
|
+
a = Machine(:whoosit)
|
|
33
|
+
assert a.instance_of?(Article)
|
|
34
|
+
assert_equal 'ooooh', a.title
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
context "defining the sub-machines" do
|
|
39
|
+
setup do
|
|
40
|
+
@group = MachineGroup.new(:article)
|
|
41
|
+
@group.base do |article, machine|
|
|
42
|
+
article.title = 'ooooh'
|
|
43
|
+
article.rating = 3
|
|
44
|
+
end
|
|
45
|
+
@group.define :arts_article do |article, machine|
|
|
46
|
+
article.title = 'awww'
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
should "create a machine for the sub-machine" do
|
|
51
|
+
a = Machine(:arts_article)
|
|
52
|
+
assert a.instance_of?(Article)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
should "set make the new machine an extension of the base" do
|
|
56
|
+
a = Machine(:arts_article)
|
|
57
|
+
assert_equal 'awww', a.title
|
|
58
|
+
assert_equal 3, a.rating
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
context "defining sub-machines with no base" do
|
|
63
|
+
setup do
|
|
64
|
+
@group = MachineGroup.new(:article)
|
|
65
|
+
@group.define :arts_article do |article, machine|
|
|
66
|
+
article.title = 'awww'
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
should "create a machine for the sub-machine" do
|
|
71
|
+
a = Machine(:arts_article)
|
|
72
|
+
assert a.instance_of?(Article)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
should "set the attributes correctly" do
|
|
76
|
+
a = Machine(:arts_article)
|
|
77
|
+
assert_equal 'awww', a.title
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
context "creating a group with a specified class and no base" do
|
|
82
|
+
setup do
|
|
83
|
+
@group = MachineGroup.new(:whoosit, :class => Article)
|
|
84
|
+
@group.define :arts_article do |article, machine|
|
|
85
|
+
article.title = 'ummm'
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
should "create the right type of object and set its attributes" do
|
|
90
|
+
a = Machine(:arts_article)
|
|
91
|
+
assert a.instance_of?(Article)
|
|
92
|
+
assert_equal 'ummm', a.title
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper.rb'
|
|
2
|
+
|
|
3
|
+
class MachineTest < Test::Unit::TestCase
|
|
4
|
+
|
|
5
|
+
def setup
|
|
6
|
+
Machine.machines.clear
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
context "building simple machines" do
|
|
10
|
+
should "add a machine to the list when defined" do
|
|
11
|
+
Machine.define :test, :hack => 'ack' do
|
|
12
|
+
end
|
|
13
|
+
assert_equal 1, Machine.machines.size
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
should "set proper machine variables when creating" do
|
|
17
|
+
Machine.define :testo, :class => Article do
|
|
18
|
+
end
|
|
19
|
+
assert_not_nil Machine.machines[:testo]
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
context "using machines" do
|
|
24
|
+
should "build an instance of the object" do
|
|
25
|
+
Machine.define :article do
|
|
26
|
+
end
|
|
27
|
+
assert Machine.build(:article).instance_of?(Article)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
should "build an instance of the provided class" do
|
|
31
|
+
Machine.define :something, :class => Article do
|
|
32
|
+
end
|
|
33
|
+
assert Machine.build(:something).instance_of?(Article)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
should "set default attributes on the built object" do
|
|
37
|
+
Machine.define :thing, :class => Article do |article, machine|
|
|
38
|
+
article.title = 'aha'
|
|
39
|
+
end
|
|
40
|
+
assert_equal 'aha', Machine.build(:thing).title
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
should "allow overriding of default attributes" do
|
|
44
|
+
Machine.define :thing, :class => Article do |article, machine|
|
|
45
|
+
article.title = 'aha'
|
|
46
|
+
end
|
|
47
|
+
assert_equal 'ooooh', Machine.build(:thing, :title => 'ooooh').title
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
should "only replace the attributes that are passed" do
|
|
51
|
+
Machine.define :thing, :class => Article do |article, machine|
|
|
52
|
+
article.title = 'aha'
|
|
53
|
+
article.rating = 123
|
|
54
|
+
end
|
|
55
|
+
assert_equal 123, Machine.build(:thing, :title => 'ooooh').rating
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
should "not save records with build" do
|
|
59
|
+
Machine.define :thing, :class => Article do |article, machine|
|
|
60
|
+
article.title = 'aha'
|
|
61
|
+
end
|
|
62
|
+
assert Machine.build(:thing).new_record?
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
should "save records with build!" do
|
|
66
|
+
Machine.define :thing, :class => Article do |article, machine|
|
|
67
|
+
article.title = 'aha'
|
|
68
|
+
end
|
|
69
|
+
assert !Machine.build!(:thing).new_record?
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
should "allow redefinition of a machine" do
|
|
73
|
+
Machine.define :article do |article, machine|
|
|
74
|
+
article.title = 'aha'
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
Machine.define :article do |article, machine|
|
|
78
|
+
article.title = 'oho'
|
|
79
|
+
end
|
|
80
|
+
assert_equal 'oho', Machine.build(:article).title
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
should 'raise an exception when using a machine that doesn\'t exist' do
|
|
84
|
+
assert_raises MachineNotFoundError do
|
|
85
|
+
Machine.build(:i_can_has_exception)
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
context "with objects that are not active record" do
|
|
91
|
+
setup do
|
|
92
|
+
Machine.define :non_model do |nonmodel, machine|
|
|
93
|
+
nonmodel.name = 'hoo'
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
should "build the object correctly" do
|
|
98
|
+
assert_equal 'hoo', Machine.build(:non_model).name
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
should "not freak out when calling build! with non-activerecord objects" do
|
|
102
|
+
assert_nothing_raised do
|
|
103
|
+
Machine.build!(:non_model).name
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
context "with associations" do
|
|
109
|
+
setup do
|
|
110
|
+
Machine.define :publication do |publication, machine|
|
|
111
|
+
publication.name = 'booya'
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
Machine.define :comment do |comment, machine|
|
|
115
|
+
comment.data = 'dsfsdf'
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
Machine.define :article do |article, machine|
|
|
119
|
+
article.comments = [machine.comment, machine.comment]
|
|
120
|
+
article.publication = machine.publication
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
should "build associated records" do
|
|
125
|
+
assert_equal 2, Machine.build(:article).comments.size
|
|
126
|
+
assert Machine.build(:article).comments[0].instance_of?(Comment)
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
should "allow passing replacement attributes" do
|
|
130
|
+
Machine.define :article do |article, machine|
|
|
131
|
+
article.comments = [machine.comment(:data => 'nice article'), machine.comment(:data => 'bad article')]
|
|
132
|
+
end
|
|
133
|
+
assert_equal ['nice article', 'bad article'].sort, Machine.build(:article).comments.map { |c| c.data }.sort
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
should "not save associated objects when using build" do
|
|
137
|
+
assert Machine.build(:article).comments[0].new_record?
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
should "save associated objects when using build!" do
|
|
141
|
+
assert !Machine.build!(:article).comments[0].new_record?
|
|
142
|
+
assert !Machine.build!(:article).publication.new_record?
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
context "extending existing factories" do
|
|
147
|
+
setup do
|
|
148
|
+
Machine.define :old_article, :class => Article do |article, machine|
|
|
149
|
+
article.title = 'old'
|
|
150
|
+
article.rating = 12
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
Machine.define :new_article, :class => Article, :extends => :old_article do |article, machine|
|
|
154
|
+
article.title = 'new'
|
|
155
|
+
article.author = 'Joe Six Pack'
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
should "create a new model with the correct attributes" do
|
|
160
|
+
article = Machine.build(:new_article)
|
|
161
|
+
assert_equal 'new', article.title
|
|
162
|
+
assert_equal 12, article.rating
|
|
163
|
+
assert_equal 'Joe Six Pack', article.author
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
should "work properly with multiple layers of extensions" do
|
|
167
|
+
Machine.define :newer_article, :class => Article, :extends => :new_article do |article, machine|
|
|
168
|
+
article.rating = 13
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
article = Machine.build(:newer_article)
|
|
172
|
+
assert_equal 'new', article.title
|
|
173
|
+
assert_equal 13, article.rating
|
|
174
|
+
assert_equal 'Joe Six Pack', article.author
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
context "loading default paths" do
|
|
179
|
+
Machine.definition_file_paths.each do |file|
|
|
180
|
+
should "automatically load definitions from #{file}.rb" do
|
|
181
|
+
Machine.stubs(:require).raises(LoadError)
|
|
182
|
+
Machine.expects(:require).with(file)
|
|
183
|
+
Machine.find_definitions
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
should "only load the first set of machines detected" do
|
|
188
|
+
first, second, third = Machine.definition_file_paths
|
|
189
|
+
Machine.expects(:require).with(first).raises(LoadError)
|
|
190
|
+
Machine.expects(:require).with(second)
|
|
191
|
+
Machine.expects(:require).with(third).never
|
|
192
|
+
Machine.find_definitions
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
context "using the helper method" do
|
|
197
|
+
setup do
|
|
198
|
+
Machine.define :article do |article, machine|
|
|
199
|
+
article.title = 'aha'
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
should "apply machines correctly" do
|
|
204
|
+
assert Machine(:article).instance_of?(Article)
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
should "set the attributes" do
|
|
208
|
+
assert_equal 'aha', Machine(:article).title
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
should "allow replacement attributes" do
|
|
212
|
+
assert_equal 'ooh', Machine(:article, :title => 'ooh').title
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
should "not save the object" do
|
|
216
|
+
assert Machine(:article).new_record?
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
context "applying a machine to an existing object" do
|
|
221
|
+
setup do
|
|
222
|
+
Machine.define :article do |article, machine|
|
|
223
|
+
article.title = 'aha'
|
|
224
|
+
end
|
|
225
|
+
@article = Article.new(:title => 'old')
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
should "update the object's attributes" do
|
|
229
|
+
Machine.apply_to(:article, @article)
|
|
230
|
+
assert_equal 'aha', @article.title
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
should "accept replacement attributes" do
|
|
234
|
+
Machine.apply_to(:article, @article, :title => 'new')
|
|
235
|
+
assert_equal 'new', @article.title
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
should "not save the object" do
|
|
239
|
+
Machine.apply_to(:article, @article)
|
|
240
|
+
assert @article.new_record?
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
context "group definition" do
|
|
245
|
+
should "yield a Group instance" do
|
|
246
|
+
thing = nil
|
|
247
|
+
Machine.define_group :user do |group|
|
|
248
|
+
thing = group
|
|
249
|
+
end
|
|
250
|
+
assert thing.kind_of?(MachineGroup)
|
|
251
|
+
end
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
context 'using sequences' do
|
|
255
|
+
setup do
|
|
256
|
+
Machine.sequence :title do |n|
|
|
257
|
+
"title-#{n}"
|
|
258
|
+
end
|
|
259
|
+
Machine.define :article do |article, machine|
|
|
260
|
+
article.title = machine.next(:title)
|
|
261
|
+
end
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
should 'be able to set values using the sequence' do
|
|
265
|
+
assert_equal 'title-1', Machine(:article).title
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
end
|
data/test/models.rb
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
ActiveRecord::Base.establish_connection(
|
|
2
|
+
:adapter => 'sqlite3',
|
|
3
|
+
:database => File.join(File.dirname(__FILE__), 'test.db')
|
|
4
|
+
)
|
|
5
|
+
|
|
6
|
+
class CreateSchema < ActiveRecord::Migration
|
|
7
|
+
def self.up
|
|
8
|
+
create_table :publications, :force => true do |t|
|
|
9
|
+
t.string :name
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
create_table :articles, :force => true do |t|
|
|
13
|
+
t.references :publication
|
|
14
|
+
t.string :title
|
|
15
|
+
t.integer :rating
|
|
16
|
+
t.string :author
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
create_table :comments, :force => true do |t|
|
|
20
|
+
t.references :article
|
|
21
|
+
t.string :data
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
CreateSchema.suppress_messages { CreateSchema.migrate(:up) }
|
|
27
|
+
|
|
28
|
+
class Publication < ActiveRecord::Base
|
|
29
|
+
has_many :articles
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
class Article < ActiveRecord::Base
|
|
33
|
+
has_many :comments
|
|
34
|
+
belongs_to :publication
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
class Comment < ActiveRecord::Base
|
|
38
|
+
belongs_to :article
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
class NonModel
|
|
42
|
+
attr_accessor :name
|
|
43
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper.rb'
|
|
2
|
+
|
|
3
|
+
class SequenceTest < Test::Unit::TestCase
|
|
4
|
+
|
|
5
|
+
should 'allow definition of sequences' do
|
|
6
|
+
Machine.sequence :thing do
|
|
7
|
+
end
|
|
8
|
+
assert_equal 1, Machine.sequences.size
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
should 'increment the sequence value' do
|
|
12
|
+
Machine.sequence :thing do |n|
|
|
13
|
+
n
|
|
14
|
+
end
|
|
15
|
+
assert_equal 1, Machine.sequences[:thing].next
|
|
16
|
+
assert_equal 2, Machine.sequences[:thing].next
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
should 'be able to output strings' do
|
|
20
|
+
Machine.sequence :thing do |n|
|
|
21
|
+
"article-#{n}"
|
|
22
|
+
end
|
|
23
|
+
assert_equal 'article-1', Machine.sequences[:thing].next
|
|
24
|
+
assert_equal 'article-2', Machine.sequences[:thing].next
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
should 'be callable through the machine' do
|
|
28
|
+
Machine.sequence :thing do |n|
|
|
29
|
+
"article-#{n}"
|
|
30
|
+
end
|
|
31
|
+
assert_equal 'article-1', Machine.next(:thing)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
should 'raise an exception when calling a nonexistent sequence' do
|
|
35
|
+
assert_raises MachineNotFoundError do
|
|
36
|
+
Machine.next(:who)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
data/test/test.db
ADDED
|
Binary file
|
data/test/test_helper.rb
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
$: << File.join(File.dirname(__FILE__), '..', 'lib')
|
|
2
|
+
$: << File.join(File.dirname(__FILE__))
|
|
3
|
+
|
|
4
|
+
require 'test/unit'
|
|
5
|
+
require 'rubygems'
|
|
6
|
+
require 'ruby-debug'
|
|
7
|
+
|
|
8
|
+
require 'activerecord'
|
|
9
|
+
require 'machine'
|
|
10
|
+
require 'mocha'
|
|
11
|
+
require 'models'
|
|
12
|
+
require 'shoulda'
|
|
13
|
+
|
metadata
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: aub-machine
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Aubrey Holland
|
|
8
|
+
- patch
|
|
9
|
+
autorequire:
|
|
10
|
+
bindir: bin
|
|
11
|
+
cert_chain: []
|
|
12
|
+
|
|
13
|
+
date: 2008-11-07 00:00:00 -08:00
|
|
14
|
+
default_executable:
|
|
15
|
+
dependencies: []
|
|
16
|
+
|
|
17
|
+
description: machine defines a factory system for creating model objects to replace fixtures in Ruby apps.
|
|
18
|
+
email: aubrey@patch.com
|
|
19
|
+
executables: []
|
|
20
|
+
|
|
21
|
+
extensions: []
|
|
22
|
+
|
|
23
|
+
extra_rdoc_files:
|
|
24
|
+
- README.textile
|
|
25
|
+
files:
|
|
26
|
+
- lib
|
|
27
|
+
- lib/machine
|
|
28
|
+
- lib/machine/association_helper.rb
|
|
29
|
+
- lib/machine/machine.rb
|
|
30
|
+
- lib/machine/machine_group.rb
|
|
31
|
+
- lib/machine/sequence.rb
|
|
32
|
+
- lib/machine.rb
|
|
33
|
+
- machine-1.0.0.gem
|
|
34
|
+
- machine.gemspec
|
|
35
|
+
- rails
|
|
36
|
+
- rails/init.rb
|
|
37
|
+
- Rakefile
|
|
38
|
+
- README.textile
|
|
39
|
+
- test
|
|
40
|
+
- test/machine_group_test.rb
|
|
41
|
+
- test/machine_test.rb
|
|
42
|
+
- test/models.rb
|
|
43
|
+
- test/sequence_test.rb
|
|
44
|
+
- test/test.db
|
|
45
|
+
- test/test_helper.rb
|
|
46
|
+
- TODO.textile
|
|
47
|
+
has_rdoc: true
|
|
48
|
+
homepage: http://github.com/aub/machine/tree/master
|
|
49
|
+
post_install_message:
|
|
50
|
+
rdoc_options:
|
|
51
|
+
- --line-numbers
|
|
52
|
+
- --inline-source
|
|
53
|
+
- --main
|
|
54
|
+
- README.textile
|
|
55
|
+
require_paths:
|
|
56
|
+
- lib
|
|
57
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - ">="
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: "0"
|
|
62
|
+
version:
|
|
63
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - ">="
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: "0"
|
|
68
|
+
version:
|
|
69
|
+
requirements: []
|
|
70
|
+
|
|
71
|
+
rubyforge_project:
|
|
72
|
+
rubygems_version: 1.2.0
|
|
73
|
+
signing_key:
|
|
74
|
+
specification_version: 2
|
|
75
|
+
summary: Machine crunches factories.
|
|
76
|
+
test_files:
|
|
77
|
+
- test/machine_test.rb
|
|
78
|
+
- test/machine_group_test.rb
|
|
79
|
+
- test/sequence_test.rb
|