pickle 0.1.16

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. data/.gitignore +2 -0
  2. data/History.txt +165 -0
  3. data/License.txt +20 -0
  4. data/README.rdoc +205 -0
  5. data/Rakefile +116 -0
  6. data/Todo.txt +4 -0
  7. data/VERSION +1 -0
  8. data/features/app/app.rb +112 -0
  9. data/features/app/blueprints.rb +11 -0
  10. data/features/app/factories.rb +23 -0
  11. data/features/app/views/notifier/email.erb +1 -0
  12. data/features/app/views/notifier/user_email.erb +6 -0
  13. data/features/email/email.feature +38 -0
  14. data/features/generator/generators.feature +54 -0
  15. data/features/path/models_page.feature +44 -0
  16. data/features/path/named_route_page.feature +10 -0
  17. data/features/pickle/create_from_active_record.feature +20 -0
  18. data/features/pickle/create_from_factory_girl.feature +43 -0
  19. data/features/pickle/create_from_machinist.feature +38 -0
  20. data/features/step_definitions/email_steps.rb +50 -0
  21. data/features/step_definitions/extra_email_steps.rb +7 -0
  22. data/features/step_definitions/fork_steps.rb +4 -0
  23. data/features/step_definitions/generator_steps.rb +42 -0
  24. data/features/step_definitions/path_steps.rb +14 -0
  25. data/features/step_definitions/pickle_steps.rb +41 -0
  26. data/features/support/env.rb +34 -0
  27. data/features/support/paths.rb +46 -0
  28. data/garlic.rb +36 -0
  29. data/init.rb +0 -0
  30. data/lib/pickle.rb +26 -0
  31. data/lib/pickle/adapter.rb +87 -0
  32. data/lib/pickle/config.rb +48 -0
  33. data/lib/pickle/email.rb +36 -0
  34. data/lib/pickle/email/parser.rb +18 -0
  35. data/lib/pickle/email/world.rb +13 -0
  36. data/lib/pickle/parser.rb +65 -0
  37. data/lib/pickle/parser/matchers.rb +87 -0
  38. data/lib/pickle/path.rb +44 -0
  39. data/lib/pickle/path/world.rb +5 -0
  40. data/lib/pickle/session.rb +151 -0
  41. data/lib/pickle/session/parser.rb +24 -0
  42. data/lib/pickle/version.rb +6 -0
  43. data/lib/pickle/world.rb +9 -0
  44. data/pickle.gemspec +107 -0
  45. data/rails_generators/pickle/pickle_generator.rb +41 -0
  46. data/rails_generators/pickle/templates/email_steps.rb +50 -0
  47. data/rails_generators/pickle/templates/env.rb +14 -0
  48. data/rails_generators/pickle/templates/paths.rb +20 -0
  49. data/rails_generators/pickle/templates/pickle_steps.rb +41 -0
  50. data/spec/lib/pickle_adapter_spec.rb +164 -0
  51. data/spec/lib/pickle_config_spec.rb +97 -0
  52. data/spec/lib/pickle_email_parser_spec.rb +49 -0
  53. data/spec/lib/pickle_email_spec.rb +131 -0
  54. data/spec/lib/pickle_parser_matchers_spec.rb +70 -0
  55. data/spec/lib/pickle_parser_spec.rb +154 -0
  56. data/spec/lib/pickle_path_spec.rb +77 -0
  57. data/spec/lib/pickle_session_spec.rb +337 -0
  58. data/spec/lib/pickle_spec.rb +24 -0
  59. data/spec/spec_helper.rb +38 -0
  60. metadata +122 -0
