sinatra-tests 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/.gitignore +15 -0
- data/LICENSE +20 -0
- data/README.rdoc +102 -0
- data/Rakefile +90 -0
- data/VERSION +1 -0
- data/lib/sinatra/tests.rb +39 -0
- data/lib/sinatra/tests/shared_specs.rb +331 -0
- data/lib/sinatra/tests/test_case.rb +153 -0
- data/sinatra-tests.gemspec +63 -0
- data/spec/sinatra/tests/test_case_spec.rb +122 -0
- data/spec/spec_helper.rb +33 -0
- metadata +107 -0
data/.document
ADDED
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 kematzy
|
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.rdoc
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
= Sinatra::Tests
|
2
|
+
|
3
|
+
Commonly used bits when testing Sinatra apps/gems.
|
4
|
+
|
5
|
+
|
6
|
+
== Installation
|
7
|
+
|
8
|
+
# Add GitHub to your RubyGems sources
|
9
|
+
$ gem sources -a http://gems.github.com
|
10
|
+
|
11
|
+
$ (sudo)? gem install kematzy-sinatra-tests
|
12
|
+
|
13
|
+
=== Dependencies
|
14
|
+
|
15
|
+
This Gem depends upon the following:
|
16
|
+
|
17
|
+
* sinatra ( >= 0.10.1 )
|
18
|
+
* rspec (>= 1.2.7 )
|
19
|
+
* rack-test (>= 0.4.1)
|
20
|
+
|
21
|
+
|
22
|
+
== Getting Started
|
23
|
+
|
24
|
+
|
25
|
+
=== Step 1
|
26
|
+
|
27
|
+
In your spec/spec_helper.rb file add the following:
|
28
|
+
|
29
|
+
require 'sinatra/tests'
|
30
|
+
|
31
|
+
By just requiring that gem, you essentially get all of this:
|
32
|
+
|
33
|
+
require 'sinatra/base'
|
34
|
+
require 'test/unit'
|
35
|
+
require 'rack/test'
|
36
|
+
require 'spec'
|
37
|
+
require 'spec/interop/test'
|
38
|
+
require 'rspec_hpricot_matchers'
|
39
|
+
|
40
|
+
and a few other goodies.
|
41
|
+
|
42
|
+
=== Step 2
|
43
|
+
|
44
|
+
Declare the following Spec block:
|
45
|
+
|
46
|
+
Spec::Runner.configure do |config|
|
47
|
+
config.include RspecHpricotMatchers
|
48
|
+
config.include Sinatra::Tests::SharedSpecs
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
=== Step 3
|
53
|
+
|
54
|
+
In your TestApp block, register the Sinatra::Tests extension, by adding the following:
|
55
|
+
|
56
|
+
class MyTestApp < Sinatra::Base
|
57
|
+
|
58
|
+
register(Sinatra::Tests)
|
59
|
+
|
60
|
+
<snip...>
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
=== Step 4
|
65
|
+
|
66
|
+
And finally define the TestCase block like this:
|
67
|
+
|
68
|
+
class Test::Unit::TestCase
|
69
|
+
include Sinatra::Tests::TestCase
|
70
|
+
|
71
|
+
Sinatra::Base.set :environment, :test
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
That's all. Now onto the niceties this provides you.
|
76
|
+
|
77
|
+
|
78
|
+
== USAGE
|
79
|
+
|
80
|
+
TODO:: write more documentation here
|
81
|
+
|
82
|
+
|
83
|
+
|
84
|
+
== RTFM
|
85
|
+
|
86
|
+
For a better understanding of this Gem, make sure you study the '<tt>sinatra-tests/spec/*_spec.rb</tt>' files.
|
87
|
+
|
88
|
+
|
89
|
+
== Errors / Bugs
|
90
|
+
|
91
|
+
If something is not behaving intuitively, it is a bug, and should be reported.
|
92
|
+
Report it here: http://github.com/kematzy/sinatra-tests/issues
|
93
|
+
|
94
|
+
== Credits
|
95
|
+
|
96
|
+
Copyright (c) 2009 Kematzy [ kematzy gmail com ]
|
97
|
+
|
98
|
+
== Licence
|
99
|
+
|
100
|
+
Released under the MIT license.
|
101
|
+
|
102
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "sinatra-tests"
|
8
|
+
gem.summary = %Q{Sinatra::Tests is a repository of common Test/RSpec helpers}
|
9
|
+
gem.email = "kematzy@gmail.com"
|
10
|
+
gem.homepage = "http://github.com/kematzy/sinatra-tests"
|
11
|
+
gem.authors = ["kematzy"]
|
12
|
+
gem.add_dependency('sinatra', '>= 0.10.1')
|
13
|
+
gem.add_dependency('rack-test', '>= 0.4.1')
|
14
|
+
gem.add_dependency('rspec', '>= 1.2.8')
|
15
|
+
gem.add_dependency('rspec_hpricot_matchers', '>= 1.0.0')
|
16
|
+
|
17
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
18
|
+
end
|
19
|
+
|
20
|
+
rescue LoadError
|
21
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
22
|
+
end
|
23
|
+
|
24
|
+
require 'spec/rake/spectask'
|
25
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
26
|
+
spec.libs << 'lib' << 'spec'
|
27
|
+
spec.spec_opts = ["--color", "--format", "specdoc", "--require", "spec/spec_helper.rb"]
|
28
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
29
|
+
end
|
30
|
+
|
31
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
32
|
+
spec.libs << 'lib' << 'spec'
|
33
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
34
|
+
spec.rcov = true
|
35
|
+
end
|
36
|
+
|
37
|
+
namespace :spec do
|
38
|
+
|
39
|
+
desc "Run all specifications silently"
|
40
|
+
Spec::Rake::SpecTask.new(:silent) do |t|
|
41
|
+
t.libs << "lib"
|
42
|
+
t.spec_opts = ["--color", "--require", "spec/spec_helper.rb"]
|
43
|
+
end
|
44
|
+
|
45
|
+
desc "Run specific spec verbosely (SPEC=/path/2/file)"
|
46
|
+
Spec::Rake::SpecTask.new(:select) do |t|
|
47
|
+
t.libs << "lib"
|
48
|
+
t.spec_files = [ENV["SPEC"]]
|
49
|
+
t.spec_opts = ["--color", "--format", "specdoc", "--require", "spec/spec_helper.rb"]
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
task :default => :spec
|
56
|
+
|
57
|
+
require 'rake/rdoctask'
|
58
|
+
Rake::RDocTask.new do |rdoc|
|
59
|
+
version = File.exist?('VERSION') ? IO.read('VERSION').chomp : "[Unknown]"
|
60
|
+
|
61
|
+
rdoc.rdoc_dir = 'rdoc'
|
62
|
+
rdoc.title = "Sinatra::Tests #{version}"
|
63
|
+
rdoc.rdoc_files.include('README*')
|
64
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
65
|
+
end
|
66
|
+
|
67
|
+
desc 'Build the rdoc HTML Files'
|
68
|
+
task :docs do
|
69
|
+
version = File.exist?('VERSION') ? IO.read('VERSION').chomp : "[Unknown]"
|
70
|
+
|
71
|
+
sh "sdoc -N --title 'Sinatra::Tests v#{version}' lib/ README.rdoc"
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
namespace :docs do
|
76
|
+
|
77
|
+
# desc 'Remove rdoc products'
|
78
|
+
# task :remove => [:clobber_rdoc]
|
79
|
+
#
|
80
|
+
# desc 'Force a rebuild of the RDOC files'
|
81
|
+
# task :rebuild => [:rerdoc]
|
82
|
+
|
83
|
+
desc 'Build docs, and open in browser for viewing (specify BROWSER)'
|
84
|
+
task :open => [:docs] do
|
85
|
+
browser = ENV["BROWSER"] || "safari"
|
86
|
+
sh "open -a #{browser} doc/index.html"
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.4
|
@@ -0,0 +1,39 @@
|
|
1
|
+
|
2
|
+
require 'haml'
|
3
|
+
require 'sinatra/base'
|
4
|
+
require 'test/unit'
|
5
|
+
require 'rack/test'
|
6
|
+
require 'spec'
|
7
|
+
require 'spec/interop/test'
|
8
|
+
require 'rspec_hpricot_matchers'
|
9
|
+
|
10
|
+
|
11
|
+
module Sinatra
|
12
|
+
module Tests
|
13
|
+
VERSION = '0.1.4' unless const_defined?(:VERSION)
|
14
|
+
def self.version; "Sinatra::Tests v#{VERSION}"; end
|
15
|
+
|
16
|
+
|
17
|
+
def self.registered(app)
|
18
|
+
|
19
|
+
app.set :environment, :test
|
20
|
+
|
21
|
+
app.get '/tests' do
|
22
|
+
case params[:engine]
|
23
|
+
when 'erb'
|
24
|
+
erb(params[:view], :layout => params[:layout] )
|
25
|
+
when 'haml'
|
26
|
+
haml(params[:view], :layout => params[:layout] )
|
27
|
+
else
|
28
|
+
params.inspect
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end #/ self.registered
|
33
|
+
|
34
|
+
end #/module Test
|
35
|
+
end #/module Sinatra
|
36
|
+
|
37
|
+
%w(test_case shared_specs).each do |f|
|
38
|
+
require "sinatra/tests/#{f}"
|
39
|
+
end
|
@@ -0,0 +1,331 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
module Sinatra
|
4
|
+
module Tests
|
5
|
+
|
6
|
+
module RSpecMatchers
|
7
|
+
|
8
|
+
##
|
9
|
+
# TODO: add some comments here
|
10
|
+
#
|
11
|
+
# ==== Examples
|
12
|
+
#
|
13
|
+
#
|
14
|
+
# @api public/private
|
15
|
+
def be_even
|
16
|
+
simple_matcher("an even number") { |given| given % 2 == 0 }
|
17
|
+
end
|
18
|
+
|
19
|
+
##
|
20
|
+
# TODO: add some comments here
|
21
|
+
#
|
22
|
+
# ==== Examples
|
23
|
+
#
|
24
|
+
#
|
25
|
+
# @api public/private
|
26
|
+
def have_a_page_title(expected)
|
27
|
+
simple_matcher do |given, matcher|
|
28
|
+
given.should have_tag('title', expected)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
##
|
33
|
+
# TODO: add some comments here
|
34
|
+
#
|
35
|
+
# ==== Examples
|
36
|
+
#
|
37
|
+
#
|
38
|
+
# @api public/private
|
39
|
+
def have_a_page_header(expected)
|
40
|
+
simple_matcher("have an h2 page header with [#{expected.inspect}]") do |given, matcher|
|
41
|
+
# matcher.description = "have an h2 page header with [#{expected.inspect}]"
|
42
|
+
given.should have_tag('h2', expected, :count => 1)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
##
|
47
|
+
# TODO: add some comments here
|
48
|
+
#
|
49
|
+
# ==== Examples
|
50
|
+
#
|
51
|
+
#
|
52
|
+
# @api public/private
|
53
|
+
def have_a_td_actions(model, buttons = %w(delete edit))
|
54
|
+
simple_matcher do |given, matcher|
|
55
|
+
tag = "div##{model.to_s.plural}-div > table##{model.to_s.plural}-table > tbody > tr > td.actions"
|
56
|
+
given.should have_tag(tag) do |td|
|
57
|
+
td.attributes['id'].should match(/#{model.to_s.singular}-actions-\d+/)
|
58
|
+
end
|
59
|
+
buttons.each do |btn|
|
60
|
+
given.should have_a_delete_btn(tag, model) if btn.to_s == 'delete'
|
61
|
+
given.should have_an_edit_btn(tag, model) if btn.to_s == 'edit'
|
62
|
+
# TODO:: fix Show button
|
63
|
+
# td.should have_a_show_btn(model) if btn.to_s == 'show'
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
##
|
69
|
+
# TODO: add some comments here
|
70
|
+
#
|
71
|
+
# ==== Examples
|
72
|
+
#
|
73
|
+
#
|
74
|
+
# @api public/private
|
75
|
+
def have_an_edit_btn(tag, model)
|
76
|
+
simple_matcher do |given, matcher|
|
77
|
+
given.should have_tag(tag + ' > a.edit-link.ui-btn','EDIT') do |a|
|
78
|
+
a.attributes['href'].should match(/\/#{model.to_s.plural}\/\d+\/edit/)
|
79
|
+
end
|
80
|
+
given.should have_tag(tag + " > a.edit-link[@title=edit #{model.to_s.singular}]",'EDIT')
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
##
|
85
|
+
# TODO: add some comments here
|
86
|
+
#
|
87
|
+
# ==== Examples
|
88
|
+
#
|
89
|
+
#
|
90
|
+
# @api public/private
|
91
|
+
def have_a_delete_btn(tag, model)
|
92
|
+
simple_matcher do |given, matcher|
|
93
|
+
given.should have_tag(tag + ' > a.delete-link.ui-btn','DELETE') do |a|
|
94
|
+
a.attributes['href'].should match(/\/#{model.to_s.plural}\/\d+/)
|
95
|
+
end
|
96
|
+
given.should have_tag(tag + " > a.delete-link[@title=delete #{model.to_s.singular}]",'DELETE')
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# def have_id_attribute(tag, id)
|
101
|
+
# simple_matcher do |given, matcher|
|
102
|
+
# given.should have_tag(tag).attributes['id'].should match(id)
|
103
|
+
# end
|
104
|
+
# end
|
105
|
+
|
106
|
+
# def have_link_title(title)
|
107
|
+
# simple_matcher do |given, matcher|
|
108
|
+
# given.attributes['title'].should == title
|
109
|
+
# end
|
110
|
+
# end
|
111
|
+
|
112
|
+
##
|
113
|
+
# TODO: add some comments here
|
114
|
+
#
|
115
|
+
# ==== Examples
|
116
|
+
#
|
117
|
+
#
|
118
|
+
# @api public/private
|
119
|
+
def have_an_ui_form_header(model, options = {} )
|
120
|
+
|
121
|
+
end
|
122
|
+
|
123
|
+
##
|
124
|
+
# TODO: add some comments here
|
125
|
+
#
|
126
|
+
# ==== Examples
|
127
|
+
#
|
128
|
+
#
|
129
|
+
# @api public/private
|
130
|
+
def have_a_ui_form_message(state, msg = nil)
|
131
|
+
simple_matcher do |given, matcher|
|
132
|
+
if msg.nil?
|
133
|
+
given.should have_tag("form > div.ui-form-message.#{state} > p") #ignoring message
|
134
|
+
else
|
135
|
+
given.should have_tag("form > div.ui-form-message.#{state} > p", msg)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
##
|
141
|
+
# TODO: add some comments here
|
142
|
+
#
|
143
|
+
# ==== Examples
|
144
|
+
#
|
145
|
+
#
|
146
|
+
# @api public/private
|
147
|
+
def have_an_admin_header(options ={})
|
148
|
+
simple_matcher do |given, matcher|
|
149
|
+
matcher.description = "be an admin_header with [#{options.inspect}]"
|
150
|
+
matcher.failure_message = "expected #{given} to have an admin-section-header with these values #{options.inspect}"
|
151
|
+
|
152
|
+
given.should have_tag('div.admin-section-header')
|
153
|
+
if options[:model]
|
154
|
+
given.should have_tag('div.admin-section-header > div.section > h2', /#{options[:model].to_s}/i )
|
155
|
+
if options[:add_new]
|
156
|
+
given.should have_tag("div.admin-section-header > div.actions > h4 > a[@href=/#{options[:model].to_s.downcase}/new]", /ADD NEW #{options[:model].to_s.singular}:?/i )
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
|
163
|
+
end #/module RSpecMatchers
|
164
|
+
|
165
|
+
# == Shared Specs
|
166
|
+
#
|
167
|
+
# === DEBUG
|
168
|
+
#
|
169
|
+
# * <b><tt>it_should_behave_like "debug => app.methods"</tt></b>
|
170
|
+
#
|
171
|
+
# dumps a list of methods for the current <tt>app</tt>
|
172
|
+
#
|
173
|
+
# * <b><tt>it_should_behave_like "debug"</tt></b>
|
174
|
+
#
|
175
|
+
# tests the body output for a <tt><debug></tt> tag.
|
176
|
+
#
|
177
|
+
#
|
178
|
+
# === RESPONSE
|
179
|
+
#
|
180
|
+
# * <b><tt>it_should_behave_like "HTTP headers"</tt></b>
|
181
|
+
#
|
182
|
+
# checks that we got a 200 status (OK), and content-type is <tt>text/html</tt>
|
183
|
+
#
|
184
|
+
#
|
185
|
+
# === HTML OUTPUT
|
186
|
+
#
|
187
|
+
# * <b><tt>it_should_behave_like "div#main-content"</tt></b>
|
188
|
+
#
|
189
|
+
# checks that the page has a <tt><div id="main-content"></div></tt>
|
190
|
+
#
|
191
|
+
# * <b><tt>it_should_behave_like "div#main-content > h2"</tt></b>
|
192
|
+
#
|
193
|
+
# checks that the page has an <tt><h2></tt> tag within the <tt><div id="main-content"></div></tt>
|
194
|
+
#
|
195
|
+
#
|
196
|
+
# ==== ADMIN SECTION
|
197
|
+
#
|
198
|
+
# * <b><tt>it_should_behave_like "div.admin-section-header > div.actions > h4 with HELP"</tt></b>
|
199
|
+
#
|
200
|
+
# checks that the page has an...
|
201
|
+
#
|
202
|
+
#
|
203
|
+
# ==== FORMS
|
204
|
+
#
|
205
|
+
# * <b><tt>it_should_behave_like "faux method > input.hidden[@value=put|delete]"</tt></b>
|
206
|
+
#
|
207
|
+
# checks that the page has an...
|
208
|
+
#
|
209
|
+
module SharedSpecs
|
210
|
+
|
211
|
+
include Sinatra::Tests::RSpecMatchers
|
212
|
+
|
213
|
+
# :stopdoc:
|
214
|
+
|
215
|
+
share_examples_for 'MyTestApp' do
|
216
|
+
|
217
|
+
before(:each) do
|
218
|
+
class ::Test::Unit::TestCase
|
219
|
+
def app; ::MyTestApp.new ; end
|
220
|
+
end
|
221
|
+
@app = app
|
222
|
+
end
|
223
|
+
|
224
|
+
after(:each) do
|
225
|
+
class ::Test::Unit::TestCase
|
226
|
+
def app; nil ; end
|
227
|
+
end
|
228
|
+
@app = nil
|
229
|
+
end
|
230
|
+
|
231
|
+
describe "Sanity" do
|
232
|
+
|
233
|
+
it "should be a MyTestApp kind of app" do
|
234
|
+
app.class.should == MyTestApp
|
235
|
+
end
|
236
|
+
|
237
|
+
# it_should_behave_like "debug => app.methods"
|
238
|
+
|
239
|
+
end #/ Sanity
|
240
|
+
|
241
|
+
end
|
242
|
+
|
243
|
+
share_examples_for 'MyAdminTestApp' do
|
244
|
+
|
245
|
+
before(:each) do
|
246
|
+
class ::Test::Unit::TestCase
|
247
|
+
def app; ::MyAdminTestApp.new ; end
|
248
|
+
end
|
249
|
+
@app = app
|
250
|
+
end
|
251
|
+
|
252
|
+
after(:each) do
|
253
|
+
class ::Test::Unit::TestCase
|
254
|
+
def app; nil ; end
|
255
|
+
end
|
256
|
+
@app = nil
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
# :startdoc:
|
261
|
+
|
262
|
+
# it_should_behave_like "debug => app.methods"
|
263
|
+
#
|
264
|
+
share_examples_for "debug => app.methods" do
|
265
|
+
it "app should have the right methods" do
|
266
|
+
app.methods.sort.should == 'debug => app.methods.sort'
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
share_examples_for "debug" do
|
271
|
+
|
272
|
+
it "should output the whole html" do
|
273
|
+
body.should have_tag('debug')
|
274
|
+
end
|
275
|
+
|
276
|
+
end #/debug
|
277
|
+
|
278
|
+
share_examples_for "HTTP headers" do
|
279
|
+
|
280
|
+
it "should return status: 200" do
|
281
|
+
assert response.ok?
|
282
|
+
end
|
283
|
+
|
284
|
+
it "should return 'text/html'" do
|
285
|
+
response.headers['Content-Type'].should == 'text/html'
|
286
|
+
# assert_equal('text/html', last_response.headers['Content-Type'])
|
287
|
+
end
|
288
|
+
|
289
|
+
end #/headers
|
290
|
+
|
291
|
+
|
292
|
+
###### HTML OUTPUT #######
|
293
|
+
|
294
|
+
share_examples_for 'div#main-content' do
|
295
|
+
it "should have a div#main-content tag" do
|
296
|
+
body.should have_tag('div#main-content')
|
297
|
+
end
|
298
|
+
end #/div
|
299
|
+
|
300
|
+
share_examples_for 'div#main-content > h2' do
|
301
|
+
it "should have a div#main-content h2 tag" do
|
302
|
+
body.should have_tag('div#main-content > h2', :count => 1)
|
303
|
+
end
|
304
|
+
end #/share_examples_for
|
305
|
+
|
306
|
+
|
307
|
+
###### ADMIN SECTIONS #######
|
308
|
+
|
309
|
+
|
310
|
+
share_examples_for 'div.admin-section-header > div.actions > h4 with HELP' do
|
311
|
+
it "should have div.admin-section-header > div.actions > h4 with HELP" do
|
312
|
+
body.should have_tag('div.admin-section-header > div.actions > h4') do |h4|
|
313
|
+
h4.inner_text.should match(/\s*HELP$/)
|
314
|
+
end
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
|
319
|
+
###### FORMS ########
|
320
|
+
|
321
|
+
share_examples_for 'faux method > input.hidden[@value=put|delete]' do
|
322
|
+
it "should have a faux method input hidden with method = PUT or DELETE" do
|
323
|
+
body.should match(/<input (name="_method"\s*|type="hidden"\s*|value="(put|delete)"\s*){3}>/)
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
327
|
+
|
328
|
+
end #/module SharedSpecs
|
329
|
+
|
330
|
+
end #/module Tests
|
331
|
+
end #/module Sinatra
|
@@ -0,0 +1,153 @@
|
|
1
|
+
|
2
|
+
module Sinatra
|
3
|
+
module Tests
|
4
|
+
|
5
|
+
##
|
6
|
+
# Sinatra::Tests::TestCase
|
7
|
+
#
|
8
|
+
# Module to be include into Test::Unit::TestCase declaration in spec_helper.rb
|
9
|
+
#
|
10
|
+
# class Test::Unit::TestCase
|
11
|
+
# include Sinatra::Tests::TestCase
|
12
|
+
#
|
13
|
+
# <snip...>
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
#
|
17
|
+
#
|
18
|
+
module TestCase
|
19
|
+
|
20
|
+
include Rack::Test::Methods
|
21
|
+
|
22
|
+
# so we can escape_html in our debug output
|
23
|
+
include Rack::Utils
|
24
|
+
alias_method :h, :escape_html
|
25
|
+
|
26
|
+
##
|
27
|
+
# Short for <tt>last_response</tt>.
|
28
|
+
# Making it easier to work with the returned response
|
29
|
+
#
|
30
|
+
# @api public
|
31
|
+
alias_method :response, :last_response
|
32
|
+
|
33
|
+
##
|
34
|
+
# Declaration of Sinatra setup
|
35
|
+
#
|
36
|
+
# @api public
|
37
|
+
def setup
|
38
|
+
Sinatra::Base.set :environment, :test
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
# Sets up a Sinatra::Base subclass defined with the block
|
43
|
+
# given. Used in setup or individual spec methods to establish
|
44
|
+
# the application.
|
45
|
+
def mock_app(base=Sinatra::Base, &block)
|
46
|
+
@app = Sinatra.new(base, &block)
|
47
|
+
end
|
48
|
+
|
49
|
+
##
|
50
|
+
# Short for <tt>last_response.body</tt>.
|
51
|
+
# Making it easier to work with the returned body of a response
|
52
|
+
#
|
53
|
+
# @api public
|
54
|
+
def body
|
55
|
+
response.body.to_s
|
56
|
+
end
|
57
|
+
# alias_method :markup, :body
|
58
|
+
|
59
|
+
##
|
60
|
+
# Short for <tt>last_response.status</tt>.
|
61
|
+
# Making it easier to work with the returned status of a response
|
62
|
+
#
|
63
|
+
# @api public
|
64
|
+
def status
|
65
|
+
response.status
|
66
|
+
end
|
67
|
+
|
68
|
+
##
|
69
|
+
# Delegate other missing methods to response.
|
70
|
+
#
|
71
|
+
def method_missing(name, *args, &block)
|
72
|
+
if response && response.respond_to?(name)
|
73
|
+
response.send(name, *args, &block)
|
74
|
+
else
|
75
|
+
super
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
##
|
80
|
+
# Also check response since we delegate there.
|
81
|
+
#
|
82
|
+
def respond_to?(symbol, include_private=false)
|
83
|
+
super || (response && response.respond_to?(symbol, include_private))
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
##
|
88
|
+
# Flexible method to test the ERB output.
|
89
|
+
#
|
90
|
+
# Accepts custom :layout & :url options passed.
|
91
|
+
#
|
92
|
+
# ==== Examples
|
93
|
+
#
|
94
|
+
# erb_app "<%= some_method('value') %>"
|
95
|
+
# body.should == 'some result'
|
96
|
+
# body.should have_tag(:some_tag)
|
97
|
+
#
|
98
|
+
# # NB! the custom URL must be declared in the MyTestApp in order to work
|
99
|
+
#
|
100
|
+
# erb_app "<%= 'custom-erb-url'.upcase %>", :url => "/custom-erb-url"
|
101
|
+
# last_request.path_info.should == "/custom-erb-url"
|
102
|
+
#
|
103
|
+
# @api public
|
104
|
+
def erb_app(view, options = {})
|
105
|
+
options = {:layout => '<%= yield %>', :url => '/tests' }.merge(options)
|
106
|
+
get options[:url], :view => view, :layout => options[:layout], :engine => :erb
|
107
|
+
end
|
108
|
+
|
109
|
+
##
|
110
|
+
# Flexible method to test the HAML output
|
111
|
+
#
|
112
|
+
# ==== Examples
|
113
|
+
#
|
114
|
+
# haml_app "= some_method('value')"
|
115
|
+
# body.should == 'some result'
|
116
|
+
# body.should have_tag(:some_tag)
|
117
|
+
#
|
118
|
+
# # NB! the custom URL must be declared in the MyTestApp in order to work
|
119
|
+
#
|
120
|
+
# haml_app "= 'custom-haml-url'.upcase", :url => "/custom-haml-url"
|
121
|
+
# last_request.path_info.should == "/custom-haml-url"
|
122
|
+
#
|
123
|
+
# @api public
|
124
|
+
def haml_app(view, options = {})
|
125
|
+
options = {:layout => '= yield ', :url => '/tests' }.merge(options)
|
126
|
+
get options[:url], :view => view, :layout => options[:layout], :engine => :haml
|
127
|
+
end
|
128
|
+
|
129
|
+
|
130
|
+
private
|
131
|
+
|
132
|
+
# RACK_OPTIONS = {
|
133
|
+
# :accept => 'HTTP_ACCEPT',
|
134
|
+
# :agent => 'HTTP_USER_AGENT',
|
135
|
+
# :host => 'HTTP_HOST',
|
136
|
+
# :session => 'rack.session',
|
137
|
+
# :cookies => 'HTTP_COOKIE',
|
138
|
+
# :content_type => 'CONTENT_TYPE'
|
139
|
+
# }
|
140
|
+
#
|
141
|
+
# def rack_options(opts)
|
142
|
+
# opts.merge(:lint => true).inject({}) do |hash,(key,val)|
|
143
|
+
# key = RACK_OPTIONS[key] || key
|
144
|
+
# hash[key] = val
|
145
|
+
# hash
|
146
|
+
# end
|
147
|
+
# end
|
148
|
+
|
149
|
+
|
150
|
+
end #/module Testcase
|
151
|
+
|
152
|
+
end #/module Tests
|
153
|
+
end #/module Sinatra
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{sinatra-tests}
|
8
|
+
s.version = "0.1.4"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["kematzy"]
|
12
|
+
s.date = %q{2009-10-08}
|
13
|
+
s.email = %q{kematzy@gmail.com}
|
14
|
+
s.extra_rdoc_files = [
|
15
|
+
"LICENSE",
|
16
|
+
"README.rdoc"
|
17
|
+
]
|
18
|
+
s.files = [
|
19
|
+
".document",
|
20
|
+
".gitignore",
|
21
|
+
"LICENSE",
|
22
|
+
"README.rdoc",
|
23
|
+
"Rakefile",
|
24
|
+
"VERSION",
|
25
|
+
"lib/sinatra/tests.rb",
|
26
|
+
"lib/sinatra/tests/shared_specs.rb",
|
27
|
+
"lib/sinatra/tests/test_case.rb",
|
28
|
+
"sinatra-tests.gemspec",
|
29
|
+
"spec/sinatra/tests/test_case_spec.rb",
|
30
|
+
"spec/spec_helper.rb"
|
31
|
+
]
|
32
|
+
s.homepage = %q{http://github.com/kematzy/sinatra-tests}
|
33
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
34
|
+
s.require_paths = ["lib"]
|
35
|
+
s.rubygems_version = %q{1.3.5}
|
36
|
+
s.summary = %q{Sinatra::Tests is a repository of common Test/RSpec helpers}
|
37
|
+
s.test_files = [
|
38
|
+
"spec/sinatra/tests/test_case_spec.rb",
|
39
|
+
"spec/spec_helper.rb"
|
40
|
+
]
|
41
|
+
|
42
|
+
if s.respond_to? :specification_version then
|
43
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
44
|
+
s.specification_version = 3
|
45
|
+
|
46
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
47
|
+
s.add_runtime_dependency(%q<sinatra>, [">= 0.10.1"])
|
48
|
+
s.add_runtime_dependency(%q<rack-test>, [">= 0.4.1"])
|
49
|
+
s.add_runtime_dependency(%q<rspec>, [">= 1.2.8"])
|
50
|
+
s.add_runtime_dependency(%q<rspec_hpricot_matchers>, [">= 1.0.0"])
|
51
|
+
else
|
52
|
+
s.add_dependency(%q<sinatra>, [">= 0.10.1"])
|
53
|
+
s.add_dependency(%q<rack-test>, [">= 0.4.1"])
|
54
|
+
s.add_dependency(%q<rspec>, [">= 1.2.8"])
|
55
|
+
s.add_dependency(%q<rspec_hpricot_matchers>, [">= 1.0.0"])
|
56
|
+
end
|
57
|
+
else
|
58
|
+
s.add_dependency(%q<sinatra>, [">= 0.10.1"])
|
59
|
+
s.add_dependency(%q<rack-test>, [">= 0.4.1"])
|
60
|
+
s.add_dependency(%q<rspec>, [">= 1.2.8"])
|
61
|
+
s.add_dependency(%q<rspec_hpricot_matchers>, [">= 1.0.0"])
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
|
2
|
+
require "#{File.dirname(File.dirname(File.expand_path(__FILE__)))}/../spec_helper"
|
3
|
+
|
4
|
+
|
5
|
+
describe "Sinatra" do
|
6
|
+
|
7
|
+
it_should_behave_like "MyTestApp"
|
8
|
+
# it_should_behave_like "MyAdminTestApp"
|
9
|
+
|
10
|
+
# it_should_behave_like "debug => app.methods"
|
11
|
+
|
12
|
+
describe "Tests" do
|
13
|
+
|
14
|
+
describe "#self.version" do
|
15
|
+
|
16
|
+
it "should return a string with the version number" do
|
17
|
+
Sinatra::Tests.version.should match(/Sinatra::Tests v\d\.\d\.\d/)
|
18
|
+
end
|
19
|
+
|
20
|
+
end #/ #version
|
21
|
+
|
22
|
+
|
23
|
+
describe "TestCase" do
|
24
|
+
|
25
|
+
describe "#h" do
|
26
|
+
|
27
|
+
it "should be possible to escape output code in tests" do
|
28
|
+
erb_app "<%= 'Unescaped <br> html' %>"
|
29
|
+
h(body).should == 'Unescaped <br> html'
|
30
|
+
end
|
31
|
+
|
32
|
+
end #/ #h
|
33
|
+
|
34
|
+
describe "#body" do
|
35
|
+
|
36
|
+
it "should be a shorter way of writing 'last_response.body'" do
|
37
|
+
erb_app "<%= 'Ignored content' %>"
|
38
|
+
body.should == 'Ignored content' # just testing to make sure it's OK
|
39
|
+
body.should == last_response.body
|
40
|
+
end
|
41
|
+
|
42
|
+
end #/ #body
|
43
|
+
|
44
|
+
describe "#status" do
|
45
|
+
|
46
|
+
it "should be a shorter way of writing 'last_response.status'" do
|
47
|
+
erb_app "<%= 'Ignored content' %>"
|
48
|
+
status.should == 200 # just testing the format
|
49
|
+
status.should == last_response.status
|
50
|
+
end
|
51
|
+
|
52
|
+
end #/ #status
|
53
|
+
|
54
|
+
describe "#response" do
|
55
|
+
|
56
|
+
it "should be a shorter way of writing 'last_response'" do
|
57
|
+
erb_app "<%= 'Ignored content' %>"
|
58
|
+
response.should be_a_kind_of(Rack::MockResponse) # just testing the format
|
59
|
+
response.should == last_response
|
60
|
+
end
|
61
|
+
|
62
|
+
end #/ #response
|
63
|
+
|
64
|
+
describe "#erb_app" do
|
65
|
+
|
66
|
+
it "should return the passed output" do
|
67
|
+
erb_app "<%= Time.now.strftime('%Y%d%m') %>"
|
68
|
+
body.should == Time.now.strftime("%Y%d%m")
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should work with a custom layout" do
|
72
|
+
erb_app "<%= Time.now.strftime('%Y%d%m') %>", :layout => "<CUSTOM><%= yield %></CUSTOM>"
|
73
|
+
body.should == "<CUSTOM>#{Time.now.strftime("%Y%d%m")}</CUSTOM>"
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should work with a custom URL" do
|
77
|
+
class MyTestApp
|
78
|
+
get '/custom-erb-url' do
|
79
|
+
erb "<customurl>#{params[:view]}</customurl>"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
erb_app "<%= 'custom-erb-url'.upcase %>", :url => "/custom-erb-url"
|
84
|
+
last_request.path_info.should == "/custom-erb-url"
|
85
|
+
body.should == "<customurl>CUSTOM-ERB-URL</customurl>"
|
86
|
+
end
|
87
|
+
|
88
|
+
end #/ #erb_app
|
89
|
+
|
90
|
+
describe "#haml_app" do
|
91
|
+
|
92
|
+
it "should return the passed output" do
|
93
|
+
haml_app "= Time.now.strftime('%Y%d%m')"
|
94
|
+
body.should == "#{Time.now.strftime("%Y%d%m")}\n"
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should work with a custom layout" do
|
98
|
+
haml_app "= Time.now.strftime('%Y%d%m')", :layout => "%CUSTOM= yield "
|
99
|
+
body.should == "<CUSTOM>#{Time.now.strftime("%Y%d%m")}</CUSTOM>\n"
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should work with a custom URL" do
|
103
|
+
pending "these tests does not really work. Find out why"
|
104
|
+
class MyTestApp
|
105
|
+
get '/custom-haml-url' do
|
106
|
+
haml "%customurl= @params[:view]"
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
haml_app "CUSTOM-URL ", :url => "/custom-haml-url"
|
111
|
+
last_request.path_info.should == "/custom-haml-url"
|
112
|
+
body.should == "<customurl>CUSTOM-URL</customurl>\n"
|
113
|
+
end
|
114
|
+
|
115
|
+
end #/ #haml_app
|
116
|
+
|
117
|
+
|
118
|
+
end #/ TestCase
|
119
|
+
|
120
|
+
|
121
|
+
end #/ Tests
|
122
|
+
end #/ Sinatra
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec'
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
4
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
5
|
+
require 'sinatra/tests'
|
6
|
+
|
7
|
+
Spec::Runner.configure do |config|
|
8
|
+
config.include RspecHpricotMatchers
|
9
|
+
config.include Sinatra::Tests::SharedSpecs
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
# quick convenience methods..
|
14
|
+
|
15
|
+
def fixtures_path
|
16
|
+
"#{File.dirname(File.expand_path(__FILE__))}/fixtures"
|
17
|
+
end
|
18
|
+
|
19
|
+
class MyTestApp < Sinatra::Base
|
20
|
+
register(Sinatra::Tests)
|
21
|
+
end
|
22
|
+
|
23
|
+
class MyAdminTestApp < MyTestApp
|
24
|
+
# register(Sinatra::Tests)
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
class Test::Unit::TestCase
|
29
|
+
include Sinatra::Tests::TestCase
|
30
|
+
|
31
|
+
Sinatra::Base.set :environment, :test
|
32
|
+
|
33
|
+
end
|
metadata
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sinatra-tests
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.4
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- kematzy
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-10-08 00:00:00 +08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: sinatra
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.10.1
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rack-test
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.4.1
|
34
|
+
version:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: rspec
|
37
|
+
type: :runtime
|
38
|
+
version_requirement:
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 1.2.8
|
44
|
+
version:
|
45
|
+
- !ruby/object:Gem::Dependency
|
46
|
+
name: rspec_hpricot_matchers
|
47
|
+
type: :runtime
|
48
|
+
version_requirement:
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 1.0.0
|
54
|
+
version:
|
55
|
+
description:
|
56
|
+
email: kematzy@gmail.com
|
57
|
+
executables: []
|
58
|
+
|
59
|
+
extensions: []
|
60
|
+
|
61
|
+
extra_rdoc_files:
|
62
|
+
- LICENSE
|
63
|
+
- README.rdoc
|
64
|
+
files:
|
65
|
+
- .document
|
66
|
+
- .gitignore
|
67
|
+
- LICENSE
|
68
|
+
- README.rdoc
|
69
|
+
- Rakefile
|
70
|
+
- VERSION
|
71
|
+
- lib/sinatra/tests.rb
|
72
|
+
- lib/sinatra/tests/shared_specs.rb
|
73
|
+
- lib/sinatra/tests/test_case.rb
|
74
|
+
- sinatra-tests.gemspec
|
75
|
+
- spec/sinatra/tests/test_case_spec.rb
|
76
|
+
- spec/spec_helper.rb
|
77
|
+
has_rdoc: true
|
78
|
+
homepage: http://github.com/kematzy/sinatra-tests
|
79
|
+
licenses: []
|
80
|
+
|
81
|
+
post_install_message:
|
82
|
+
rdoc_options:
|
83
|
+
- --charset=UTF-8
|
84
|
+
require_paths:
|
85
|
+
- lib
|
86
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: "0"
|
91
|
+
version:
|
92
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: "0"
|
97
|
+
version:
|
98
|
+
requirements: []
|
99
|
+
|
100
|
+
rubyforge_project:
|
101
|
+
rubygems_version: 1.3.5
|
102
|
+
signing_key:
|
103
|
+
specification_version: 3
|
104
|
+
summary: Sinatra::Tests is a repository of common Test/RSpec helpers
|
105
|
+
test_files:
|
106
|
+
- spec/sinatra/tests/test_case_spec.rb
|
107
|
+
- spec/spec_helper.rb
|