sinatra-tests 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|