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,4 @@
1
+ * Add email_for (same concept as path_to)
2
+ * fix problem with save_and_open_emails
3
+ * Translations
4
+ * Investigate using Treetop for pre-parsing
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.16
@@ -0,0 +1,112 @@
1
+ # Routes
2
+ ActionController::Routing::Routes.draw do |map|
3
+ map.resources :spoons, :controller => 'default'
4
+ map.resources :forks, :controller => 'default' do |fork|
5
+ fork.resources :tines, :controller => 'default' do |tine|
6
+ tine.resources :comments, :controller => 'default'
7
+ end
8
+ end
9
+ map.resources :users, :controller => 'default'
10
+ end
11
+
12
+ # Migrations
13
+ ActiveRecord::Migration.suppress_messages do
14
+ ActiveRecord::Schema.define(:version => 0) do
15
+ create_table :forks, :force => true do |t|
16
+ t.string :name
17
+ end
18
+
19
+ create_table :spoons, :force => true do |t|
20
+ t.string :name
21
+ t.boolean :round, :default => true, :null => false
22
+ end
23
+
24
+ create_table :tines, :force => true do |t|
25
+ t.belongs_to :fork
26
+ t.boolean :rusty, :default => false, :null => false
27
+ end
28
+
29
+ create_table :users, :force => true do |t|
30
+ t.string :name, :status, :email
31
+ end
32
+ end
33
+ end
34
+
35
+
36
+ # Factories for these Fork & Spoon
37
+ class Fork < ActiveRecord::Base
38
+ validates_presence_of :name
39
+ has_many :tines
40
+
41
+ def completely_rusty?
42
+ tines.map(&:rusty?).uniq == [true]
43
+ end
44
+
45
+ def fancy?
46
+ name =~ /fancy/i
47
+ end
48
+ end
49
+
50
+ class Tine < ActiveRecord::Base
51
+ validates_presence_of :fork
52
+ belongs_to :fork
53
+ end
54
+
55
+ # Machinist bluepriint for this
56
+ class Spoon < ActiveRecord::Base
57
+ validates_presence_of :name
58
+ end
59
+
60
+ # we don;t want abstract classes getting in there
61
+ class AbstractUser < ActiveRecord::Base
62
+ self.abstract_class = true
63
+ end
64
+
65
+ # No factory or blueprint for this
66
+ class User < AbstractUser
67
+ validates_presence_of :name
68
+ end
69
+
70
+ # controllers
71
+ class DefaultController < ActionController::Base
72
+ def index
73
+ render :text => "index: I was invoked with #{request.path}"
74
+ end
75
+
76
+ def show
77
+ render :text => "show: I was invoked with #{request.path}"
78
+ end
79
+
80
+ def new
81
+ render :text => "new: I was invoked with #{request.path}"
82
+ end
83
+
84
+ def edit
85
+ render :text => "edit: I was invoked with #{request.path}"
86
+ end
87
+ end
88
+
89
+ # notifiers
90
+ class Notifier < ActionMailer::Base
91
+ include ActionController::UrlWriter
92
+
93
+ # BC 2.1
94
+ if respond_to?(:view_paths)
95
+ view_paths << "#{File.dirname(__FILE__)}/views"
96
+ else
97
+ self.template_root = "#{File.dirname(__FILE__)}/views"
98
+ end
99
+
100
+ def user_email(user)
101
+ @recipients = user.email
102
+ @subject = 'A user email'
103
+ @body[:user] = user
104
+ @body[:path] = user_path(user)
105
+ end
106
+
107
+ def email(to, subject, body)
108
+ @recipients = to
109
+ @subject = subject
110
+ @body[:body] = body
111
+ end
112
+ end
@@ -0,0 +1,11 @@
1
+ # Blueprints
2
+ require 'machinist/active_record'
3
+
4
+ Sham.spoon_name { |i| "Spoon #{i}" }
5
+
6
+ Spoon.blueprint do
7
+ name { Sham.spoon_name }
8
+ end
9
+
10
+ # reset shams between scenarios
11
+ Before { Sham.reset }
@@ -0,0 +1,23 @@
1
+ # Factories
2
+ require 'factory_girl'
3
+
4
+ Factory.sequence :fork_name do |n|
5
+ "fork %d04" % n
6
+ end
7
+
8
+ Factory.define :fork do |f|
9
+ f.name { Factory.next(:fork_name) }
10
+ end
11
+
12
+ Factory.define :tine do |t|
13
+ t.association :fork
14
+ end
15
+
16
+ Factory.define :rusty_tine, :class => Tine do |t|
17
+ t.association :fork
18
+ t.rusty true
19
+ end
20
+
21
+ Factory.define :fancy_fork, :class => Fork do |t|
22
+ t.name { "Fancy " + Factory.next(:fork_name) }
23
+ end
@@ -0,0 +1 @@
1
+ <%= @body %>
@@ -0,0 +1,6 @@
1
+ Dear <%= @user.name %>,
2
+
3
+ This is where you should go: <%= @path %>
4
+
5
+ Cheers,
6
+ The Pickle Team
@@ -0,0 +1,38 @@
1
+ Feature: I can test emails are sent
2
+ In order write features with emails as outcomes
3
+ As a feature writer
4
+ I want to easily see what emails have been delivered
5
+
6
+ Scenario: Deliver an email, and test it's properties
7
+ Given an email "Gday" with body: "Gday Mate" is delivered to fred@gmail.com
8
+ Then 1 email should be delivered
9
+ And the email should have subject: "Gday", to: "fred@gmail.com"
10
+ And the email should contain "Mate"
11
+ And the email should not contain "Foo"
12
+
13
+ Scenario: Deliver some emails, restrict scope
14
+ Given an email "cool" with body: "body1" is delivered to fred@gmail.com
15
+ And an email "tasty" with body: "body2" is delivered to fred@gmail.com
16
+ And an email "cool" with body: "body3" is delivered to joe@gmail.com
17
+
18
+ Then 2 emails should be delivered to fred@gmail.com
19
+ And the 1st email should have subject: "cool"
20
+ And the 2nd email should have subject: "tasty"
21
+
22
+ And 2 emails should be delivered with subject: "cool"
23
+ And the 1st email should be delivered to fred@gmail.com
24
+ And the 2nd email should be delivered to joe@gmail.com
25
+
26
+ And 1 email should be delivered with subject: "cool", to: "fred@gmail.com"
27
+
28
+ Scenario: Deliver some emails, reset deliveries
29
+ Given an email "cool" with body: "body1" is delivered to fred@gmail.com
30
+ And all emails have been delivered
31
+ Then 0 emails should be delivered
32
+
33
+ Scenario: Deliver emails to user
34
+ Given a user exists with name: "Fred", email: "fred@gmail.com"
35
+ And the user's email is delivered
36
+ Then 1 email should be delivered to the user
37
+ And the email should contain "Dear Fred"
38
+ And the email should link to the user's page
@@ -0,0 +1,54 @@
1
+ Feature: allow pickle to generate steps
2
+ In order to get going with pickle
3
+ As a dev
4
+ I want to be able to generate steps
5
+
6
+ Scenario: cucumber is not yet installed
7
+ When I run "script/generate pickle"
8
+ Then I should see "try running script/generate cucumber"
9
+
10
+ Scenario Outline: script/generate pickle on fresh cuc install
11
+ Given cucumber has been freshly generated
12
+ When I run "<GENERATE PICKLE>"
13
+ Then the file <STEPS FILE> should exist
14
+ And the file features/support/env.rb should match /<ENV.RB SHOULD MATCH>/
15
+
16
+ Examples:
17
+ | GENERATE PICKLE | STEPS FILE | ENV.RB SHOULD MATCH |
18
+ | script/generate pickle | features/step_definitions/pickle_steps.rb | require 'pickle\/world' |
19
+ | script/generate pickle | features/step_definitions/pickle_steps.rb | Example of configuring pickle: |
20
+ | script/generate pickle email| features/step_definitions/email_steps.rb | require 'pickle\/email\/world' |
21
+
22
+ Scenario: script/generate pickle path on fresh cuc install
23
+ Given cucumber has been freshly generated
24
+ When I run "script/generate pickle path"
25
+ Then the file features/support/env.rb should match /require 'pickle\/world'/
26
+ And the file features/support/paths.rb should match /added by script/generate pickle path/
27
+ And the file features/support/paths.rb should be identical to the local support/paths.rb
28
+
29
+ Scenario Outline: script/generate pickle, when env.rb has already requires pickle
30
+ Given cucumber has been freshly generated
31
+ And env.rb already requires <ENV.RB CONTAINS>
32
+ When I run "<GENERATE PICKLE>"
33
+ Then the file features/support/env.rb should not match /<ENV.RB SHOULD NOT MATCH>/
34
+
35
+ Examples:
36
+ | ENV.RB CONTAINS | GENERATE PICKLE | ENV.RB SHOULD NOT MATCH |
37
+ | pickle/world | script/generate pickle | Example of configuring pickle: |
38
+ | pickle/world | script/generate pickle | require 'pickle\/world'.*require 'pickle\/world' |
39
+ | pickle/path/world | script/generate pickle path | require 'pickle\/path\/world'.*require 'pickle\/path\/world' |
40
+ | pickle/email/world| script/generate pickle email | require 'pickle\/email\/world'.*require 'pickle\/email\/world'|
41
+
42
+ Scenario: script/generate pickle page email
43
+ Given cucumber has been freshly generated
44
+ When I run "script/generate pickle path email"
45
+ Then the file features/step_definitions/email_steps.rb should exist
46
+ And the file features/step_definitions/pickle_steps.rb should exist
47
+ And the file features/support/env.rb should match /require 'pickle\/world'/
48
+ And the file features/support/env.rb should match /require 'pickle\/path\/world'/
49
+ And the file features/support/env.rb should match /require 'pickle\/email\/world'/
50
+ And the file features/support/paths.rb should match /added by script/generate pickle path/
51
+
52
+
53
+
54
+
@@ -0,0 +1,44 @@
1
+ Feature: I can visit a page for a model
2
+ In order to easily go to pages for models I've created
3
+ As a feature writer
4
+ I want to be able visit pages their model
5
+
6
+ Scenario: create a spoon, go its page
7
+ Given a spoon exists
8
+ When I go to the spoon's page
9
+ Then I should be at the spoon's page
10
+ And the spoon's page should match route /spoons/:id
11
+
12
+ Scenario: create a spoon, go to its edit page, check lots of different refs to it
13
+ Given a spoon: "fred" exists
14
+ When I go to spoon: "fred"'s edit page
15
+ Then I should be at the 1st spoon's edit page
16
+ And the 1st spoon's edit page should match route /spoons/:id/edit
17
+ And the spoon's edit page should match route /spoons/:id/edit
18
+ And the spoon: "fred"'s edit page should match route /spoons/:id/edit
19
+
20
+ Scenario: go to a fork's nested tines page
21
+ Given a fork exists
22
+ When I go to the fork's tines page
23
+ Then I should be at the fork's tines page
24
+ And the fork's tines page should match route /forks/:fork_id/tines
25
+
26
+ Scenario: go to a fork's new tine page
27
+ Given a fork exists
28
+ When I go to the fork's new tine page
29
+ Then I should be at the fork's new tine page
30
+ And the fork's new tine page should match route /forks/:fork_id/tines/new
31
+
32
+ Scenario: go to a tine in fork context page
33
+ Given a fork exists
34
+ And a tine exists with fork: the fork
35
+ When I go to the fork's tine's page
36
+ Then I should be at the fork's tine's page
37
+ And the fork's tine's page should match route /forks/:fork_id/tines/:id
38
+
39
+ Scenario: go to a tine's comments in fork context
40
+ Given a fork exists
41
+ And a tine exists with fork: the fork
42
+ When I go to the fork's tine's comments page
43
+ Then I should be at the fork's tine's comments page
44
+ And the fork's tine's comments page should match route /forks/:fork_id/tines/:tine_id/comments
@@ -0,0 +1,10 @@
1
+ Feature: I can visit a page by named route
2
+ In order to nav in my features
3
+ As a feature writer
4
+ I want to be able visit named routes
5
+
6
+ Scenario: visit the new spoons page
7
+ When I go to the new spoon page
8
+ Then I should be at the new spoon page
9
+ And the new spoon page should match route /spoons/new
10
+
@@ -0,0 +1,20 @@
1
+ Feature: I can easily create models from my blueprints
2
+
3
+ As a plain old AR user
4
+ I want to be able to create models with fields
5
+ So that I can create models quickly and easily in my features
6
+
7
+ Scenario: I create a user, and see if it looks right
8
+ Given a user exists with name: "Fred"
9
+ Then the user should not have a status
10
+
11
+ Scenario: I create a user, and see if it looks right
12
+ Given a user exists with name: "Fred", status: "crayzee"
13
+ Then a user should exist with name: "Fred"
14
+ And a user should exist with status: "crayzee"
15
+
16
+ Scenario: I create a user via a mapping
17
+ Given I exist with status: "pwned", name: "fred"
18
+ Then I should have a status
19
+ And the user: "me" should have a status
20
+
@@ -0,0 +1,43 @@
1
+ Feature: I can easily create models from my factories
2
+
3
+ As a pickle user
4
+ I want to be able to leverage my factories
5
+ So that I can create models quickly and easily in my features
6
+
7
+ Scenario: I create a fork, and see if it looks right
8
+ Given a fork exists
9
+ Then the fork should not be completely rusty
10
+
11
+ Scenario: I create a fork, and see if it looks right
12
+ Given a fork exists with name: "Forky"
13
+ Then a fork should exist with name: "Forky"
14
+ And the fork should not be completely rusty
15
+
16
+ Scenario: I create some forks, and some tines
17
+ Given a fork: "one" exists
18
+ And a tine exists with fork: fork "one"
19
+ And another tine exists with fork: fork "one"
20
+
21
+ And a fancy fork exists
22
+ And a tine exists with fork: the fancy fork
23
+
24
+ Then the first tine should be tine of the fork: "one"
25
+ And the 2nd tine should be tine of fork: "one"
26
+ And the last tine should be tine of the fancy fork
27
+
28
+ Then the first tine should be in fork "one"'s tines
29
+ And the 2nd tine should be in fork: "one"'s tines
30
+ And the last tine should be in the fancy fork's tines
31
+
32
+ Scenario: I create a fork with a tine, and find the tine by the fork
33
+ Given a fork exists
34
+ And a tine exists with fork: the fork
35
+
36
+ Then a tine should exist with fork: the fork
37
+
38
+ And the fork should be the tine's fork
39
+
40
+ Scenario: I create fork via a mapping
41
+ Given killah fork exists
42
+ Then the fork should be fancy
43
+ And the fancy fork: "of cornwood" should be fancy
@@ -0,0 +1,38 @@
1
+ Feature: I can easily create models from my blueprints
2
+
3
+ As a machinist user
4
+ I want to be able to leverage my blueprints
5
+ So that I can create models quickly and easily in my features
6
+
7
+ Scenario: I create a spoon, and see if it looks right
8
+ Given a spoon exists
9
+ Then the spoon should be round
10
+
11
+ Scenario: I create a non round spoon, and see if it looks right
12
+ Given a spoon exists with round: false
13
+ Then the spoon should not be round
14
+
15
+ Scenario: I create a named spoon, and see if it has the name
16
+ Given a spoon exists with name: "Pete", round: false
17
+ Then a spoon should exist with name: "Pete"
18
+ And the spoon should not be round
19
+
20
+ Scenario: I create 7 spoons of various roundness
21
+ Given 2 spoons exist with round: false
22
+ And 2 spoons exist with round: true
23
+ And a spoon exists with round: false
24
+
25
+ Then the 1st spoon should not be round
26
+ And the 2nd spoon should not be round
27
+ And the 3rd spoon should be round
28
+ And the 4th spoon should be round
29
+ And the 5th spoon should not be round
30
+
31
+ And 3 spoons should exist with round: false
32
+ And the 1st spoon should not be round
33
+ And the 2nd spoon should not be round
34
+ And the last spoon should not be round
35
+
36
+ And 2 spoons should exist with round: true
37
+ And the first spoon should be round
38
+ And the last spoon should be round
@@ -0,0 +1,50 @@
1
+ # this file generated by script/generate pickle email
2
+
3
+ ActionMailer::Base.delivery_method = :test
4
+ ActionMailer::Base.perform_deliveries = true
5
+
6
+ Before do
7
+ ActionMailer::Base.deliveries.clear
8
+ end
9
+
10
+ Given(/^all emails? (?:have|has) been delivered$/) do
11
+ ActionMailer::Base.deliveries.clear
12
+ end
13
+
14
+ Given(/^(\d)+ emails? should be delivered$/) do |count|
15
+ emails.size.should == count.to_i
16
+ end
17
+
18
+ Then(/^(\d)+ emails? should be delivered to (.*)$/) do |count, to|
19
+ to =~ /^#{capture_model}$/ && to = model($1).email
20
+ emails("to: \"#{to}\"").size.should == count.to_i
21
+ end
22
+
23
+ Then(/^(\d)+ emails? should be delivered with #{capture_fields}$/) do |count, fields|
24
+ emails(fields).size.should == count.to_i
25
+ end
26
+
27
+ Then(/^#{capture_email} should be delivered to (.+)$/) do |email_ref, to|
28
+ to =~ /^#{capture_model}$/ && to = model($1).email
29
+ email(email_ref, "to: \"#{to}\"").should_not be_nil
30
+ end
31
+
32
+ Then(/^#{capture_email} should have #{capture_fields}$/) do |email_ref, fields|
33
+ email(email_ref, fields).should_not be_nil
34
+ end
35
+
36
+ Then(/^#{capture_email} should contain "(.*)"$/) do |email_ref, text|
37
+ email(email_ref).body.should =~ /#{text}/
38
+ end
39
+
40
+ Then(/^#{capture_email} should not contain "(.*)"$/) do |email_ref, text|
41
+ email(email_ref).body.should_not =~ /#{text}/
42
+ end
43
+
44
+ Then(/^#{capture_email} should link to (.+)$/) do |email_ref, page|
45
+ email(email_ref).body.should =~ /#{path_to(page)}/
46
+ end
47
+
48
+ Then(/^show me the emails?$/) do
49
+ save_and_open_emails
50
+ end