machinist 2.0.0.beta2 → 2.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/.gitignore CHANGED
@@ -1,6 +1,7 @@
1
- .bundle
2
1
  .DS_Store
3
- coverage
4
- doc
5
- pkg
6
- tags
2
+ /.bundle
3
+ /.rvmrc
4
+ /coverage
5
+ /doc
6
+ /pkg
7
+ /tags
data/Gemfile CHANGED
@@ -1,8 +1,2 @@
1
- source :gemcutter
2
-
3
- gem "activerecord"
4
- gem "mysql"
5
- gem "rake"
6
- gem "rcov"
7
- gem "rspec", ">= 2.0.0.beta.12"
8
- gem "jeweler"
1
+ source "http://rubygems.org"
2
+ gemspec
@@ -0,0 +1,47 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ machinist (2.0.0.beta2)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ activemodel (3.0.9)
10
+ activesupport (= 3.0.9)
11
+ builder (~> 2.1.2)
12
+ i18n (~> 0.5.0)
13
+ activerecord (3.0.9)
14
+ activemodel (= 3.0.9)
15
+ activesupport (= 3.0.9)
16
+ arel (~> 2.0.10)
17
+ tzinfo (~> 0.3.23)
18
+ activesupport (3.0.9)
19
+ arel (2.0.10)
20
+ builder (2.1.2)
21
+ diff-lcs (1.1.2)
22
+ i18n (0.5.0)
23
+ mysql (2.8.1)
24
+ rake (0.9.2)
25
+ rcov (0.9.9)
26
+ rdoc (3.6.1)
27
+ rspec (2.6.0)
28
+ rspec-core (~> 2.6.0)
29
+ rspec-expectations (~> 2.6.0)
30
+ rspec-mocks (~> 2.6.0)
31
+ rspec-core (2.6.4)
32
+ rspec-expectations (2.6.0)
33
+ diff-lcs (~> 1.1.2)
34
+ rspec-mocks (2.6.0)
35
+ tzinfo (0.3.28)
36
+
37
+ PLATFORMS
38
+ ruby
39
+
40
+ DEPENDENCIES
41
+ activerecord
42
+ machinist!
43
+ mysql
44
+ rake
45
+ rcov
46
+ rdoc
47
+ rspec
@@ -2,23 +2,36 @@
2
2
 
3
3
  *Fixtures aren't fun. Machinist is.*
4
4
 
