spbtv_pickle 0.5.1

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 (80) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +10 -0
  5. data/Gemfile +3 -0
  6. data/Gemfile.lock.development +158 -0
  7. data/History.txt +499 -0
  8. data/License.txt +20 -0
  9. data/README.md +566 -0
  10. data/Rakefile +20 -0
  11. data/Rakefile.d/cucumber.rake +27 -0
  12. data/Rakefile.d/release.rake +44 -0
  13. data/Rakefile.d/rspec.rake +3 -0
  14. data/Rakefile.d/yard.rake +5 -0
  15. data/Todo.txt +3 -0
  16. data/autotest/discover.rb +9 -0
  17. data/features/app/app.rb +128 -0
  18. data/features/app/blueprints.rb +6 -0
  19. data/features/app/fabricators.rb +6 -0
  20. data/features/app/factories.rb +25 -0
  21. data/features/app/views/notifier/email.erb +1 -0
  22. data/features/app/views/notifier/user_email.erb +6 -0
  23. data/features/email/email.feature +64 -0
  24. data/features/generator/generators.feature +59 -0
  25. data/features/path/models_page.feature +44 -0
  26. data/features/path/named_route_page.feature +10 -0
  27. data/features/pickle/create_from_active_record.feature +83 -0
  28. data/features/pickle/create_from_fabrication.feature +46 -0
  29. data/features/pickle/create_from_factory_girl.feature +66 -0
  30. data/features/pickle/create_from_machinist.feature +46 -0
  31. data/features/step_definitions/email_steps.rb +1 -0
  32. data/features/step_definitions/extra_email_steps.rb +12 -0
  33. data/features/step_definitions/fork_steps.rb +4 -0
  34. data/features/step_definitions/generator_steps.rb +52 -0
  35. data/features/step_definitions/path_steps.rb +14 -0
  36. data/features/step_definitions/pickle_steps.rb +1 -0
  37. data/features/step_definitions/raise_error_steps.rb +7 -0
  38. data/features/support/email.rb +1 -0
  39. data/features/support/env.rb +14 -0
  40. data/features/support/paths.rb +47 -0
  41. data/features/support/pickle.rb +27 -0
  42. data/features/support/pickle_app.rb +4 -0
  43. data/init.rb +0 -0
  44. data/lib/generators/pickle_generator.rb +44 -0
  45. data/lib/pickle.rb +26 -0
  46. data/lib/pickle/adapter.rb +183 -0
  47. data/lib/pickle/adapters/active_record.rb +67 -0
  48. data/lib/pickle/adapters/data_mapper.rb +42 -0
  49. data/lib/pickle/adapters/mongoid.rb +54 -0
  50. data/lib/pickle/config.rb +49 -0
  51. data/lib/pickle/email.rb +87 -0
  52. data/lib/pickle/email/parser.rb +18 -0
  53. data/lib/pickle/email/world.rb +13 -0
  54. data/lib/pickle/parser.rb +65 -0
  55. data/lib/pickle/parser/matchers.rb +87 -0
  56. data/lib/pickle/path.rb +45 -0
  57. data/lib/pickle/path/world.rb +5 -0
  58. data/lib/pickle/session.rb +244 -0
  59. data/lib/pickle/session/parser.rb +34 -0
  60. data/lib/pickle/version.rb +3 -0
  61. data/lib/pickle/world.rb +14 -0
  62. data/lib/spbtv_pickle.rb +1 -0
  63. data/rails_generators/pickle/pickle_generator.rb +31 -0
  64. data/rails_generators/pickle/templates/email.rb +21 -0
  65. data/rails_generators/pickle/templates/email_steps.rb +65 -0
  66. data/rails_generators/pickle/templates/paths.rb +47 -0
  67. data/rails_generators/pickle/templates/pickle.rb +29 -0
  68. data/rails_generators/pickle/templates/pickle_steps.rb +105 -0
  69. data/spbtv_pickle.gemspec +38 -0
  70. data/spec/pickle/adapter_spec.rb +203 -0
  71. data/spec/pickle/config_spec.rb +112 -0
  72. data/spec/pickle/email/parser_spec.rb +51 -0
  73. data/spec/pickle/email_spec.rb +187 -0
  74. data/spec/pickle/parser/matchers_spec.rb +70 -0
  75. data/spec/pickle/parser_spec.rb +165 -0
  76. data/spec/pickle/path_spec.rb +120 -0
  77. data/spec/pickle/session_spec.rb +448 -0
  78. data/spec/pickle_spec.rb +24 -0
  79. data/spec/spec_helper.rb +78 -0
  80. metadata +370 -0
