rspec-rr 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +20 -0
- data/README.textile +42 -0
- data/Rakefile +46 -0
- data/TODO.txt +3 -0
- data/VERSION.yml +4 -0
- data/generators/rspec_default_values.rb +19 -0
- data/generators/rspec_rr_scaffold/rspec_rr_scaffold_generator.rb +154 -0
- data/generators/rspec_rr_scaffold/templates/controller_spec.rb +180 -0
- data/init.rb +9 -0
- data/install.rb +0 -0
- data/lib/spec/rr.rb +3 -0
- data/lib/spec/rr/mocks.rb +71 -0
- data/spec/spec.opts +6 -0
- data/spec/spec/rr/ar_classes.rb +30 -0
- data/spec/spec/rr/mocks_spec.rb +115 -0
- data/spec/spec/rr/null_object_spec.rb +32 -0
- data/spec/spec_helper.rb +14 -0
- data/tasks/rspec_rr_tasks.rake +4 -0
- data/uninstall.rb +0 -0
- metadata +85 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2008 [Joseph Wilk]
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.textile
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
h1. Rspec-rr
|
2
|
+
|
3
|
+
Allow rspec-rails helpers and RR test double framework to play nicely.
|
4
|
+
|
5
|
+
Dependent on:
|
6
|
+
|
7
|
+
"http://github.com/dchelimsky/rspec/":http://github.com/dchelimsky/rspec/
|
8
|
+
|
9
|
+
"http://github.com/dchelimsky/rspec-rails/":http://github.com/dchelimsky/rspec-rails/
|
10
|
+
|
11
|
+
"http://github.com/btakita/rr/tree/master":http://github.com/btakita/rr/tree/master
|
12
|
+
|
13
|
+
h2. Install
|
14
|
+
|
15
|
+
Install via:
|
16
|
+
<pre><code>script/plugin install git://github.com/josephwilk/rspec-rr.git</code></pre>
|
17
|
+
Or grab it directly from git
|
18
|
+
<pre><code>git clone git://github.com/josephwilk/rspec-rr.git</code></pre>
|
19
|
+
Finally in your spec_helper.rb after your:
|
20
|
+
<pre><code>require 'spec'
|
21
|
+
require 'spec/rails'</code></pre>
|
22
|
+
Add:
|
23
|
+
<pre><code>
|
24
|
+
require 'spec/rr'
|
25
|
+
</code></pre>
|
26
|
+
|
27
|
+
h2. Generator
|
28
|
+
|
29
|
+
Instead of using rspec_scaffold use:
|
30
|
+
<pre><code>script/generate rspec_rr_scaffold</code></pre>
|
31
|
+
|
32
|
+
h2. License
|
33
|
+
|
34
|
+
(The MIT License)
|
35
|
+
|
36
|
+
Copyright (c) 2008 Joseph Wilk
|
37
|
+
|
38
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
39
|
+
|
40
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
41
|
+
|
42
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/rdoctask'
|
3
|
+
require 'spec/rake/spectask'
|
4
|
+
require 'rcov'
|
5
|
+
|
6
|
+
desc 'Default: run unit tests.'
|
7
|
+
task :default => :spec
|
8
|
+
|
9
|
+
begin
|
10
|
+
require 'jeweler'
|
11
|
+
Jeweler::Tasks.new do |gem|
|
12
|
+
gem.name = "rspec-rr"
|
13
|
+
gem.summary = %Q{Helping Rspec and Rspec-rails play nicely with RR the test double framework}
|
14
|
+
gem.description = %Q{Helping Rspec and Rspec-rails play nicely with RR the test double framework.}
|
15
|
+
gem.email = "joe@josephwilk.net"
|
16
|
+
gem.homepage = "http://github.com/josephwilk/rspec-rr"
|
17
|
+
gem.authors = ["Joseph Wilk"]
|
18
|
+
|
19
|
+
gem.add_development_dependency 'rspec'
|
20
|
+
end
|
21
|
+
|
22
|
+
Jeweler::GemcutterTasks.new
|
23
|
+
rescue LoadError
|
24
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
desc "Run all specs"
|
29
|
+
Spec::Rake::SpecTask.new do |t|
|
30
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
31
|
+
t.spec_opts = ['--options', 'spec/spec.opts']
|
32
|
+
unless ENV['NO_RCOV']
|
33
|
+
t.rcov = true
|
34
|
+
t.rcov_dir = 'coverage'
|
35
|
+
t.rcov_opts = ['--exclude', 'lib/spec_rr.rb,,\/var\/lib\/gems,\/Library\/Ruby,\.autotest']
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
desc 'Generate documentation for the rspec-rr plugin.'
|
40
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
41
|
+
rdoc.rdoc_dir = 'rdoc'
|
42
|
+
rdoc.title = 'Rspec-rr'
|
43
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
44
|
+
rdoc.rdoc_files.include('README')
|
45
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
46
|
+
end
|
data/TODO.txt
ADDED
data/VERSION.yml
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
module Rails
|
2
|
+
module Generator
|
3
|
+
class GeneratedAttribute
|
4
|
+
def default_value
|
5
|
+
@default_value ||= case type
|
6
|
+
when :int, :integer then "\"1\""
|
7
|
+
when :float then "\"1.5\""
|
8
|
+
when :decimal then "\"9.99\""
|
9
|
+
when :datetime, :timestamp, :time then "Time.now"
|
10
|
+
when :date then "Date.today"
|
11
|
+
when :string, :text then "\"value for #{@name}\""
|
12
|
+
when :boolean then "false"
|
13
|
+
else
|
14
|
+
""
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,154 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../rspec_default_values'
|
2
|
+
|
3
|
+
class RspecRrScaffoldGenerator < Rails::Generator::NamedBase
|
4
|
+
default_options :skip_migration => false
|
5
|
+
|
6
|
+
attr_reader :controller_name,
|
7
|
+
:controller_class_path,
|
8
|
+
:controller_file_path,
|
9
|
+
:controller_class_nesting,
|
10
|
+
:controller_class_nesting_depth,
|
11
|
+
:controller_class_name,
|
12
|
+
:controller_singular_name,
|
13
|
+
:controller_plural_name,
|
14
|
+
:resource_edit_path,
|
15
|
+
:default_file_extension
|
16
|
+
alias_method :controller_file_name, :controller_singular_name
|
17
|
+
alias_method :controller_table_name, :controller_plural_name
|
18
|
+
|
19
|
+
def initialize(runtime_args, runtime_options = {})
|
20
|
+
super
|
21
|
+
|
22
|
+
@controller_name = @name.pluralize
|
23
|
+
|
24
|
+
base_name, @controller_class_path, @controller_file_path, @controller_class_nesting, @controller_class_nesting_depth = extract_modules(@controller_name)
|
25
|
+
@controller_class_name_without_nesting, @controller_singular_name, @controller_plural_name = inflect_names(base_name)
|
26
|
+
|
27
|
+
if @controller_class_nesting.empty?
|
28
|
+
@controller_class_name = @controller_class_name_without_nesting
|
29
|
+
else
|
30
|
+
@controller_class_name = "#{@controller_class_nesting}::#{@controller_class_name_without_nesting}"
|
31
|
+
end
|
32
|
+
|
33
|
+
if Rails::VERSION::STRING < "2.0.0"
|
34
|
+
@resource_generator = "scaffold_resource"
|
35
|
+
@default_file_extension = "rhtml"
|
36
|
+
else
|
37
|
+
@resource_generator = "scaffold"
|
38
|
+
@default_file_extension = "html.erb"
|
39
|
+
end
|
40
|
+
|
41
|
+
if ActionController::Base.respond_to?(:resource_action_separator)
|
42
|
+
@resource_edit_path = "/edit"
|
43
|
+
else
|
44
|
+
@resource_edit_path = ";edit"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def manifest
|
49
|
+
record do |m|
|
50
|
+
|
51
|
+
# Check for class naming collisions.
|
52
|
+
m.class_collisions(controller_class_path, "#{controller_class_name}Controller", "#{controller_class_name}Helper")
|
53
|
+
m.class_collisions(class_path, "#{class_name}")
|
54
|
+
|
55
|
+
# Controller, helper, views, and spec directories.
|
56
|
+
m.directory(File.join('app/models', class_path))
|
57
|
+
m.directory(File.join('app/controllers', controller_class_path))
|
58
|
+
m.directory(File.join('app/helpers', controller_class_path))
|
59
|
+
m.directory(File.join('app/views', controller_class_path, controller_file_name))
|
60
|
+
m.directory(File.join('spec/controllers', controller_class_path))
|
61
|
+
m.directory(File.join('spec/models', class_path))
|
62
|
+
m.directory(File.join('spec/helpers', class_path))
|
63
|
+
m.directory File.join('spec/fixtures', class_path)
|
64
|
+
m.directory File.join('spec/views', controller_class_path, controller_file_name)
|
65
|
+
|
66
|
+
# Controller spec, class, and helper.
|
67
|
+
m.template 'rspec_scaffold:routing_spec.rb',
|
68
|
+
File.join('spec/controllers', controller_class_path, "#{controller_file_name}_routing_spec.rb")
|
69
|
+
|
70
|
+
m.template 'rspec_rr_scaffold:controller_spec.rb',
|
71
|
+
File.join('spec/controllers', controller_class_path, "#{controller_file_name}_controller_spec.rb")
|
72
|
+
|
73
|
+
m.template "#{@resource_generator}:controller.rb",
|
74
|
+
File.join('app/controllers', controller_class_path, "#{controller_file_name}_controller.rb")
|
75
|
+
|
76
|
+
m.template 'rspec_scaffold:helper_spec.rb',
|
77
|
+
File.join('spec/helpers', class_path, "#{controller_file_name}_helper_spec.rb")
|
78
|
+
|
79
|
+
m.template "#{@resource_generator}:helper.rb",
|
80
|
+
File.join('app/helpers', controller_class_path, "#{controller_file_name}_helper.rb")
|
81
|
+
|
82
|
+
for action in scaffold_views
|
83
|
+
m.template(
|
84
|
+
"#{@resource_generator}:view_#{action}.#{@default_file_extension}",
|
85
|
+
File.join('app/views', controller_class_path, controller_file_name, "#{action}.#{default_file_extension}")
|
86
|
+
)
|
87
|
+
end
|
88
|
+
|
89
|
+
# Model class, unit test, and fixtures.
|
90
|
+
m.template 'model:model.rb', File.join('app/models', class_path, "#{file_name}.rb")
|
91
|
+
m.template 'model:fixtures.yml', File.join('spec/fixtures', class_path, "#{table_name}.yml")
|
92
|
+
m.template 'rspec_model:model_spec.rb', File.join('spec/models', class_path, "#{file_name}_spec.rb")
|
93
|
+
|
94
|
+
# View specs
|
95
|
+
m.template "rspec_scaffold:edit_erb_spec.rb",
|
96
|
+
File.join('spec/views', controller_class_path, controller_file_name, "edit.#{default_file_extension}_spec.rb")
|
97
|
+
m.template "rspec_scaffold:index_erb_spec.rb",
|
98
|
+
File.join('spec/views', controller_class_path, controller_file_name, "index.#{default_file_extension}_spec.rb")
|
99
|
+
m.template "rspec_scaffold:new_erb_spec.rb",
|
100
|
+
File.join('spec/views', controller_class_path, controller_file_name, "new.#{default_file_extension}_spec.rb")
|
101
|
+
m.template "rspec_scaffold:show_erb_spec.rb",
|
102
|
+
File.join('spec/views', controller_class_path, controller_file_name, "show.#{default_file_extension}_spec.rb")
|
103
|
+
|
104
|
+
unless options[:skip_migration]
|
105
|
+
m.migration_template(
|
106
|
+
'model:migration.rb', 'db/migrate',
|
107
|
+
:assigns => {
|
108
|
+
:migration_name => "Create#{class_name.pluralize.gsub(/::/, '')}",
|
109
|
+
:attributes => attributes
|
110
|
+
},
|
111
|
+
:migration_file_name => "create_#{file_path.gsub(/\//, '_').pluralize}"
|
112
|
+
)
|
113
|
+
end
|
114
|
+
|
115
|
+
m.route_resources controller_file_name
|
116
|
+
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
protected
|
121
|
+
# Override with your own usage banner.
|
122
|
+
def banner
|
123
|
+
"Usage: #{$0} rspec_rr_scaffold ModelName [field:type field:type]"
|
124
|
+
end
|
125
|
+
|
126
|
+
def add_options!(opt)
|
127
|
+
opt.separator ''
|
128
|
+
opt.separator 'Options:'
|
129
|
+
opt.on("--skip-migration",
|
130
|
+
"Don't generate a migration file for this model") { |v| options[:skip_migration] = v }
|
131
|
+
end
|
132
|
+
|
133
|
+
def scaffold_views
|
134
|
+
%w[ index show new edit ]
|
135
|
+
end
|
136
|
+
|
137
|
+
def model_name
|
138
|
+
class_name.demodulize
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
module Rails
|
143
|
+
module Generator
|
144
|
+
class GeneratedAttribute
|
145
|
+
def input_type
|
146
|
+
@input_type ||= case type
|
147
|
+
when :text then "textarea"
|
148
|
+
else
|
149
|
+
"input"
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
@@ -0,0 +1,180 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../spec_helper')
|
2
|
+
|
3
|
+
describe <%= controller_class_name %>Controller do
|
4
|
+
|
5
|
+
def mock_<%= file_name %>(stubs={})
|
6
|
+
@mock_<%= file_name %> ||= mock_model(<%= class_name %>, stubs)
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "responding to GET index" do
|
10
|
+
|
11
|
+
it "should expose all <%= table_name.pluralize %> as @<%= table_name.pluralize %>" do
|
12
|
+
mock(<%= class_name %>).find(:all){[mock_<%= file_name %>]}
|
13
|
+
get :index
|
14
|
+
assigns[:<%= table_name %>].should == [mock_<%= file_name %>]
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "with mime type of xml" do
|
18
|
+
|
19
|
+
it "should render all <%= table_name.pluralize %> as xml" do
|
20
|
+
request.env["HTTP_ACCEPT"] = "application/xml"
|
21
|
+
<%= file_name.pluralize %> = []
|
22
|
+
mock(<%= class_name %>).find(:all){<%= file_name.pluralize %>}
|
23
|
+
mock(<%= file_name.pluralize %>).to_xml(){"generated XML"}
|
24
|
+
get :index
|
25
|
+
response.body.should == "generated XML"
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "responding to GET show" do
|
33
|
+
|
34
|
+
it "should expose the requested <%= file_name %> as @<%= file_name %>" do
|
35
|
+
mock(<%= class_name %>).find("37"){mock_<%= file_name %>}
|
36
|
+
get :show, :id => "37"
|
37
|
+
assigns[:<%= file_name %>].should equal(mock_<%= file_name %>)
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "with mime type of xml" do
|
41
|
+
|
42
|
+
it "should render the requested <%= file_name %> as xml" do
|
43
|
+
request.env["HTTP_ACCEPT"] = "application/xml"
|
44
|
+
mock(<%= class_name %>).find("37"){mock_<%= file_name %>}
|
45
|
+
mock(mock_<%= file_name %>).to_xml{"generated XML"}
|
46
|
+
get :show, :id => "37"
|
47
|
+
response.body.should == "generated XML"
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "responding to GET new" do
|
55
|
+
|
56
|
+
it "should expose a new <%= file_name %> as @<%= file_name %>" do
|
57
|
+
#We need to call new before any mocking
|
58
|
+
mock_<%= file_name %>
|
59
|
+
mock(<%= class_name %>).new{mock_<%= file_name %>}
|
60
|
+
get :new
|
61
|
+
assigns[:<%= file_name %>].should equal(mock_<%= file_name %>)
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "responding to GET edit" do
|
67
|
+
|
68
|
+
it "should expose the requested <%= file_name %> as @<%= file_name %>" do
|
69
|
+
mock(<%= class_name %>).find("37"){mock_<%= file_name %>}
|
70
|
+
get :edit, :id => "37"
|
71
|
+
assigns[:<%= file_name %>].should equal(mock_<%= file_name %>)
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "responding to POST create" do
|
77
|
+
|
78
|
+
describe "with valid params" do
|
79
|
+
|
80
|
+
it "should expose a newly created <%= file_name %> as @<%= file_name %>" do
|
81
|
+
<%= file_name %> = mock_<%= file_name %>(:save => true)
|
82
|
+
mock(<%= class_name %>).new({'these' => 'params'}){<%= file_name %>}
|
83
|
+
post :create, :<%= file_name %> => {:these => 'params'}
|
84
|
+
assigns(:<%= file_name %>).should equal(mock_<%= file_name %>)
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should redirect to the created <%= file_name %>" do
|
88
|
+
<%= file_name %> = mock_<%= file_name %>(:save => true)
|
89
|
+
stub(<%= class_name %>).new{<%= file_name %>}
|
90
|
+
post :create, :<%= file_name %> => {}
|
91
|
+
response.should redirect_to(<%= table_name.singularize %>_url(mock_<%= file_name %>))
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
describe "with invalid params" do
|
97
|
+
|
98
|
+
it "should expose a newly created but unsaved <%= file_name %> as @<%= file_name %>" do
|
99
|
+
<%= file_name %> = mock_<%= file_name %>(:save => false)
|
100
|
+
stub(<%= class_name %>).new({'these' => 'params'}){<%= file_name %>}
|
101
|
+
post :create, :<%= file_name %> => {:these => 'params'}
|
102
|
+
assigns(:<%= file_name %>).should equal(mock_<%= file_name %>)
|
103
|
+
end
|
104
|
+
|
105
|
+
it "should re-render the 'new' template" do
|
106
|
+
<%= file_name %> = mock_<%= file_name %>(:save => false)
|
107
|
+
stub(<%= class_name %>).new{<%= file_name %>}
|
108
|
+
post :create, :<%= file_name %> => {}
|
109
|
+
response.should render_template('new')
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
describe "responding to PUT udpate" do
|
117
|
+
|
118
|
+
describe "with valid params" do
|
119
|
+
|
120
|
+
it "should update the requested <%= file_name %>" do
|
121
|
+
mock(<%= class_name %>).find("37"){mock_<%= file_name %>}
|
122
|
+
mock(mock_<%= file_name %>).update_attributes({'these' => 'params'})
|
123
|
+
put :update, :id => "37", :<%= file_name %> => {:these => 'params'}
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should expose the requested <%= file_name %> as @<%= file_name %>" do
|
127
|
+
stub(<%= class_name %>).find{mock_<%= file_name %>(:update_attributes => true)}
|
128
|
+
put :update, :id => "1"
|
129
|
+
assigns(:<%= file_name %>).should equal(mock_<%= file_name %>)
|
130
|
+
end
|
131
|
+
|
132
|
+
it "should redirect to the <%= file_name %>" do
|
133
|
+
stub(<%= class_name %>).find{mock_<%= file_name %>(:update_attributes => true)}
|
134
|
+
put :update, :id => "1"
|
135
|
+
response.should redirect_to(<%= table_name.singularize %>_url(mock_<%= file_name %>))
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
139
|
+
|
140
|
+
describe "with invalid params" do
|
141
|
+
|
142
|
+
it "should update the requested <%= file_name %>" do
|
143
|
+
mock(<%= class_name %>).find("37"){mock_<%= file_name %>}
|
144
|
+
mock(mock_<%= file_name %>).update_attributes({'these' => 'params'})
|
145
|
+
put :update, :id => "37", :<%= file_name %> => {:these => 'params'}
|
146
|
+
end
|
147
|
+
|
148
|
+
it "should expose the <%= file_name %> as @<%= file_name %>" do
|
149
|
+
stub(<%= class_name %>).find{mock_<%= file_name %>(:update_attributes => false)}
|
150
|
+
put :update, :id => "1"
|
151
|
+
assigns(:<%= file_name %>).should equal(mock_<%= file_name %>)
|
152
|
+
end
|
153
|
+
|
154
|
+
it "should re-render the 'edit' template" do
|
155
|
+
stub(<%= class_name %>).find{mock_<%= file_name %>(:update_attributes => false)}
|
156
|
+
put :update, :id => "1"
|
157
|
+
response.should render_template('edit')
|
158
|
+
end
|
159
|
+
|
160
|
+
end
|
161
|
+
|
162
|
+
end
|
163
|
+
|
164
|
+
describe "responding to DELETE destroy" do
|
165
|
+
|
166
|
+
it "should destroy the requested <%= file_name %>" do
|
167
|
+
mock(<%= class_name %>).find("37"){mock_<%= file_name %>}
|
168
|
+
mock(mock_<%= file_name %>).destroy
|
169
|
+
delete :destroy, :id => "37"
|
170
|
+
end
|
171
|
+
|
172
|
+
it "should redirect to the <%= table_name %> list" do
|
173
|
+
stub(<%= class_name %>).find(){mock_<%= file_name %>(:destroy => true)}
|
174
|
+
delete :destroy, :id => "1"
|
175
|
+
response.should redirect_to(<%= table_name %>_url)
|
176
|
+
end
|
177
|
+
|
178
|
+
end
|
179
|
+
|
180
|
+
end
|
data/init.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
# Placeholder to satisfy Rails.
|
2
|
+
#
|
3
|
+
# Do NOT add any require statements to this file. Doing
|
4
|
+
# so will cause Rails to load this plugin all of the time.
|
5
|
+
#
|
6
|
+
# Running 'ruby script/generate rspec' will
|
7
|
+
# generate spec/spec_helper.rb, which includes the necessary
|
8
|
+
# require statements and configuration. This file should
|
9
|
+
# be required by all of your spec files.
|
data/install.rb
ADDED
File without changes
|
data/lib/spec/rr.rb
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
Spec::Rails::Mocks.module_eval do
|
2
|
+
|
3
|
+
module NullObject
|
4
|
+
include ::RR::Space::Reader
|
5
|
+
|
6
|
+
def method_missing(method_name, *args, &block)
|
7
|
+
space.record_call(self, method_name, args, block)
|
8
|
+
nil
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
# Creates a mock object instance for a +model_class+ with common
|
13
|
+
# methods stubbed out. Additional methods may be easily stubbed (via
|
14
|
+
# add_stubs) if +stubs+ is passed.
|
15
|
+
def mock_model(model_class, options_and_stubs = {})
|
16
|
+
@options = parse_options(options_and_stubs)
|
17
|
+
|
18
|
+
m = model_class.new
|
19
|
+
id = next_id
|
20
|
+
|
21
|
+
# our equivalent to Rspecs :errors => ''# stub("errors", :count => 0)
|
22
|
+
stub(errors_stub = Object.new).count{0}
|
23
|
+
|
24
|
+
options_and_stubs.reverse_merge!(
|
25
|
+
:id => id,
|
26
|
+
:to_param => "#{id}",
|
27
|
+
:new_record? => false,
|
28
|
+
:errors => errors_stub
|
29
|
+
)
|
30
|
+
|
31
|
+
m.extend NullObject if null_object?
|
32
|
+
|
33
|
+
options_and_stubs.each do |method,value|
|
34
|
+
stub(m).__send__(method) { value }
|
35
|
+
end
|
36
|
+
|
37
|
+
yield m if block_given?
|
38
|
+
m
|
39
|
+
end
|
40
|
+
|
41
|
+
def stub_model(model_class, stubs={})
|
42
|
+
stubs = {:id => next_id}.merge(stubs)
|
43
|
+
@options = parse_options(stubs)
|
44
|
+
|
45
|
+
returning model_class.new do |model|
|
46
|
+
model.extend NullObject if null_object?
|
47
|
+
|
48
|
+
model.id = stubs.delete(:id)
|
49
|
+
model.extend Spec::Rails::Mocks::ModelStubber
|
50
|
+
stubs.each do |k,v|
|
51
|
+
if model.has_attribute?(k)
|
52
|
+
model[k] = stubs.delete(k)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
stubs.each do |k,v|
|
56
|
+
stub(model).__send__(k) { v }
|
57
|
+
end
|
58
|
+
yield model if block_given?
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
def parse_options(options)
|
64
|
+
options.has_key?(:null_object) ? {:null_object => options.delete(:null_object)} : {}
|
65
|
+
end
|
66
|
+
|
67
|
+
def null_object?
|
68
|
+
@options[:null_object]
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
data/spec/spec.opts
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
class FakeActiveRecord
|
2
|
+
|
3
|
+
attr_accessor :errors, :name, :id
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@errors = Error.new
|
7
|
+
@name = @id
|
8
|
+
end
|
9
|
+
|
10
|
+
def create!
|
11
|
+
end
|
12
|
+
|
13
|
+
def has_attribute?(k)
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
class Error
|
19
|
+
def count
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class MockableModel < FakeActiveRecord
|
24
|
+
end
|
25
|
+
|
26
|
+
class SubMockableModel < MockableModel
|
27
|
+
end
|
28
|
+
|
29
|
+
class AssociatedModel < FakeActiveRecord
|
30
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper.rb'
|
2
|
+
require File.dirname(__FILE__) + '/ar_classes.rb'
|
3
|
+
|
4
|
+
describe "RR overriding" do
|
5
|
+
|
6
|
+
describe "mocking a model" do
|
7
|
+
|
8
|
+
it "should create a instance of model" do
|
9
|
+
mockable = MockableModel.new
|
10
|
+
mock(MockableModel).new{mockable}.once
|
11
|
+
|
12
|
+
mock_model(MockableModel)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should return a real model" do
|
16
|
+
mock_model(MockableModel).should be_instance_of(MockableModel)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should add stub to model" do
|
20
|
+
model = mock_model(MockableModel, :are_you_mocking_me_sir? => true)
|
21
|
+
|
22
|
+
model.are_you_mocking_me_sir?.should be_true
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should allow stubbing of error" do
|
26
|
+
#This is the nearest way we can express errors in RR
|
27
|
+
stub(error_stub = Object.new).count{5}
|
28
|
+
model = mock_model(MockableModel, :errors => error_stub )
|
29
|
+
|
30
|
+
model.errors.count.should eql(5)
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "null_object => true" do
|
34
|
+
|
35
|
+
it "should return nil for unknown method" do
|
36
|
+
model = mock_model(MockableModel, :null_object => true)
|
37
|
+
|
38
|
+
model.a_method_which_does_not_exist.should == nil
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "null_object => false" do
|
44
|
+
|
45
|
+
before(:each) do
|
46
|
+
@model = mock_model(MockableModel, :null_object => false)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should raise an error for unknown method" do
|
50
|
+
lambda{
|
51
|
+
@model.a_method_which_does_not_exist
|
52
|
+
}.should raise_error NoMethodError
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should not stub null_object method" do
|
56
|
+
lambda{
|
57
|
+
@model.null_object
|
58
|
+
}.should raise_error NoMethodError
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "stubbing a model" do
|
66
|
+
|
67
|
+
it "should create a instance of model" do
|
68
|
+
mockable = MockableModel.new
|
69
|
+
mock(MockableModel).new{mockable}.once
|
70
|
+
|
71
|
+
stub_model(MockableModel, :new_record? => true)
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should return a real model" do
|
75
|
+
stub_model(MockableModel).should be_instance_of(MockableModel)
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should add stub to model" do
|
79
|
+
model = stub_model(MockableModel, :new_record? => true)
|
80
|
+
|
81
|
+
model.should be_new_record
|
82
|
+
end
|
83
|
+
|
84
|
+
describe "null_object => true" do
|
85
|
+
|
86
|
+
it "should return nil for unknown method" do
|
87
|
+
model = stub_model(MockableModel, :null_object => true)
|
88
|
+
model.a_method_which_does_not_exist.should == nil
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
describe "null_object => false" do
|
94
|
+
|
95
|
+
before(:each) do
|
96
|
+
@model = stub_model(MockableModel, :null_object => false)
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should raise an error for unknown method" do
|
100
|
+
lambda{
|
101
|
+
@model.a_method_which_does_not_exist
|
102
|
+
}.should raise_error NoMethodError
|
103
|
+
end
|
104
|
+
|
105
|
+
it "should not stub null_object method" do
|
106
|
+
lambda{
|
107
|
+
@model.null_object
|
108
|
+
}.should raise_error NoMethodError
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper.rb'
|
2
|
+
|
3
|
+
describe NullObject do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
@subject = Object.new
|
7
|
+
@subject.extend NullObject
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should overide nil methods when using stub" do
|
11
|
+
stub(@subject).testing{ true }
|
12
|
+
|
13
|
+
@subject.testing.should == true
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should overide nil methods when using mock" do
|
17
|
+
mock(@subject).testing{ true }
|
18
|
+
|
19
|
+
@subject.testing.should == true
|
20
|
+
end
|
21
|
+
|
22
|
+
include RR::Adapters::Rspec
|
23
|
+
|
24
|
+
it "should record undefined methods that return nil" do
|
25
|
+
pending do
|
26
|
+
@subject.moonkins
|
27
|
+
@subject.should have_received(:moonkins)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
ENV["RAILS_ENV"] = "test"
|
2
|
+
|
3
|
+
dir = File.dirname(__FILE__)
|
4
|
+
$LOAD_PATH.unshift(File.expand_path("#{dir}/../../rspec/lib"))
|
5
|
+
$LOAD_PATH.unshift(File.expand_path("#{dir}/../../rspec-rails/lib"))
|
6
|
+
$LOAD_PATH.unshift(File.expand_path("#{dir}/../lib"))
|
7
|
+
|
8
|
+
require "#{dir}/../../../../config/environment"
|
9
|
+
require 'spec/rails'
|
10
|
+
require 'spec/rr'
|
11
|
+
|
12
|
+
Spec::Runner.configure do |config|
|
13
|
+
config.mock_with :rr
|
14
|
+
end
|
data/uninstall.rb
ADDED
File without changes
|
metadata
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rspec-rr
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Joseph Wilk
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2010-07-19 00:00:00 +01:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rspec
|
17
|
+
type: :development
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
description: Helping Rspec and Rspec-rails play nicely with RR the test double framework.
|
26
|
+
email: joe@josephwilk.net
|
27
|
+
executables: []
|
28
|
+
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files:
|
32
|
+
- README.textile
|
33
|
+
files:
|
34
|
+
- MIT-LICENSE
|
35
|
+
- README.textile
|
36
|
+
- Rakefile
|
37
|
+
- TODO.txt
|
38
|
+
- VERSION.yml
|
39
|
+
- generators/rspec_default_values.rb
|
40
|
+
- generators/rspec_rr_scaffold/rspec_rr_scaffold_generator.rb
|
41
|
+
- generators/rspec_rr_scaffold/templates/controller_spec.rb
|
42
|
+
- init.rb
|
43
|
+
- install.rb
|
44
|
+
- lib/spec/rr.rb
|
45
|
+
- lib/spec/rr/mocks.rb
|
46
|
+
- spec/spec.opts
|
47
|
+
- spec/spec/rr/ar_classes.rb
|
48
|
+
- spec/spec/rr/mocks_spec.rb
|
49
|
+
- spec/spec/rr/null_object_spec.rb
|
50
|
+
- spec/spec_helper.rb
|
51
|
+
- tasks/rspec_rr_tasks.rake
|
52
|
+
- uninstall.rb
|
53
|
+
has_rdoc: true
|
54
|
+
homepage: http://github.com/josephwilk/rspec-rr
|
55
|
+
licenses: []
|
56
|
+
|
57
|
+
post_install_message:
|
58
|
+
rdoc_options:
|
59
|
+
- --charset=UTF-8
|
60
|
+
require_paths:
|
61
|
+
- lib
|
62
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: "0"
|
67
|
+
version:
|
68
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: "0"
|
73
|
+
version:
|
74
|
+
requirements: []
|
75
|
+
|
76
|
+
rubyforge_project:
|
77
|
+
rubygems_version: 1.3.5
|
78
|
+
signing_key:
|
79
|
+
specification_version: 3
|
80
|
+
summary: Helping Rspec and Rspec-rails play nicely with RR the test double framework
|
81
|
+
test_files:
|
82
|
+
- spec/spec/rr/ar_classes.rb
|
83
|
+
- spec/spec/rr/mocks_spec.rb
|
84
|
+
- spec/spec/rr/null_object_spec.rb
|
85
|
+
- spec/spec_helper.rb
|