cranky 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/README.rdoc +185 -0
  2. data/lib/cranky.rb +1 -1
  3. metadata +3 -3
@@ -0,0 +1,185 @@
1
+ = Cranky
2
+
3
+ Cranky is a fixtures replacement inspired by the excellent Factory Girl, but simpler and with less magic going on.
4
+
5
+ In short use this if you want to naturally create factory methods that you feel 100% in control of and without a block in sight.
6
+
7
+ == Install
8
+
9
+ First install the gem...
10
+
11
+ gem install cranky
12
+
13
+ Or for rails stick it in your environment.rb or Gemfile as normal...
14
+
15
+ # environment.rb
16
+ config.gem "cranky"
17
+
18
+ # Gemfile
19
+ gem "cranky"
20
+
21
+ Then in your spec_helper.rb ...
22
+
23
+ # spec_helper.rb
24
+ require "cranky"
25
+ require "factories/my_factories"
26
+
27
+ The above assumes that you have created your factory methods in a file called my_factories.rb in the spec/factories directory.
28
+ You can create as many different factory files as you want, just require them in the same way.
29
+
30
+ == Usage Syntax
31
+
32
+ Cranky steals its core syntax from Factory Girl...
33
+
34
+ Factory.build(:user) # Build a user instance without saving
35
+ Factory.create(:user) # Build and save a user instance
36
+ Factory.build(:user, :name => "Ian") # Override a default attribute value
37
+
38
+ == Define Your Factories
39
+
40
+ This is where Cranky really shines, if you can create Ruby methods you can pretty much create your factories without having to refer to the syntax documentation ever again.
41
+
42
+ The only rules are:
43
+
44
+ 1. Your factory must use the +Cranky+ class
45
+ 2. Your factory method must return the object you wanted to create
46
+ 3. You can access the overrides passed in via options[:key] (not really a rule!)
47
+
48
+ So for example to create a simple user factory...
49
+
50
+ # factories/my_factories.rb
51
+ class Cranky
52
+
53
+ # Simple factory method to create a user instance, you would call this via Factory.build(:user)
54
+ def user
55
+ u = User.new
56
+ u.name = options[:name] || "Jimmy" # Use the passed in name if present, or the default
57
+ u
58
+ end
59
+
60
+ end
61
+
62
+ Now of course you are working in straight Ruby here, so you can extend this any way you want as long as you follow the above rules.
63
+
64
+ For example here it is with the capability to automatically create a default account association...
65
+
66
+ # factories/my_factories.rb
67
+ class Cranky
68
+
69
+ # Return the default account if it already exists, or call the account factory to make one
70
+ def default_account
71
+ @default_account ||= create(:account)
72
+ end
73
+
74
+ def user
75
+ u = User.new
76
+ u.name = options[:name] || "Jimmy"
77
+ u.account = default_account
78
+ u
79
+ end
80
+
81
+ ... # Create the account factory in the same way
82
+
83
+ end
84
+
85
+ Quite often the database will be cleared between tests however the instance variable in the factory will not necessarily be reset which could lead to problems if the tests check for the associated record in the database.
86
+ So a nice tip is to implement default associations like this (assuming you're using Rails)...
87
+
88
+ # Return the default account if it already exists, or call the account factory to make one
89
+ def default_account
90
+ # If the default account exists, but has been cleared from the database...
91
+ if @default_account && !Account.exists?(@default_account.id)
92
+ @default_account = nil
93
+ end
94
+ @default_account ||= create(:account)
95
+ end
96
+
97
+ == Helpers
98
+
99
+ Of course its nice to get some help...
100
+
101
+ === Define
102
+
103
+ Most of your factories are likely to simply define a list of mimimum attribute values, use the define helper for this.
104
+
105
+ # The user factory re-written using the define helper
106
+ def user
107
+ define :name => "Jimmy",
108
+ :account => default_account
109
+ end
110
+
111
+ Note that you don't have to worry about handling the overrides here, they will be applied automatically if present, just define the defaults.
112
+
113
+ The best thing about this is that there are no pesky blocks to worry about. The define argument is just a regular hash, you have complete freedom to choose how you generate the values to be passed into it.
114
+
115
+ The define method will return the object, you can grab this for additional manipulation as you would expect...
116
+
117
+ def user
118
+ u = define :name => "Jimmy",
119
+ :account => default_account
120
+ u.do_something
121
+ u # Remember to return it at the end
122
+ end
123
+
124
+ If for any reason you want to have your factory method named differently from the model it instantiates you can pass in a :class attribute to the define method...
125
+
126
+ # Called via Factory.create(:jimmy)
127
+ def jimmy
128
+ define :class => :user,
129
+ :name => "Jimmy",
130
+ :account => default_account
131
+ end
132
+
133
+ === Inherit
134
+
135
+ You can inherit from other factories via the inherit method. So for example to create an admin user you might do...
136
+
137
+ # Called via Factory.create(:admin)
138
+ def admin
139
+ inherit(:user, :account => admin_account) # Pass in any attribute overrides you want
140
+ end
141
+
142
+ === Unique Attributes (n)
143
+
144
+ If you want to generate unique attributes you can call the n method which will automatically increment the next time it is called.
145
+ For example to give each user a unique name...
146
+
147
+ def user
148
+ define :name => "Jimmy#{n}",
149
+ :account => default_account
150
+ end
151
+
152
+ Note that every time n is called it will increment, it does not implement a unique counter per attribute.
153
+
154
+ === Reset
155
+
156
+ Reset all instance variables in the factory. This may be useful to run between tests depending on your factory logic...
157
+
158
+ before(:each) do
159
+ Factory.reset
160
+ end
161
+
162
+ === Debug
163
+
164
+ Sometimes it is useful to be warned that your factory is generating invalid instances (although quite often your tests may intentionally generate invalid instances, so use this with care). By turning on debug the Factory will raise an error if the generated instance is invalid...
165
+
166
+ Factory.debug = true
167
+
168
+ Note that this relies on the instance having a valid? method, so in practice this may only work with Rails.
169
+
170
+ === Attributes For
171
+
172
+ Returns the attributes that would be applied for a given factory...
173
+
174
+ valid_attributes = Factory.attributes_for(:user)
175
+
176
+ Requires that the instance has an attributes method, so again may only work under Rails.
177
+
178
+ == Additional Features
179
+
180
+ Want any? Feel free to let me know.
181
+
182
+ == Thanks
183
+
184
+ Cranky was inspired by factory_girl[http://github.com/thoughtbot/factory_girl] and miniskirt[http://gist.github.com/273579].
185
+ Thanks to both.
@@ -1,6 +1,6 @@
1
1
  class Cranky
2
2
 
3
- VERSION = "0.0.1"
3
+ VERSION = "0.0.2"
4
4
 
5
5
  # Dir.glob("#{File.expand_path(File.dirname(__FILE__))}/*.rb").each do |file|
6
6
  # require file
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 1
9
- version: 0.0.1
8
+ - 2
9
+ version: 0.0.2
10
10
  platform: ruby
11
11
  authors:
12
12
  - Stephen McGinty
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-05-22 00:00:00 -05:00
17
+ date: 2010-05-23 00:00:00 -05:00
18
18
  default_executable:
19
19
  dependencies: []
20
20