nakajima / fixjour

Word to your object mother.

This URL has Read+Write access

fixjour / README.textile
54c750f5 » nakajima 2008-12-28 started 1 h1. fixjour
2
56bb85e2 » nakajima 2009-02-18 Bumped gemspec for new rele... 3 Another fixture replacement. Gets you some methods (@new_*@, @create_*@ and
4 @valid_*_attributes@) methods and some confidence.
559928f0 » nakajima 2008-12-28 better README, simpler Fixj... 5
25b30872 » nakajima 2009-03-09 Oops, this isn't Markdown 6 "View the RDoc":http://gitrdoc.com/nakajima/fixjour/tree/master (still underway, but has a bit of helpful stuff)
858083a2 » nakajima 2009-03-09 Added link to RDoc 7
5af8b205 » nakajima 2009-06-30 Added link to Working with ... Comment 8 "Recommend Me on the Working with Rails":http://www.workingwithrails.com/person/7973-pat-nakajima
9
807b81fc » patmaddox 2009-05-02 Added development dependenc... 10 h2. Contribute
11
dd5713d3 » nakajima 2009-05-17 Perhaps more anal than whit... Comment 12 Fixjour has some developer dependencies. Install them as shown below,
13 and run rake to make sure the tests pass. Then dive in!
807b81fc » patmaddox 2009-05-02 Added development dependenc... 14
15 <pre>
16 fixjour:$ gem build fixjour.gemspec
17 fixjour:$ sudo gem install --development fixjour
18 fixjour:$ rake
19 Do the tests pass?
20 </pre>
877bf786 » nakajima 2009-01-05 added section on constraints 21 h2. The focus of this project is liberation through constraints.
22984a48 » nakajima 2008-12-29 added comments for nicer rd... 22
23 It uses the bits of object mother systems that worked well for
24 me in the past, and actively discourages the bits that have caused
25 me pain.
26
9bb35205 » nakajima 2009-01-06 meh, header 27 The constraints:
877bf786 » nakajima 2009-01-05 added section on constraints 28
29 h4. One builder per model
30
31 If you try to define a builder more than once per model, you'll
32 run into a @Fixjour::RedundantBuilder@ error. One builder per
33 model decreases confusion.
34
35 h4. No redundant object creation methods
36
37 If you try to define a method that's already been defined by
38 a Fixjour builder, you'll run into a @Fixjour::RedundantBuilder@
39 error. If you find the need to alter the behavior of a builder
40 for a particular set of tests, you should just wrap the creation
41 methods defined by Fixjour, preferably with a name that describes
42 how the new method is different from the Fixjour method.
43
44 h4. Processing the overrides hash is bad
45
46 If you want to mess with the overrides hash that can be passed
47 into any of the creation methods, you must use the @process@
48 method (see below). To enforce this, the @delete@ method is actually
49 private for the overrides hash.
50
fdcfcbcb » nakajima 2008-12-29 for the time being, builder... 51 h2. What it gets you:
fc5d4dd7 » nakajima 2008-12-29 beefed up readme 52
53 With this setup:
54
55 <pre>
56 Fixjour do
2e88fa35 » nakajima 2009-01-08 advertise better builder bl... 57 define_builder(Person) do |klass, overrides|
58 klass.new(:name => 'Pat', :age => 22)
fc5d4dd7 » nakajima 2008-12-29 beefed up readme 59 end
60 end
61
62 include Fixjour
63 </pre>
64
65 You get:
66
e13f3534 » nakajima 2008-12-29 better Textile for the GitHub 67 h3. @new_person(overrides={})@
fc5d4dd7 » nakajima 2008-12-29 beefed up readme 68
69 The @new_person@ method basically just returns the result
70 of your builder block, which should *always return an unsaved
71 instance of the model class*. You can pass it overrides in a
72 hash like so: @new_person(:name => nil)@.
73
e13f3534 » nakajima 2008-12-29 better Textile for the GitHub 74 h3. @create_person(overrides={})@
fc5d4dd7 » nakajima 2008-12-29 beefed up readme 75
76 The @create_person@ method calls @new_person@, passing in any
77 overrides you pass it, calls @save!@ on the result, and returns
78 the saved object.
79
e13f3534 » nakajima 2008-12-29 better Textile for the GitHub 80 h3. @valid_person_attributes(overrides={})@
fc5d4dd7 » nakajima 2008-12-29 beefed up readme 81
82 The @valid_person_attributes@ returns a hash of valid person
83 attributes that are derived from the @new_person@ method, and
84 ideal for things like testing controllers. It can also take
85 attribute override options like so: @valid_person_attributes(:name => nil)@.
86
fdcfcbcb » nakajima 2008-12-29 for the time being, builder... 87 h2. Usage:
fc5d4dd7 » nakajima 2008-12-29 beefed up readme 88
89 You specify builder sets for your ActiveRecord models in a
fdcfcbcb » nakajima 2008-12-29 for the time being, builder... 90 @Fixjour@ block using the @define_builder@ helper, which can
91 be used in one of two ways:
92
93 h3. Using a builder block
94
95 Pass @define_builder@ a model class for which you want a new set
fc5d4dd7 » nakajima 2008-12-29 beefed up readme 96 of creation methods, and a block which returns a new valid
2e88fa35 » nakajima 2009-01-08 advertise better builder bl... 97 model object. The block will be passed two arguments: a proxy
98 object for your class, and an overrides hash. If you call @new@
99 on the class proxy, it will return a new instance of the class,
100 with whatever attributes you specify as defaults. It will also
101 automatically merge any override options in all of the methods
102 generated by Fixjour.
fc5d4dd7 » nakajima 2008-12-29 beefed up readme 103
fdcfcbcb » nakajima 2008-12-29 for the time being, builder... 104 Example:
105
106 <pre>
2e88fa35 » nakajima 2009-01-08 advertise better builder bl... 107 define_builder(Person) do |klass, overrides|
108 klass.new(:name => "Pat", :age => 22)
fdcfcbcb » nakajima 2008-12-29 for the time being, builder... 109 end
110 </pre>
111
98818d7c » Pat Nakajima & Mike Dalessio 2009-01-05 added some docs 112 If you want to process an option in the overrides hash, you can use
113 the @process@ method:
114
115 <pre>
2e88fa35 » nakajima 2009-01-08 advertise better builder bl... 116 define_builder(Person) do |klass, overrides|
98818d7c » Pat Nakajima & Mike Dalessio 2009-01-05 added some docs 117 overrides.process(:child) do |is_child|
118 overrides[:age] = 14 if is_child
119 end
120
2e88fa35 » nakajima 2009-01-08 advertise better builder bl... 121 klass.new(:name => "Pat", :age => 22)
98818d7c » Pat Nakajima & Mike Dalessio 2009-01-05 added some docs 122 end
123
fa1c235d » nakajima 2009-01-05 clarified override processi... 124 # the default
125 person = new_person
126 person.age # => 22
127
128 # using the override
98818d7c » Pat Nakajima & Mike Dalessio 2009-01-05 added some docs 129 person = new_person(:child => true)
130 person.age # => 14
131 </pre>
132
133 In the above example, the @:child@ key will be deleted from the @overrides@
134 hash and made available as the @is_child@ block argument where you can handle
135 things accordingly.
136
c262943b » nakajima 2009-01-05 documented fact that the #d... 137 *Note:* The @delete@ method is private on the overrides hash passed into the
138 builder block. This is meant to encourage you to only use the @process@ method
139 instead. Why? First, because processing the overrides hash is a smell. Deal
140 with it. Second, using the @process@ method provides some indication to readers
141 that you're screwing with the overrides hash, and that's a good thing.
142
be861d7c » nakajima 2009-02-08 Document "protected" helper... 143 h4. @attr_protected@ fields
144
145 If you have fields that cannot be mass-assigned, use the @protected@ helper:
146
147 define_builder(Article) do |klass, overrides|
148 klass.protected :author
149 klass.new :title => "The title", :body => "good", :author => new_user
150 end
151
152 If you use the @protected@ helper to declare @attr_protected@ fields, you can
153 then treat them the same as any other field in your test methods.
154
fc5d4dd7 » nakajima 2008-12-29 beefed up readme 155 h4. With Associations
156
c9d1391c » nakajima 2008-12-29 added some notes to the README 157 To specify an associated object, you can call that object's @new_*@ method:
fc5d4dd7 » nakajima 2008-12-29 beefed up readme 158
159 <pre>
160 Fixjour do
2e88fa35 » nakajima 2009-01-08 advertise better builder bl... 161 define_builder(Post) do |klass, overrides|
162 klass.new(:name => 'a post', :body => 'texted')
fc5d4dd7 » nakajima 2008-12-29 beefed up readme 163 end
164
2e88fa35 » nakajima 2009-01-08 advertise better builder bl... 165 define_builder(Comment) do |klass, overrides|
166 klass.new(:body => 'Oh ok!', :post => new_post)
fc5d4dd7 » nakajima 2008-12-29 beefed up readme 167 end
168 end
169
170 include Fixjour
171
172 new_comment.post.name # => 'a post'
173 </pre>
559928f0 » nakajima 2008-12-28 better README, simpler Fixj... 174
c9d1391c » nakajima 2008-12-29 added some notes to the README 175 Note that it's never a good idea to use a @create_*@ method in a
176 build block.
177
4936e174 » nakajima 2008-12-29 added verification for crea... 178 h3. Verifying your setups
179
180 Fixjour requires more work on your part, so it also includes a way
181 to verify that your creation methods are behaving the way they should.
182 Call @Fixjour.verify!@ to ensure the following things:
183
184 # Creation methods are returning valid objects by default.
185 # @new_*@ methods are returning new records.
186 # @new_*@ and @create_*@ methods return instances of the correct class.
187
ed7ea2e8 » bmabey 2009-02-05 docs - how to use Fixjour i... 188 h3. Recommended usage with RSpec and Cucumber
189
dd5713d3 » nakajima 2009-05-17 Perhaps more anal than whit... Comment 190 If you want to use Fixjour with RSpec and Cucumber you probably want to avoid adding the builder methods onto Object directly. To do this you should first create a file where your Fixjour builder definitions can live. Say for example you put it at spec/fixjour_builders.rb. To take advantage of these builders from RSpec use the following code in your spec_helper.rb:
ed7ea2e8 » bmabey 2009-02-05 docs - how to use Fixjour i... 191
192 <pre>
193 require File.expand_path(File.dirname(__FILE__) + "/fixjour_builders.rb")
194
195 Spec::Runner.configure do |config|
196 config.include(Fixjour) # This will add the builder methods to your ExampleGroups and not pollute Object
197 ...
198 end
199 </pre>
200
feb00942 » olauzon 2009-04-15 Added README instructions f... 201 To use the same builders in Cucumber you simply need to include Fixjour into your World object from features/support/env.rb:
ed7ea2e8 » bmabey 2009-02-05 docs - how to use Fixjour i... 202
203 <pre>
204 require File.expand_path(File.dirname(__FILE__) +'/../../spec/fixjour_builders.rb')
205 World { |world| world.extend(Fixjour) }
206 </pre>
207
dd5713d3 » nakajima 2009-05-17 Perhaps more anal than whit... Comment 208 Be sure to do this after you define your World object. So, if you are using Rails you should include Fixjour after you require 'cucumber/rails/world'.
ed7ea2e8 » bmabey 2009-02-05 docs - how to use Fixjour i... 209
feb00942 » olauzon 2009-04-15 Added README instructions f... 210 In *Cucumber version 0.2.3.2 and later* you need to pass in a module to the World method to extend it:
211
212 <pre>
213 require File.expand_path(File.dirname(__FILE__) +'/../../spec/fixjour_builders.rb')
214 World(Fixjour)
215 </pre>
216
217 (See the Cucumber::StepMother#World RDoc or "http://wiki.github.com/aslakhellesoy/cucumber/a-whole-new-world":http://wiki.github.com/aslakhellesoy/cucumber/a-whole-new-world.)
218
c823c9e0 » nakajima 2009-02-10 Added list of contributors 219 h4. Contributors
220
221 * "Pat Maddox":http://github.com/pat-maddox - Sparked the original idea and fixed my bugs
222 * "Ben Mabey":http://github.com/bmabey - Added docs and fixed my bugs
223 * "Aaron Quint":http://github.com/quirkey - Pointed out valid attrs problem and fixed my bugs
224
527c21c0 » nakajima 2008-12-29 added TODO and link to the ... 225 h4. TODO
226
2e1095fc » nakajima 2009-01-30 added DangerousBuilder veri... 227 * There should be a @Builder@ class.
527c21c0 » nakajima 2008-12-29 added TODO and link to the ... 228
b9591c60 » nakajima 2009-02-22 Added link to mailing list. 229 h4. "Join the mailing list.":http://groups.google.com/group/fixjour
527c21c0 » nakajima 2008-12-29 added TODO and link to the ... 230
85c401f8 » nakajima 2008-12-29 added some alternatives 231 I've talked to smart people who like these instead:
232
233 * "fixturereplacement":http://github.com/smtlaissezfaire/fixturereplacement/tree/master
234 * "factory girl":http://github.com/thoughtbot/factory_girl/tree
235
ed7ea2e8 » bmabey 2009-02-05 docs - how to use Fixjour i... 236 (c) Copyright 2008 Pat Nakajima, released under MIT License.