cucumber_scaffold 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/Manifest ADDED
@@ -0,0 +1,12 @@
1
+ Manifest
2
+ README.rdoc
3
+ Rakefile
4
+ TODO
5
+ cucumber_scaffold.gemspec
6
+ lib/generators/cucumber_scaffold/feature/USAGE
7
+ lib/generators/cucumber_scaffold/feature/feature_generator.rb
8
+ lib/generators/cucumber_scaffold/feature/templates/feature.feature
9
+ lib/generators/cucumber_scaffold/feature/templates/steps.rb
10
+ lib/generators/cucumber_scaffold/install/USAGE
11
+ lib/generators/cucumber_scaffold/install/install_generator.rb
12
+ lib/generators/cucumber_scaffold/install/templates/shared/web_steps_additional.rb
data/README.rdoc ADDED
@@ -0,0 +1,226 @@
1
+ == Installation
2
+
3
+ $ gem install cucumber_scaffold
4
+
5
+ == Usage
6
+
7
+ $ rails generate cucumber_scaffold:install
8
+ $ rails generate cucumber_scaffold:feature Post name:string body:text
9
+
10
+ == Sample Output
11
+
12
+ # Generated by cucumber_scaffold - http://github.com/andyw8/cucumber_scaffold
13
+
14
+ Feature: Manage Posts
15
+ In order to [goal]
16
+ [stakeholder]
17
+ wants [behaviour]
18
+
19
+ @index
20
+ Scenario: List all posts
21
+ Given the following posts:
22
+ | name | body |
23
+ | name 1 | body 1 |
24
+ | name 2 | body 2 |
25
+ | name 3 | body 3 |
26
+ When I go to the posts page
27
+ Then I should see the following posts:
28
+ | Name | Body |
29
+ | name 1 | body 1 |
30
+ | name 2 | body 2 |
31
+ | name 3 | body 3 |
32
+
33
+ @show
34
+ Scenario: View a post
35
+ Given the following post:
36
+ | name | name 1 |
37
+ | body | body 1 |
38
+ When I go to the page for that post
39
+ Then I should see the following post:
40
+ | Name: | name 1 |
41
+ | Body: | body 1 |
42
+
43
+ @edit
44
+ Scenario: Edit a post
45
+ Given the following post:
46
+ | name | name 1 |
47
+ | body | body 1 |
48
+ When I go to the edit page for that post
49
+ Then I should see the following form field values:
50
+ | Name | name 1 |
51
+ | Body | body 1 |
52
+
53
+ @index @destroy
54
+ Scenario: Delete a post via the index page
55
+ Given the following posts:
56
+ | name | body |
57
+ | name 1 | body 1 |
58
+ | name 2 | body 2 |
59
+ | name 3 | body 3 |
60
+ When I go to the posts page
61
+ And I click "Destroy" in the 2nd row
62
+ Then I should see the following posts:
63
+ | Name | Body |
64
+ | name 1 | body 1 |
65
+ | name 3 | body 3 |
66
+ And I should be on the posts page
67
+
68
+ @new @create @show
69
+ Scenario: Create a new post
70
+ Pending
71
+ # Given I am on the new post page
72
+ # When I fill in the following:
73
+ # | Name | name 1 |
74
+ # | Body | body 1 |
75
+ # And I press "Create"
76
+ # Then I should see "Post was successfully created."
77
+ # And I should see the following post:
78
+ # | Name: | name 1 |
79
+ # | Body: | body 1 |
80
+ #
81
+ # In order to confirm that the user is redirected to the correct page
82
+ # after create, you'll need to add an entry to paths.rb to uniquely
83
+ # find a post, e.g.:
84
+ #
85
+ # when /page for the post with name "([^"]*)"$/
86
+ # conditions = { :conditions => {:name => $1} }
87
+ # matches = Post.all(conditions)
88
+ # if matches.size == 0
89
+ # raise "Could not find any posts using criteria #{conditions.inspect}"
90
+ # elsif matches.size > 1
91
+ # raise "Could not find a unique post using criteria #{conditions.inspect} (#{matches.size} matches)"
92
+ # end
93
+ # post_path(matches.first)
94
+ #
95
+ # Then add a step such as this to the scenario:
96
+ #
97
+ # And I should be on the page for the post with name "..."
98
+
99
+ @new @create
100
+ Scenario: Attempt to create a new post with invalid input
101
+ Pending
102
+ # You should use this scenario as the basis for scenarios involving ActiveRecord validations, or delete it if it's not required
103
+ # Given I am on the new post page
104
+ # When I fill in the following:
105
+ # | Name | name 1 |
106
+ # | Body | body 1 |
107
+ # And I press "Create"
108
+ # Then I should see "prohibited this post from being saved:"
109
+ #
110
+ # [You should add checks for specific errors here. It may be appropriate to add extra scenarios.]
111
+ #
112
+ # And I should be on the posts page
113
+ # And I should see the following form field values:
114
+ # | Name: | name 1 |
115
+ # | Body: | body 1 |
116
+
117
+ @edit @update
118
+ Scenario: Attempt to update a post with invalid input
119
+ Pending
120
+ # You should use this scenario as the basis for scenarios involving ActiveRecord validations, or delete it if it's not required
121
+ # Given a post exists
122
+ # When I go to the edit page for that post
123
+ # And I fill in the following:
124
+ # | Name | name 1 |
125
+ # | Body | body 1 |
126
+ # And I press "Update"
127
+ # Then I should see "prohibited this post from being saved:"
128
+ #
129
+ # [You should add checks for specific errors here. It may be appropriate to add extra scenarios.]
130
+ #
131
+ # And I should be on the page for that post
132
+ # And I should see the following form field values:
133
+ # | Name: | name 1 |
134
+ # | Body: | body 1 |
135
+
136
+ @edit @update @show
137
+ Scenario: Update a post
138
+ Given a post exists
139
+ When I go to the edit page for that post
140
+ And I fill in the following:
141
+ | Name | name 1 updated |
142
+ | Body | body 1 updated |
143
+ And I press "Update"
144
+ Then I should be on the page for that post
145
+ And I should see "Post was successfully updated."
146
+ And I should see the following post:
147
+ | Name: | name 1 updated |
148
+ | Body: | body 1 updated |
149
+
150
+ @index @new
151
+ Scenario: Navigate from the posts page to the new post page
152
+ Given I am on the posts page
153
+ When I follow "New Post"
154
+ Then I should be on the new post page
155
+
156
+ @index @show
157
+ Scenario: Navigate from posts page to the show post page
158
+ Given the following posts:
159
+ | name | body |
160
+ | name 1 | body 1 |
161
+ | name 2 | body 2 |
162
+ | name 3 | body 3 |
163
+ When I go to the posts page
164
+ And I click "Show" in the 2nd row
165
+ Then I should be on the page for the 2nd post
166
+
167
+ @index @edit
168
+ Scenario: Navigate from posts page to the edit post page
169
+ Given the following posts:
170
+ | name | body |
171
+ | name 1 | body 1 |
172
+ | name 2 | body 2 |
173
+ | name 3 | body 3 |
174
+ When I go to the posts page
175
+ And I click "Edit" in the 2nd row
176
+ Then I should be on the edit page for the 2nd post
177
+
178
+ @new @index
179
+ Scenario: Navigate from new post page to posts page
180
+ Given I am on the new post page
181
+ When I follow "Back"
182
+ Then I should be on the posts page
183
+
184
+ @edit @show
185
+ Scenario: Navigate from the edit post page to the show post page
186
+ Given a post exists
187
+ When I go to the edit page for that post
188
+ And I follow "Show"
189
+ Then I should be on the page for that post
190
+
191
+ @edit @index
192
+ Scenario: Navigate from edit post page to the posts page
193
+ Given a post exists
194
+ When I go to the edit page for that post
195
+ And I follow "Back"
196
+ Then I should be on the posts page
197
+
198
+ @show @edit
199
+ Scenario: Navigate from show post page to edit post page
200
+ Given a post exists
201
+ When I go to the page for that post
202
+ And I follow "Edit"
203
+ Then I should be on the edit page for that post
204
+
205
+ @show @index
206
+ Scenario: Navigate from show post page to posts page
207
+ Given a post exists
208
+ And I am on the page for that post
209
+ And I follow "Back"
210
+ Then I should be on the posts page
211
+
212
+ @index
213
+ Scenario: Posts page title
214
+ When I go to the posts page
215
+ Then the heading should be "Listing posts"
216
+
217
+ @new
218
+ Scenario: New post page title
219
+ When I go to the new post page
220
+ Then the heading should be "New post"
221
+
222
+ @edit
223
+ Scenario: Edit post page title
224
+ Given a post exists
225
+ When I go to the edit page for that post
226
+ Then the heading should be "Editing post"
data/Rakefile ADDED
@@ -0,0 +1,13 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'echoe'
4
+
5
+ Echoe.new('cucumber_scaffold', '0.1.0') do |p|
6
+ p.description = "Generate scaffolding for Cucumber features and steps definitions"
7
+ p.url = "http://github.com/andyw8/cucumber_scaffold"
8
+ p.author = "Andy Waite"
9
+ p.email = "andy@andywaite.com"
10
+ p.development_dependencies = []
11
+ end
12
+
13
+ Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
data/TODO ADDED
@@ -0,0 +1,11 @@
1
+ * Test with webrat as well as capybara
2
+ * Test with Rails 2.x
3
+ * Test with Formtastic
4
+ * Test with inherited_resources
5
+ * Test with with inherited_resources_views
6
+ * Add support for booleans (checkboxes)
7
+ * Add support for date/time fields
8
+ * Add support for belongs_to associations
9
+ * Test for model names containing more than one word (e.g. DocumentCategory)
10
+ * Add automated test suite
11
+ * Prevent excess whitespace in generated files
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{cucumber_scaffold}
5
+ s.version = "0.1.0"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Andy Waite"]
9
+ s.date = %q{2010-11-06}
10
+ s.description = %q{Generate scaffolding for Cucumber features and steps definitions}
11
+ s.email = %q{andy@andywaite.com}
12
+ s.extra_rdoc_files = ["README.rdoc", "TODO", "lib/generators/cucumber_scaffold/feature/USAGE", "lib/generators/cucumber_scaffold/feature/feature_generator.rb", "lib/generators/cucumber_scaffold/feature/templates/feature.feature", "lib/generators/cucumber_scaffold/feature/templates/steps.rb", "lib/generators/cucumber_scaffold/install/USAGE", "lib/generators/cucumber_scaffold/install/install_generator.rb", "lib/generators/cucumber_scaffold/install/templates/shared/web_steps_additional.rb"]
13
+ s.files = ["Manifest", "README.rdoc", "Rakefile", "TODO", "cucumber_scaffold.gemspec", "lib/generators/cucumber_scaffold/feature/USAGE", "lib/generators/cucumber_scaffold/feature/feature_generator.rb", "lib/generators/cucumber_scaffold/feature/templates/feature.feature", "lib/generators/cucumber_scaffold/feature/templates/steps.rb", "lib/generators/cucumber_scaffold/install/USAGE", "lib/generators/cucumber_scaffold/install/install_generator.rb", "lib/generators/cucumber_scaffold/install/templates/shared/web_steps_additional.rb"]
14
+ s.homepage = %q{http://github.com/andyw8/cucumber_scaffold}
15
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Cucumber_scaffold", "--main", "README.rdoc"]
16
+ s.require_paths = ["lib"]
17
+ s.rubyforge_project = %q{cucumber_scaffold}
18
+ s.rubygems_version = %q{1.3.7}
19
+ s.summary = %q{Generate scaffolding for Cucumber features and steps definitions}
20
+
21
+ if s.respond_to? :specification_version then
22
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
23
+ s.specification_version = 3
24
+
25
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
26
+ else
27
+ end
28
+ else
29
+ end
30
+ end
@@ -0,0 +1,22 @@
1
+ Description:
2
+ Scaffolding for Cucumber features
3
+
4
+ Example:
5
+
6
+ rails generate cucumber_scaffold_feature Post title:string body:text
7
+
8
+ This will create:
9
+ features/manage_posts.rb
10
+ features/step_definitions/post_steps.rb
11
+
12
+ and will modify:
13
+ features/support/paths.rb
14
+
15
+ Options:
16
+
17
+ --nifty
18
+ Generate features and steps which match the scaffold created by nifty-generators
19
+ ( https://github.com/ryanb/nifty-generators )
20
+
21
+ --tags
22
+ Include Cucumbers @tags matching each scenario to one or more controller actions
@@ -0,0 +1,194 @@
1
+ module CucumberScaffold
2
+ class FeatureGenerator < Rails::Generators::NamedBase
3
+
4
+ INDENT = " "
5
+ LINE_BREAK_WITH_INDENT = "\n#{INDENT}"
6
+ LINE_BREAK_WITH_INDENT_COMMENTED = "\n#{INDENT}# "
7
+
8
+ argument :model_name, :type => :string
9
+
10
+ source_root File.expand_path('../templates', __FILE__)
11
+
12
+ def initialize(args, *options)
13
+ # copied setup from
14
+ # http://apidock.com/rails/Rails/Generators/NamedBase/new/class
15
+ args[0] = args[0].dup if args[0].is_a?(String) && args[0].frozen?
16
+ super
17
+ assign_names!(self.name)
18
+ parse_attributes! if respond_to?(:attributes)
19
+ args.shift
20
+ @args = args
21
+ end
22
+
23
+ def do_it
24
+ @attributes = []
25
+ @args.each do |param_pair|
26
+ name, type = param_pair.split(':')
27
+ @attributes << { name => type }
28
+ end
29
+
30
+ template('feature.feature', "features/manage_#{plural}.feature")
31
+ template('steps.rb', "features/step_definitions/#{singular}_steps.rb")
32
+
33
+ extra_paths = <<EOF
34
+ when /edit page for that #{singular}/
35
+ edit_#{singular}_path(@#{singular})
36
+ when /page for that #{singular}/
37
+ raise 'no #{singular}' unless @#{singular}
38
+ #{singular}_path(@#{singular})
39
+ when /edit page for the (\\d+)(?:st|nd|rd|th) #{singular}/
40
+ raise 'no #{plural}' unless @#{plural}
41
+ nth_#{singular} = @#{plural}[$1.to_i - 1]
42
+ edit_#{singular}_path(nth_#{singular})
43
+ when /page for the (\\d+)(?:st|nd|rd|th) #{singular}/
44
+ raise 'no #{plural}' unless @#{plural}
45
+ nth_#{singular} = @#{plural}[$1.to_i - 1]
46
+ #{singular}_path(nth_#{singular})
47
+ EOF
48
+
49
+ gsub_file 'features/support/paths.rb', /'\/'/mi do |match|
50
+ "#{match}\n" + extra_paths
51
+ end
52
+
53
+ end
54
+
55
+ private
56
+
57
+ def generated_by
58
+ '# Generated by cucumber_scaffold - http://github.com/andyw8/cucumber_scaffold'
59
+ end
60
+
61
+ def nifty?
62
+ options[:nifty].present?
63
+ end
64
+
65
+ def singular
66
+ name.underscore.downcase
67
+ end
68
+
69
+ def plural
70
+ singular.pluralize
71
+ end
72
+
73
+ def singular_title
74
+ singular.titleize
75
+ end
76
+
77
+ def plural_title
78
+ plural.titleize
79
+ end
80
+
81
+ def activerecord_table_header_row
82
+ make_row(attribute_names)
83
+ end
84
+
85
+ def html_table_header_row
86
+ make_row(attribute_names.map(&:titleize))
87
+ end
88
+
89
+ def attribute_names
90
+ @attributes.collect {|a| a.first[0]}
91
+ end
92
+
93
+ def html_single_resource(updated=nil, commented=nil)
94
+ lines = []
95
+ @attributes.each do |pair|
96
+ attribute_name = pair.first[0]
97
+ attribute_value = pair.first[1]
98
+ lines << "| #{attribute_name.titleize}: | #{default_value(attribute_name, attribute_value, updated)} |"
99
+ end
100
+ lines.join(commented ? LINE_BREAK_WITH_INDENT_COMMENTED : LINE_BREAK_WITH_INDENT)
101
+ end
102
+
103
+ def form_single_resource_commented
104
+ form_single_resource(false, true)
105
+ end
106
+
107
+ def html_single_resource_commented
108
+ html_single_resource(false, true)
109
+ end
110
+
111
+ def form_single_resource(updated=nil, commented=nil)
112
+ lines = []
113
+ @attributes.each do |pair|
114
+ attribute_name = pair.first[0]
115
+ attribute_value = pair.first[1]
116
+ lines << "| #{attribute_name.titleize} | #{default_value(attribute_name, attribute_value, updated)} |"
117
+ end
118
+ result = lines.join(commented ? LINE_BREAK_WITH_INDENT_COMMENTED : LINE_BREAK_WITH_INDENT)
119
+ end
120
+
121
+ def activerecord_single_resource(updated=nil)
122
+ lines = []
123
+ @attributes.each do |pair|
124
+ attribute_name = pair.first[0]
125
+ attribute_value = pair.first[1]
126
+ lines << "| #{attribute_name} | #{default_value(attribute_name, attribute_value, updated)} |"
127
+ end
128
+ lines.join(LINE_BREAK_WITH_INDENT)
129
+ end
130
+
131
+ def html_resources
132
+ [html_table_header_row,
133
+ html_table_row(1),
134
+ html_table_row(2),
135
+ html_table_row(3)].join(LINE_BREAK_WITH_INDENT)
136
+ end
137
+
138
+ def activerecord_resources
139
+ [activerecord_table_header_row,
140
+ activerecord_table_row(1),
141
+ activerecord_table_row(2),
142
+ activerecord_table_row(3)].join(LINE_BREAK_WITH_INDENT)
143
+ end
144
+
145
+ def activerecord_single_resource_updated
146
+ activerecord_single_resource(true)
147
+ end
148
+
149
+ def form_single_resource_updated
150
+ form_single_resource(true)
151
+ end
152
+
153
+ def html_single_resource_updated
154
+ html_single_resource(true)
155
+ end
156
+
157
+ def default_value(attribute_name, attribute_type, updated=false, index=1)
158
+ # TODO use an options hash instead of all these arguments
159
+ if ['string', 'text'].include?(attribute_type)
160
+ result = "#{attribute_name} #{index}"
161
+ result += ' updated' if updated
162
+ elsif attribute_type == 'integer'
163
+ result = 10 + index
164
+ result = -result if updated
165
+ else
166
+ raise "Cannot create default value for attribute type '#{attribute_type}'"
167
+ end
168
+ result
169
+ end
170
+
171
+ def activerecord_table_row(n)
172
+ data = []
173
+ @attributes.each do |attribute|
174
+ attribute_name = attribute.first[0]
175
+ attribute_type = attribute.first[1]
176
+ data << default_value(attribute_name, attribute_type, false, n)
177
+ end
178
+ make_row(data)
179
+ end
180
+
181
+ def html_table_row(n)
182
+ activerecord_table_row(n)
183
+ end
184
+
185
+ def tags(tags)
186
+ tags
187
+ end
188
+
189
+ def make_row(data)
190
+ "| #{data.join(' | ')} |"
191
+ end
192
+
193
+ end
194
+ end
@@ -0,0 +1,282 @@
1
+ <%= generated_by %>
2
+ <%
3
+ update_button_title = 'Update'
4
+ create_button_title = 'Create'
5
+
6
+ if nifty?
7
+ successful_update_message = "Successfully updated #{singular}."
8
+ successful_create_message = "Successfully created #{singular}."
9
+ successful_destroy_message = "Successfully destroyed #{singular}."
10
+ new_heading = "New #{singular_title}"
11
+ edit_heading = "Edit #{singular_title}"
12
+ index_heading = plural_title
13
+ show_heading = singular_title
14
+ new_title = new_heading
15
+ edit_title = edit_heading
16
+ index_title = index_heading
17
+ show_title = show_heading
18
+ back_to_all = 'Back to List'
19
+ problems_intro = 'Correct the following errors and try again.'
20
+ else
21
+ problems_intro =
22
+ successful_update_message = "#{singular_title} was successfully updated."
23
+ successful_create_message = "#{singular_title} was successfully created."
24
+ index_heading = "Listing #{plural}"
25
+ edit_heading = "Editing #{singular}"
26
+ new_heading = "New #{singular}"
27
+ back_to_all = 'Back'
28
+ problems_intro = "prohibited this post from being saved:"
29
+ end
30
+
31
+ pending_explanation_1 = "You should use this scenario as the basis for scenarios involving ActiveRecord validations, or delete it if it's not required"
32
+ pending_explanation_2 = "[You should add checks for specific errors here. It may be appropriate to add extra scenarios.]"
33
+ -%>
34
+
35
+ Feature: Manage <%= plural_title %>
36
+ In order to [goal]
37
+ [stakeholder]
38
+ wants [behaviour]
39
+
40
+ <%= tags('@index') %>
41
+ Scenario: List all <%= plural %>
42
+ Given the following <%= plural %>:
43
+ <%= activerecord_table_header_row %>
44
+ <%= activerecord_table_row(1) %>
45
+ <%= activerecord_table_row(2) %>
46
+ <%= activerecord_table_row(3) %>
47
+ When I go to the <%= plural %> page
48
+ Then I should see the following <%= plural %>:
49
+ <%= html_table_header_row %>
50
+ <%= html_table_row(1) %>
51
+ <%= html_table_row(2) %>
52
+ <%= html_table_row(3) %>
53
+
54
+ <%= tags('@show') %>
55
+ Scenario: View a <%= singular %>
56
+ Given the following <%= singular %>:
57
+ <%= activerecord_single_resource %>
58
+ When I go to the page for that <%= singular %>
59
+ Then I should see the following <%= singular %>:
60
+ <%= html_single_resource %>
61
+
62
+ <%= tags('@edit') %>
63
+ Scenario: Edit a <%= singular %>
64
+ Given the following <%= singular %>:
65
+ <%= activerecord_single_resource %>
66
+ When I go to the edit page for that <%= singular %>
67
+ Then I should see the following form field values:
68
+ <%= form_single_resource %>
69
+
70
+ <%= tags('@index @destroy') %>
71
+ Scenario: Delete a <%= singular %> via the index page
72
+ Given the following <%= plural %>:
73
+ <%= activerecord_table_header_row %>
74
+ <%= activerecord_table_row(1) %>
75
+ <%= activerecord_table_row(2) %>
76
+ <%= activerecord_table_row(3) %>
77
+ When I go to the <%= plural %> page
78
+ And I click "Destroy" in the 2nd row
79
+ Then I should see the following <%= plural %>:
80
+ <%= html_table_header_row %>
81
+ <%= activerecord_table_row(1) %>
82
+ <%= activerecord_table_row(3) %>
83
+ And I should be on the <%= plural %> page
84
+ <% if successful_destroy_message %>
85
+ And I should see "<%= successful_destroy_message %>"
86
+ <% end -%>
87
+
88
+ <% if nifty? %>
89
+ <%= tags('@show @destroy @index') %>
90
+ Scenario: Delete a <%= singular %> via the show page
91
+ Given the following <%= plural %>:
92
+ <%= activerecord_table_header_row %>
93
+ <%= activerecord_table_row(1) %>
94
+ <%= activerecord_table_row(2) %>
95
+ <%= activerecord_table_row(3) %>
96
+ When I go to the page for the 2nd post
97
+ And I follow "Destroy"
98
+ Then I should see the following <%= plural %>:
99
+ <%= html_table_header_row %>
100
+ <%= activerecord_table_row(1) %>
101
+ <%= activerecord_table_row(3) %>
102
+ And I should be on the <%= plural %> page
103
+ And I should see "<%= successful_destroy_message %>"
104
+ <% end -%>
105
+
106
+ <%= tags('@new @create @show') %>
107
+ Scenario: Create a new <%= singular %>
108
+ Pending
109
+ # Given I am on the new <%= singular %> page
110
+ # When I fill in the following:
111
+ # <%= form_single_resource_commented %>
112
+ # And I press "<%= create_button_title %>"
113
+ # Then I should see "<%= successful_create_message %>"
114
+ # And I should see the following <%= singular %>:
115
+ # <%= html_single_resource_commented %>
116
+ #
117
+ # In order to confirm that the user is redirected to the correct page
118
+ # after create, you'll need to add an entry to paths.rb to uniquely
119
+ # find a <%= singular %>, e.g.:
120
+ #
121
+ # when /page for the <%= singular %> with name "([^"]*)"$/
122
+ # conditions = { :conditions => {:name => $1} }
123
+ # matches = <%= singular_title %>.all(conditions)
124
+ # if matches.size == 0
125
+ # raise "Could not find any <%= plural %> using criteria #{conditions.inspect}"
126
+ # elsif matches.size > 1
127
+ # raise "Could not find a unique <%= singular %> using criteria #{conditions.inspect} (#{matches.size} matches)"
128
+ # end
129
+ # <%= singular %>_path(matches.first)
130
+ #
131
+ # Then add a step such as this to the scenario:
132
+ #
133
+ # And I should be on the page for the <%= singular %> with name "..."
134
+
135
+ <%= tags('@new @create') %>
136
+ Scenario: Attempt to create a new <%= singular %> with invalid input
137
+ Pending
138
+ # <%= pending_explanation_1 %>
139
+ # Given I am on the new <%= singular %> page
140
+ # When I fill in the following:
141
+ # <%= form_single_resource_commented %>
142
+ # And I press "<%= create_button_title %>"
143
+ # Then I should see "<%= problems_intro %>"
144
+ #
145
+ # <%= pending_explanation_2 %>
146
+ #
147
+ # And I should be on the <%= plural %> page
148
+ # And I should see the following form field values:
149
+ # <%= html_single_resource_commented %>
150
+
151
+ <%= tags('@edit @update') %>
152
+ Scenario: Attempt to update a <%= singular %> with invalid input
153
+ Pending
154
+ # <%= pending_explanation_1 %>
155
+ # Given a <%= singular %> exists
156
+ # When I go to the edit page for that <%= singular %>
157
+ # And I fill in the following:
158
+ # <%= form_single_resource_commented %>
159
+ # And I press "<%= update_button_title %>"
160
+ # Then I should see "<%= problems_intro %>"
161
+ #
162
+ # <%= pending_explanation_2 %>
163
+ #
164
+ # And I should be on the page for that <%= singular %>
165
+ # And I should see the following form field values:
166
+ # <%= html_single_resource_commented %>
167
+
168
+ <%= tags('@edit @update @show') %>
169
+ Scenario: Update a <%= singular %>
170
+ Given a <%= singular %> exists
171
+ When I go to the edit page for that <%= singular %>
172
+ And I fill in the following:
173
+ <%= form_single_resource_updated %>
174
+ And I press "<%= update_button_title %>"
175
+ Then I should be on the page for that <%= singular %>
176
+ And I should see "<%= successful_update_message %>"
177
+ And I should see the following <%= singular %>:
178
+ <%= html_single_resource_updated %>
179
+
180
+ <%= tags('@index @new') %>
181
+ Scenario: Navigate from the <%= plural %> page to the new <%= singular %> page
182
+ Given I am on the <%= plural %> page
183
+ When I follow "New <%= singular_title %>"
184
+ Then I should be on the new <%= singular %> page
185
+
186
+ <%= tags('@index @show') %>
187
+ Scenario: Navigate from <%= plural %> page to the show <%= singular %> page
188
+ Given the following <%= plural %>:
189
+ <%= activerecord_table_header_row %>
190
+ <%= activerecord_table_row(1) %>
191
+ <%= activerecord_table_row(2) %>
192
+ <%= activerecord_table_row(3) %>
193
+ When I go to the <%= plural %> page
194
+ And I click "Show" in the 2nd row
195
+ Then I should be on the page for the 2nd <%= singular %>
196
+
197
+ <%= tags('@index @edit') %>
198
+ Scenario: Navigate from <%= plural %> page to the edit <%= singular %> page
199
+ Given the following <%= plural %>:
200
+ <%= activerecord_table_header_row %>
201
+ <%= activerecord_table_row(1) %>
202
+ <%= activerecord_table_row(2) %>
203
+ <%= activerecord_table_row(3) %>
204
+ When I go to the <%= plural %> page
205
+ And I click "Edit" in the 2nd row
206
+ Then I should be on the edit page for the 2nd <%= singular %>
207
+
208
+ <%= tags('@new @index') %>
209
+ Scenario: Navigate from new <%= singular %> page to <%= plural %> page
210
+ Given I am on the new <%= singular %> page
211
+ When I follow "<%= back_to_all %>"
212
+ Then I should be on the <%= plural %> page
213
+
214
+ <%= tags('@edit @show') %>
215
+ Scenario: Navigate from the edit <%= singular %> page to the show <%= singular %> page
216
+ Given a <%= singular %> exists
217
+ When I go to the edit page for that <%= singular %>
218
+ And I follow "Show"
219
+ Then I should be on the page for that <%= singular %>
220
+
221
+ <%= tags('@edit @index') %>
222
+ Scenario: Navigate from edit <%= singular %> page to the <%= plural %> page
223
+ Given a <%= singular %> exists
224
+ When I go to the edit page for that <%= singular %>
225
+ And I follow "<%= back_to_all %>"
226
+ Then I should be on the <%= plural %> page
227
+
228
+ <%= tags('@show @edit') %>
229
+ Scenario: Navigate from show <%= singular %> page to edit <%= singular %> page
230
+ Given a <%= singular %> exists
231
+ When I go to the page for that <%= singular %>
232
+ And I follow "Edit"
233
+ Then I should be on the edit page for that <%= singular %>
234
+
235
+ <%= tags('@show @index') %>
236
+ Scenario: Navigate from show <%= singular %> page to <%= plural %> page
237
+ Given a <%= singular %> exists
238
+ And I am on the page for that <%= singular %>
239
+ <% if nifty? %>
240
+ And I follow "View All"
241
+ <% else %>
242
+ And I follow "Back"
243
+ <% end %>
244
+ Then I should be on the <%= plural %> page
245
+
246
+ <%= tags('@index') %>
247
+ Scenario: <%= plural_title %> page title
248
+ When I go to the <%= plural %> page
249
+ Then the heading should be "<%= index_heading %>"
250
+ <% if index_title %>
251
+ And the title should be "<%= index_title %>"
252
+ <% end -%>
253
+
254
+ <%= tags('@show') %>
255
+ <% if show_heading || index_title %>
256
+ Scenario: <%= singular_title %> page title
257
+ Given a <%= singular %> exists
258
+ When I go to the page for that <%= singular %>
259
+ <% if show_heading %>
260
+ Then the heading should be "<%= show_heading %>"
261
+ <% end %>
262
+ <% if index_title %>
263
+ And the title should be "<%= show_title %>"
264
+ <% end -%>
265
+ <% end -%>
266
+
267
+ <%= tags('@new') %>
268
+ Scenario: New <%= singular %> page title
269
+ When I go to the new <%= singular %> page
270
+ Then the heading should be "<%= new_heading %>"
271
+ <% if index_title %>
272
+ And the title should be "<%= new_title %>"
273
+ <% end -%>
274
+
275
+ <%= tags('@edit') %>
276
+ Scenario: Edit <%= singular %> page title
277
+ Given a <%= singular %> exists
278
+ When I go to the edit page for that <%= singular %>
279
+ Then the heading should be "<%= edit_heading %>"
280
+ <% if index_title %>
281
+ And the title should be "<%= edit_title %>"
282
+ <% end -%>
@@ -0,0 +1,40 @@
1
+ <%= generated_by %>
2
+
3
+ Given /^a <%= singular %> exists$/ do
4
+ @<%= singular %> = <%= singular_title %>.create!(valid_<%= singular %>_attributes)
5
+ end
6
+
7
+ Then /^I should see the following <%= singular %>:$/ do |expected_table|
8
+
9
+ <% if nifty? %>
10
+ show_fields_css_query = 'body p strong'
11
+ <% else %>
12
+ show_fields_css_query = 'body p b'
13
+ <% end %>
14
+
15
+ actual_table = tableish(show_fields_css_query, lambda{|label| [label, label.next]})
16
+ actual = {}
17
+ actual_table.each do |form_entry|
18
+ attr_name = form_entry[0]
19
+ attr_value = form_entry[1]
20
+ actual[attr_name] = attr_value
21
+ end
22
+ assert_equal actual, expected_table.rows_hash
23
+ end
24
+
25
+ Then /^I should see the following <%= plural %>:$/ do |expected_table|
26
+ expected_table.diff!(tableish('table tr', 'td,th'))
27
+ end
28
+
29
+ Given /^the following <%= plural %>:$/ do |table|
30
+ @<%= plural %> = <%= singular_title %>.create!(table.hashes)
31
+ end
32
+
33
+ Given /^the following <%= singular %>:$/ do |table|
34
+ @<%= singular %> = <%= singular_title %>.create!(table.rows_hash)
35
+ end
36
+
37
+ def valid_<%= singular %>_attributes
38
+ # You may want to a factory for this
39
+ {}
40
+ end
@@ -0,0 +1,9 @@
1
+ Description:
2
+ Scaffolding installer for Cucumber features
3
+
4
+ Example:
5
+
6
+ rails generate cucumber_scaffold_install
7
+
8
+ This will create:
9
+ features/shared/web_steps_additional.rbtching each scenario to one or more controller actions
@@ -0,0 +1,13 @@
1
+ module CucumberScaffold
2
+ class InstallGenerator < Rails::Generators::Base
3
+
4
+ source_root File.expand_path('../templates', __FILE__)
5
+
6
+ def do_it
7
+
8
+ template('shared/web_steps_additional.rb', 'features/step_definitions/web_steps_additional.rb')
9
+
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,38 @@
1
+ When /^I click "([^"]*)" in the (\d+)(?:st|nd|rd|th) row$/ do |link, pos|
2
+ within("table tr:nth-child(#{pos.to_i+1})") do
3
+ click_link link
4
+ end
5
+ end
6
+
7
+ Then /^the heading should be "([^"]*)"$/ do |heading|
8
+ Then %{I should see "#{heading}" within "h1"}
9
+ end
10
+
11
+ Then /^the title should be "([^"]*)"$/ do |title|
12
+ Then %{I should see "#{title}" within "title"}
13
+ end
14
+
15
+ When /^I should see the following form field values:$/ do |table|
16
+ form_fields = tableish('form label', lambda{ |label| [label, form_field_for_label(label)]})
17
+ form_fields_hash = {}
18
+ form_fields.each do |form_field|
19
+ attr_name = form_field[0]
20
+ attr_value = form_field[1]
21
+ form_fields_hash[attr_name] = attr_value
22
+ end
23
+ assert_equal table.rows_hash, form_fields_hash
24
+ end
25
+
26
+ def form_field_for_label(label)
27
+ input_tags = label.parent.css('input,textarea')
28
+ return if input_tags.size == 0
29
+ if input_tags.size > 1
30
+ raise "Wrong number of input tags while parsing form (found #{input_tags.size})"
31
+ end
32
+ input_tag = input_tags.first
33
+ if input_tag.name == 'textarea'
34
+ input_tag.inner_html
35
+ elsif input_tag.name == 'input'
36
+ input_tag['value']
37
+ end
38
+ end
metadata ADDED
@@ -0,0 +1,92 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cucumber_scaffold
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Andy Waite
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-11-06 00:00:00 +00:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: Generate scaffolding for Cucumber features and steps definitions
23
+ email: andy@andywaite.com
24
+ executables: []
25
+
26
+ extensions: []
27
+
28
+ extra_rdoc_files:
29
+ - README.rdoc
30
+ - TODO
31
+ - lib/generators/cucumber_scaffold/feature/USAGE
32
+ - lib/generators/cucumber_scaffold/feature/feature_generator.rb
33
+ - lib/generators/cucumber_scaffold/feature/templates/feature.feature
34
+ - lib/generators/cucumber_scaffold/feature/templates/steps.rb
35
+ - lib/generators/cucumber_scaffold/install/USAGE
36
+ - lib/generators/cucumber_scaffold/install/install_generator.rb
37
+ - lib/generators/cucumber_scaffold/install/templates/shared/web_steps_additional.rb
38
+ files:
39
+ - Manifest
40
+ - README.rdoc
41
+ - Rakefile
42
+ - TODO
43
+ - cucumber_scaffold.gemspec
44
+ - lib/generators/cucumber_scaffold/feature/USAGE
45
+ - lib/generators/cucumber_scaffold/feature/feature_generator.rb
46
+ - lib/generators/cucumber_scaffold/feature/templates/feature.feature
47
+ - lib/generators/cucumber_scaffold/feature/templates/steps.rb
48
+ - lib/generators/cucumber_scaffold/install/USAGE
49
+ - lib/generators/cucumber_scaffold/install/install_generator.rb
50
+ - lib/generators/cucumber_scaffold/install/templates/shared/web_steps_additional.rb
51
+ has_rdoc: true
52
+ homepage: http://github.com/andyw8/cucumber_scaffold
53
+ licenses: []
54
+
55
+ post_install_message:
56
+ rdoc_options:
57
+ - --line-numbers
58
+ - --inline-source
59
+ - --title
60
+ - Cucumber_scaffold
61
+ - --main
62
+ - README.rdoc
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ hash: 3
71
+ segments:
72
+ - 0
73
+ version: "0"
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ hash: 11
80
+ segments:
81
+ - 1
82
+ - 2
83
+ version: "1.2"
84
+ requirements: []
85
+
86
+ rubyforge_project: cucumber_scaffold
87
+ rubygems_version: 1.3.7
88
+ signing_key:
89
+ specification_version: 3
90
+ summary: Generate scaffolding for Cucumber features and steps definitions
91
+ test_files: []
92
+