saki 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -41,6 +41,10 @@ The only assumption is that you are using factories instead of fixtures. You al
41
41
 
42
42
  with_existing :user, :state => "happy" do...
43
43
 
44
+ `with_signed_in` is similar to `with_existing` but after creating the object it passes it into a `sign_in` method:
45
+
46
+ with_signed_in :admin do...
47
+
44
48
  `on_visiting` preferably uses some dynamic functions for establishing a path: `new_X_path`, `Xs_path`, `edit_X_path`, `X_path` and `new_X_path`. In these cases, substitute X for the resource name (e.g. `new_user_path`).
45
49
 
46
50
  Note that for examples like `edit_user_path`, it behaves with a slight difference from the rails route helpers, because it assumes that there already exists an instance variable named `@user`. Since the `edit_user_path` call occurs when there is no `@user`, we can't mention it explicitly.
@@ -49,9 +53,9 @@ For cases where the resource is nested, these path helpers have a :parent => par
49
53
 
50
54
  on_visiting auctions_path(:parent => :user) do ...
51
55
 
52
- `on_visiting` also takes a path as a string, or a lambda that executes within a before block to set up the path. It also takes a symbol which is the name of a method name. This is useful when the code is dependent on an instance variable for path creation.
56
+ `on_visiting` also takes a path as a string, or a proc that executes within a before block to set up the path. It also takes a symbol which is the name of a method name. This is useful when the code is dependent on an instance variable for path creation.
53
57
 
54
- path_for_user = lambda { user_path(@user) }
58
+ path_for_user = proc { user_path(@user) }
55
59
 
56
60
  on_visiting path_for_user do ...
57
61
 
@@ -65,10 +69,10 @@ or you can do
65
69
 
66
70
  `on_following_link_to` works the same as on_visiting, but it first validates that the link exists, and then follows it.
67
71
 
68
- `where` is a function taking as a parameter a lambda to execute in the before block.
72
+ `where` is a function taking as a parameter a proc to execute in the before block.
69
73
 
70
74
  def self.creating_a_user
