spbtv_pickle 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
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