machinist 2.0.0.beta2 → 2.0

Sign up to get free protection for your applications and to get access to all the features.
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