Commit 1fb5bbf6bea269d95504b37f97f87f687ccb2c8d

Authored by Dan Croak
1 parent 75ebbbce

upgraded coulda

Showing 25 changed files with 349 additions and 315 deletions   Show diff stats
vendor/plugins/coulda/README.textile
1 h1. Coulda generators 1 h1. Coulda generators
2 2
3 -A plugin that overrides Rails' model, controller, & helper generators. It also adds a view generator. It uses Shoulda & Factory Girl for tests. 3 +A Rails plugin for feature, view, controller, model, & helper generators. It is meant to be used as part of an "Outside-In" Test-Driven Development cycle.
4 4
5 h2. Requirements 5 h2. Requirements
6 6
  7 +* "Cucumber":http://github.com/aslakhellesoy/cucumber
7 * "Shoulda":http://github.com/thoughtbot/shoulda 8 * "Shoulda":http://github.com/thoughtbot/shoulda
8 * "Factory Girl":http://github.com/thoughtbot/factory_girl 9 * "Factory Girl":http://github.com/thoughtbot/factory_girl
  10 +* "Mocha":http://github.com/jferris/mocha
9 11
10 h2. Installation 12 h2. Installation
11 13
12 $ script/plugin install git://github.com/dancroak/coulda.git 14 $ script/plugin install git://github.com/dancroak/coulda.git
13 15
  16 +h2. Feature generator
  17 +
  18 + $ script/generate feature Posts new create
  19 +
  20 +generates...
  21 +
  22 +<pre><code> Scenario: Create a new post
  23 + Given I am on the new post page
  24 + When I create a 'post' named 'A new post'
  25 + Then I should see 'A new post'</code></pre>
  26 +
  27 +Now run it:
  28 +
  29 + $ cucumber features/posts.feature
  30 +
  31 +The failure will be:
  32 +
  33 + undefined method `new_post_path'
  34 +
  35 +To get past this error, we'll create just the route we need:
  36 +
  37 + map.resources :posts, :only => [:new]
  38 +
  39 +Running the test again, we have a new failure:
  40 +
  41 + uninitialized constant PostsController
  42 +
  43 +h2. Controller test generator
  44 +
  45 +We've reached a point in our Outside-In cycle where we want to spiral down into a tighter feedback loop to unit test the non-existant controller.
  46 +
  47 + $ script/generate controller_test Posts new create
  48 +
  49 +h2. Controller generator
  50 +
  51 + $ script/generate controller Posts new create
  52 +
  53 +generates...
  54 +
  55 +
14 h2. Model generator 56 h2. Model generator
15 57
16 $ script/generate model User 58 $ script/generate model User
@@ -20,14 +62,6 @@ h2. Model generator @@ -20,14 +62,6 @@ h2. Model generator
20 * migration 62 * migration
21 * model 63 * model
22 64
23 -h2. Controller generator  
24 -  
25 - $ script/generate controller Users new  
26 -  
27 -* functional test (Shoulda & Factory Girl), only test RESTful new action  
28 -* controller, only RESTful new action  
29 -* no helper file  
30 -  
31 h2. Helper generator 65 h2. Helper generator
32 66
33 $ script/generate helper Navigation 67 $ script/generate helper Navigation
@@ -39,16 +73,11 @@ h2. View generator @@ -39,16 +73,11 @@ h2. View generator
39 73
40 $ script/generate view Posts new 74 $ script/generate view Posts new
41 75
42 -* We're not sure we like this one yet. Let us know what you think.  
43 -  
44 h2. Model generator: belongs_to 76 h2. Model generator: belongs_to
45 77
46 $ script/generate model post user:belongs_to 78 $ script/generate model post user:belongs_to
47 79
48 -* "add_index" in the migration  
49 -* "belongs_to" in the model  
50 -* "should_belong_to" in unit test  
51 -* association in the factory 80 +generates...
52 81
53 <pre><code>class CreatePosts < ActiveRecord::Migration 82 <pre><code>class CreatePosts < ActiveRecord::Migration
54 def self.up 83 def self.up
vendor/plugins/coulda/features/controller_generator.feature
@@ -9,7 +9,6 @@ Feature: Rails controller generator @@ -9,7 +9,6 @@ Feature: Rails controller generator
9 When I generate a "Posts" controller with "index" action 9 When I generate a "Posts" controller with "index" action
10 Then a standard "index" functional test for "posts" should be generated 10 Then a standard "index" functional test for "posts" should be generated
11 And an empty "index" controller action for "posts" should be generated 11 And an empty "index" controller action for "posts" should be generated
12 - And only a "index" action for RESTful "posts" route should be generated  
13 12
14 Scenario: Controller generator for new action 13 Scenario: Controller generator for new action
15 Given a Rails app 14 Given a Rails app
@@ -17,7 +16,6 @@ Feature: Rails controller generator @@ -17,7 +16,6 @@ Feature: Rails controller generator
17 When I generate a "Posts" controller with "new" action 16 When I generate a "Posts" controller with "new" action
18 Then a standard "new" functional test for "posts" should be generated 17 Then a standard "new" functional test for "posts" should be generated
19 And a "new" controller action for "posts" should be generated 18 And a "new" controller action for "posts" should be generated
20 - And only a "new" action for RESTful "posts" route should be generated  
21 19
22 Scenario: Controller generator for create action 20 Scenario: Controller generator for create action
23 Given a Rails app 21 Given a Rails app
@@ -25,7 +23,6 @@ Feature: Rails controller generator @@ -25,7 +23,6 @@ Feature: Rails controller generator
25 When I generate a "Posts" controller with "create" action 23 When I generate a "Posts" controller with "create" action
26 Then a standard "create" functional test for "posts" should be generated 24 Then a standard "create" functional test for "posts" should be generated
27 And a "create" controller action for "posts" should be generated 25 And a "create" controller action for "posts" should be generated
28 - And only a "create" action for RESTful "posts" route should be generated  
29 26
30 Scenario: Controller generator for create action when Cucumber is installed 27 Scenario: Controller generator for create action when Cucumber is installed
31 Given a Rails app with Cucumber 28 Given a Rails app with Cucumber
@@ -33,7 +30,6 @@ Feature: Rails controller generator @@ -33,7 +30,6 @@ Feature: Rails controller generator
33 When I generate a "Posts" controller with "create" action 30 When I generate a "Posts" controller with "create" action
34 Then a standard "create" functional test for "posts" should be generated 31 Then a standard "create" functional test for "posts" should be generated
35 And a "create" controller action for "posts" should be generated 32 And a "create" controller action for "posts" should be generated
36 - And only a "create" action for RESTful "posts" route should be generated  
37 33
38 Scenario: Controller generator for show action 34 Scenario: Controller generator for show action
39 Given a Rails app 35 Given a Rails app
@@ -41,7 +37,6 @@ Feature: Rails controller generator @@ -41,7 +37,6 @@ Feature: Rails controller generator
41 When I generate a "Posts" controller with "show" action 37 When I generate a "Posts" controller with "show" action
42 Then a standard "show" functional test for "posts" should be generated 38 Then a standard "show" functional test for "posts" should be generated
43 And a "show" controller action for "posts" should be generated 39 And a "show" controller action for "posts" should be generated
44 - And only a "show" action for RESTful "posts" route should be generated  
45 40
46 Scenario: Controller generator for edit action 41 Scenario: Controller generator for edit action
47 Given a Rails app 42 Given a Rails app
@@ -49,7 +44,6 @@ Feature: Rails controller generator @@ -49,7 +44,6 @@ Feature: Rails controller generator
49 When I generate a "Posts" controller with "edit" action 44 When I generate a "Posts" controller with "edit" action
50 Then a standard "edit" functional test for "posts" should be generated 45 Then a standard "edit" functional test for "posts" should be generated
51 And a "edit" controller action for "posts" should be generated 46 And a "edit" controller action for "posts" should be generated
52 - And only a "edit" action for RESTful "posts" route should be generated  
53 47
54 Scenario: Controller generator for update action 48 Scenario: Controller generator for update action
55 Given a Rails app 49 Given a Rails app
@@ -57,7 +51,6 @@ Feature: Rails controller generator @@ -57,7 +51,6 @@ Feature: Rails controller generator
57 When I generate a "Posts" controller with "update" action 51 When I generate a "Posts" controller with "update" action
58 Then a standard "update" functional test for "posts" should be generated 52 Then a standard "update" functional test for "posts" should be generated
59 And a "update" controller action for "posts" should be generated 53 And a "update" controller action for "posts" should be generated
60 - And only a "update" action for RESTful "posts" route should be generated  
61 54
62 Scenario: Controller generator for destroy action 55 Scenario: Controller generator for destroy action
63 Given a Rails app 56 Given a Rails app
@@ -65,5 +58,4 @@ Feature: Rails controller generator @@ -65,5 +58,4 @@ Feature: Rails controller generator
65 When I generate a "Posts" controller with "destroy" action 58 When I generate a "Posts" controller with "destroy" action
66 Then a standard "destroy" functional test for "posts" should be generated 59 Then a standard "destroy" functional test for "posts" should be generated
67 And a "destroy" controller action for "posts" should be generated 60 And a "destroy" controller action for "posts" should be generated
68 - And only a "destroy" action for RESTful "posts" route should be generated  
69 61
vendor/plugins/coulda/features/feature_generator.feature 0 → 100644
@@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
  1 +Feature: Rails controller generator
  2 + In order to better do Test-Driven Development with Rails
  3 + As a user
  4 + I want to generate Shoulda & Factory Girl tests for only RESTful actions I need.
  5 +
  6 + Scenario: Feature generator for new action
  7 + Given a Rails app with Cucumber
  8 + And the coulda plugin is installed
  9 + When I generate a "new" feature for "Posts"
  10 + Then a "posts" feature for the "create" scenario should be generated
  11 + And a "posts" step definition should be generated
  12 + And a new post page path should be generated
  13 +
  14 + Scenario: Feature generator for create action same as new
  15 + Given a Rails app with Cucumber
  16 + And the coulda plugin is installed
  17 + When I generate a "create" feature for "Posts"
  18 + Then a "posts" feature for the "create" scenario should be generated
  19 + And a "posts" step definition should be generated
  20 + And a new post page path should be generated
  21 +
vendor/plugins/coulda/features/step_definitions/controller_steps.rb
@@ -5,180 +5,155 @@ When /^I generate a &quot;(.*)&quot; controller with &quot;(.*)&quot; action$/ do |controller, actio @@ -5,180 +5,155 @@ When /^I generate a &quot;(.*)&quot; controller with &quot;(.*)&quot; action$/ do |controller, actio
5 end 5 end
6 6
7 Then /^a standard "index" functional test for "posts" should be generated$/ do 7 Then /^a standard "index" functional test for "posts" should be generated$/ do
8 - assert_generated_functional_test_for("posts") do |body|  
9 - expected = " context 'GET to index' do\n" <<  
10 - " setup { get :index }\n\n" <<  
11 - " should_render_template :index\n" <<  
12 - " should_respond_with :success\n" <<  
13 - " end"  
14 - assert body.include?(expected),  
15 - "expected #{expected} but was #{body.inspect}" 8 + assert_generated_file("test/functional/posts_controller_test.rb") do
  9 + " context 'GET to index' do\n" <<
  10 + " setup { get :index }\n\n" <<
  11 + " should_render_template :index\n" <<
  12 + " should_respond_with :success\n" <<
  13 + " end"
  14 + end
  15 +end
  16 +
  17 +Then /^an empty "index" controller action for "posts" should be generated$/ do
  18 + assert_generated_file("app/controllers/posts_controller.rb") do
  19 + " def index\n" <<
  20 + " end"
16 end 21 end
17 end 22 end
18 23
19 Then /^a standard "new" functional test for "posts" should be generated$/ do 24 Then /^a standard "new" functional test for "posts" should be generated$/ do
20 - assert_generated_functional_test_for("posts") do |body|  
21 - expected = " context 'GET to new' do\n" <<  
22 - " setup { get :new }\n\n" <<  
23 - " should_assign_to :post\n" <<  
24 - " should_render_template :new\n" <<  
25 - " should_respond_with :success\n" <<  
26 - " end"  
27 - assert body.include?(expected),  
28 - "expected #{expected} but was #{body.inspect}" 25 + assert_generated_file("test/functional/posts_controller_test.rb") do
  26 + " context 'GET to new' do\n" <<
  27 + " setup { get :new }\n\n" <<
  28 + " should_assign_to :post\n" <<
  29 + " should_render_template :new\n" <<
  30 + " should_respond_with :success\n" <<
  31 + " end"
29 end 32 end
30 end 33 end
31 34
32 Then /^a standard "create" functional test for "posts" should be generated$/ do 35 Then /^a standard "create" functional test for "posts" should be generated$/ do
33 - assert_generated_functional_test_for("posts") do |body|  
34 - expected = " context 'POST to create with valid parameters' do\n" <<  
35 - " setup do\n" <<  
36 - " post :create, :post => Factory.attributes_for(:post)\n" <<  
37 - " end\n\n" <<  
38 - " should_set_the_flash_to /created/i\n" <<  
39 - " should_redirect_to('posts index') { posts_path }\n" <<  
40 - " end"  
41 - assert body.include?(expected),  
42 - "expected #{expected} but was #{body.inspect}" 36 + assert_generated_file("test/functional/posts_controller_test.rb") do
  37 + " context 'POST to create with valid parameters' do\n" <<
  38 + " setup do\n" <<
  39 + " post :create, :post => Factory.attributes_for(:post)\n" <<
  40 + " end\n\n" <<
  41 + " should_set_the_flash_to /created/i\n" <<
  42 + " should_redirect_to('posts index') { posts_path }\n" <<
  43 + " end"
43 end 44 end
44 end 45 end
45 46
46 Then /^a standard "show" functional test for "posts" should be generated$/ do 47 Then /^a standard "show" functional test for "posts" should be generated$/ do
47 - assert_generated_functional_test_for("posts") do |body|  
48 - expected = " context 'GET to show for existing post' do\n" <<  
49 - " setup do\n" <<  
50 - " @post = Factory(:post)\n" <<  
51 - " get :show, :id => @post.to_param\n" <<  
52 - " end\n\n" <<  
53 - " should_assign_to :post, :equals => '@post'\n" <<  
54 - " should_render_template :show\n" <<  
55 - " should_respond_with :success\n" <<  
56 - " end"  
57 - assert body.include?(expected),  
58 - "expected #{expected} but was #{body.inspect}" 48 + assert_generated_file("test/functional/posts_controller_test.rb") do
  49 + " context 'GET to show for existing post' do\n" <<
  50 + " setup do\n" <<
  51 + " @post = Factory(:post)\n" <<
  52 + " get :show, :id => @post.to_param\n" <<
  53 + " end\n\n" <<
  54 + " should_assign_to :post, :equals => '@post'\n" <<
  55 + " should_render_template :show\n" <<
  56 + " should_respond_with :success\n" <<
  57 + " end"
59 end 58 end
60 end 59 end
61 60
62 Then /^a standard "edit" functional test for "posts" should be generated$/ do 61 Then /^a standard "edit" functional test for "posts" should be generated$/ do
63 - assert_generated_functional_test_for("posts") do |body|  
64 - expected = " context 'GET to edit for existing post' do\n" <<  
65 - " setup do\n" <<  
66 - " @post = Factory(:post)\n" <<  
67 - " get :edit, :id => @post.to_param\n" <<  
68 - " end\n\n" <<  
69 - " should_assign_to :post, :equals => '@post'\n" <<  
70 - " should_render_template :edit\n" <<  
71 - " should_respond_with :success\n" <<  
72 - " end"  
73 - assert body.include?(expected),  
74 - "expected #{expected} but was #{body.inspect}" 62 + assert_generated_file("test/functional/posts_controller_test.rb") do
  63 + " context 'GET to edit for existing post' do\n" <<
  64 + " setup do\n" <<
  65 + " @post = Factory(:post)\n" <<
  66 + " get :edit, :id => @post.to_param\n" <<
  67 + " end\n\n" <<
  68 + " should_assign_to :post, :equals => '@post'\n" <<
  69 + " should_render_template :edit\n" <<
  70 + " should_respond_with :success\n" <<
  71 + " end"
75 end 72 end
76 end 73 end
77 74
78 Then /^a standard "update" functional test for "posts" should be generated$/ do 75 Then /^a standard "update" functional test for "posts" should be generated$/ do
79 - assert_generated_functional_test_for("posts") do |body|  
80 - expected = " context 'PUT to update for existing post' do\n" <<  
81 - " setup do\n" <<  
82 - " @post = Factory(:post)\n" <<  
83 - " put :update, :id => @post.to_param,\n" <<  
84 - " :post => Factory.attributes_for(:post)\n" <<  
85 - " end\n\n" <<  
86 - " should_set_the_flash_to /updated/i\n" <<  
87 - " should_redirect_to('posts index') { posts_path }\n" <<  
88 - " end"  
89 - assert body.include?(expected),  
90 - "expected #{expected} but was #{body.inspect}" 76 + assert_generated_file("test/functional/posts_controller_test.rb") do
  77 + " context 'PUT to update for existing post' do\n" <<
  78 + " setup do\n" <<
  79 + " @post = Factory(:post)\n" <<
  80 + " put :update, :id => @post.to_param,\n" <<
  81 + " :post => Factory.attributes_for(:post)\n" <<
  82 + " end\n\n" <<
  83 + " should_set_the_flash_to /updated/i\n" <<
  84 + " should_redirect_to('posts index') { posts_path }\n" <<
  85 + " end"
91 end 86 end
92 end 87 end
93 88
94 Then /^a standard "destroy" functional test for "posts" should be generated$/ do 89 Then /^a standard "destroy" functional test for "posts" should be generated$/ do
95 - assert_generated_functional_test_for("posts") do |body|  
96 - expected = " context 'given a post' do\n" <<  
97 - " setup { @post = Factory(:post) }\n\n" <<  
98 - " context 'DELETE to destroy' do\n" <<  
99 - " setup { delete :destroy, :id => @post.to_param }\n\n" <<  
100 - " should_destroy :post\n" <<  
101 - " should_set_the_flash_to /deleted/i\n" <<  
102 - " should_redirect_to('posts index') { posts_path }\n" <<  
103 - " end\n" <<  
104 - " end"  
105 - assert body.include?(expected),  
106 - "expected #{expected} but was #{body.inspect}" 90 + assert_generated_file("test/functional/posts_controller_test.rb") do
  91 + " context 'given a post' do\n" <<
  92 + " setup { @post = Factory(:post) }\n\n" <<
  93 + " context 'DELETE to destroy' do\n" <<
  94 + " setup { delete :destroy, :id => @post.to_param }\n\n" <<
  95 + " should_destroy :post\n" <<
  96 + " should_set_the_flash_to /deleted/i\n" <<
  97 + " should_redirect_to('posts index') { posts_path }\n" <<
  98 + " end\n" <<
  99 + " end"
107 end 100 end
108 end 101 end
109 102
110 Then /^a "new" controller action for "posts" should be generated$/ do 103 Then /^a "new" controller action for "posts" should be generated$/ do
111 - assert_generated_controller_for("posts") do |body|  
112 - expected = " def new\n" <<  
113 - " @post = Post.new\n" <<  
114 - " end"  
115 - assert body.include?(expected),  
116 - "expected #{expected} but was #{body.inspect}" 104 + assert_generated_file("app/controllers/posts_controller.rb") do
  105 + " def new\n" <<
  106 + " @post = Post.new\n" <<
  107 + " end"
117 end 108 end
118 end 109 end
119 110
120 Then /^a "create" controller action for "posts" should be generated$/ do 111 Then /^a "create" controller action for "posts" should be generated$/ do
121 - assert_generated_controller_for("posts") do |body|  
122 - expected = " def create\n" <<  
123 - " @post = Post.new(params[:post])\n" <<  
124 - " @post.save\n" <<  
125 - " flash[:success] = 'Post created.'\n" <<  
126 - " redirect_to posts_path\n" <<  
127 - " end"  
128 - assert body.include?(expected),  
129 - "expected #{expected} but was #{body.inspect}" 112 + assert_generated_file("app/controllers/posts_controller.rb") do
  113 + " def create\n" <<
  114 + " @post = Post.new(params[:post])\n" <<
  115 + " @post.save\n" <<
  116 + " flash[:success] = 'Post created.'\n" <<
  117 + " redirect_to posts_path\n" <<
  118 + " end"
130 end 119 end
131 end 120 end
132 121
133 Then /^a "show" controller action for "posts" should be generated$/ do 122 Then /^a "show" controller action for "posts" should be generated$/ do
134 - assert_generated_controller_for("posts") do |body|  
135 - expected = " def show\n" <<  
136 - " @post = Post.find(params[:id])\n" <<  
137 - " end"  
138 - assert body.include?(expected),  
139 - "expected #{expected} but was #{body.inspect}" 123 + assert_generated_file("app/controllers/posts_controller.rb") do
  124 + " def show\n" <<
  125 + " @post = Post.find(params[:id])\n" <<
  126 + " end"
140 end 127 end
141 end 128 end
142 129
143 Then /^a "edit" controller action for "posts" should be generated$/ do 130 Then /^a "edit" controller action for "posts" should be generated$/ do
144 - assert_generated_controller_for("posts") do |body|  
145 - expected = " def edit\n" <<  
146 - " @post = Post.find(params[:id])\n" <<  
147 - " end"  
148 - assert body.include?(expected),  
149 - "expected #{expected} but was #{body.inspect}" 131 + assert_generated_file("app/controllers/posts_controller.rb") do
  132 + " def edit\n" <<
  133 + " @post = Post.find(params[:id])\n" <<
  134 + " end"
150 end 135 end
151 end 136 end
152 137
153 Then /^a "update" controller action for "posts" should be generated$/ do 138 Then /^a "update" controller action for "posts" should be generated$/ do
154 - assert_generated_controller_for("posts") do |body|  
155 - expected = " def update\n" <<  
156 - " @post = Post.find(params[:id])\n" <<  
157 - " @post.update_attributes(params[:post])\n" <<  
158 - " flash[:success] = 'Post updated.'\n" <<  
159 - " redirect_to posts_path\n" <<  
160 - " end"  
161 - assert body.include?(expected),  
162 - "expected #{expected} but was #{body.inspect}" 139 + assert_generated_file("app/controllers/posts_controller.rb") do
  140 + " def update\n" <<
  141 + " @post = Post.find(params[:id])\n" <<
  142 + " @post.update_attributes(params[:post])\n" <<
  143 + " flash[:success] = 'Post updated.'\n" <<
  144 + " redirect_to posts_path\n" <<
  145 + " end"
163 end 146 end
164 end 147 end
165 148
166 Then /^a "destroy" controller action for "posts" should be generated$/ do 149 Then /^a "destroy" controller action for "posts" should be generated$/ do
167 - assert_generated_controller_for("posts") do |body|  
168 - expected = " def destroy\n" <<  
169 - " @post = Post.find(params[:id])\n" <<  
170 - " @post.destroy\n" <<  
171 - " flash[:success] = 'Post deleted.'\n" <<  
172 - " redirect_to posts_path\n" <<  
173 - " end"  
174 - assert body.include?(expected),  
175 - "expected #{expected} but was #{body.inspect}"  
176 - end  
177 -end  
178 -  
179 -Then /^an empty "(.*)" controller action for "(.*)" should be generated$/ do |action, controller|  
180 - assert_generated_controller_for(controller) do |body|  
181 - assert_has_empty_method(body, action) 150 + assert_generated_file("app/controllers/posts_controller.rb") do
  151 + " def destroy\n" <<
  152 + " @post = Post.find(params[:id])\n" <<
  153 + " @post.destroy\n" <<
  154 + " flash[:success] = 'Post deleted.'\n" <<
  155 + " redirect_to posts_path\n" <<
  156 + " end"
182 end 157 end
183 end 158 end
184 159
vendor/plugins/coulda/features/step_definitions/cucumber_steps.rb
@@ -2,20 +2,39 @@ Given /^a Rails app with Cucumber$/ do @@ -2,20 +2,39 @@ Given /^a Rails app with Cucumber$/ do
2 system "rails rails_root" 2 system "rails rails_root"
3 @rails_root = File.join(File.dirname(__FILE__), "..", "..", "rails_root") 3 @rails_root = File.join(File.dirname(__FILE__), "..", "..", "rails_root")
4 require 'cucumber' 4 require 'cucumber'
  5 + system "cd #{@rails_root} && ruby script/generate cucumber"
5 end 6 end
6 7
7 -Then /^a Cucumber "([^\"]*)" functional test for "([^\"]*)" should be generated$/ do |arg1, arg2|  
8 - pending 8 +When /^I generate a "([^\"]*)" feature for "([^\"]*)"$/ do |feature, resource|
  9 + system "cd #{@rails_root} && " <<
  10 + "script/generate feature #{resource} #{feature} && " <<
  11 + "cd .."
9 end 12 end
10 13
11 -Then /^a standard "posts" feature for the "new" scenario should be generated$/ do  
12 - assert_generated_file("features/posts.feature") do |body|  
13 - expected = " Scenario: Create a new 'post'\n" <<  
14 - " Given I am on the new post page\n" <<  
15 - " When I create a 'post' named 'A new post'\n" <<  
16 - " Then I should see 'A new post'"  
17 - assert body.include?(expected),  
18 - "expected #{expected} but was #{body.inspect}" 14 +Then /^a "posts" feature for the "([^\"]*)" scenario should be generated$/ do |action|
  15 + if %w(new create).include?(action)
  16 + assert_generated_file("features/posts.feature") do
  17 + " Scenario: Create a new post\n" <<
  18 + " Given I am on the new post page\n" <<
  19 + " When I create a post named \"A new post\"\n" <<
  20 + " Then I should see \"A new post\""
  21 + end
  22 + end
  23 +end
  24 +
  25 +Then /^a "posts" step definition should be generated$/ do
  26 + assert_generated_file("features/step_definitions/posts_steps.rb") do
  27 + "When /^I create a post named \"([^\\\"]*)\"$/ do |name|\n" <<
  28 + " fills_in :name, :with => name\n" <<
  29 + " click_button 'Create'\n"
  30 + "end"
  31 + end
  32 +end
  33 +
  34 +Then /^a new post page path should be generated$/ do
  35 + assert_generated_file("features/support/paths.rb") do
  36 + " when /the new post page/i\n" <<
  37 + " new_post_path"
19 end 38 end
20 end 39 end
21 40
vendor/plugins/coulda/features/step_definitions/helper_steps.rb
@@ -5,10 +5,10 @@ When /^I generate a helper named &quot;(.*)&quot;$/ do |name| @@ -5,10 +5,10 @@ When /^I generate a helper named &quot;(.*)&quot;$/ do |name|
5 end 5 end
6 6
7 Then /^a helper should be generated for "(.*)"$/ do |name| 7 Then /^a helper should be generated for "(.*)"$/ do |name|
8 - assert_generated_helper_for(name) 8 + assert_generated_file("app/helpers/#{name}_helper.rb")
9 end 9 end
10 10
11 Then /^a helper test should be generated for "(.*)"$/ do |name| 11 Then /^a helper test should be generated for "(.*)"$/ do |name|
12 - assert_generated_helper_test_for(name) 12 + assert_generated_file("test/unit/helpers/#{name}_helper_test.rb")
13 end 13 end
14 14
vendor/plugins/coulda/features/step_definitions/model_steps.rb
@@ -28,26 +28,10 @@ end @@ -28,26 +28,10 @@ end
28 28
29 # MODEL 29 # MODEL
30 30
31 -Then /^a model with comments should be generated for "(.*)"$/ do |model|  
32 - model.downcase!  
33 - assert_generated_model_for(model) do |body|  
34 - comments = []  
35 - comments << "# includes: mixed in behavior" <<  
36 - "# properties: attributes, associations" <<  
37 - "# lifecycle: validations, callbacks" <<  
38 - "# class methods: self.method, named_scopes" <<  
39 - "# instance methods" <<  
40 - "# non-public interface: protected helpers"  
41 - comments.each do |comment|  
42 - assert body.include?(comment), body.inspect  
43 - end  
44 - end  
45 -end  
46 -  
47 Then /^the "(.*)" model should have "(.*)" macro$/ do |model, macro| 31 Then /^the "(.*)" model should have "(.*)" macro$/ do |model, macro|
48 model.downcase! 32 model.downcase!
49 - assert_generated_model_for(model) do |body|  
50 - assert body.include?(macro), body.inspect 33 + assert_generated_file("app/models/#{model}.rb") do
  34 + macro
51 end 35 end
52 end 36 end
53 37
@@ -55,31 +39,28 @@ end @@ -55,31 +39,28 @@ end
55 39
56 Then /^a factory should be generated for "(.*)"$/ do |model| 40 Then /^a factory should be generated for "(.*)"$/ do |model|
57 model.downcase! 41 model.downcase!
58 - assert_generated_factory_for(model) do |body|  
59 - expected = "Factory.define :#{model.downcase} do |#{model.downcase}|\n" <<  
60 - "end\n"  
61 - assert_equal expected, body 42 + assert_generated_file("test/factories/#{model}.rb") do
  43 + "Factory.define :#{model.downcase} do |#{model.downcase}|\n" <<
  44 + "end\n"
62 end 45 end
63 end 46 end
64 47
65 Then /^a factory for "(.*)" should have an? "(.*)" (.*)$/ do |model, attr_name, attr_type| 48 Then /^a factory for "(.*)" should have an? "(.*)" (.*)$/ do |model, attr_name, attr_type|
66 model.downcase! 49 model.downcase!
67 - assert_generated_factory_for(model) do |body|  
68 - expected = "Factory.define :#{model} do |#{model}|\n" <<  
69 - " #{model}.#{attr_name} { '#{attr_type}' }\n" <<  
70 - "end\n"  
71 - assert_equal expected, body 50 + assert_generated_file("test/factories/#{model}.rb") do
  51 + "Factory.define :#{model} do |#{model}|\n" <<
  52 + " #{model}.#{attr_name} { '#{attr_type}' }\n" <<
  53 + "end\n"
72 end 54 end
73 end 55 end
74 56
75 Then /^a factory for "(.*)" should have an association to "(.*)"$/ do |model, associated_model| 57 Then /^a factory for "(.*)" should have an association to "(.*)"$/ do |model, associated_model|
76 model.downcase! 58 model.downcase!
77 associated_model.downcase! 59 associated_model.downcase!
78 - assert_generated_factory_for(model) do |body|  
79 - expected = "Factory.define :#{model} do |#{model}|\n" <<  
80 - " #{model}.association(:#{associated_model})\n" <<  
81 - "end\n"  
82 - assert_equal expected, body 60 + assert_generated_file("test/factories/#{model}.rb") do
  61 + "Factory.define :#{model} do |#{model}|\n" <<
  62 + " #{model}.association(:#{associated_model})\n" <<
  63 + "end\n"
83 end 64 end
84 end 65 end
85 66
@@ -87,35 +68,32 @@ end @@ -87,35 +68,32 @@ end
87 68
88 Then /^a unit test should be generated for "(.*)"$/ do |model| 69 Then /^a unit test should be generated for "(.*)"$/ do |model|
89 model.downcase! 70 model.downcase!
90 - assert_generated_unit_test_for(model) do |body|  
91 - match = "assert_valid Factory.build(:#{model})"  
92 - assert body.include?(match), body.inspect 71 + assert_generated_file("test/unit/#{model}_test.rb") do
  72 + "assert_valid Factory.build(:#{model})"
93 end 73 end
94 end 74 end
95 75
96 Then /^the "(.*)" unit test should have "(.*)" macro$/ do |model, macro| 76 Then /^the "(.*)" unit test should have "(.*)" macro$/ do |model, macro|
97 model.downcase! 77 model.downcase!
98 - assert_generated_unit_test_for(model) do |body|  
99 - assert body.include?(macro), body.inspect 78 + assert_generated_file("test/unit/#{model}_test.rb") do
  79 + macro
100 end 80 end
101 end 81 end
102 82
103 # MIGRATION 83 # MIGRATION
104 84
105 Then /^the "(.*)" table should have db index on "(.*)"$/ do |table, foreign_key| 85 Then /^the "(.*)" table should have db index on "(.*)"$/ do |table, foreign_key|
106 - assert_generated_migration(table) do |body|  
107 - index = "add_index :#{table}, :#{foreign_key}"  
108 - assert body.include?(index), body.inspect 86 + assert_generated_migration(table) do
  87 + "add_index :#{table}, :#{foreign_key}"
109 end 88 end
110 end 89 end
111 90
112 Then /^the "(.*)" table should have paperclip columns for "(.*)"$/ do |table, attr| 91 Then /^the "(.*)" table should have paperclip columns for "(.*)"$/ do |table, attr|
113 - up = " table.string :#{attr}_file_name\n" <<  
114 - " table.string :#{attr}_content_type\n" <<  
115 - " table.integer :#{attr}_file_size\n" <<  
116 - " table.datetime :#{attr}_updated_at"  
117 - assert_generated_migration(table) do |body|  
118 - assert body.include?(up), body.inspect 92 + assert_generated_migration(table) do
  93 + " table.string :#{attr}_file_name\n" <<
  94 + " table.string :#{attr}_content_type\n" <<
  95 + " table.integer :#{attr}_file_size\n" <<
  96 + " table.datetime :#{attr}_updated_at"
119 end 97 end
120 end 98 end
121 99
vendor/plugins/coulda/features/step_definitions/view_steps.rb
@@ -5,14 +5,12 @@ When /^I generate a &quot;([^\&quot;]*)&quot; view for &quot;([^\&quot;]*)&quot;$/ do |view, resource| @@ -5,14 +5,12 @@ When /^I generate a &quot;([^\&quot;]*)&quot; view for &quot;([^\&quot;]*)&quot;$/ do |view, resource|
5 end 5 end
6 6
7 When /^a standard "new" view for "posts" should be generated$/ do 7 When /^a standard "new" view for "posts" should be generated$/ do
8 - assert_generated_file("app/views/posts/new.html.erb") do |body|  
9 - expected = "<h1>New post</h1>\n\n" <<  
10 - "<% form_for(@post) do |form| %>\n" <<  
11 - " <%= form.error_messages %>\n" <<  
12 - " <%= form.submit 'Create', :disable_with => 'Please wait...' %>\n" <<  
13 - "<% end %>"  
14 - assert body.include?(expected),  
15 - "expected #{expected} but was #{body.inspect}" 8 + assert_generated_file("app/views/posts/new.html.erb") do
  9 + "<h1>New post</h1>\n\n" <<
  10 + "<% form_for(@post) do |form| %>\n" <<
  11 + " <%= form.error_messages %>\n" <<
  12 + " <%= form.submit 'Create', :disable_with => 'Please wait...' %>\n" <<
  13 + "<% end %>"
16 end 14 end
17 end 15 end
18 16
vendor/plugins/coulda/features/support/env.rb
@@ -2,52 +2,15 @@ require &#39;test/unit&#39; @@ -2,52 +2,15 @@ require &#39;test/unit&#39;
2 2
3 module Test::Unit::Assertions 3 module Test::Unit::Assertions
4 4
5 - def assert_generated_controller_for(name)  
6 - assert_generated_file "app/controllers/#{name}_controller.rb" do |body|  
7 - yield body if block_given?  
8 - end  
9 - end  
10 -  
11 - def assert_generated_model_for(name)  
12 - assert_generated_file "app/models/#{name}.rb" do |body|  
13 - yield body if block_given?  
14 - end  
15 - end  
16 -  
17 - def assert_generated_helper_for(name)  
18 - assert_generated_file "app/helpers/#{name}_helper.rb" do |body|  
19 - yield body if block_given?  
20 - end  
21 - end  
22 -  
23 - def assert_generated_factory_for(name)  
24 - assert_generated_file "test/factories/#{name}.rb" do |body|  
25 - yield body if block_given?  
26 - end  
27 - end  
28 -  
29 - def assert_generated_functional_test_for(name)  
30 - assert_generated_file "test/functional/#{name}_controller_test.rb" do |body|  
31 - yield body if block_given?  
32 - end  
33 - end  
34 -  
35 - def assert_generated_unit_test_for(name)  
36 - assert_generated_file "test/unit/#{name}_test.rb" do |body|  
37 - yield body if block_given?  
38 - end  
39 - end  
40 -  
41 - def assert_generated_helper_test_for(name)  
42 - assert_generated_file "test/unit/helpers/#{name}_helper_test.rb" do |body|  
43 - yield body if block_given?  
44 - end  
45 - end  
46 -  
47 def assert_generated_file(path) 5 def assert_generated_file(path)
48 assert_file_exists(path) 6 assert_file_exists(path)
49 - File.open(File.join(@rails_root, path)) do |file|  
50 - yield file.read if block_given? 7 + if block_given?
  8 + File.open(File.join(@rails_root, path)) do |file|
  9 + expected = yield
  10 + body = file.read
  11 + assert body.include?(expected),
  12 + "expected #{expected} but was #{body.inspect}"
  13 + end
51 end 14 end
52 end 15 end
53 16
@@ -60,8 +23,8 @@ module Test::Unit::Assertions @@ -60,8 +23,8 @@ module Test::Unit::Assertions
60 23
61 def assert_generated_views_for(name, *actions) 24 def assert_generated_views_for(name, *actions)
62 actions.each do |action| 25 actions.each do |action|
63 - assert_generated_file("app/views/#{name}/#{action}.html.erb") do |body|  
64 - yield body if block_given? 26 + assert_generated_file("app/views/#{name}/#{action}.html.erb") do
  27 + yield if block_given?
65 end 28 end
66 end 29 end
67 end 30 end
@@ -69,18 +32,14 @@ module Test::Unit::Assertions @@ -69,18 +32,14 @@ module Test::Unit::Assertions
69 def assert_generated_migration(name) 32 def assert_generated_migration(name)
70 file = Dir.glob("#{@rails_root}/db/migrate/*_#{name}.rb").first 33 file = Dir.glob("#{@rails_root}/db/migrate/*_#{name}.rb").first
71 file = file.match(/db\/migrate\/[0-9]+_\w+/).to_s << ".rb" 34 file = file.match(/db\/migrate\/[0-9]+_\w+/).to_s << ".rb"
72 - assert_generated_file file do |body|  
73 - assert_match /timestamps/, body, "should have timestamps defined"  
74 - yield body if block_given?  
75 - end 35 + assert_generated_file(file) { "timestamps" }
  36 + assert_generated_file(file) { yield if block_given? }
76 end 37 end
77 38
78 def assert_generated_route_for(name, *actions) 39 def assert_generated_route_for(name, *actions)
79 - assert_generated_file("config/routes.rb") do |body|  
80 - routeable_actions = actions.collect { |action| ":#{action}" }.join(", ")  
81 - expected = " map.resources :#{name.to_s}, :only => [#{routeable_actions}]"  
82 - assert body.include?(expected),  
83 - "expected #{expected} but was #{body.inspect}" 40 + routeable_actions = actions.collect { |action| ":#{action}" }.join(", ")
  41 + assert_generated_file("config/routes.rb") do
  42 + " map.resources :#{name.to_s}, :only => [#{routeable_actions}]"
84 end 43 end
85 end 44 end
86 45
vendor/plugins/coulda/features/view_generator.feature
1 -Feature: Rails controller generator  
2 - In order to better do Test-Driven Development with Rails  
3 - As a user  
4 - I want to generate Shoulda & Factory Girl tests for only RESTful actions I need. 1 +Feature: Rails view generator
  2 + In order to do Test-Driven Development with Rails
  3 + As a developer
  4 + I want to generate a view to make a functional test pass
5 5
6 - Scenario: View generator for new action when Cucumber is installed  
7 - Given a Rails app with Cucumber 6 + Scenario: View generator for new action
  7 + Given a Rails app
8 And the coulda plugin is installed 8 And the coulda plugin is installed
9 When I generate a "new" view for "Posts" 9 When I generate a "new" view for "Posts"
10 Then a standard "new" view for "posts" should be generated 10 Then a standard "new" view for "posts" should be generated
11 - And a standard "posts" feature for the "new" scenario should be generated  
12 11
vendor/plugins/coulda/generators/controller/controller_generator.rb
1 -require File.join(File.dirname(__FILE__), "..", "support", "insert_commands") 1 +require File.join(File.dirname(__FILE__), "..", "support", "generator_helper")
2 2
3 class ControllerGenerator < Rails::Generator::NamedBase 3 class ControllerGenerator < Rails::Generator::NamedBase
4 def manifest 4 def manifest
@@ -17,9 +17,6 @@ class ControllerGenerator &lt; Rails::Generator::NamedBase @@ -17,9 +17,6 @@ class ControllerGenerator &lt; Rails::Generator::NamedBase
17 File.join('test/functional', 17 File.join('test/functional',
18 class_path, 18 class_path,
19 "#{file_name}_controller_test.rb") 19 "#{file_name}_controller_test.rb")
20 -  
21 - m.insert_into "config/routes.rb",  
22 - "map.resources :#{file_name}, :only => [#{routeable_actions}]"  
23 end 20 end
24 end 21 end
25 22
vendor/plugins/coulda/generators/controller/templates/controller.rb
1 class <%= class_name %>Controller < ApplicationController 1 class <%= class_name %>Controller < ApplicationController
2 -<% resource = file_name.singularize -%>  
3 -<% resources = file_name.pluralize -%>  
4 -<% resource_class = class_name.singularize -%>  
5 -  
6 <% if actions.include?("index") -%> 2 <% if actions.include?("index") -%>
7 def index 3 def index
8 end 4 end
vendor/plugins/coulda/generators/controller/templates/functional_test.rb
1 require 'test_helper' 1 require 'test_helper'
2 2
3 class <%= class_name %>ControllerTest < ActionController::TestCase 3 class <%= class_name %>ControllerTest < ActionController::TestCase
4 -<% resource = file_name.singularize -%>  
5 -<% resources = file_name.pluralize -%>  
6 -<% resource_class = class_name.singularize -%>  
7 -  
8 <% if actions.include?("index") -%> 4 <% if actions.include?("index") -%>
9 context 'GET to index' do 5 context 'GET to index' do
10 setup { get :index } 6 setup { get :index }
vendor/plugins/coulda/generators/feature/feature_generator.rb 0 → 100644
@@ -0,0 +1,28 @@ @@ -0,0 +1,28 @@
  1 +require File.join(File.dirname(__FILE__), "..", "support", "generator_helper")
  2 +
  3 +class FeatureGenerator < Rails::Generator::NamedBase
  4 + def manifest
  5 + record do |m|
  6 + m.directory 'features'
  7 + m.directory 'features/step_definitions'
  8 + m.directory 'features/support'
  9 +
  10 + path = File.join('features', "#{resources}.feature")
  11 + m.template 'feature.feature', path
  12 +
  13 + path = File.join('features', 'step_definitions', "#{resources}_steps.rb")
  14 + m.template 'step_definition.rb', path
  15 +
  16 + path = File.join('features', 'support', "paths.rb")
  17 + m.insert_into path, insertable_path
  18 + end
  19 + end
  20 +
  21 + def insertable_path
  22 + if %w(new create).any? { |action| actions.include?(action) }
  23 + " when /the new #{resource} page/i\n" <<
  24 + " new_#{resource}_path\n"
  25 + end
  26 + end
  27 +end
  28 +
vendor/plugins/coulda/generators/feature/templates/feature.feature 0 → 100644
@@ -0,0 +1,6 @@ @@ -0,0 +1,6 @@
  1 +<% if %w(new create).any? { |action| actions.include?(action) } -%>
  2 + Scenario: Create a new <%= resource %>
  3 + Given I am on the new <%= resource %> page
  4 + When I create a <%= resource %> named "A new <%= resource %>"
  5 + Then I should see "A new <%= resource %>"
  6 +<% end -%>
vendor/plugins/coulda/generators/feature/templates/step_definition.rb 0 → 100644
@@ -0,0 +1,4 @@ @@ -0,0 +1,4 @@
  1 +When /^I create a <%= resource %> named "([^\"]*)"$/ do |name|
  2 + fills_in :name, :with => name
  3 + click_button 'Create'
  4 +end
vendor/plugins/coulda/generators/helper/helper_generator.rb
  1 +require File.join(File.dirname(__FILE__), "..", "support", "generator_helper")
  2 +
1 class HelperGenerator < Rails::Generator::NamedBase 3 class HelperGenerator < Rails::Generator::NamedBase
2 def manifest 4 def manifest
3 record do |m| 5 record do |m|
vendor/plugins/coulda/generators/model/model_generator.rb
  1 +require File.join(File.dirname(__FILE__), "..", "support", "generator_helper")
  2 +
1 class ModelGenerator < Rails::Generator::NamedBase 3 class ModelGenerator < Rails::Generator::NamedBase
2 default_options :skip_timestamps => false, 4 default_options :skip_timestamps => false,
3 :skip_migration => false, 5 :skip_migration => false,
vendor/plugins/coulda/generators/model/templates/unit_test.rb
1 -require File.dirname(__FILE__) + '/../test_helper' 1 +require 'test_helper'
2 2
3 class <%= class_name %>Test < ActiveSupport::TestCase 3 class <%= class_name %>Test < ActiveSupport::TestCase
4 should "be valid with factory" do 4 should "be valid with factory" do
@@ -12,5 +12,5 @@ class &lt;%= class_name %&gt;Test &lt; ActiveSupport::TestCase @@ -12,5 +12,5 @@ class &lt;%= class_name %&gt;Test &lt; ActiveSupport::TestCase
12 <% if attribute.type == :paperclip -%> 12 <% if attribute.type == :paperclip -%>
13 should_have_attached_file :<%= attribute.name %> 13 should_have_attached_file :<%= attribute.name %>
14 <% end -%> 14 <% end -%>
15 -<% end -%> 15 +<% end -%>
16 end 16 end
vendor/plugins/coulda/generators/support/generator_helper.rb 0 → 100644
@@ -0,0 +1,31 @@ @@ -0,0 +1,31 @@
  1 +require File.join(File.dirname(__FILE__), "insert_commands")
  2 +
  3 +module Coulda
  4 + module GeneratorHelper
  5 + REMOVABLE_COLUMNS = ["created_at", "updated_at", "email_confirmed",
  6 + "encrypted_password", "salt", "token", "token_expires_at"]
  7 +
  8 + def resource
  9 + file_name.singularize
  10 + end
  11 +
  12 + def resources
  13 + file_name.pluralize
  14 + end
  15 +
  16 + def resource_class
  17 + class_name.singularize
  18 + end
  19 +
  20 + def columns_for_form
  21 + resource_class.content_columns.
  22 + collect { |column| [column.name, column.type] }.
  23 + delete_if { |column| REMOVABLE_COLUMNS.include?(column.first) }
  24 + end
  25 + end
  26 +end
  27 +
  28 +class Rails::Generator::NamedBase
  29 + include Coulda::GeneratorHelper
  30 +end
  31 +
vendor/plugins/coulda/generators/support/insert_commands.rb
@@ -9,10 +9,15 @@ end @@ -9,10 +9,15 @@ end
9 Rails::Generator::Commands::Create.class_eval do 9 Rails::Generator::Commands::Create.class_eval do
10 def insert_into(file, line) 10 def insert_into(file, line)
11 logger.insert "#{line} into #{file}" 11 logger.insert "#{line} into #{file}"
12 - unless options[:pretend] || file_contains?(file, line)  
13 - start_of_routes_file = "ActionController::Routing::Routes.draw"  
14 - gsub_file file, /^(class|module|#{start_of_routes_file}) .+$/ do |match|  
15 - "#{match}\n #{line}" 12 + unless file_contains?(file, line)
  13 + if file =~ /^module NavigationHelpers/
  14 + gsub_file file, /#{Coulda::Insertable.cucumber_paths}/ do |match|
  15 + "#{match}\n#{line}"
  16 + end
  17 + else
  18 + gsub_file file, /^(class|module|#{Coulda::Insertable.routes}) .+$/ do |match|
  19 + "#{match}\n #{line}"
  20 + end
16 end 21 end
17 end 22 end
18 end 23 end
@@ -21,9 +26,7 @@ end @@ -21,9 +26,7 @@ end
21 Rails::Generator::Commands::Destroy.class_eval do 26 Rails::Generator::Commands::Destroy.class_eval do
22 def insert_into(file, line) 27 def insert_into(file, line)
23 logger.remove "#{line} from #{file}" 28 logger.remove "#{line} from #{file}"
24 - unless options[:pretend]  
25 - gsub_file file, "\n #{line}", ''  
26 - end 29 + gsub_file file, "\n #{line}", ''
27 end 30 end
28 end 31 end
29 32
@@ -33,3 +36,15 @@ Rails::Generator::Commands::List.class_eval do @@ -33,3 +36,15 @@ Rails::Generator::Commands::List.class_eval do
33 end 36 end
34 end 37 end
35 38
  39 +module Coulda
  40 + module Insertable
  41 + def self.routes
  42 + "ActionController::Routing::Routes.draw"
  43 + end
  44 +
  45 + def self.cucumber_paths
  46 + "case page_name\n"
  47 + end
  48 + end
  49 +end
  50 +
vendor/plugins/coulda/generators/view/templates/feature.feature
@@ -1,10 +0,0 @@ @@ -1,10 +0,0 @@
1 -<% resource = file_name.singularize -%>  
2 -<% resources = file_name.pluralize -%>  
3 -<% resource_class = class_name.singularize -%>  
4 -  
5 -<% if %w(new create).any? { |action| actions.include?(action) } -%>  
6 - Scenario: Create a new '<%= resource %>'  
7 - Given I am on the new <%= resource %> page  
8 - When I create a '<%= resource %>' named 'A new <%= resource %>'  
9 - Then I should see 'A new <%= resource %>'  
10 -<% end -%>  
vendor/plugins/coulda/generators/view/templates/view_new.html.erb
1 -<% resource = file_name.singularize -%>  
2 <h1>New <%= resource %></h1> 1 <h1>New <%= resource %></h1>
3 2
4 <%% form_for(@<%= resource %>) do |form| %> 3 <%% form_for(@<%= resource %>) do |form| %>
vendor/plugins/coulda/generators/view/templates/view_show.html.erb
1 -<h1><%= singular_name %></h1> 1 +<h1><%= resource %></h1>
2 2
3 -<%%= link_to 'Edit', edit_<%= singular_name %>_path(@<%= singular_name %>) %> 3 +<%%= link_to 'Edit', edit_<%= resource %>_path(@<%= resource %>) %>
4 4
vendor/plugins/coulda/generators/view/view_generator.rb
  1 +require File.join(File.dirname(__FILE__), "..", "support", "generator_helper")
  2 +
1 class ViewGenerator < Rails::Generator::NamedBase 3 class ViewGenerator < Rails::Generator::NamedBase
2 def manifest 4 def manifest
3 record do |m| 5 record do |m|
4 m.directory File.join('app/views', class_path, file_name) 6 m.directory File.join('app/views', class_path, file_name)
5 - m.directory 'features'  
6 7
7 if actions.include?("new") 8 if actions.include?("new")
8 path = File.join('app/views', class_path, file_name, "new.html.erb") 9 path = File.join('app/views', class_path, file_name, "new.html.erb")
9 m.template 'view_new.html.erb', path 10 m.template 'view_new.html.erb', path
10 -  
11 - path = File.join('features', "#{file_name.pluralize}.feature")  
12 - m.template 'feature.feature', path  
13 end 11 end
14 end 12 end
15 end 13 end