71
- lambda {
75
+ proc {
72
76
  @user = Factory.build @user
73
77
  fill_in "user[email]", :with => @user.email
74
78
  click_button "Create"
@@ -118,6 +122,14 @@ You can generate new acceptance tests with `rails generate saki:spec SPEC_NAME`.
118
122
  end
119
123
  end
120
124
 
125
+ ## Saki as your default integration testing library
126
+
127
+ If you want to use Saki for generating integration tests for your scaffolding, simply add to your development.rb file
128
+
129
+ require "generators/saki/integration_generator"
130
+
131
+ Then, provided that your integration library is set to :rspec, Saki will create integration tests for your scaffolding for complete test coverage. Note that these cases are left simple for now, but can be built up upon feedback. Also you might need to implement additional functions depending on your use case.
132
+
121
133
  ## Why no specs/tests for Saki, oh test guy?
122
134
 
123
135
  They'll get there :). Saki is extracted from some spec helpers I used in moving from Cucumber to Steak. Once I realized they also work as helpers for vanilla RSpec acceptance testing I made them a separate gem.
@@ -130,6 +142,10 @@ I haven't pimped that up yet, but will at some point. Personally I'm a "green-d
130
142
 
131
143
  The motivation behind my migration from Cucumber and to Saki, are described in blog posts [Encumbered by Cucumber](http://ludicast.com/articles/1), [Introducing Saki](http://ludicast.com/articles/2).
132
144
 
145
+ ## Ruby 1.9.2
146
+
147
+ To work with Ruby 1.9.2 the `where` function takes procs but not lambdas.
148
+
133
149
  ## Thanks
134
150
 
135
151
  The generators are stolen directly from Steak with some adjustments.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.1
1
+ 0.1.2
@@ -0,0 +1,19 @@
1
+ require 'generators/rspec/integration/integration_generator'
2
+
3
+ module Rspec
4
+ module Generators
5
+ class IntegrationGenerator < Base
6
+ argument :attributes, :type => :array, :default => [], :banner => "field:type field:type"
7
+
8
+ source_paths << File.join(File.dirname(__FILE__), 'templates')
9
+
10
+ def create_integration_file
11
+ template 'full_integration_spec.rb',
12
+ File.join('spec/acceptance', class_path, "#{table_name}_spec.rb")
13
+ end
14
+ def resource_name
15
+ file_name.tableize.singularize
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,35 @@
1
+ require File.dirname(__FILE__) + '/acceptance_helper'
2
+
3
+ integrate "<%= resource_name %> resource" do
4
+
5
+ def fill_in_<%= resource_name %>_details<%-
6
+ attributes.each do |attribute|
7
+ %>
8
+ fill_in "<%= resource_name %>[<%= attribute.name %>]", :with => @<%= resource_name %>.<%= attribute.name %><%-
9
+ end
10
+ %>
11
+ end
12
+
13
+ def has_<%= resource_name %>_details<%-
14
+ attributes.each do |attribute|
15
+ %>
16
+ page.should have_content(@<%= resource_name %>.<%= attribute.name %>)<%-
17
+ end
18
+ %>
19
+ end
20
+
21
+ on_visiting new_<%= resource_name %>_path do
22
+ it { lets_me_create_the(:<%= resource_name %>) }
23
+ it { shows_failure_on_invalid_create }
24
+ end
25
+
26
+ with_existing :<%= resource_name %> do
27
+ it { shows_in_list(:<%= resource_name %>) }
28
+
29
+ on_visiting edit_<%= resource_name %>_path do
30
+ it { lets_me_edit_the(:<%= resource_name %>) }
31
+ it { shows_failure_on_invalid_update_of(:<%= resource_name %>) }
32
+ end
33
+ end
34
+
35
+ end
@@ -1,8 +1,104 @@
1
1
  require 'rspec/core'
2
2
 
3
3
  module Saki
4
+ module RestfulPathwayHelpers
5
+ def shows_in_list(resource, attrs = nil)
6
+ visit "/#{resource.to_s.pluralize}"
7
+ resource_instance = eval "@#{resource}"
8
+ if attrs
9
+ attrs.each do |attr|
10
+ page.should have_content(resource_instance.send(attr))
11
+ end
12
+ elsif respond_to?("displays_#{resource}")
13
+ send "displays_#{resource}"
14
+ else
15
+ page.should have_content(resource_instance.name)
16
+ end
17
+ has_index_link_list(resource_instance)
18
+ end
19
+
20
+ def has_index_link_list(item, opts = {})
21
+ has_link_for item, opts
22
+ has_link_for_editing item, opts
23
+ has_link_for_deleting item, opts
24
+ has_link_for_creating item.class.to_s.tableize.singularize, opts
25
+ end
26
+
27
+ def has_show_link_list(item, opts = {})
28
+ has_link_for_editing item, opts
29
+ has_link_for_deleting item, opts
30
+ has_link_for_indexing item.class.to_s.tableize.singularize, opts
31
+ end
32
+
33
+ def shows_failure_on_invalid_update_of(model)
34
+ if respond_to?("invalidate_#{model}_form")
35
+ send("invalidate_#{model}_form")
36
+ else
37
+ fill_in "#{model}[name]", :with => ""
38
+ end
39
+ click_button "Update"
40
+ page.should have_xpath("//input[@type='submit' and starts-with(@value, 'Update')]")
41
+ page.should have_content("error")
42
+ end
43
+
44
+ def shows_failure_on_invalid_create
45
+ click_button "Create"
46
+ page.should have_xpath("//input[@type='submit' and starts-with(@value, 'Create')]")
47
+ page.should have_content("error")
48
+ end
49
+
50
+ def lets_me_edit_the(item_name)
51
+ eval %{
52
+ @#{item_name} = factory_build item_name
53
+ fill_in_#{item_name}_details
54
+ click_button "Update"
55
+ refetch(item_name)
56
+ has_#{item_name}_details
57
+ }
58
+ end
59
+
60
+ def create(item_name)
61
+ eval %{
62
+ @#{item_name} = factory_build :#{item_name}
63
+ if respond_to? :before_#{item_name}_create
64
+ before_#{item_name}_create
65
+ end
66
+ fill_in_#{item_name}_details
67
+ click_button "Create"
68
+ }
69
+ end
70
+
71
+ def refetch
72
+
73
+
74
+ def lets_me_create_the(item_name)
75
+ eval %{
76
+ create(:#{item_name})
77
+ refetch(item_name)
78
+ if respond_to? :after_#{item_name}_create
79
+ after_#{item_name}_create
80
+ end
81
+ has_#{item_name}_details
82
+ has_show_link_list(@#{item_name})
83
+ }
84
+ end
85
+
86
+ def refetch(item_name)
87
+ eval "@#{item_name} = respond_to?(:refetch_#{item_name}_func) ? refetch_#{item_name}_func : @#{item_name}.class.where(:name => @#{item_name}.name).first"
88
+ end
89
+
90
+ def factory_build(name, hash = {})
91
+ Factory.build name, hash
92
+ end
93
+
94
+ def factory(name, hash = {})
95
+ Factory name, hash
96
+ end
97
+
98
+ end
99
+
4
100
  module GeneralHelpers
5
- extend ActiveSupport::Concern
101
+ extend ActiveSupport::Concern
6
102
  def default_factory(name, opts = {})
7
103
  Factory name, opts
8
104
  end
@@ -17,12 +113,22 @@ module Saki
17
113
  end
18
114
  end
19
115
 
116
+ def with_signed_in resource, opts={}, &block
117
+ context "with signed in #{resource}" do
118
+ before do
119
+ instance_variable_set "@#{resource}", default_factory(resource, opts)
120
+ eval "sign_in @#{resource}"
121
+ end
122
+ module_eval &block
123
+ end
124
+ end
125
+
20
126
  def where(executable, *opts, &block)
21
127
  context "anonymous closure" do
22
128
  before { instance_eval &executable }
23
129
  module_eval &block
24
130
  end
25
- end
131
+ end
26
132
  end
27
133
 
28
134
  end
@@ -78,7 +184,7 @@ module Saki
78
184
  def has_link_for_indexing(model_type, opts = {})
79
185
  href = add_opts "/#{model_type.to_s.tableize}", opts
80
186
  has_link href
81
- end
187
+ end
82
188
 
83
189
  def should_be_on(page_name)
84
190
  current_path = URI.parse(current_url).path
@@ -195,4 +301,5 @@ module RSpec::Core::ObjectExtensions
195
301
  end
196
302
 
197
303
  RSpec.configuration.include Saki::GeneralHelpers
198
- RSpec.configuration.include Saki::AcceptanceHelpers, :type => :acceptance
304
+ RSpec.configuration.include Saki::AcceptanceHelpers, :type => :acceptance
305
+ RSpec.configuration.include Saki::RestfulPathwayHelpers, :type => :acceptance
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{saki}
8
- s.version = "0.1.1"
8
+ s.version = "0.1.2"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Nate Kidwell"]
12
- s.date = %q{2010-09-19}
12
+ s.date = %q{2010-10-15}
13
13
  s.description = %q{Cucumber scenarios are long and confusing sometimes. Release yourself from the tyranny of client-centered specing!}
14
14
  s.email = %q{nate@ludicast.com}
15
15
  s.extra_rdoc_files = [
@@ -24,9 +24,11 @@ Gem::Specification.new do |s|
24
24
  "Rakefile",
25
25
  "VERSION",
26
26
  "lib/generators/saki/install_generator.rb",
27
+ "lib/generators/saki/integration_generator.rb",
27
28
  "lib/generators/saki/spec_generator.rb",
28
29
  "lib/generators/saki/templates/acceptance_helper.rb",
29
30
  "lib/generators/saki/templates/acceptance_spec.rb",
31
+ "lib/generators/saki/templates/full_integration_spec.rb",
30
32
  "lib/generators/saki/templates/helpers.rb",
31
33
  "lib/saki.rb",
32
34
  "saki.gemspec",
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 1
8
- - 1
9
- version: 0.1.1
8
+ - 2
9
+ version: 0.1.2
10
10
  platform: ruby
11
11
  authors:
12
12
  - Nate Kidwell
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-09-19 00:00:00 -04:00
17
+ date: 2010-10-15 00:00:00 -04:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -47,9 +47,11 @@ files:
47
47
  - Rakefile
48
48
  - VERSION
49
49
  - lib/generators/saki/install_generator.rb
50
+ - lib/generators/saki/integration_generator.rb
50
51
  - lib/generators/saki/spec_generator.rb
51
52
  - lib/generators/saki/templates/acceptance_helper.rb
52
53
  - lib/generators/saki/templates/acceptance_spec.rb
54
+ - lib/generators/saki/templates/full_integration_spec.rb
53
55
  - lib/generators/saki/templates/helpers.rb
54
56
  - lib/saki.rb
55
57
  - saki.gemspec