elight-machinist 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/.autotest +7 -0
- data/.gitignore +1 -0
- data/MIT-LICENSE +20 -0
- data/README.markdown +201 -0
- data/Rakefile +20 -0
- data/init.rb +10 -0
- data/lib/machinist.rb +88 -0
- data/lib/sham.rb +65 -0
- data/machinist.gemspec +22 -0
- data/spec/machinist_spec.rb +110 -0
- data/spec/sham_spec.rb +45 -0
- data/spec/spec_helper.rb +9 -0
- metadata +71 -0
data/.autotest
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Autotest.add_hook :initialize do |at|
|
|
2
|
+
at.clear_mappings
|
|
3
|
+
|
|
4
|
+
at.add_mapping(%r%^spec/(.*)_spec.rb$%) {|filename, _| filename }
|
|
5
|
+
at.add_mapping(%r%^lib/(.*).rb$%) {|_, match| "spec/#{match[1]}_spec.rb" }
|
|
6
|
+
at.add_mapping(%r%^spec/spec_helper.rb$%) { at.files_matching(%r%^spec/(.*)_spec.rb$%) }
|
|
7
|
+
end
|
data/.gitignore
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
coverage
|
data/MIT-LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright (c) 2008 Peter Yandell
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.markdown
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
Machinist
|
|
2
|
+
=========
|
|
3
|
+
|
|
4
|
+
*Fixtures aren't fun. Machinist is.*
|
|
5
|
+
|
|
6
|
+
Machinist lets you construct test data on the fly, but instead of doing this:
|
|
7
|
+
|
|
8
|
+
describe Comment do
|
|
9
|
+
before do
|
|
10
|
+
@user = User.create!(:name => "Test User")
|
|
11
|
+
@post = Post.create!(:title => "Test Post", :author => @user, :body => "Lorem ipsum...")
|
|
12
|
+
@comment = Comment.create!(
|
|
13
|
+
:post => @post, :author_name => "Test Commenter", :author_email => "commenter@example.com",
|
|
14
|
+
:spam => true
|
|
15
|
+
)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it "should not include comments marked as spam in the without_spam named scope" do
|
|
19
|
+
Comment.without_spam.should_not include(@comment)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
you can just do this:
|
|
24
|
+
|
|
25
|
+
describe Comment do
|
|
26
|
+
before do
|
|
27
|
+
@comment = Comment.make(:spam => true)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it "should not include comments marked as spam in the without_spam named scope" do
|
|
31
|
+
Comment.without_spam.should_not include(@comment)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
Machinist generates data for the fields you don't care about, and constructs any necessary associated objects.
|
|
36
|
+
|
|
37
|
+
You tell Machinist how to do this with blueprints:
|
|
38
|
+
|
|
39
|
+
require 'faker'
|
|
40
|
+
|
|
41
|
+
Sham.name { Faker::Name.name }
|
|
42
|
+
Sham.email { Faker::Internet.email }
|
|
43
|
+
Sham.title { Faker::Lorem.sentence }
|
|
44
|
+
Sham.body { Faker::Lorem.paragraph }
|
|
45
|
+
|
|
46
|
+
User.blueprint do
|
|
47
|
+
name { Sham.name }
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
Post.blueprint do
|
|
51
|
+
title { Sham.title }
|
|
52
|
+
author { User.make }
|
|
53
|
+
body { Sham.body }
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
Comment.blueprint do
|
|
57
|
+
post
|
|
58
|
+
author_name { Sham.name }
|
|
59
|
+
author_email { Sham.email }
|
|
60
|
+
body { Sham.body }
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
Installation
|
|
65
|
+
------------
|
|
66
|
+
|
|
67
|
+
Install the plugin:
|
|
68
|
+
|
|
69
|
+
./script/plugin install git://github.com/notahat/machinist.git
|
|
70
|
+
|
|
71
|
+
Create a blueprints.rb in your test (or spec) directory, and require it in your test\_helper.rb (or spec\_helper.rb):
|
|
72
|
+
|
|
73
|
+
require File.expand_path(File.dirname(__FILE__) + "/blueprints")
|
|
74
|
+
|
|
75
|
+
Set Sham to reset before each test. In the `class Test::Unit::TestCase` block in your test\_helper.rb, add:
|
|
76
|
+
|
|
77
|
+
setup { Sham.reset }
|
|
78
|
+
|
|
79
|
+
or, if you're on RSpec, in the `Spec::Runner.configure` block in your spec\_helper.rb, add:
|
|
80
|
+
|
|
81
|
+
config.before(:each) { Sham.reset }
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
Sham - Generating Attribute Values
|
|
85
|
+
----------------------------------
|
|
86
|
+
|
|
87
|
+
Sham lets you generate random but repeatable unique attributes values.
|
|
88
|
+
|
|
89
|
+
For example, you could define a way to generate random names as:
|
|
90
|
+
|
|
91
|
+
Sham.name { (1..10).map { ('a'..'z').to_a.rand } }
|
|
92
|
+
|
|
93
|
+
Then, to generate a name, call:
|
|
94
|
+
|
|
95
|
+
Sham.name
|
|
96
|
+
|
|
97
|
+
So why not just define a method? Sham ensures two things for you:
|
|
98
|
+
|
|
99
|
+
1. You get the same sequence of values each time your test is run
|
|
100
|
+
2. You don't get any duplicate values
|
|
101
|
+
|
|
102
|
+
Sham works very well with the excellent [Faker gem](http://faker.rubyforge.org/) by Benjamin Curtis. Using this, a much nicer way to generate names is:
|
|
103
|
+
|
|
104
|
+
Sham.name { Faker::Name.name }
|
|
105
|
+
|
|
106
|
+
Sham also supports generating numbered sequences if you prefer.
|
|
107
|
+
|
|
108
|
+
Sham.name {|index| "Name #{index}" }
|
|
109
|
+
|
|
110
|
+
If you want to allow duplicate values for a sham, you can pass the `:unique` option:
|
|
111
|
+
|
|
112
|
+
Sham.coin_toss(:unique => false) { rand(2) == 0 : 'heads' : 'tails' }
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
Blueprints - Generating ActiveRecord Objects
|
|
116
|
+
--------------------------------------------
|
|
117
|
+
|
|
118
|
+
A blueprint describes how to build a generic object for an ActiveRecord model. The idea is that you let the blueprint take care of constructing all the objects and attributes that you don't care about in your test, leaving you to focus on the just the things that you're testing.
|
|
119
|
+
|
|
120
|
+
A simple blueprint might look like this:
|
|
121
|
+
|
|
122
|
+
Comment.blueprint do
|
|
123
|
+
body "A comment!"
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
Once that's defined, you can construct a comment from this blueprint with:
|
|
127
|
+
|
|
128
|
+
Comment.make
|
|
129
|
+
|
|
130
|
+
Machinist calls `save!` on your ActiveRecord model to create the comment, so it will throw an exception if the blueprint doesn't pass your validations. It also calls `reload` after the `save!`.
|
|
131
|
+
|
|
132
|
+
You can override values defined in the blueprint by passing parameters to make:
|
|
133
|
+
|
|
134
|
+
Comment.make(:body => "A different comment!")
|
|
135
|
+
|
|
136
|
+
Rather than providing a constant value for an attribute, you can use Sham to generate a value for each new object:
|
|
137
|
+
|
|
138
|
+
Sham.body { Faker::Lorem.paragraph }
|
|
139
|
+
Comment.blueprint do
|
|
140
|
+
body { Sham.body }
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
Notice the curly braces around `Sham.body`. If you call `Comment.make` with your own body attribute, this block will not be executed.
|
|
144
|
+
|
|
145
|
+
You can use this same syntax to generate associated objects:
|
|
146
|
+
|
|
147
|
+
Comment.blueprint do
|
|
148
|
+
post { Post.make }
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
If the associated model has the same name as the field, you can abbreviate this to:
|
|
152
|
+
|
|
153
|
+
Comment.blueprint do
|
|
154
|
+
post
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
You can refer to already assigned attributes when constructing a new attribute:
|
|
158
|
+
|
|
159
|
+
Comment.blueprint do
|
|
160
|
+
post
|
|
161
|
+
body { "Comment on " + post.name }
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
You can also override associated objects when calling make:
|
|
165
|
+
|
|
166
|
+
post = Post.make
|
|
167
|
+
3.times { Comment.make(:post => post) }
|
|
168
|
+
|
|
169
|
+
It's common to need to construct an object with particular attributes, or a particular object graph, in a number of tests. The best way to abstract out the construction is to put something like this in your blueprints.rb:
|
|
170
|
+
|
|
171
|
+
class Post
|
|
172
|
+
def self.make_with_comments(attributes = {})
|
|
173
|
+
Post.make(attributes) do |post|
|
|
174
|
+
3.times { Comment.make(:post => post) }
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
Note that make can take a block, into which it will pass the newly constructed object.
|
|
180
|
+
|
|
181
|
+
If you want to generate an object graph without saving to the database, use make\_unsaved:
|
|
182
|
+
|
|
183
|
+
Comment.make_unsaved
|
|
184
|
+
|
|
185
|
+
This will generate both the Comment and the associated Post without saving either.
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
Credits
|
|
189
|
+
-------
|
|
190
|
+
|
|
191
|
+
Written by [Pete Yandell](http://notahat.com/).
|
|
192
|
+
|
|
193
|
+
Contributors:
|
|
194
|
+
|
|
195
|
+
- [Roland Swingler](http://github.com/knaveofdiamonds)
|
|
196
|
+
|
|
197
|
+
Thanks to Thoughtbot's [Factory Girl](http://github.com/thoughtbot/factory_girl/tree/master). Machinist was written because I loved the idea behind Factory Girl, but I thought the philosophy wasn't quite right, and I hated the syntax.
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
Copyright (c) 2008 Peter Yandell, released under the MIT license
|
data/Rakefile
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require 'rake'
|
|
2
|
+
require 'rake/gempackagetask'
|
|
3
|
+
require 'rake/clean'
|
|
4
|
+
require 'spec/rake/spectask'
|
|
5
|
+
|
|
6
|
+
desc 'Default: run specs.'
|
|
7
|
+
task :default => :spec
|
|
8
|
+
|
|
9
|
+
desc 'Run all the specs for the machinist plugin.'
|
|
10
|
+
Spec::Rake::SpecTask.new do |t|
|
|
11
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
|
12
|
+
t.rcov = false
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
spec = eval(File.read(File.join(File.dirname(__FILE__), 'machinist.gemspec')))
|
|
16
|
+
|
|
17
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
|
18
|
+
pkg.need_zip = true
|
|
19
|
+
pkg.need_tar = true
|
|
20
|
+
end
|
data/init.rb
ADDED
data/lib/machinist.rb
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
require 'active_support'
|
|
2
|
+
require 'active_record'
|
|
3
|
+
|
|
4
|
+
module Machinist
|
|
5
|
+
def self.with_save_nerfed
|
|
6
|
+
begin
|
|
7
|
+
@@nerfed = true
|
|
8
|
+
yield
|
|
9
|
+
ensure
|
|
10
|
+
@@nerfed = false
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
@@nerfed = false
|
|
15
|
+
def self.nerfed?
|
|
16
|
+
@@nerfed
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
module ActiveRecordExtensions
|
|
20
|
+
def self.included(base)
|
|
21
|
+
base.extend(ClassMethods)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
module ClassMethods
|
|
25
|
+
def blueprint(&blueprint)
|
|
26
|
+
@blueprint = blueprint
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def make(attributes = {})
|
|
30
|
+
raise "No blueprint for class #{self}" if @blueprint.nil?
|
|
31
|
+
lathe = Lathe.new(self.new, attributes)
|
|
32
|
+
lathe.instance_eval(&@blueprint)
|
|
33
|
+
unless Machinist.nerfed?
|
|
34
|
+
lathe.object.save!
|
|
35
|
+
lathe.object.reload
|
|
36
|
+
end
|
|
37
|
+
returning(lathe.object) do |object|
|
|
38
|
+
yield object if block_given?
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def make_unsaved(attributes = {})
|
|
43
|
+
returning(Machinist.with_save_nerfed { make(attributes) }) do |object|
|
|
44
|
+
yield object if block_given?
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
class Lathe
|
|
51
|
+
def initialize(object, attributes)
|
|
52
|
+
@object = object
|
|
53
|
+
@assigned_attributes = []
|
|
54
|
+
attributes.each do |key, value|
|
|
55
|
+
@object.send("#{key}=", value)
|
|
56
|
+
@assigned_attributes << key
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
attr_reader :object
|
|
61
|
+
|
|
62
|
+
def method_missing(symbol, *args, &block)
|
|
63
|
+
if @assigned_attributes.include?(symbol)
|
|
64
|
+
@object.send(symbol)
|
|
65
|
+
else
|
|
66
|
+
value = if block
|
|
67
|
+
block.call
|
|
68
|
+
elsif args.first.is_a?(Hash) || args.empty?
|
|
69
|
+
symbol.to_s.camelize.constantize.make(args.first || {})
|
|
70
|
+
else
|
|
71
|
+
args.first
|
|
72
|
+
end
|
|
73
|
+
@object.send("#{symbol}=", value)
|
|
74
|
+
@assigned_attributes << symbol
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
if RAILS_ENV == 'test'
|
|
81
|
+
require 'sham'
|
|
82
|
+
|
|
83
|
+
class ActiveRecord::Base
|
|
84
|
+
include Machinist::ActiveRecordExtensions
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
|
data/lib/sham.rb
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
require 'active_support'
|
|
2
|
+
|
|
3
|
+
class Sham
|
|
4
|
+
@@shams = {}
|
|
5
|
+
|
|
6
|
+
# Over-ride module's built-in name method, so we can re-use it for
|
|
7
|
+
# generating names. This is a bit of a no-no, but we get away with
|
|
8
|
+
# it in this context.
|
|
9
|
+
def self.name(*args, &block)
|
|
10
|
+
method_missing(:name, *args, &block)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.method_missing(symbol, *args, &block)
|
|
14
|
+
if block_given?
|
|
15
|
+
@@shams[symbol] = Sham.new(symbol, args.pop || {}, &block)
|
|
16
|
+
else
|
|
17
|
+
sham = @@shams[symbol]
|
|
18
|
+
raise "No sham defined for #{symbol}" if sham.nil?
|
|
19
|
+
sham.fetch_value
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def self.reset
|
|
24
|
+
@@shams.values.each(&:reset)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def initialize(name, options = {}, &block)
|
|
28
|
+
@name = name
|
|
29
|
+
@generator = block
|
|
30
|
+
@offset = 0
|
|
31
|
+
@unique = options.has_key?(:unique) ? options[:unique] : true
|
|
32
|
+
generate_values(12)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def reset
|
|
36
|
+
@offset = 0
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def fetch_value
|
|
40
|
+
# Generate more values if we need them.
|
|
41
|
+
if @offset >= @values.length
|
|
42
|
+
generate_values(2 * @values.length)
|
|
43
|
+
raise "Can't generate more unique values for Sham.#{@name}" if @offset >= @values.length
|
|
44
|
+
end
|
|
45
|
+
returning @values[@offset] do
|
|
46
|
+
@offset += 1
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
private
|
|
51
|
+
|
|
52
|
+
def generate_values(count)
|
|
53
|
+
@values = seeded { (1..count).map(&@generator) }
|
|
54
|
+
@values.uniq! if @unique
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def seeded
|
|
58
|
+
begin
|
|
59
|
+
srand(1)
|
|
60
|
+
yield
|
|
61
|
+
ensure
|
|
62
|
+
srand
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
data/machinist.gemspec
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MACHINIST_SPEC = Gem::Specification.new do |s|
|
|
2
|
+
s.name = "machinist"
|
|
3
|
+
s.author = "notahat"
|
|
4
|
+
s.homepage = "http://github.com/notahat/machinist/tree"
|
|
5
|
+
s.version = "1.0.0"
|
|
6
|
+
s.date = "2008-11-22"
|
|
7
|
+
s.summary = "Im in ur specs machining your fixtures"
|
|
8
|
+
s.has_rdoc = true
|
|
9
|
+
s.files = [
|
|
10
|
+
".autotest",
|
|
11
|
+
".gitignore",
|
|
12
|
+
"MIT-LICENSE",
|
|
13
|
+
"README.markdown",
|
|
14
|
+
"Rakefile",
|
|
15
|
+
"machinist.gemspec",
|
|
16
|
+
"init.rb",
|
|
17
|
+
"lib/machinist.rb",
|
|
18
|
+
"lib/sham.rb"
|
|
19
|
+
]
|
|
20
|
+
s.test_files = ["spec/machinist_spec.rb", "spec/sham_spec.rb", "spec/spec_helper.rb"]
|
|
21
|
+
s.add_dependency "activesupport"
|
|
22
|
+
end
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
|
2
|
+
require 'machinist'
|
|
3
|
+
|
|
4
|
+
class Base
|
|
5
|
+
include Machinist::ActiveRecordExtensions
|
|
6
|
+
|
|
7
|
+
def save!; @saved = true; end
|
|
8
|
+
def reload; @reloaded = true; self; end
|
|
9
|
+
|
|
10
|
+
def saved?; @saved; end
|
|
11
|
+
def reloaded?; @reloaded; end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
class Post < Base
|
|
15
|
+
attr_accessor :title
|
|
16
|
+
attr_accessor :body
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
class Comment < Base
|
|
20
|
+
attr_accessor :post
|
|
21
|
+
attr_accessor :author
|
|
22
|
+
attr_accessor :body
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
Post.blueprint do
|
|
26
|
+
title "An Example Post"
|
|
27
|
+
body { "The quick brown fox." }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
Comment.blueprint do
|
|
31
|
+
post
|
|
32
|
+
author "Fred Bloggs"
|
|
33
|
+
body "Just a comment."
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
describe Machinist do
|
|
37
|
+
describe "make methd" do
|
|
38
|
+
before do
|
|
39
|
+
@post = Post.make
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it "should set a field from a constant in the blueprint" do
|
|
43
|
+
@post.title.should == "An Example Post"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it "should set a field from a block in the blueprint" do
|
|
47
|
+
@post.body.should == "The quick brown fox."
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it "should save the object" do
|
|
51
|
+
@post.should be_saved
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it "should reload the object" do
|
|
55
|
+
@post.should be_reloaded
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
describe "make_unsaved method" do
|
|
60
|
+
before do
|
|
61
|
+
@comment = Comment.make_unsaved
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it "should not save the object" do
|
|
65
|
+
@comment.should_not be_saved
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it "should not reload the object" do
|
|
69
|
+
@comment.should_not be_reloaded
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it "should not save associated objects" do
|
|
73
|
+
@comment.post.should_not be_saved
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it "should not reload associated objects" do
|
|
77
|
+
@comment.post.should_not be_reloaded
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
it "should override a field from the blueprint with a parameter" do
|
|
82
|
+
post = Post.make(:title => "A Different Title")
|
|
83
|
+
post.title.should == "A Different Title"
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
it "should create an associated object for a field with no arguments in the blueprint" do
|
|
87
|
+
comment = Comment.make
|
|
88
|
+
comment.post.should_not be_nil
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
it "should allow passing a block to make" do
|
|
92
|
+
comments = nil
|
|
93
|
+
post = Post.make do |post|
|
|
94
|
+
comments = (1..3).map { Comment.make(:post => post) }
|
|
95
|
+
end
|
|
96
|
+
post.should be_an_instance_of(Post)
|
|
97
|
+
comments.should_not be_nil
|
|
98
|
+
comments.each {|comment| comment.post.should == post }
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
it "should not nerf make within a block passed to make_unsaved" do
|
|
102
|
+
comment = nil
|
|
103
|
+
post = Post.make_unsaved do |post|
|
|
104
|
+
comment = Comment.make(:post => post)
|
|
105
|
+
end
|
|
106
|
+
post.should_not be_saved
|
|
107
|
+
comment.should be_saved
|
|
108
|
+
comment.post.should == post
|
|
109
|
+
end
|
|
110
|
+
end
|
data/spec/sham_spec.rb
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
|
2
|
+
require 'sham'
|
|
3
|
+
|
|
4
|
+
Sham.random { rand }
|
|
5
|
+
Sham.half_index {|index| index/2 }
|
|
6
|
+
Sham.coin_toss(:unique => false) {|index| index % 2 == 1 ? 'heads' : 'tails' }
|
|
7
|
+
Sham.limited {|index| index%10 }
|
|
8
|
+
Sham.index {|index| index }
|
|
9
|
+
Sham.name {|index| index }
|
|
10
|
+
|
|
11
|
+
describe Sham do
|
|
12
|
+
it "should ensure generated values are unique" do
|
|
13
|
+
values = (1..10).map { Sham.half_index }
|
|
14
|
+
values.should == (0..9).to_a
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "should generate non-unique values when asked" do
|
|
18
|
+
values = (1..4).map { Sham.coin_toss }
|
|
19
|
+
values.should == ['heads', 'tails', 'heads', 'tails']
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "should generate more than a dozen values" do
|
|
23
|
+
values = (1..25).map { Sham.index }
|
|
24
|
+
values.should == (1..25).to_a
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "should generate the same sequence of values after a reset" do
|
|
28
|
+
values1 = (1..10).map { Sham.random }
|
|
29
|
+
Sham.reset
|
|
30
|
+
values2 = (1..10).map { Sham.random }
|
|
31
|
+
values2.should == values1
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "should die when it runs out of unique values" do
|
|
35
|
+
lambda {
|
|
36
|
+
(1..100).map { Sham.limited }
|
|
37
|
+
}.should raise_error(RuntimeError)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it "should allow over-riding the name method" do
|
|
41
|
+
Sham.name.should == 1
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: elight-machinist
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- notahat
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
|
|
12
|
+
date: 2008-11-22 00:00:00 -08:00
|
|
13
|
+
default_executable:
|
|
14
|
+
dependencies:
|
|
15
|
+
- !ruby/object:Gem::Dependency
|
|
16
|
+
name: activesupport
|
|
17
|
+
version_requirement:
|
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
19
|
+
requirements:
|
|
20
|
+
- - ">="
|
|
21
|
+
- !ruby/object:Gem::Version
|
|
22
|
+
version: "0"
|
|
23
|
+
version:
|
|
24
|
+
description:
|
|
25
|
+
email:
|
|
26
|
+
executables: []
|
|
27
|
+
|
|
28
|
+
extensions: []
|
|
29
|
+
|
|
30
|
+
extra_rdoc_files: []
|
|
31
|
+
|
|
32
|
+
files:
|
|
33
|
+
- .autotest
|
|
34
|
+
- .gitignore
|
|
35
|
+
- MIT-LICENSE
|
|
36
|
+
- README.markdown
|
|
37
|
+
- Rakefile
|
|
38
|
+
- machinist.gemspec
|
|
39
|
+
- init.rb
|
|
40
|
+
- lib/machinist.rb
|
|
41
|
+
- lib/sham.rb
|
|
42
|
+
has_rdoc: true
|
|
43
|
+
homepage: http://github.com/notahat/machinist/tree
|
|
44
|
+
post_install_message:
|
|
45
|
+
rdoc_options: []
|
|
46
|
+
|
|
47
|
+
require_paths:
|
|
48
|
+
- lib
|
|
49
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - ">="
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: "0"
|
|
54
|
+
version:
|
|
55
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
56
|
+
requirements:
|
|
57
|
+
- - ">="
|
|
58
|
+
- !ruby/object:Gem::Version
|
|
59
|
+
version: "0"
|
|
60
|
+
version:
|
|
61
|
+
requirements: []
|
|
62
|
+
|
|
63
|
+
rubyforge_project:
|
|
64
|
+
rubygems_version: 1.2.0
|
|
65
|
+
signing_key:
|
|
66
|
+
specification_version: 2
|
|
67
|
+
summary: Im in ur specs machining your fixtures
|
|
68
|
+
test_files:
|
|
69
|
+
- spec/machinist_spec.rb
|
|
70
|
+
- spec/sham_spec.rb
|
|
71
|
+
- spec/spec_helper.rb
|