cucumber_scaffold 0.1.0

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.
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
+