@@ -0,0 +1,2 @@
1
+ doc/*
2
+ .garlic
@@ -0,0 +1,165 @@
1
+ == 0.1.16 - 13 Oct 2009
2
+
3
+ * 1 minor enhancement
4
+ * release gem on gemcutter and rubyforge
5
+
6
+
7
+ == 0.1.15 - 28 Aug 2009
8
+
9
+ * 1 minor enhancement
10
+ * avoid namespace collision on replace by renaming mapping#replace -> mapping#replacement [nruth]
11
+
12
+
13
+ == 0.1.14 - 9 July 2009
14
+
15
+ * 1 minor enhancement
16
+ * update specs and features for latest cucumber and machinist changes
17
+
18
+
19
+ == 0.1.13 - 16 June 2009
20
+
21
+ * 2 minor enhancements
22
+ * model! and created_model! raise an error if pickle name can't be found
23
+ * path_to_pickle uses the above to give back a better error message
24
+
25
+
26
+ == 0.1.12 - 7 Apr 2009
27
+
28
+ * 2 minor enhancements
29
+ * rationalised Rakefile
30
+ * update World extensions for latest cucumber changes
31
+
32
+
33
+ == 0.1.11 - 22 Feb 2009
34
+
35
+ * 2 minor enhancements
36
+ * Pickle now supports multiple machinist blueprints
37
+ * Fix confusing adapter/adaptor comment generator comment
38
+
39
+
40
+ == 0.1.10 - 13 Feb 2009
41
+
42
+ * 2 minor enhancements
43
+ * Made pickle paths generator compatible with latest cucumber
44
+ * Simplified and Rakefile, including auto push api docs to gh-pages on ci build
45
+
46
+
47
+ == 0.1.9 - 29 Jan 2009
48
+
49
+ * 1 minor enhancement
50
+ * Pickle::Adapter.model_classes excludes those without tables
51
+
52
+
53
+ == 0.1.8 - 29 Jan 2009
54
+
55
+ * API change
56
+ * pickle_path becomes path_to_pickle, to avoid named route clashes
57
+
58
+ * 2 minor enhancements
59
+ * Updated features for cucumber 0.2 compat
60
+ * Made paths allow for optional possesives
61
+
62
+
63
+ == 0,1,7
64
+
65
+ * 2 API changes
66
+ * script/generate pickle path[s] now amends the features/support/paths.rb file
67
+ instead of creating pge_to_path and path_steps.
68
+
69
+ * pickle_email_steps is renamed email_steps
70
+
71
+
72
+ == 0.1.6
73
+
74
+ * 1 API change
75
+ * to use pickle env.rb should contain "require 'pickle/world'". You should remove all trace of
76
+ pickle from features/support/env.rb and re run script/generate pickle
77
+
78
+ * 2 major enhancements
79
+
80
+ * generate email steps with `script/generate pickle email`
81
+ email steps allow you to do things like this:
82
+
83
+ Then 2 emails should be delivered
84
+ And the first email should be delivered to fred@gmail.com
85
+ And the 2nd email should be delivered to the user: "ethel"
86
+
87
+ Then 1 email should be delivered with subject: "Activate your account"
88
+ And the email should link to the user's page
89
+
90
+ take a look at features/step_definitions/pickle_email_steps.rb
91
+
92
+ * generate path steps with `script/generate pickle path`
93
+ path steps allow you to do things like this
94
+
95
+ When I go to the comment's page
96
+ Then I should be at the user's new comment page
97
+
98
+ take a look at features/step_definitions/pickle_path_steps.rb, and modify page_to_path to suit your needs
99
+
100
+ * 4 minor enhancements
101
+ * Improved documentation
102
+ * abstract models no longer kill pickle
103
+ * Actually test that the generators work
104
+ * Made Pickle::Session a plain ole mixin, as a separate class was unnecessary
105
+ * Pickle uses the cucumber World API
106
+
107
+
108
+ == 0.1.5
109
+
110
+ * API change
111
+ * CaptureModel, etc are now 'capture_model' methods
112
+
113
+ * 3 major enhancements
114
+ * Steps for asserting that <n> models exist, matching certain criteria
115
+ * Steps for asserting associations added to generated pickle steps
116
+ 'Then the user should be in the post's commenters'
117
+ 'Then the forum: "awesome" should be the 2nd post's forum'
118
+ * configuration can now occur any time before a step is defined, which makes
119
+ for much more intuitive env.rb
120
+
121
+ * 2 minor enhancement
122
+ * predicate matching is less prone to step conflicts because we preload a
123
+ big list of all the predicate and column methods
124
+ * field values now handle booleans and numerics
125
+
126
+
127
+ == 0.1.4
128
+
129
+ * 1 major enhancement
130
+ * You can create multiple models with ease, for eg.
131
+ 'Given 10 users exist with role: "admin"'
132
+
133
+ * 1 minor enhancement
134
+ * You can do Pickle.configure (just like Webrat.configure)
135
+
136
+
137
+ == 0.1.3 - Bugfix release
138
+
139
+ * 1 minor enhancement
140
+ * make generated steps compatible with Rails 2.1
141
+
142
+
143
+ == 0.1.2
144
+
145
+ * 2 major enhancements
146
+ * create your pickle steps with script/generate pickle
147
+ * Adapter based architecture, supports Machinist, FactoryGirl, and vanilla ActiveRecord
148
+
149
+ * 1 minor enhancement
150
+ * model_names now defaults to subclasses of AR::Base
151
+ * #original_model => #created_model
152
+
153
+
154
+ == 0.1.1
155
+
156
+ * 1 major enhancement:
157
+ * made pickle a github gem
158
+
159
+ * 1 minor enhancement:
160
+ * Added intentions for pickle in README.textile
161
+
162
+
163
+ == Prior to gems
164
+
165
+ * Initial release: everything is subject to sweeping change
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008-2009 Ian White - ian.w.white@gmail.com
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,205 @@
1
+ = pickle
2
+
3
+ Pickle gives you cucumber steps that create your models easily from factory-girl or
4
+ machinist factories/blueprints. You can also just use ActiveRecord but it's not as cool.
5
+
6
+ References to the models are stored, not necessarily for the purpose of checking the db
7
+ (although you could use it for that), but for enabling easy reference to urls, and for
8
+ building complex givens which require a bunch of models collaborating
9
+
10
+ == CI
11
+
12
+ It's tested against all stable branches of 2.x rails, and edge, with the latest versions of rspec, cucumber, factory_girl, machinist.
13
+
14
+ == Install
15
+
16
+ Install pickle either as a rails plugin, or a gem
17
+
18
+ # gem form rubyforge or gemcutter
19
+ sudo gem install pickle
20
+
21
+ # plugin
22
+ script/plugin install git://github.com/ianwhite/pickle.git
23
+
24
+ # or, plugin as submodule
25
+ git submodule add git://github.com/ianwhite/pickle.git vendor/plugins/pickle
26
+
27
+ # or, github gem
28
+ sudo gem install ianwhite-pickle
29
+
30
+ == Get Started
31
+
32
+ (you'd better install cucumber)
33
+
34
+ script/generate pickle [paths] [email]
35
+
36
+ Now have a look at <tt>features/step_definitions/pickle_steps.rb</tt>
37
+
38
+ If you want path steps and email steps then just add 'paths' and/or 'email'. The code/steps will be
39
+ written to <tt>features/env/paths.rb</tt> and
40
+ <tt>features/step_definitions/email_steps.rb</tt> respectively.
41
+
42
+ === Using with plain ole Active Record
43
+
44
+ If you have an AR called 'Post', with required fields 'title', and 'body', then you can now write
45
+ steps like this
46
+
47
+ Given a post exists with title: "My Post", body: "My body"
48
+
49
+ === Using with factory-girl or machinist
50
+
51
+ But you're using Machinist or FactoryGirl right?! To leverage all of the factories/blueprints
52
+ you've written, you can just do stuff like
53
+
54
+ Given a user exists
55
+ And another user exists with role: "admin"
56
+
57
+ # later
58
+ Then a user should exist with name: "Fred"
59
+ And that user should be activated # this uses rspec predicate matchers
60
+
61
+ ==== Machinst: require your blueprints and reset Shams
62
+
63
+ (The latest version of pickle supports {multiple blueprints}[http://github.com/notahat/machinist/commit/d6492e6927a8aa1819926e48b22377171fd20496], for
64
+ earlier versions of machinist use pickle <= 0.1.10)
65
+
66
+ In your <tt>features/support/env.rb</tt> add the following lines at the bottom
67
+
68
+ require "#{Rails.root}/spec/blueprints" # or wherever they live
69
+ Before { Sham.reset } # reset Shams in between scenarios
70
+
71
+ === Configuring Pickle
72
+
73
+ You can tell pickle to use another factory adapter (see Pickle::Adapter), or
74
+ create mappings from english expressions to pickle model names. You can also
75
+ override many of the options on the Pickle::Config object if you so choose
76
+
77
+ require 'pickle/world'
78
+
79
+ Pickle.configure do |config|
80
+ config.adapters = [:machinist, YourOwnAdapterClass]
81
+ config.map 'me', 'myself', 'my', 'I', :to => 'user: "me"'
82
+ end
83
+
84
+ == API
85
+
86
+ === Steps
87
+
88
+ When you run <tt>script/generate pickle</tt> you get the following steps
89
+
90
+ ==== Given steps
91
+
92
+ "Given <b>a model</b> exists", e.g.
93
+
94
+ Given a user exists
95
+ Given a user: "fred" exists
96
+ Given the user exists
97
+
98
+ "Given <b>a model</b> exists with <b>fields</b>", e.g.
99
+
100
+ Given a user exists with name: "Fred"
101
+ Given a user exists with name: "Fred", activated: false
102
+
103
+ You can refer to other models in the fields
104
+
105
+ Given a user exists
106
+ And a post exists with author: the user
107
+
108
+ Given a person: "fred" exists
109
+ And a person: "ethel" exists
110
+ And a fatherhood exists with parent: user "fred", child: user "ethel"
111
+
112
+ "Given <b>n</b> models exist", e.g.
113
+
114
+ Given 10 users exist
115
+
116
+ "Given <b>n</b> <b>models</b> exist with <b>fields</b>", examples:
117
+
118
+ Given 10 users exist with activated: false
119
+
120
+ ==== Then steps
121
+
122
+ ===== Asserting existence of models
123
+
124
+ "Then <b>a model</b> should exist", e.g.
125
+
126
+ Then a user should exist
127
+
128
+ "Then <b>a model</b> should exist with <b>fields</b>", e.g.
129
+
130
+ Then a user: "fred" should exist with name: "Fred" # we can label the found user for later use
131
+
132
+ You can use other models, booleans, numerics, and strings as fields
133
+
134
+ Then a person should exist with child: person "ethel"
135
+ Then a user should exist with activated: false
136
+ Then a user should exist with activated: true, email: "fred@gmail.com"
137
+
138
+ "Then <b>n</b> <b>models</b> should exist", e.g.
139
+
140
+ Then 10 events should exist
141
+
142
+ "Then <b>n</b> <b>models</b> should exist with <b>fields</b>", e.g.
143
+
144
+ Then 2 people should exist with father: person "fred"
145
+
146
+ ===== Asserting associations
147
+
148
+ One-to-one assocs: "Then <b>a model</b> should be <b>other model</b>'s <b>association</b>", e.g.
149
+
150
+ Then the person: "fred" should be person: "ethel"'s father
151
+
152
+ Many-to-one assocs: "Then <b>a model</b> should be [in|one of] <b>other model</b>'s <b>association</b>", e.g.
153
+
154
+ Then the person: "ethel" should be one of person: "fred"'s children
155
+ Then the comment should be in the post's comments
156
+
157
+ ===== Asserting predicate methods
158
+
159
+ "Then <b>a model</b> should [be|have] [a|an] <b>predicate</b>", e.g.
160
+
161
+ Then the user should have a status # => user.status?.should == true
162
+ Then the car: "batmobile" should be fast # => car.fast?.should == true
163
+
164
+ "Then <b>a model</b> should [be|have] [a|an] <b>predicate</b>", e.g.
165
+
166
+ Then person: "fred" should not be childless # => fred.childless?.should == false
167
+
168
+ === Regexps for use in your own steps
169
+
170
+ By default you get some regexps available in the main namespace for use
171
+ in creating your own steps: `capture_model`, `capture_fields`, and others (see lib/pickle.rb)
172
+
173
+ (You can use any of the regexps that Pickle uses by using the Pickle.parser namespace, see
174
+ Pickle::Parser::Matchers for the methods available)
175
+
176
+ *capture_model*
177
+
178
+ Given /^#{capture_model} exists$/ do |model_name|
179
+ model(model_name).should_not == nil
180
+ end
181
+
182
+ Then /^I should be at the (.*?) page$/ |page|
183
+ if page =~ /#{capture_model}'s/
184
+ url_for(model($1))
185
+ else
186
+ # ...
187
+ end
188
+ end
189
+
190
+ Then /^#{capture_model} should be one of #{capture_model}'s posts$/ do |post, forum|
191
+ model(forum).posts.should include(post)
192
+ end
193
+
194
+ *capture_fields*
195
+
196
+ This is useful for setting attributes, and knows about pickle model names so that you
197
+ can build up composite objects with ease
198
+
199
+ Given /^#{capture_model} exists with #{capture_fields}$/ do |model_name, fields|
200
+ create_model(model_name, fields)
201
+ end
202
+
203
+ # example of use
204
+ Given a user exists
205
+ And a post exists with author: the user # this step will assign the above user as :author on the post
@@ -0,0 +1,116 @@
1
+ # use pluginized rpsec if it exists
2
+ rspec_base = File.expand_path(File.dirname(__FILE__) + '/../rspec/lib')
3
+ $LOAD_PATH.unshift(rspec_base) if File.exist?(rspec_base) and !$LOAD_PATH.include?(rspec_base)
4
+
5
+ require 'spec/rake/spectask'
6
+ require 'spec/rake/verify_rcov'
7
+
8
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/lib'
9
+ require 'pickle/version'
10
+
11
+ PluginName = 'pickle'
12
+
13
+ task :default => [:spec]
14
+
15
+ desc "Run the specs for #{PluginName}"
16
+ Spec::Rake::SpecTask.new(:spec) do |t|
17
+ t.spec_files = FileList['spec/**/*_spec.rb']
18
+ t.spec_opts = ["--colour"]
19
+ end
20
+
21
+ desc "Generate RCov report for #{PluginName}"
22
+ Spec::Rake::SpecTask.new(:rcov) do |t|
23
+ t.spec_files = FileList['spec/**/*_spec.rb']
24
+ t.rcov = true
25
+ t.rcov_dir = 'doc/coverage'
26
+ t.rcov_opts = ['--text-report', '--exclude', "spec/,rcov.rb,#{File.expand_path(File.join(File.dirname(__FILE__),'../../..'))}"]
27
+ end
28
+
29
+ namespace :rcov do
30
+ desc "Verify RCov threshold for #{PluginName}"
31
+ RCov::VerifyTask.new(:verify => :rcov) do |t|
32
+ t.threshold = 100.0
33
+ t.index_html = File.join(File.dirname(__FILE__), 'doc/coverage/index.html')
34
+ end
35
+ end
36
+
37
+ # cucumber features require an enclosing rails app
38
+ plugins_base = File.expand_path(File.join(File.dirname(__FILE__), '..'))
39
+ cucumber_base = File.join(plugins_base, 'cucumber/lib')
40
+ if File.exists?(cucumber_base) && plugins_base =~ /\/vendor\/plugins$/ # if we're in rails app
41
+ $:.unshift(cucumber_base)
42
+ require 'cucumber/rake/task'
43
+
44
+ desc "Run features for #{PluginName} (progress)"
45
+ Cucumber::Rake::Task.new(:features) do |t|
46
+ t.fork = true
47
+ t.cucumber_opts = ['--format', 'progress', '--require', 'features']
48
+ end
49
+
50
+ desc "Run features for #{PluginName} (full output)"
51
+ namespace :features do
52
+ Cucumber::Rake::Task.new(:full) do |t|
53
+ t.cucumber_opts = ['--format', 'pretty', '--require', 'features']
54
+ end
55
+ end
56
+ end
57
+
58
+ # the following optional tasks are for CI, gems and doc building
59
+ begin
60
+ require 'hanna/rdoctask'
61
+ require 'garlic/tasks'
62
+ require 'grancher/task'
63
+
64
+ task :cruise => ['garlic:all', 'doc:publish']
65
+
66
+ Rake::RDocTask.new(:doc) do |d|
67
+ d.options << '--all'
68
+ d.rdoc_dir = 'doc'
69
+ d.main = 'README.rdoc'
70
+ d.title = "#{PluginName} API docs"
71
+ d.rdoc_files.include('README.rdoc', 'History.txt', 'License.txt', 'Todo.txt', 'lib/**/*.rb')
72
+ end
73
+
74
+ namespace :doc do
75
+ task :publish => :doc do
76
+ Rake::Task['doc:push'].invoke unless uptodate?('.git/refs/heads/gh-pages', 'doc')
77
+ end
78
+
79
+ Grancher::Task.new(:push) do |g|
80
+ g.keep_all
81
+ g.directory 'doc', 'doc'
82
+ g.branch = 'gh-pages'
83
+ g.push_to = 'origin'
84
+ end
85
+ end
86
+ rescue LoadError
87
+ end
88
+
89
+ begin
90
+ require 'jeweler'
91
+
92
+ Jeweler::Tasks.new do |s|
93
+ s.name = "pickle"
94
+ s.version = Pickle::Version::String
95
+ s.summary = "Easy model creation and reference in your cucumber features"
96
+ s.description = "Easy model creation and reference in your cucumber features"
97
+ s.email = "ian.w.white@gmail.com"
98
+ s.homepage = "http://github.com/ianwhite/pickle/tree"
99
+ s.authors = ["Ian White"]
100
+ s.rubyforge_project = 'pickle'
101
+ end
102
+
103
+ Jeweler::GemcutterTasks.new
104
+
105
+ Jeweler::RubyforgeTasks.new do |rubyforge|
106
+ rubyforge.doc_task = "doc"
107
+ end
108
+
109
+ namespace :release do
110
+ desc "Release current version to github, gemcutter and rubyforge"
111
+ task :all => ['release', 'gemcutter:release', 'rubyforge:release']
112
+ end
113
+
114
+ rescue LoadError
115
+ puts "Jeweler not available for gem tasks. Install it with: sudo gem install jeweler"
116
+ end