Commit 1fb5bbf6bea269d95504b37f97f87f687ccb2c8d
1 parent
75ebbbce
Exists in
master
and in
1 other branch
upgraded coulda
Showing
25 changed files
with
349 additions
and
315 deletions
Show diff stats
vendor/plugins/coulda/README.textile
1 | 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 | 5 | h2. Requirements |
6 | 6 | |
7 | +* "Cucumber":http://github.com/aslakhellesoy/cucumber | |
7 | 8 | * "Shoulda":http://github.com/thoughtbot/shoulda |
8 | 9 | * "Factory Girl":http://github.com/thoughtbot/factory_girl |
10 | +* "Mocha":http://github.com/jferris/mocha | |
9 | 11 | |
10 | 12 | h2. Installation |
11 | 13 | |
12 | 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 | 56 | h2. Model generator |
15 | 57 | |
16 | 58 | $ script/generate model User |
... | ... | @@ -20,14 +62,6 @@ h2. Model generator |
20 | 62 | * migration |
21 | 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 | 65 | h2. Helper generator |
32 | 66 | |
33 | 67 | $ script/generate helper Navigation |
... | ... | @@ -39,16 +73,11 @@ h2. View generator |
39 | 73 | |
40 | 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 | 76 | h2. Model generator: belongs_to |
45 | 77 | |
46 | 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 | 82 | <pre><code>class CreatePosts < ActiveRecord::Migration |
54 | 83 | def self.up | ... | ... |
vendor/plugins/coulda/features/controller_generator.feature
... | ... | @@ -9,7 +9,6 @@ Feature: Rails controller generator |
9 | 9 | When I generate a "Posts" controller with "index" action |
10 | 10 | Then a standard "index" functional test for "posts" should be generated |
11 | 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 | 13 | Scenario: Controller generator for new action |
15 | 14 | Given a Rails app |
... | ... | @@ -17,7 +16,6 @@ Feature: Rails controller generator |
17 | 16 | When I generate a "Posts" controller with "new" action |
18 | 17 | Then a standard "new" functional test for "posts" should be generated |
19 | 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 | 20 | Scenario: Controller generator for create action |
23 | 21 | Given a Rails app |
... | ... | @@ -25,7 +23,6 @@ Feature: Rails controller generator |
25 | 23 | When I generate a "Posts" controller with "create" action |
26 | 24 | Then a standard "create" functional test for "posts" should be generated |
27 | 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 | 27 | Scenario: Controller generator for create action when Cucumber is installed |
31 | 28 | Given a Rails app with Cucumber |
... | ... | @@ -33,7 +30,6 @@ Feature: Rails controller generator |
33 | 30 | When I generate a "Posts" controller with "create" action |
34 | 31 | Then a standard "create" functional test for "posts" should be generated |
35 | 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 | 34 | Scenario: Controller generator for show action |
39 | 35 | Given a Rails app |
... | ... | @@ -41,7 +37,6 @@ Feature: Rails controller generator |
41 | 37 | When I generate a "Posts" controller with "show" action |
42 | 38 | Then a standard "show" functional test for "posts" should be generated |
43 | 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 | 41 | Scenario: Controller generator for edit action |
47 | 42 | Given a Rails app |
... | ... | @@ -49,7 +44,6 @@ Feature: Rails controller generator |
49 | 44 | When I generate a "Posts" controller with "edit" action |
50 | 45 | Then a standard "edit" functional test for "posts" should be generated |
51 | 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 | 48 | Scenario: Controller generator for update action |
55 | 49 | Given a Rails app |
... | ... | @@ -57,7 +51,6 @@ Feature: Rails controller generator |
57 | 51 | When I generate a "Posts" controller with "update" action |
58 | 52 | Then a standard "update" functional test for "posts" should be generated |
59 | 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 | 55 | Scenario: Controller generator for destroy action |
63 | 56 | Given a Rails app |
... | ... | @@ -65,5 +58,4 @@ Feature: Rails controller generator |
65 | 58 | When I generate a "Posts" controller with "destroy" action |
66 | 59 | Then a standard "destroy" functional test for "posts" should be generated |
67 | 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 @@ |
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 "(.*)" controller with "(.*)" action$/ do |controller, actio |
5 | 5 | end |
6 | 6 | |
7 | 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 | 21 | end |
17 | 22 | end |
18 | 23 | |
19 | 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 | 32 | end |
30 | 33 | end |
31 | 34 | |
32 | 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 | 44 | end |
44 | 45 | end |
45 | 46 | |
46 | 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 | 58 | end |
60 | 59 | end |
61 | 60 | |
62 | 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 | 72 | end |
76 | 73 | end |
77 | 74 | |
78 | 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 | 86 | end |
92 | 87 | end |
93 | 88 | |
94 | 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 | 100 | end |
108 | 101 | end |
109 | 102 | |
110 | 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 | 108 | end |
118 | 109 | end |
119 | 110 | |
120 | 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 | 119 | end |
131 | 120 | end |
132 | 121 | |
133 | 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 | 127 | end |
141 | 128 | end |
142 | 129 | |
143 | 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 | 135 | end |
151 | 136 | end |
152 | 137 | |
153 | 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 | 146 | end |
164 | 147 | end |
165 | 148 | |
166 | 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 | 157 | end |
183 | 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 | 2 | system "rails rails_root" |
3 | 3 | @rails_root = File.join(File.dirname(__FILE__), "..", "..", "rails_root") |
4 | 4 | require 'cucumber' |
5 | + system "cd #{@rails_root} && ruby script/generate cucumber" | |
5 | 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 | 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 | 38 | end |
20 | 39 | end |
21 | 40 | ... | ... |
vendor/plugins/coulda/features/step_definitions/helper_steps.rb
... | ... | @@ -5,10 +5,10 @@ When /^I generate a helper named "(.*)"$/ do |name| |
5 | 5 | end |
6 | 6 | |
7 | 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 | 9 | end |
10 | 10 | |
11 | 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 | 13 | end |
14 | 14 | ... | ... |
vendor/plugins/coulda/features/step_definitions/model_steps.rb
... | ... | @@ -28,26 +28,10 @@ end |
28 | 28 | |
29 | 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 | 31 | Then /^the "(.*)" model should have "(.*)" macro$/ do |model, macro| |
48 | 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 | 35 | end |
52 | 36 | end |
53 | 37 | |
... | ... | @@ -55,31 +39,28 @@ end |
55 | 39 | |
56 | 40 | Then /^a factory should be generated for "(.*)"$/ do |model| |
57 | 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 | 45 | end |
63 | 46 | end |
64 | 47 | |
65 | 48 | Then /^a factory for "(.*)" should have an? "(.*)" (.*)$/ do |model, attr_name, attr_type| |
66 | 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 | 54 | end |
73 | 55 | end |
74 | 56 | |
75 | 57 | Then /^a factory for "(.*)" should have an association to "(.*)"$/ do |model, associated_model| |
76 | 58 | model.downcase! |
77 | 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 | 64 | end |
84 | 65 | end |
85 | 66 | |
... | ... | @@ -87,35 +68,32 @@ end |
87 | 68 | |
88 | 69 | Then /^a unit test should be generated for "(.*)"$/ do |model| |
89 | 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 | 73 | end |
94 | 74 | end |
95 | 75 | |
96 | 76 | Then /^the "(.*)" unit test should have "(.*)" macro$/ do |model, macro| |
97 | 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 | 80 | end |
101 | 81 | end |
102 | 82 | |
103 | 83 | # MIGRATION |
104 | 84 | |
105 | 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 | 88 | end |
110 | 89 | end |
111 | 90 | |
112 | 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 | 97 | end |
120 | 98 | end |
121 | 99 | ... | ... |
vendor/plugins/coulda/features/step_definitions/view_steps.rb
... | ... | @@ -5,14 +5,12 @@ When /^I generate a "([^\"]*)" view for "([^\"]*)"$/ do |view, resource| |
5 | 5 | end |
6 | 6 | |
7 | 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 | 14 | end |
17 | 15 | end |
18 | 16 | ... | ... |
vendor/plugins/coulda/features/support/env.rb
... | ... | @@ -2,52 +2,15 @@ require 'test/unit' |
2 | 2 | |
3 | 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 | 5 | def assert_generated_file(path) |
48 | 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 | 14 | end |
52 | 15 | end |
53 | 16 | |
... | ... | @@ -60,8 +23,8 @@ module Test::Unit::Assertions |
60 | 23 | |
61 | 24 | def assert_generated_views_for(name, *actions) |
62 | 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 | 28 | end |
66 | 29 | end |
67 | 30 | end |
... | ... | @@ -69,18 +32,14 @@ module Test::Unit::Assertions |
69 | 32 | def assert_generated_migration(name) |
70 | 33 | file = Dir.glob("#{@rails_root}/db/migrate/*_#{name}.rb").first |
71 | 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 | 37 | end |
77 | 38 | |
78 | 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 | 43 | end |
85 | 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 | 8 | And the coulda plugin is installed |
9 | 9 | When I generate a "new" view for "Posts" |
10 | 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 | 3 | class ControllerGenerator < Rails::Generator::NamedBase |
4 | 4 | def manifest |
... | ... | @@ -17,9 +17,6 @@ class ControllerGenerator < Rails::Generator::NamedBase |
17 | 17 | File.join('test/functional', |
18 | 18 | class_path, |
19 | 19 | "#{file_name}_controller_test.rb") |
20 | - | |
21 | - m.insert_into "config/routes.rb", | |
22 | - "map.resources :#{file_name}, :only => [#{routeable_actions}]" | |
23 | 20 | end |
24 | 21 | end |
25 | 22 | ... | ... |
vendor/plugins/coulda/generators/controller/templates/controller.rb
vendor/plugins/coulda/generators/controller/templates/functional_test.rb
1 | 1 | require 'test_helper' |
2 | 2 | |
3 | 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 | 4 | <% if actions.include?("index") -%> |
9 | 5 | context 'GET to index' do |
10 | 6 | setup { get :index } | ... | ... |
vendor/plugins/coulda/generators/feature/feature_generator.rb
0 → 100644
... | ... | @@ -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 @@ |
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
vendor/plugins/coulda/generators/helper/helper_generator.rb
vendor/plugins/coulda/generators/model/model_generator.rb
vendor/plugins/coulda/generators/model/templates/unit_test.rb
1 | -require File.dirname(__FILE__) + '/../test_helper' | |
1 | +require 'test_helper' | |
2 | 2 | |
3 | 3 | class <%= class_name %>Test < ActiveSupport::TestCase |
4 | 4 | should "be valid with factory" do |
... | ... | @@ -12,5 +12,5 @@ class <%= class_name %>Test < ActiveSupport::TestCase |
12 | 12 | <% if attribute.type == :paperclip -%> |
13 | 13 | should_have_attached_file :<%= attribute.name %> |
14 | 14 | <% end -%> |
15 | -<% end -%> | |
15 | +<% end -%> | |
16 | 16 | end | ... | ... |
vendor/plugins/coulda/generators/support/generator_helper.rb
0 → 100644
... | ... | @@ -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 | 9 | Rails::Generator::Commands::Create.class_eval do |
10 | 10 | def insert_into(file, line) |
11 | 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 | 21 | end |
17 | 22 | end |
18 | 23 | end |
... | ... | @@ -21,9 +26,7 @@ end |
21 | 26 | Rails::Generator::Commands::Destroy.class_eval do |
22 | 27 | def insert_into(file, line) |
23 | 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 | 30 | end |
28 | 31 | end |
29 | 32 | |
... | ... | @@ -33,3 +36,15 @@ Rails::Generator::Commands::List.class_eval do |
33 | 36 | end |
34 | 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 | -<% 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
vendor/plugins/coulda/generators/view/templates/view_show.html.erb
vendor/plugins/coulda/generators/view/view_generator.rb
1 | +require File.join(File.dirname(__FILE__), "..", "support", "generator_helper") | |
2 | + | |
1 | 3 | class ViewGenerator < Rails::Generator::NamedBase |
2 | 4 | def manifest |
3 | 5 | record do |m| |
4 | 6 | m.directory File.join('app/views', class_path, file_name) |
5 | - m.directory 'features' | |
6 | 7 | |
7 | 8 | if actions.include?("new") |
8 | 9 | path = File.join('app/views', class_path, file_name, "new.html.erb") |
9 | 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 | 11 | end |
14 | 12 | end |
15 | 13 | end | ... | ... |