5
- - [Home page](http://github.com/notahat/machinist/tree/machinist2)
6
- - [What's new in Machinist 2](http://wiki.github.com/notahat/machinist/machinist-2)
7
- - [Installation](http://wiki.github.com/notahat/machinist/installation)
8
- - [Documentation](http://wiki.github.com/notahat/machinist/getting-started)
9
- - [Google group](http://groups.google.com/group/machinist-users)
10
- - [Issue tracker](http://github.com/notahat/machinist/issues)
5
+ Machinist 2 is **still in beta**!
11
6
 
7
+ If you're using Rails 3, you'll want to give Machinist 2 a go, but be aware
8
+ that the documentation is still patchy.
12
9
 
13
- # Introduction
10
+ That said, have a look at [the
11
+ specs](https://github.com/notahat/machinist/tree/master/spec), starting with
12
+ [the spec for
13
+ Machinable](https://github.com/notahat/machinist/blob/master/spec/machinable_spec.rb).
14
+ No, really, have a look. I wrote this code to be read, and the specs do a
15
+ pretty clean job of documenting what it all does.
14
16
 
15
- Machinist makes it easy to create objects within your tests. It generates data
17
+ If, on the other hand, you want the tried, tested, and well-documented official
18
+ release version of Machinist, [then go with Machinist
19
+ 1](http://github.com/notahat/machinist/tree/1.0-maintenance).
20
+
21
+ - [Home page](http://github.com/notahat/machinist)
22
+ - [Google group](http://groups.google.com/group/machinist-users), for support
23
+ - [Bug tracker](http://github.com/notahat/machinist/issues), for reporting Machinist bugs
24
+
25
+
26
+ ## Introduction
27
+
28
+ Machinist makes it easy to create objects for use in tests. It generates data
16
29
  for the attributes you don't care about, and constructs any necessary
17
- associated objects, leaving you to specify only the attributes you *do* care
18
- about in your tests. For example:
30
+ associated objects, leaving you to specify only the fields you care about in
31
+ your test. For example:
19
32
 
20
- describe Comment do
21
- it "should not include spam in the without_spam scope" do
33
+ describe Comment, "without_spam scope" do
34
+ it "doesn't include spam" do
22
35
  # This will make a Comment, a Post, and a User (the author of the
23
36
  # Post), generate values for all their attributes, and save them:
24
37
  spam = Comment.make!(:spam => true)
@@ -34,7 +47,7 @@ You tell Machinist how to do this with blueprints:
34
47
  User.blueprint do
35
48
  username { "user#{sn}" } # Each user gets a unique serial number.
36
49
  end
37
-
50
+
38
51
  Post.blueprint do
39
52
  author
40
53
  title { "Post #{sn}" }
@@ -43,13 +56,208 @@ You tell Machinist how to do this with blueprints:
43
56
 
44
57
  Comment.blueprint do
45
58
  post
46
- email { "commenter-#{sn}@example.com" }
59
+ email { "commenter#{sn}@example.com" }
47
60
  body { "Lorem ipsum..." }
48
61
  end
49
62
 
50
- Check out the
51
- [documentation](http://wiki.github.com/notahat/machinist/getting-started) for
52
- more info.
63
+
64
+ ## Installation
65
+
66
+ ### Upgrading from Machinist 1
67
+
68
+ See [the wiki](http://wiki.github.com/notahat/machinist/machinist-2).
69
+
70
+ ### Rails 3
71
+
72
+ In your app's `Gemfile`, in the `group :test` section, add:
73
+
74
+ gem 'machinist', '>= 2.0.0.beta2'
75
+
76
+ Then run:
77
+
78
+ bundle
79
+ rails generate machinist:install
80
+
81
+ If you want Machinist to automatically add a blueprint to your blueprints file
82
+ whenever you generate a model, add the following to your `config/application.rb`
83
+ inside the Application class:
84
+
85
+ config.generators do |g|
86
+ g.fixture_replacement :machinist
87
+ end
88
+
89
+ ### Rails 2
90
+
91
+ See [the wiki](http://wiki.github.com/notahat/machinist/rails-2).
92
+
93
+
94
+ ## Usage
95
+
96
+ ### Blueprints
97
+
98
+ A blueprint describes how to generate an object. The blueprint takes care of
99
+ providing attributes that your test doesn't care about, leaving you to focus on
100
+ just the attributes that are important for the test.
101
+
102
+ A simple blueprint might look like this:
103
+
104
+ Post.blueprint do
105
+ title { "A Post" }
106
+ body { "Lorem ipsum..." }
107
+ end
108
+
109
+ You can then construct a Post from this blueprint with:
110
+
111
+ Post.make!
112
+
113
+ When you call `make!`, Machinist calls `Post.new`, then runs through the
114
+ attributes in your blueprint, calling the block for each attribute to generate
115
+ a value. It then saves and reloads the Post. (It throws an exception if the
116
+ Post can't be saved.)
117
+
118
+ You can override values defined in the blueprint by passing a hash to make:
119
+
120
+ Post.make!(:title => "A Specific Title")
121
+
122
+ If you want to generate an object without saving it to the database, replace
123
+ `make!` with `make`.
124
+
125
+
126
+ ### Unique Attributes
127
+
128
+ For attributes that need to be unique, you can call the `sn` method from
129
+ within the attribute block to get a unique serial number for the object.
130
+
131
+ User.blueprint do
132
+ username { "user-#{sn}" }
133
+ end
134
+
135
+
136
+ ### Associations
137
+
138
+ If your object needs associated objects, you can generate them like this:
139
+
140
+ Comment.blueprint do
141
+ post { Post.make }
142
+ end
143
+
144
+ Calling `Comment.make!` will construct a Comment and its associated Post, and
145
+ save both.
146
+
147
+ Machinist is smart enough to look at the association and work out what sort of
148
+ object it needs to create, so you can shorten the above blueprint to:
149
+
150
+ Comment.blueprint do
151
+ post
152
+ end
153
+
154
+ If you want to override the value for post when constructing the comment, you
155
+ can do this:
156
+
157
+ post = Post.make(:title => "A particular title)
158
+ comment = Comment.make(:post => post)
159
+
160
+
161
+ For `has_many` and `has_and_belongs_to_many` associations, you can create
162
+ multiple associated objects like this:
163
+
164
+ Post.blueprint do
165
+ comments(3) # Makes 3 comments.
166
+ end
167
+
168
+
169
+ ### Named Blueprints
170
+
171
+ Named blueprints let you define variations on an object. For example, suppose
172
+ some of your Users are administrators:
173
+
174
+ User.blueprint do
175
+ name { "User #{sn}" }
176
+ email { "user-#{sn}@example.com" }
177
+ end
178
+
179
+ User.blueprint(:admin) do
180
+ name { "Admin User #{sn}" }
181
+ admin { true }
182
+ end
183
+
184
+ Calling:
185
+
186
+ User.make!(:admin)
187
+
188
+ will use the `:admin` blueprint.
189
+
190
+ Named blueprints call the default blueprint to set any attributes not
191
+ specifically provided, so in this example the `email` attribute will still be
192
+ generated even for an admin user.
193
+
194
+ You must define a default blueprint for any class that has a named blueprint,
195
+ even if the default blueprint is empty.
196
+
197
+
198
+ ### Blueprints on Plain Old Ruby Objects
199
+
200
+ Machinist also works with plain old Ruby objects. Let's say you have a class like:
201
+
202
+ class Post
203
+ extend Machinist::Machinable
204
+
205
+ attr_accessor :title
206
+ attr_accessor :body
207
+ end
208
+
209
+ You can blueprint the Post class just like anything else:
210
+
211
+ Post.blueprint do
212
+ title { "A title!" }
213
+ body { "A body!" }
214
+ end
215
+
216
+ And `Post.make` will construct a new Post.
217
+
218
+
219
+ ### Other Tricks
220
+
221
+ You can refer to already assigned attributes when constructing a new attribute:
222
+
223
+ Post.blueprint do
224
+ author { "Author #{sn}" }
225
+ body { "Post by #{object.author}" }
226
+ end
227
+
228
+
229
+ ## Compatibility
230
+
231
+ I've tested this with:
232
+
233
+ Ruby versions: 1.8.7, 1.9.2
234
+ Rails versions: 2.3, 3.0
235
+
236
+ It may well be happy with other versions too, but I'm not promising anything.
237
+ Compatibility patches are welcome.
238
+
239
+
240
+ ## Developing
241
+
242
+ The Machinist specs and source code were written to be read, and I'm pretty
243
+ happy with them. Don't be afraid to have a look under the hood!
244
+
245
+ If you want to submit a patch:
246
+
247
+ - Fork the project.
248
+ - Make your feature addition or bug fix.
249
+ - Add tests for it. This is important so I don't break it in a
250
+ future version unintentionally.
251
+ - Commit, do not mess with rakefile, version, or history.
252
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
253
+ - Send me a pull request. Bonus points for topic branches.
254
+
255
+
256
+ ## Status
257
+
258
+ In active use in a number of large Rails 2 apps.
259
+
260
+ Development has been sporadic, but is picking up again.
53
261
 
54
262
 
55
263
  ## Contributors
@@ -67,11 +275,13 @@ Other contributors include:
67
275
  [Jeremy Grant](http://github.com/jeremygrant),
68
276
  [Jon Guymon](http://github.com/gnarg),
69
277
  [James Healy](http://github.com/yob),
278
+ [Ben Hoskings](http://github.com/benhoskings),
70
279
  [Evan David Light](http://github.com/elight),
71
280
  [Chris Lloyd](http://github.com/chrislloyd),
72
281
  [Adam Meehan](http://github.com/adzap),
73
282
  [Kyle Neath](http://github.com/kneath),
74
283
  [Lawrence Pit](http://github.com/lawrencepit),
284
+ [Xavier Shay](http://github.com/xaviershay),
75
285
  [T.J. Sheehy](http://github.com/tjsheehy),
76
286
  [Roland Swingler](http://github.com/knaveofdiamonds),
77
287
  [Gareth Townsend](http://github.com/quamen),
@@ -82,4 +292,4 @@ Thanks to Thoughtbot's [Factory
82
292
  Girl](http://github.com/thoughtbot/factory_girl/tree/master). Machinist was
83
293
  written because I loved the idea behind Factory Girl, but I thought the
84
294
  philosophy wasn't quite right, and I hated the syntax.
85
-
295
+
data/Rakefile CHANGED
@@ -1,25 +1,10 @@
1
1
  require 'rubygems'
2
2
  require 'bundler'
3
- Bundler.setup
3
+ Bundler::GemHelper.install_tasks
4
4
 
5
5
  require 'rake'
6
6
  require 'rspec/core/rake_task'
7
- require 'rake/rdoctask'
8
-
9
- begin
10
- require 'jeweler'
11
- Jeweler::Tasks.new do |gem|
12
- gem.name = "machinist"
13
- gem.summary = "Fixtures aren't fun. Machinist is."
14
- gem.email = "pete@notahat.com"
15
- gem.homepage = "http://github.com/notahat/machinist"
16
- gem.authors = ["Pete Yandell"]
17
- gem.has_rdoc = false
18
- end
19
- Jeweler::GemcutterTasks.new
20
- rescue LoadError
21
- puts "Jeweler not available. Install it with: gem install jeweler"
22
- end
7
+ require 'rdoc/task'
23
8
 
24
9
 
25
10
  RSpec::Core::RakeTask.new
@@ -30,13 +15,13 @@ RSpec::Core::RakeTask.new(:rcov) do |spec|
30
15
  end
31
16
 
32
17
  desc 'Run the specs.'
33
- task :default => :spec
18
+ task :default => :rcov
34
19
 
35
20
 
36
- Rake::RDocTask.new(:rdoc) do |rdoc|
21
+ RDoc::Task.new(:rdoc) do |rdoc|
37
22
  rdoc.rdoc_dir = 'doc'
38
23
  rdoc.title = 'Machinist'
39
- rdoc.options << '--line-numbers' << '--inline-source'
24
+ rdoc.options << '--line-numbers'
40
25
  rdoc.rdoc_files.include('lib')
41
26
  end
42
27
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.0.0.beta2
1
+ 2.0
@@ -15,24 +15,15 @@ module Machinist
15
15
  end
16
16
 
17
17
  def test_helper
18
- if rspec?
19
- inject_into_file("spec/spec_helper.rb", :after => "Rspec.configure do |config|\n") do
20
- " # Reset the Machinist cache before each spec.\n" +
21
- " config.before(:each) { Machinist.reset_before_test }\n\n"
22
- end
23
- else
18
+ if test_unit?
24
19
  inject_into_file("test/test_helper.rb", :after => "require 'rails/test_help'\n") do
25
20
  "require File.expand_path(File.dirname(__FILE__) + '/blueprints')\n"
26
21
  end
27
- inject_into_class("test/test_helper.rb", ActiveSupport::TestCase) do
28
- " # Reset the Machinist cache before each test.\n" +
29
- " setup { Machinist.reset_before_test }\n\n"
30
- end
31
22
  end
32
23
  end
33
-
24
+
34
25
  def cucumber_support
35
- if options[:cucumber]
26
+ if cucumber?
36
27
  template "machinist.rb.erb", "features/support/machinist.rb"
37
28
  end
38
29
  end
@@ -43,6 +34,13 @@ module Machinist
43
34
  options[:test_framework].to_sym == :rspec
44
35
  end
45
36
 
37
+ def test_unit?
38
+ options[:test_framework].to_sym == :test_unit
39
+ end
40
+
41
+ def cucumber?
42
+ options[:cucumber]
43
+ end
46
44
  end
47
45
  end
48
46
  end