pickle 0.1.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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