pickle 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -137,30 +137,51 @@ describe Pickle::Email do
137
137
  end
138
138
 
139
139
  describe "following links in emails" do
140
+ let(:body) { 'some text <a href="http://example.com/page">example page</a> more text' }
141
+
140
142
  before do
141
143
  allow(self).to receive(:open_in_browser)
142
- allow(@email1).to receive(:body).and_return('some text <a href="http://example.com/page">example page</a> more text')
143
144
  end
144
145
 
145
- it "should find a link for http://example.com/page" do
146
- expect(self).to receive(:visit).with('http://example.com/page')
147
- visit_in_email(@email1, 'http://example.com/page')
148
- end
146
+ shared_examples_for 'an email with links' do
147
+ it "should find a link for http://example.com/page" do
148
+ expect(self).to receive(:visit).with('http://example.com/page')
149
+ visit_in_email(@email1, 'http://example.com/page')
150
+ end
151
+
152
+ it "should find a link for \"example page\"" do
153
+ expect(self).to receive(:visit).with('http://example.com/page')
154
+ visit_in_email(@email1, 'example page')
155
+ end
156
+
157
+ it "should follow the first link in an email" do
158
+ expect(self).to receive(:visit).with('http://example.com/page')
159
+ click_first_link_in_email(@email1)
160
+ end
149
161
 
150
- it "should find a link for \"example page\"" do
151
- expect(self).to receive(:visit).with('http://example.com/page')
152
- visit_in_email(@email1, 'example page')
162
+ it "should not raise an error when the email body is not a string, but needs to_s [#26]" do
163
+ allow(self).to receive(:visit)
164
+ allow(@email1).to receive(:body).and_return(:a_string_body)
165
+ expect { click_first_link_in_email(@email1) }.not_to raise_error
166
+ end
153
167
  end
154
168
 
155
- it "should follow the first link in an email" do
156
- expect(self).to receive(:visit).with('http://example.com/page')
157
- click_first_link_in_email(@email1)
169
+ describe "non multi-part emails" do
170
+ before do
171
+ allow(@email1).to receive(:multipart?).and_return(false)
172
+ allow(@email1).to receive(:body).and_return(body)
173
+ end
174
+
175
+ it_behaves_like 'an email with links'
158
176
  end
159
-
160
- it "should not raise an error when the email body is not a string, but needs to_s [#26]" do
161
- allow(self).to receive(:visit)
162
- allow(@email1).to receive(:body).and_return(:a_string_body)
163
- expect { click_first_link_in_email(@email1) }.not_to raise_error
177
+
178
+ context "multi-part emails" do
179
+ before do
180
+ allow(@email1).to receive(:multipart?).and_return(true)
181
+ allow(@email1).to receive_message_chain(:html_part, :body).and_return(body)
182
+ end
183
+
184
+ it_behaves_like 'an email with links'
164
185
  end
165
186
  end
166
187
  end
@@ -165,6 +165,22 @@ describe Pickle::Session do
165
165
  end
166
166
  end
167
167
 
168
+ describe "#create_models" do
169
+ before do
170
+ allow(user_factory).to receive(:create).and_return(user)
171
+ end
172
+
173
+ it "should call the factory's create one time for each record" do
174
+ expect(user_factory).to receive(:create).exactly(10).times
175
+ create_models(10, "a user")
176
+ end
177
+
178
+ it "should parse the fields only once across all records" do
179
+ expect(self).to receive(:parse_fields).once
180
+ create_models(10, "a user")
181
+ end
182
+ end
183
+
168
184
  describe "with hash" do
169
185
  it "should call user_factory.create({'foo' => 'bar'})" do
170
186
  expect(user_factory).to receive(:create).with({'foo' => 'bar'})
@@ -271,7 +287,7 @@ describe Pickle::Session do
271
287
 
272
288
  it_should_behave_like "after storing a single user"
273
289
  end
274
-
290
+
275
291
  it "should cope with spaces in the factory name (ie. it should make it canonical)" do
276
292
  allow(pickle_parser).to receive(:canonical).and_return('user')
277
293
  expect(pickle_parser).to receive(:canonical).with('u ser').and_return('user')
@@ -283,11 +299,11 @@ describe Pickle::Session do
283
299
  let(:fred) { double("fred", :class => user_class, :id => 2) }