@@ -0,0 +1,20 @@
1
+ $:.unshift File.expand_path('lib')
2
+
3
+ # load given tasks file, reporting errors without failing
4
+ def load_tasks(tasks)
5
+ load tasks
6
+ rescue Exception => exception
7
+ $stderr << "** loading #{tasks.sub(File.expand_path('.'),'')} failed: "
8
+ case exception
9
+ when LoadError
10
+ $stderr << "to use, install the gems it requires\n"
11
+ else
12
+ $stderr << ([exception.message] + exception.backtrace[0..2]).join("\n ") << "\n\n"
13
+ end
14
+ end
15
+
16
+ Dir["Rakefile.d/*.rake"].sort.each {|t| load_tasks t}
17
+
18
+ task :default => :spec
19
+
20
+ task :ci => ['rcov:verify', 'cucumber']
@@ -0,0 +1,27 @@
1
+ require 'cucumber/rake/task'
2
+
3
+ desc "Run features"
4
+ Cucumber::Rake::Task.new(:cucumber => [:cucumber_test_app]) do |t|
5
+ t.cucumber_opts = ['--format', 'pretty', '--require', 'features']
6
+ end
7
+
8
+ desc "setup a rails app for running cucumber"
9
+ file "cucumber_test_app" do
10
+ puts "** setting up cucumber test app **"
11
+ Rake::Task['cucumber:setup'].invoke
12
+ end
13
+
14
+ namespace :cucumber do
15
+ task :setup do
16
+ Bundler.with_clean_env do
17
+ gemfile = "cucumber_test_app/Gemfile"
18
+ rm_rf "cucumber_test_app"
19
+ sh "bundle exec rails new cucumber_test_app --skip-javascript --skip-sprockets"
20
+ sh "echo 'gem \"cucumber-rails\", :require => false' >> #{gemfile}"
21
+ sh "echo 'gem \"rspec-rails\", \"~>3.0\"' >> #{gemfile}"
22
+ sh "echo 'gem \"capybara\"' >> #{gemfile}"
23
+ sh "bundle install --gemfile=#{gemfile}"
24
+ sh "ln -s ../../.. cucumber_test_app/vendor/plugins/pickle"
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,44 @@
1
+ # tasks for building and releasing the software
2
+ require 'git'
3
+ require 'pickle/version'
4
+
5
+ task :build do
6
+ system "gem build pickle.gemspec"
7
+ end
8
+
9
+ namespace :release do
10
+ task :rubygems => :pre do
11
+ system "gem push pickle-#{Pickle::VERSION}.gem"
12
+ end
13
+
14
+ task :github => :pre do
15
+ tag = "v#{Pickle::VERSION}"
16
+ git = Git.open('.')
17
+
18
+ if (git.tag(tag) rescue nil)
19
+ raise "** repo is already tagged with: #{tag}"
20
+ end
21
+
22
+ git.add_tag(tag)
23
+ git.push('origin', tag)
24
+ end
25
+
26
+ task :pre => [:spec, :cucumber, :build] do
27
+ git = Git.open('.')
28
+
29
+ if File.exists?("Gemfile.lock") && File.read("Gemfile.lock") != File.read("Gemfile.lock.development")
30
+ cp "Gemfile.lock", "Gemfile.lock.development"
31
+ raise "** Gemfile.lock.development has been updated, please commit these changes."
32
+ end
33
+
34
+ if (git.status.changed + git.status.added + git.status.deleted).any?
35
+ raise "** repo is not clean, try committing some files"
36
+ end
37
+
38
+ if git.object('HEAD').sha != git.object('origin/master').sha
39
+ raise "** origin does not match HEAD, have you pushed?"
40
+ end
41
+ end
42
+
43
+ task :all => ['release:github', 'release:rubygems']
44
+ end
@@ -0,0 +1,3 @@
1
+ require 'rspec/core/rake_task'
2
+
3
+ RSpec::Core::RakeTask.new(:spec)
@@ -0,0 +1,5 @@
1
+ require 'yard'
2
+
3
+ YARD::Rake::YardocTask.new(:doc) do |t|
4
+ t.files = ['lib/**/*.rb', 'rails_generators/**/*.rb']
5
+ end
@@ -0,0 +1,3 @@
1
+ * add 'scope' steps see http://gist.github.com/239570
2
+ * cleanup path_to_pickle and paths.rb (maybe have poly_pickle_path with same semantics as polymorphic_path, but accepting pickle refs)
3
+ * Translations
@@ -0,0 +1,9 @@
1
+ require 'autotest/bundler'
2
+
3
+ Autotest.add_hook :initialize do |autotest|
4
+ %w{.git .DS_Store ._* vendor tmp email cucumber_test_app}.each do |exception|
5
+ autotest.add_exception(exception)
6
+ end
7
+ end
8
+
9
+ Autotest.add_discovery { "rspec2" }
@@ -0,0 +1,128 @@
1
+ # Routes
2
+ Rails.application.routes.draw do
3
+ resources :spoons, :controller => 'default'
4
+ resources :forks, :controller => 'default' do
5
+ resources :tines, :controller => 'default' do
6
+ resources :comments, :controller => 'default'
7
+ end
8
+ end
9
+ 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
+ t.decimal :attitude_score, :precision => 4, :scale => 2
32
+ t.boolean :has_stale_password, :default => false
33
+ end
34
+
35
+ create_table :knives, :force => true do |t|
36
+ t.string :name
37
+ t.boolean :sharp, :null => false
38
+ end
39
+ end
40
+ end
41
+
42
+
43
+ # Factories for these Fork & Spoon
44
+ class Fork < ActiveRecord::Base
45
+ validates_presence_of :name
46
+ has_many :tines
47
+
48
+ def completely_rusty?
49
+ tines.map(&:rusty?).uniq == [true]
50
+ end
51
+
52
+ def fancy?
53
+ name =~ /fancy/i
54
+ end
55
+ end
56
+
57
+ class Tine < ActiveRecord::Base
58
+ validates_presence_of :fork
59
+ belongs_to :fork
60
+ end
61
+
62
+ # Machinist blueprint for this
63
+ class Spoon < ActiveRecord::Base
64
+ validates_presence_of :name
65
+ end
66
+
67
+ # Fabricator class
68
+ class Knife < ActiveRecord::Base
69
+ validates_presence_of :name
70
+ end
71
+
72
+ # we don't want abstract classes getting in there
73
+ class AbstractUser < ActiveRecord::Base
74
+ self.abstract_class = true
75
+ end
76
+
77
+ # No factory or blueprint for this
78
+ class User < AbstractUser
79
+ validates_presence_of :name
80
+
81
+ def positive_person?
82
+ !no_attitude? && attitude_score > 0
83
+ end
84
+
85
+ def no_attitude?
86
+ attitude_score.nil?
87
+ end
88
+ end
89
+
90
+ # controllers
91
+ class DefaultController < ActionController::Base
92
+ def index
93
+ render :text => "index: I was invoked with #{request.path}"
94
+ end
95
+
96
+ def show
97
+ render :text => "show: I was invoked with #{request.path}"
98
+ end
99
+
100
+ def new
101
+ render :text => "new: I was invoked with #{request.path}"
102
+ end
103
+
104
+ def edit
105
+ render :text => "edit: I was invoked with #{request.path}"
106
+ end
107
+ end
108
+
109
+ # notifiers
110
+ class Notifier < ActionMailer::Base
111
+ include Rails.application.routes.url_helpers
112
+
113
+ # BC 2.1
114
+ self.view_paths = "#{File.dirname(__FILE__)}/views"
115
+
116
+ def user_email(user)
117
+ @recipients = user.email
118
+ @subject = 'A user email'
119
+ @user = user
120
+ @path = user_path(user)
121
+ end
122
+
123
+ def email(to, subject, body)
124
+ @recipients = to
125
+ @subject = subject
126
+ @body = body
127
+ end
128
+ end
@@ -0,0 +1,6 @@
1
+ # Blueprints
2
+ require 'machinist/active_record'
3
+
4
+ Spoon.blueprint do
5
+ name { "A Spoon" }
6
+ end
@@ -0,0 +1,6 @@
1
+ require 'fabrication'
2
+
3
+ Fabricator(:knife) do
4
+ name 'David'
5
+ sharp true
6
+ end
@@ -0,0 +1,25 @@
1
+ # Factories
2
+ require 'factory_girl'
3
+
4
+ FactoryGirl.define do
5
+ sequence :fork_name do |n|
6
+ "fork %d04" % n
7
+ end
8
+
9
+ factory :fork do |f|
10
+ f.name { FactoryGirl.generate(:fork_name) }
11
+ end
12
+
13
+ factory :tine do |t|
14
+ t.association :fork
15
+ end
16
+
17
+ factory :rusty_tine, :class => Tine do |t|
18
+ t.association :fork
19
+ t.rusty true
20
+ end
21
+
22
+ factory :fancy_fork, :class => Fork do |t|
23
+ t.name { "Fancy " + FactoryGirl.generate(:fork_name) }
24
+ end
25
+ 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,64 @@
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 not be delivered to "frood@fmail.com"
10
+ And the email should have subject: "Gday", to: "fred@gmail.com"
11
+ And the email should contain "Mate"
12
+ And the email should not contain "Foo"
13
+
14
+ Scenario: Deliver some emails, restrict scope
15
+ Given an email "cool" with body: "body1" is delivered to fred@gmail.com
16
+ And an email "tasty" with body: "body2" is delivered to fred@gmail.com
17
+ And an email "cool" with body: "body3" is delivered to joe@gmail.com
18
+
19
+ Then 2 emails should be delivered to fred@gmail.com
20
+ And the 1st email should have subject: "cool"
21
+ And the 2nd email should have subject: "tasty"
22
+
23
+ And 2 emails should be delivered with subject: "cool"
24
+ And the 1st email should be delivered to fred@gmail.com
25
+ And the 2nd email should be delivered to joe@gmail.com
26
+
27
+ And 1 email should be delivered with subject: "cool", to: "fred@gmail.com"
28
+
29
+ Scenario: Deliver some emails, reset deliveries
30
+ Given an email "cool" with body: "body1" is delivered to fred@gmail.com
31
+ And all emails have been delivered
32
+ Then 0 emails should be delivered
33
+
34
+ Scenario: Deliver emails to user
35
+ Given a user exists with name: "Fred", email: "fred@gmail.com"
36
+ And the user's email is delivered
37
+ Then 1 email should be delivered to the user
38
+ And the email should contain "Dear Fred"
39
+ And the email should link to the user's page
40
+
41
+ Scenario: Following the first link in an email
42
+ Given a user exists with name: "Fred", email: "fred@gmail.com"
43
+ And an email with a link "example page" to the user's page is delivered to fred@gmail.com
44
+ Then 1 email should be delivered to the user
45
+ And I click the first link in the email
46
+ Then I should be at the user's page
47
+
48
+ Scenario: Following a link in an email by url
49
+ Given a user exists with name: "Fred", email: "fred@gmail.com"
50
+ And an email with a link "example page" to the user's page is delivered to fred@gmail.com
51
+ Then 1 email should be delivered to the user
52
+ And I follow "example.com/" in the email
53
+ Then I should be at the user's page
54
+
55
+ Scenario: Following a link in an email by the text
56
+ Given a user exists with name: "Fred", email: "fred@gmail.com"
57
+ And an email with a link "example page" to the user's page is delivered to fred@gmail.com
58
+ Then 1 email should be delivered to the user
59
+ And I follow "example page" in the email
60
+ Then I should be at the user's page
61
+
62
+ Scenario: Save and open email
63
+ Given an email "Gday" with body: "Gday Mate" is delivered to fred@gmail.com
64
+ Then show me the email
@@ -0,0 +1,59 @@
1
+ @gen
2
+ Feature: allow pickle to generate steps
3
+ In order to get going with pickle
4
+ As a dev
5
+ I want to be able to generate steps
6
+
7
+ Scenario: script/generate pickle on fresh cuke install
8
+ Given cucumber has been freshly generated
9
+ When I run "rails g pickle -f"
10
+ Then the file features/support/pickle.rb should exist
11
+ And the file features/support/pickle.rb should match /require 'pickle\/world'/
12
+ And the file features/step_definitions/pickle_steps.rb should be identical to the local step_definitions/pickle_steps.rb
13
+
14
+ Scenario: script/generate pickle path on fresh cuke install
15
+ Given cucumber has been freshly generated
16
+ When I run "rails g pickle --paths -f"
17
+ Then the file features/support/pickle.rb should exist
18
+ And the file features/support/pickle.rb should match /require 'pickle\/world'/
19
+ And the file features/support/pickle.rb should match /require 'pickle\/path\/world'/
20
+ And the file features/step_definitions/pickle_steps.rb should be identical to the local step_definitions/pickle_steps.rb
21
+ And the file features/support/paths.rb should be identical to the local support/paths.rb
22
+
23
+ Scenario: script/generate pickle email on fresh cuke install
24
+ Given cucumber has been freshly generated
25
+ When I run "rails g pickle --email -f"
26
+ Then the file features/support/pickle.rb should exist
27
+ And the file features/support/pickle.rb should match /require 'pickle\/world'/
28
+ And the file features/support/pickle.rb should match /require 'pickle\/email\/world'/
29
+ And the file features/step_definitions/pickle_steps.rb should be identical to the local step_definitions/pickle_steps.rb
30
+ And the file features/step_definitions/email_steps.rb should be identical to the local step_definitions/email_steps.rb
31
+ And the file features/support/email.rb should be identical to the local support/email.rb
32
+
33
+ Scenario: script/generate pickle path email on fresh cuke install
34
+ Given cucumber has been freshly generated
35
+ When I run "rails g pickle --paths --email -f"
36
+ Then the file features/support/pickle.rb should exist
37
+ And the file features/support/pickle.rb should be identical to the local support/pickle.rb
38
+ And the file features/support/pickle.rb should match /require 'pickle\/world'/
39
+ And the file features/support/pickle.rb should match /require 'pickle\/path\/world'/
40
+ And the file features/support/pickle.rb should match /require 'pickle\/email\/world'/
41
+ And the file features/step_definitions/pickle_steps.rb should be identical to the local step_definitions/pickle_steps.rb
42
+ And the file features/support/paths.rb should be identical to the local support/paths.rb
43
+ And the file features/step_definitions/email_steps.rb should be identical to the local step_definitions/email_steps.rb
44
+ And the file features/support/email.rb should be identical to the local support/email.rb
45
+
46
+ Scenario: regenerating pickle
47
+ Given cucumber has been freshly generated
48
+ And pickle path email has been freshly generated
49
+ When I run "rails g pickle --paths --email -f"
50
+ Then the file features/support/pickle.rb should match /require 'pickle\/world'/
51
+ And the file features/support/pickle.rb should match /require 'pickle\/path\/world'/
52
+ And the file features/support/pickle.rb should match /require 'pickle\/email\/world'/
53
+ And the file features/step_definitions/pickle_steps.rb should be identical to the local step_definitions/pickle_steps.rb
54
+ And the file features/support/paths.rb should be identical to the local support/paths.rb
55
+ And the file features/step_definitions/email_steps.rb should be identical to the local step_definitions/email_steps.rb
56
+ But the file features/support/pickle.rb should not match /require 'pickle\/world'.*require 'pickle\/world'/
57
+ And the file features/support/pickle.rb should not match /require 'pickle\/path\/world'.*require 'pickle\/path\/world'/
58
+ And the file features/support/pickle.rb should not match /require 'pickle\/email\/world'.*require 'pickle\/email\/world'/
59
+ And the file features/support/email.rb should be identical to the local support/email.rb
@@ -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