284
300
  let(:shirl) { double("shirl", :class => user_class, :id => 3) }
285
301
  let(:noname) { double("noname", :class => user_class, :id => 4) }
286
-
302
+
287
303
  if defined? ::FactoryGirl
288
- let(:super_admin_factory) { Pickle::Adapter::FactoryGirl.new(double(:build_class => user_class, :name => :super_admin)) }
304
+ let(:super_admin_factory) { Pickle::Adapter::FactoryGirl.new(double(:build_class => user_class, :name => :super_admin), :super_admin) }
289
305
  else
290
- let(:super_admin_factory) { Pickle::Adapter::FactoryGirl.new(double(:build_class => user_class, :factory_name => :super_admin)) }
306
+ let(:super_admin_factory) { Pickle::Adapter::FactoryGirl.new(double(:build_class => user_class, :factory_name => :super_admin), :super_admin) }
291
307
  end
292
308
 
293
309
  before do
@@ -414,7 +430,7 @@ describe Pickle::Session do
414
430
  let :ar_class do
415
431
  double('ActiveRecord', :column_names => ['user_id', 'user_type'], :const_get => ActiveRecord::Base::PickleAdapter)
416
432
  end
417
-
433
+
418
434
  it "should return {'user_id' => <the user.id>, 'user_type' => <the user.base_class>}" do
419
435
  expect(user.class).to receive(:base_class).and_return(double('User base class', :name => 'UserBase'))
420
436
  expect(convert_models_to_attributes(ar_class, :user => user)).to eq({'user_id' => user.id, 'user_type' => 'UserBase'})
metadata CHANGED
@@ -1,16 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pickle
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ian White
8
8
  - James Le Cuirot
9
- - Niklas Hofer
10
9
  autorequire:
11
10
  bindir: bin
12
11
  cert_chain: []
13
- date: 2014-11-16 00:00:00.000000000 Z
12
+ date: 2015-01-12 00:00:00.000000000 Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: cucumber
@@ -209,7 +208,7 @@ dependencies:
209
208
  - !ruby/object:Gem::Version
210
209
  version: '0'
211
210
  - !ruby/object:Gem::Dependency
212
- name: sqlite3-ruby
211
+ name: sqlite3
213
212
  requirement: !ruby/object:Gem::Requirement
214
213
  requirements:
215
214
  - - ">="
@@ -226,7 +225,6 @@ description: Easy model creation and reference in your cucumber features
226
225
  email:
227
226
  - ian.w.white@gmail.com
228
227
  - chewi@aura-online.co.uk
229
- - niklas+dev@lanpartei.de
230
228
  executables: []
231
229
  extensions: []
232
230
  extra_rdoc_files: []
@@ -238,7 +236,7 @@ files:
238
236
  - Gemfile.lock.development
239
237
  - History.txt
240
238
  - License.txt
241
- - README.rdoc
239
+ - README.md
242
240
  - Rakefile
243
241
  - Rakefile.d/cucumber.rake
244
242
  - Rakefile.d/release.rake
@@ -1,483 +0,0 @@
1
- = pickle
2
-
3
- {<img src="https://travis-ci.org/ianwhite/pickle.svg" alt="Build Status" />}[https://travis-ci.org/ianwhite/pickle]
4
-
5
- Pickle gives you cucumber steps that create your models easily from factory-girl,
6
- machinist, or fabrication. You can also just use ActiveRecord as a factory but it's not as cool.
7
-
8
- Pickle can make use of different ORMs for finding records. Currently ActiveRecord, DataMapper, MongoID adapters are
9
- provided. More adapters welcome!
10
-
11
- References to the models are stored in the current world, not necessarily for the purpose of checking the db
12
- (although you could use it for that), but for enabling easy reference to urls, and for
13
- building complex givens which require a bunch of models collaborating
14
-
15
- == Quickstart
16
-
17
- This is a quickstart guide for rails apps. Firstly, install {cucumber-rails}[http://github.com/aslakhellesoy/cucumber-rails], and its dependencies.
18
- Then do the following:
19
-
20
- === Rails 3:
21
-
22
- Add the gem to your Gemfile:
23
-
24
- gem 'pickle'
25
-
26
- Then install with:
27
-
28
- bundle install
29
-
30
- Discover the options for the generator:
31
-
32
- rails g pickle --help
33
-
34
- Run the generator, e.g:
35
-
36
- rails g pickle --paths --email
37
-
38
- === For Rails 2:
39
-
40
- Add the following to config/environments/cucumber:
41
-
42
- config.gem 'pickle'
43
-
44
- Install the gem with
45
-
46
- rake gems:install RAILS_ENV=cucumber
47
-
48
- Run the generator with:
49
-
50
- script/generate pickle [paths] [email]
51
-
52
- == Resources
53
-
54
- <b>GitHub</b> for code: https://github.com/ianwhite/pickle
55
-
56
- <b>RubyGems</b> for the gem: https://rubygems.org/gems/pickle
57
-
58
- <b>RubyDoc.info</b> for docs: http://www.rubydoc.info/github/ianwhite/pickle
59
-
60
- <b>Google Group</b> for questions: https://groups.google.com/group/pickle-cucumber
61
-
62
- <b>Railscast</b> presentation: http://railscasts.com/episodes/186-pickle-with-cucumber
63
-
64
- <b>Blog articles</b>: {rubyflare: pickle my cucumber}[http://rubyflare.com/2009/10/28/pickle-my-cucumber/]
65
-
66
-
67
- == Using Pickle
68
-
69
- Now have a look at <tt>features/step_definitions/pickle_steps.rb</tt>
70
-
71
- If you want path steps and email steps then just add the 'paths' and/or 'email' options to the generator.
72
- The code/steps will be written to <tt>features/env/paths.rb</tt> and
73
- <tt>features/step_definitions/email_steps.rb</tt> respectively.
74
-
75
- === Using with plain ole Active Record, DataMapper or Mongoid
76
-
77
- Pickle comes with ORM adapters for Active Record, DataMapper and Mongoid.
78
-
79
- If you have a model called 'Post', with required fields 'title', and 'body', then you can now write
80
- steps like this
81
-
82
- Given a post exists with title: "My Post", body: "My body"
83
-
84
- === Using with factory-girl or machinist
85
-
86
- But you're using Machinist or FactoryGirl right?! To leverage all of the factories/blueprints
87
- you've written, you can just do stuff like
88
-
89
- Given a user exists
90
- And another user exists with role: "admin"
91
-
92
- # later
93
- Then a user should exist with name: "Fred"
94
- And that user should be activated # this uses rspec predicate matchers
95
-
96
- ==== Machinist: require your blueprints
97
-
98
- In your <tt>features/support/env.rb</tt> add the following lines at the bottom
99
-
100
- require "#{Rails.root}/spec/blueprints" # or wherever they live
101
-
102
- ==== FactoryGirl: make sure factories are loaded
103
-
104
- In your config/environments/cucumber.rb file, make sure the factory-girl gem is included (unless it's installed as a plugin).
105
-
106
- If that doesn't solve loading issues then require your factories.rb file directly in a file called 'features/support/factory_girl.rb'
107
-
108
- # example features/support/factory_girl.rb
109
- require File.dirname(__FILE__) + '/../../spec/factories'
110
-
111
- === Using with an ORM other than ActiveRecord, DataMapper, or Mongoid
112
-
113
- Pickle can be used with any modelling library provided there is an adapter written for it.
114
-
115
- Adapters are very simple and exist a module or class with the name "PickleAdapter" available to the class. For example
116
-
117
- User.const_get(:PickleAdapter) #=> should return a pickle adapter
118
-
119
- The Active Record and DataMapper ones can be found at
120
- ActiveRecord::Base::PickleAdapter, DataMapper::Resource::PickleAdapter, Mongoid::Document::PickleAdapter respectively.
121
-
122
- See how to implement one by looking at the ones provided in the pickle source in lib/pickle/adapters/*
123
-
124
- === Configuring Pickle
125
-
126
- You can tell pickle to use another factory adapter (see Pickle::Adapter), or
127
- create mappings from english expressions to pickle model names. You can also
128
- override many of the options on the Pickle::Config object if you so choose.
129
-
130
- In: <tt>features/support/pickle.rb</tt>
131
-
132
- require 'pickle/world'
133
-
134
- Pickle.configure do |config|
135
- config.adapters = [:machinist, :active_record, YourOwnAdapterClass]
136
- config.map 'me', 'myself', 'my', 'I', :to => 'user: "me"'
137
- end
138
-
139
- Out of the box pickle looks for machinist, factory-girl, then uses the ORM(s) that you're using to create models.
140
-
141
- If you find that your steps aren't working with your factories, it's probably the case that your factory setup is not being included in your cucumber environment (see comments above regarding machinist and factory-girl).
142
-
143
- == API
144
-
145
- === Steps
146
-
147
- When you run <tt>script/generate pickle</tt> you get the following steps
148
-
149
- ==== Given steps
150
-
151
- "Given <b>a model</b> exists", e.g.
152
-
153
- Given a user exists
154
- Given a user: "fred" exists
155
- Given the user exists
156
-
157
- "Given <b>a model</b> exists with <b>fields</b>", e.g.
158
-
159
- Given a user exists with name: "Fred"
160
- Given a user exists with name: "Fred", activated: false
161
-
162
- This last step could be better expressed by using Machinist/FactoryGirl to create an activated user. Then you can do
163
-
164
- Given an activated user exists with name: "Fred"
165
-
166
- You can refer to other models in the fields
167
-
168
- Given a user exists
169
- And a post exists with author: the user
170
-
171
- Given a person "fred" exists
172
- And a person "ethel" exists
173
- And a fatherhood exists with parent: person "fred", child: person "ethel"
174
-
175
- This last step is given by the default pickle steps, but it would be better written as:
176
-
177
- And "fred" is the father of "ethel"
178
-
179
- It is expected that you'll need to expand upon the default pickle steps to make your features readable. To write the
180
- above step, you could do something like:
181
-
182
- Given /^"(\w+)" is the father of "(\w+)"$/ do |father, child|
183
- Fatherhood.create! :father => model!("person: \"#{father}\""), :child => model!("person: \"#{child}\"")
184
- end
185
-
186
- "Given <b>n models</b> exist", e.g.
187
-
188
- Given 10 users exist
189
-
190
- "Given <b>n models</b> exist with <b>fields</b>", examples:
191
-
192
- Given 10 users exist with activated: false
193
-
194
- "Given the following <b>models</b> exist:", examples:
195
-
196
- Given the following users exist
197
- | name | activated |
198
- | Fred | false |
199
- | Ethel | true |
200
-
201
- ===== Named machinist blueprints
202
-
203
- "Given <b> a <i>named</i> model</b> exists with <b>fields</b>"
204
-
205
- The latest version of pickle supports {named machinist blueprints}[http://github.com/notahat/machinist/commit/d6492e6927a8aa1819926e48b22377171fd20496].
206
-
207
- If you had the following blueprints:
208
-
209
- User.blueprint do
210
- name
211
- email
212
- end
213
-
214
- User.blueprint(:super_admin) do
215
- role { "admin" }
216
- end
217
-
218
- User.blueprint(:activated) do
219
- activated { true }
220
- end
221
-
222
- You could create a user with pickle by simply adding the name of the blueprint before the model:
223
-
224
- Given a super admin user exists
225
- And an activated user exists with name: "Fred"
226
-
227
- This is much nicer than having to set up common configurations in your steps all the time, and far more readable to boot.
228
-
229
-
230
- ==== Then steps
231
-
232
- ===== Asserting existence of models
233
-
234
- "Then <b>a model</b> should exist", e.g.
235
-
236
- Then a user should exist
237
-
238
- "Then <b>a model</b> should exist with <b>fields</b>", e.g.
239
-
240
- Then a user: "fred" should exist with name: "Fred" # we can label the found user for later use
241
-
242
- You can use other models, booleans, numerics, and strings as fields
243
-
244
- Then a person should exist with child: person "ethel"
245
- Then a user should exist with activated: false
246
- Then a user should exist with activated: true, email: "fred@gmail.com"
247
-
248
- "Then <b>n models</b> should exist", e.g.
249
-
250
- Then 10 events should exist
251
-
252
- "Then <b>n models</b> should exist with <b>fields</b>", e.g.
253
-
254
- Then 2 people should exist with father: person "fred"
255
-
256
- "Then the following <b>models</b> exist". This allows the creation of multiple models
257
- using a table syntax. Using a column with the singularized name of the model creates a referenceable model. E.g.
258
-
259
- Then the following users exist:
260
- | name | activated |
261
- | Freddy | false |
262
-
263
- Then the following users exist:
264
- | user | name | activated |
265
- | Fred | Freddy | false |
266
-
267
- ===== Asserting associations
268
-
269
- One-to-one assocs: "Then <b>a model</b> should be <b>other model</b>'s <b>association</b>", e.g.
270
-
271
- Then the person: "fred" should be person: "ethel"'s father
272
-
273
- Many-to-one assocs: "Then <b>a model</b> should be [in|one of] <b>other model</b>'s <b>association</b>", e.g.
274
-
275
- Then the person: "ethel" should be one of person: "fred"'s children
276
- Then the comment should be in the post's comments
277
-
278
- ===== Asserting predicate methods
279
-
280
- "Then <b>a model</b> should [be|have] [a|an] <b>predicate</b>", e.g.
281
-
282
- Then the user should have a status # => user.status.should be_present
283
- Then the user should have a stale password # => user.should have_stale_password
284
- Then the car: "batmobile" should be fast # => car.should be_fast
285
-
286
- "Then <b>a model</b> should not [be|have] [a|an] <b>predicate</b>", e.g.
287
-
288
- Then person: "fred" should not be childless # => fred.should_not be_childless
289
-
290
- === Regexps for use in your own steps
291
-
292
- By default you get some regexps available in the main namespace for use
293
- in creating your own steps: `capture_model`, `capture_fields`, and others (see lib/pickle.rb)
294
-
295
- (You can use any of the regexps that Pickle uses by using the Pickle.parser namespace, see
296
- Pickle::Parser::Matchers for the methods available)
297
-
298
- *capture_model*
299
-
300
- Given /^#{capture_model} exists$/ do |model_name|
301
- model(model_name).should_not == nil
302
- end
303
-
304
- Then /^I should be at the (.*?) page$/ |page|
305
- if page =~ /#{capture_model}'s/
306
- url_for(model($1))
307
- else
308
- # ...
309
- end
310
- end
311
-
312
- Then /^#{capture_model} should be one of #{capture_model}'s posts$/ do |post, forum|
313
- post = model!(post)
314
- forum = model!(forum)
315
- forum.posts.should include(post)
316
- end
317
-
318
- *capture_fields*
319
-
320
- This is useful for setting attributes, and knows about pickle model names so that you
321
- can build up composite objects with ease
322
-
323
- Given /^#{capture_model} exists with #{capture_fields}$/ do |model_name, fields|
324
- create_model(model_name, fields)
325
- end
326
-
327
- # example of use
328
- Given a user exists
329
- And a post exists with author: the user # this step will assign the above user as :author on the post
330
-
331
- === Email Steps
332
-
333
- When you run <tt>rails g pickle --email</tt> you get steps for handling email.
334
-
335
- The general pattern of use is to clear the email queue (if necessary), have your app perform something that sends emails, assert that emails have been delivered, then assert
336
- those emails have particular properties.
337
-
338
- For example:
339
-
340
- Background:
341
- Given a user has signed up
342
- And all emails have been delivered
343
- And the user has signed in
344
-
345
- Scenario: User buys a fork
346
- Given I am on the fork page
347
- And I press "Buy Fork!"
348
- Then 1 email should be delivered to the user
349
- And the email should contain "You can haz Fork!"
350
- When I follow the "my account" link in the email
351
- Then I should be on the account page
352
-
353
- And 1 email should be delivered to "sales@example.com"
354
- And the email should contain the user's page
355
- And the email should contain "User can haz Fork!"
356
-
357
- You can refer to emails that were found in the <tt>Then <i>n</i> emails should be delivered</tt> in the following ways:
358
-
359
- the email (refers to last email)
360
- the 1st email
361
- the last email
362
- email to: "joe@example.com"
363
- email subject: "some subject"
364
- email to: "joe@example.com", subject: "some subject"
365
-
366
- ==== Map expressions to email addresses
367
-
368
- By default a step like
369
-
370
- Then 2 emails should be delivered to the user "Ethel"
371
-
372
- Will look for the <tt>email</tt> attribute on the found model. This is configurable in much the same way as
373
- page names for url paths. Have a look at <tt>features/support/email.rb</tt> to add your own custom mappings.
374
-
375
- For example:
376
-
377
- # in features/support/email.rb
378
- when /^#{capture_model} sales team$/
379
- model!($1).sales_email
380
-
381
- # in a feature
382
- Given a site exists
383
- And someone buys something form the site
384
- Then 1 email should be delivered to the site sales team
385
-
386
- More detail on the emails steps follows:
387
-
388
- ==== Given steps
389
-
390
- Clear the email queue, e.g.
391
-
392
- Given all email has been delivered
393
- Given all emails have been delivered
394
-
395
- ==== When steps
396
-
397
- When <b>[I|they]</b> follow <b>[text_or_regex|the first link]</b> the email, e.g.
398
-
399
- When I click the first link in the email
400
- When I follow "http://example.com/pickle" in the email
401
- When I follow "some link text" in the email
402
-
403
- ==== Then steps
404
-
405
- Then <b>n</b> email(s) should be delivered to <b>address</b>, e.g.
406
-
407
- Then 1 email should be delivered to joe@example.com
408
-
409
- Then <b>n</b> email(s) should be delivered with <b>fields</b>, e.g.
410
-
411
- Then 2 emails should be delivered with subject: "Welcome to pickle"
412
- Then 2 email should be delivered with to: "joe@example.com", from: "pickle@example.com"
413
-
414
- Then <b>fields</b> should be delivered to <b>address</b>, e.g.
415
-
416
- Then subject: "Welcome to pickle" should be delivered to joe@example.com
417
-
418
- Then <b>fields</b> should be not delivered to <b>address</b>, e.g.
419
-
420
- Then subject: "Welcome to pickle" should not be delivered to pickle@example.com
421
-
422
- Then <b>email</b> should have <b>fields</b>, e.g.
423
-
424
- Then the email should have subject: "Welcome to pickle", from: "pickle@example.com"
425
-
426
- Then <b>email</b> should contain "<b>text</b>", e.g.
427
-
428
- Then the email should contain "Thank you for choosing pickle"
429
-
430
- Then <b>email</b> should not contain "<b>text</b>", e.g.
431
-
432
- Then the email should not contain "v1@gr@"
433
-
434
- Then <b>email</b> should link to "<b>href</b>", e.g.
435
-
436
- Then the email should link to http://example.com/pickle
437
-
438
- Then show me the email(s), will open the email(s) in your browser (depends on OS X)
439
-
440
- Then show me the email(s)
441
-
442
- == Run the tests
443
-
444
- To run the specs and features, you can start from the last known good set of gem dependencies in Gemfile.lock.development:
445
-
446
- git clone http://github.com/ianwhite/pickle
447
- cd pickle
448
- cp Gemfile.lock.development Gemfile.lock
449
- bundle
450
-
451
- To run the specs & features do:
452
-
453
- bundle exec rake spec
454
- bundle exec rake cucumber
455
-
456
- == Contributors
457
-
458
- The following people have made Pickle better:
459
-
460
- * {Jules Copeland}[http://github.com/julescopeland]
461
- * {David Padilla}[http://github.com/dabit]
462
- * {Ari Epstein}[http://github.com/aepstein]
463
- * {Jonathan Hinkle}[http://github.com/hynkle]
464
- * {Devin Walters and Nick Karpenske}[http://github.com/bendyworks]
465
- * {Marc Lee}[http://github.com/maleko]
466
- * {Sebastian Zuchmanski}[http://github.com/sebcioz]
467
- * {Paul Gideon Dann}[http://github.com/giddie]
468
- * {Tom Meier}[http://github.com/tommeier]
469
- * {Sean Hussey}[http://github.com/seanhussey]
470
- * Brian Rose & Kevin Olsen
471
- * {Christopher Darroch}[http://github.com/chrisdarroch]
472
- * {Szymon Nowak}[http://github.com/szimek]
473
- * {H.J. Blok}[http://github.com/hjblok]
474
- * {Daniel Neighman}[http://github.com/hassox]
475
- * {Josh Bassett}[http://github.com/nullobject]
476
- * {Nick Rutherford}[http://github.com/nruth]
477
- * {Tobi Knaup}[http://github.com/guenter]
478
- * {Michael MacDonald}[http://github.com/schlick]
479
- * {Michael Moen}[http://github.com/UnderpantsGnome]
480
- * {Myron Marston}[http://github.com/myronmarston]
481
- * {Stephan Hagemann}[http://github.com/xing]
482
- * {Chris Flipse}[http://github.com/cflipse]
483
-