pivotal-screw-unit-server 0.5.3
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/CHANGES +27 -0
- data/README.markdown +354 -0
- data/Rakefile +42 -0
- data/VERSION.yml +4 -0
- data/bin/screw_unit +6 -0
- data/bin/screw_unit_server +20 -0
- data/core/CHANGES +10 -0
- data/core/EXAMPLE.html +68 -0
- data/core/LICENSE +22 -0
- data/core/README.markdown +307 -0
- data/core/example/models/cat.js +5 -0
- data/core/example/models/man.js +17 -0
- data/core/example/spec/matchers/have.js +8 -0
- data/core/example/spec/models/cat_spec.js +31 -0
- data/core/example/spec/models/man_spec.js +34 -0
- data/core/example/spec/spec_helper.js +5 -0
- data/core/example/spec/suite.html +25 -0
- data/core/lib/jquery-1.3.2.js +4376 -0
- data/core/lib/jquery.fn.js +30 -0
- data/core/lib/jquery.print.js +109 -0
- data/core/lib/screw.behaviors.js +93 -0
- data/core/lib/screw.builder.js +95 -0
- data/core/lib/screw.css +90 -0
- data/core/lib/screw.events.js +45 -0
- data/core/lib/screw.matchers.js +244 -0
- data/core/spec/behaviors_spec.js +188 -0
- data/core/spec/matchers_spec.js +372 -0
- data/core/spec/print_spec.js +158 -0
- data/core/spec/spec_helper.js +0 -0
- data/core/spec/suite.html +19 -0
- data/core/spec/with_screw_context_spec.js +9 -0
- data/init.rb +0 -0
- data/lib/screw_unit.rb +23 -0
- data/lib/screw_unit/representations.rb +2 -0
- data/lib/screw_unit/representations/spec.html.rb +117 -0
- data/spec/functional/functional_spec.rb +25 -0
- data/spec/functional/functional_spec_helper.rb +43 -0
- data/spec/functional/functional_spec_server_starter.rb +68 -0
- data/spec/functional_suite.rb +10 -0
- data/spec/spec_suite.rb +3 -0
- data/spec/unit/js_test_core/specs/spec_file_spec.rb +68 -0
- data/spec/unit/unit_spec_helper.rb +51 -0
- data/spec/unit_suite.rb +10 -0
- data/vendor/js-test-core/CHANGES +28 -0
- data/vendor/js-test-core/README +12 -0
- data/vendor/js-test-core/Rakefile +73 -0
- data/vendor/js-test-core/lib/js_test_core.rb +46 -0
- data/vendor/js-test-core/lib/js_test_core/app.rb +12 -0
- data/vendor/js-test-core/lib/js_test_core/client.rb +129 -0
- data/vendor/js-test-core/lib/js_test_core/configuration.rb +35 -0
- data/vendor/js-test-core/lib/js_test_core/extensions.rb +3 -0
- data/vendor/js-test-core/lib/js_test_core/extensions/selenium/client/driver.rb +7 -0
- data/vendor/js-test-core/lib/js_test_core/extensions/time.rb +6 -0
- data/vendor/js-test-core/lib/js_test_core/models.rb +8 -0
- data/vendor/js-test-core/lib/js_test_core/models/selenium_session.rb +80 -0
- data/vendor/js-test-core/lib/js_test_core/representations.rb +11 -0
- data/vendor/js-test-core/lib/js_test_core/representations/dir.html.rb +24 -0
- data/vendor/js-test-core/lib/js_test_core/representations/not_found.html.rb +15 -0
- data/vendor/js-test-core/lib/js_test_core/representations/page.html.rb +41 -0
- data/vendor/js-test-core/lib/js_test_core/representations/spec.html.rb +24 -0
- data/vendor/js-test-core/lib/js_test_core/resources.rb +16 -0
- data/vendor/js-test-core/lib/js_test_core/resources/core_file.rb +19 -0
- data/vendor/js-test-core/lib/js_test_core/resources/file.rb +62 -0
- data/vendor/js-test-core/lib/js_test_core/resources/implementations_deprecation.rb +12 -0
- data/vendor/js-test-core/lib/js_test_core/resources/not_found.rb +35 -0
- data/vendor/js-test-core/lib/js_test_core/resources/resource.rb +16 -0
- data/vendor/js-test-core/lib/js_test_core/resources/selenium_session.rb +104 -0
- data/vendor/js-test-core/lib/js_test_core/resources/spec_file.rb +63 -0
- data/vendor/js-test-core/lib/js_test_core/resources/web_root.rb +11 -0
- data/vendor/js-test-core/lib/js_test_core/selenium_server_configuration.rb +48 -0
- data/vendor/js-test-core/spec/example_core/JsTestCore.css +0 -0
- data/vendor/js-test-core/spec/example_core/JsTestCore.js +0 -0
- data/vendor/js-test-core/spec/example_core/subdir/SubDirFile.js +0 -0
- data/vendor/js-test-core/spec/example_public/favicon.ico +0 -0
- data/vendor/js-test-core/spec/example_public/javascripts/foo.js +3 -0
- data/vendor/js-test-core/spec/example_public/javascripts/large_file.js +59 -0
- data/vendor/js-test-core/spec/example_public/javascripts/subdir/bar.js +1 -0
- data/vendor/js-test-core/spec/example_public/robots.txt +0 -0
- data/vendor/js-test-core/spec/example_public/stylesheets/example.css +3 -0
- data/vendor/js-test-core/spec/example_specs/custom_dir_and_suite/passing_spec.js +6 -0
- data/vendor/js-test-core/spec/example_specs/custom_suite.html +8 -0
- data/vendor/js-test-core/spec/example_specs/failing_spec.js +5 -0
- data/vendor/js-test-core/spec/example_specs/foo/failing_spec.js +6 -0
- data/vendor/js-test-core/spec/example_specs/foo/passing_spec.js +6 -0
- data/vendor/js-test-core/spec/spec_helpers/be_http.rb +32 -0
- data/vendor/js-test-core/spec/spec_helpers/example_group.rb +36 -0
- data/vendor/js-test-core/spec/spec_helpers/fake_selenium_driver.rb +27 -0
- data/vendor/js-test-core/spec/spec_helpers/show_test_exceptions.rb +22 -0
- data/vendor/js-test-core/spec/spec_suite.rb +2 -0
- data/vendor/js-test-core/spec/specs/failing_spec.js +0 -0
- data/vendor/js-test-core/spec/unit/js_test_core/client_spec.rb +192 -0
- data/vendor/js-test-core/spec/unit/js_test_core/configuration_spec.rb +44 -0
- data/vendor/js-test-core/spec/unit/js_test_core/models/selenium_session_spec.rb +85 -0
- data/vendor/js-test-core/spec/unit/js_test_core/resources/core_file_spec.rb +60 -0
- data/vendor/js-test-core/spec/unit/js_test_core/resources/file_spec.rb +81 -0
- data/vendor/js-test-core/spec/unit/js_test_core/resources/implementations_deprecation_spec.rb +18 -0
- data/vendor/js-test-core/spec/unit/js_test_core/resources/not_found_spec.rb +51 -0
- data/vendor/js-test-core/spec/unit/js_test_core/resources/selenium_session_spec.rb +362 -0
- data/vendor/js-test-core/spec/unit/js_test_core/resources/spec_file_spec.rb +120 -0
- data/vendor/js-test-core/spec/unit/js_test_core/resources/web_root_spec.rb +28 -0
- data/vendor/js-test-core/spec/unit/js_test_core/selenium_server_configuration_spec.rb +49 -0
- data/vendor/js-test-core/spec/unit/unit_spec_helper.rb +28 -0
- data/vendor/js-test-core/spec/unit_suite.rb +10 -0
- data/vendor/js-test-core/vendor/lucky-luciano/README.markdown +7 -0
- data/vendor/js-test-core/vendor/lucky-luciano/lib/lucky_luciano.rb +4 -0
- data/vendor/js-test-core/vendor/lucky-luciano/lib/lucky_luciano/resource.rb +135 -0
- data/vendor/js-test-core/vendor/lucky-luciano/lib/lucky_luciano/rspec.rb +4 -0
- data/vendor/js-test-core/vendor/lucky-luciano/lib/lucky_luciano/rspec/be_http.rb +32 -0
- data/vendor/js-test-core/vendor/lucky-luciano/spec/lucky_luciano/resource_spec.rb +231 -0
- data/vendor/js-test-core/vendor/lucky-luciano/spec/spec_helper.rb +48 -0
- data/vendor/js-test-core/vendor/lucky-luciano/spec/spec_suite.rb +4 -0
- metadata +198 -0
@@ -0,0 +1,28 @@
|
|
1
|
+
require File.expand_path("#{File.dirname(__FILE__)}/../../unit_spec_helper")
|
2
|
+
|
3
|
+
module JsTestCore
|
4
|
+
module Resources
|
5
|
+
describe WebRoot do
|
6
|
+
macro("includes a link to the spec suite") do |relative_path|
|
7
|
+
it "includes a link to the spec suite" do
|
8
|
+
response = get(relative_path)
|
9
|
+
response.should be_http(
|
10
|
+
200,
|
11
|
+
{},
|
12
|
+
""
|
13
|
+
)
|
14
|
+
doc = Nokogiri::HTML(response.body)
|
15
|
+
doc.css("a[href='/specs']").should_not be_nil
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "GET " do
|
20
|
+
send("includes a link to the spec suite", "")
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "GET /" do
|
24
|
+
send("includes a link to the spec suite", "/")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require File.expand_path("#{File.dirname(__FILE__)}/../unit_spec_helper")
|
2
|
+
|
3
|
+
module JsTestCore
|
4
|
+
describe SeleniumServerConfiguration do
|
5
|
+
describe '#query_string' do
|
6
|
+
context "when not passed explicit options" do
|
7
|
+
it "defaults selenium_browser_start_command to '*firefox' and selenium_host to 'localhost' and selenium_port to 4444 and ignores spec_url" do
|
8
|
+
configuration = SeleniumServerConfiguration.new
|
9
|
+
configuration.query_string.should include("selenium_browser_start_command=#{CGI.escape("*firefox")}")
|
10
|
+
configuration.query_string.should include("selenium_host=localhost")
|
11
|
+
configuration.query_string.should include("selenium_port=4444")
|
12
|
+
configuration.query_string.should_not include("spec_url")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context "when passed explicit options" do
|
17
|
+
attr_reader :configuration, :selenium_browser_start_command, :selenium_host, :selenium_port, :spec_url
|
18
|
+
before do
|
19
|
+
@selenium_browser_start_command = "*iexplore"
|
20
|
+
@selenium_host = "google.com"
|
21
|
+
@selenium_port = "4332"
|
22
|
+
@spec_url = "http://foobar.com/foo"
|
23
|
+
@configuration = SeleniumServerConfiguration.new(
|
24
|
+
:selenium_browser_start_command => selenium_browser_start_command,
|
25
|
+
:selenium_host => selenium_host,
|
26
|
+
:selenium_port => selenium_port,
|
27
|
+
:spec_url => spec_url
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "sets the selenium_browser_start_command option" do
|
32
|
+
configuration.query_string.should include("selenium_browser_start_command=#{CGI.escape(selenium_browser_start_command)}")
|
33
|
+
end
|
34
|
+
|
35
|
+
it "sets the selenium_host option" do
|
36
|
+
configuration.query_string.should include("selenium_host=#{selenium_host}")
|
37
|
+
end
|
38
|
+
|
39
|
+
it "sets the selenium_port option" do
|
40
|
+
configuration.query_string.should include("selenium_port=#{selenium_port}")
|
41
|
+
end
|
42
|
+
|
43
|
+
it "sets the spec_url option" do
|
44
|
+
configuration.query_string.should include("spec_url=#{spec_url}")
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "spec"
|
3
|
+
require "spec/autorun"
|
4
|
+
require "rack/test"
|
5
|
+
ARGV.push("-b")
|
6
|
+
|
7
|
+
dir = File.dirname(__FILE__)
|
8
|
+
LIBRARY_ROOT_DIR = File.expand_path("#{dir}/../..")
|
9
|
+
$LOAD_PATH.unshift File.expand_path("#{LIBRARY_ROOT_DIR}/lib")
|
10
|
+
require "js_test_core"
|
11
|
+
require "nokogiri"
|
12
|
+
require "guid"
|
13
|
+
require "#{LIBRARY_ROOT_DIR}/spec/spec_helpers/be_http"
|
14
|
+
require "#{LIBRARY_ROOT_DIR}/spec/spec_helpers/example_group"
|
15
|
+
require "#{LIBRARY_ROOT_DIR}/spec/spec_helpers/fake_selenium_driver"
|
16
|
+
require "#{LIBRARY_ROOT_DIR}/spec/spec_helpers/show_test_exceptions"
|
17
|
+
|
18
|
+
Spec::Runner.configure do |config|
|
19
|
+
config.mock_with :rr
|
20
|
+
end
|
21
|
+
|
22
|
+
Sinatra::Application.use ShowTestExceptions
|
23
|
+
Sinatra::Application.set :raise_errors, true
|
24
|
+
Sinatra::Application.set :show_exceptions, false
|
25
|
+
JsTestCore::App.set :raise_errors, true
|
26
|
+
JsTestCore::App.set :show_exceptions, false
|
27
|
+
|
28
|
+
Sinatra::Application.use(JsTestCore::App)
|
@@ -0,0 +1,7 @@
|
|
1
|
+
Lucky Luciano, is a library that makes it easy to organize your Sinatra routes into Restful Resources.
|
2
|
+
|
3
|
+
## Who was this Lucky Luciano person?
|
4
|
+
|
5
|
+
Lucky Luciano was a mob boss and an alleged friend of Frank Sinatra.
|
6
|
+
|
7
|
+
http://news.bbc.co.uk/2/hi/special_report/1998/05/98/sinatra/94360.stm
|
@@ -0,0 +1,135 @@
|
|
1
|
+
module LuckyLuciano
|
2
|
+
class Resource
|
3
|
+
class << self
|
4
|
+
attr_reader :base_path_definition
|
5
|
+
|
6
|
+
def map(base_path_definition)
|
7
|
+
@base_path_definition = base_path_definition
|
8
|
+
end
|
9
|
+
|
10
|
+
def recorded_http_handlers
|
11
|
+
@recorded_http_handlers ||= []
|
12
|
+
end
|
13
|
+
|
14
|
+
def route_handler
|
15
|
+
create_sinatra_handler
|
16
|
+
end
|
17
|
+
|
18
|
+
["get", "put", "post", "delete"].each do |http_verb|
|
19
|
+
class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
|
20
|
+
def #{http_verb}(relative_path, opts={}, &block)
|
21
|
+
recorded_http_handlers << [:#{http_verb}, relative_path, opts, block]
|
22
|
+
end
|
23
|
+
RUBY
|
24
|
+
end
|
25
|
+
|
26
|
+
def path(*sub_paths)
|
27
|
+
params = sub_paths.last.is_a?(Hash) ? sub_paths.pop : {}
|
28
|
+
|
29
|
+
sub_path_definition = sub_paths.join("/")
|
30
|
+
|
31
|
+
full_path = "#{base_path(params)}/#{path_from_definition(sub_path_definition, params)}".
|
32
|
+
gsub("//", "/").gsub(/\/$/, "")
|
33
|
+
|
34
|
+
base_path_param_keys = param_keys_from(base_path_definition)
|
35
|
+
query_params = params.delete_if do |key, value|
|
36
|
+
base_path_param_keys.include?(key)
|
37
|
+
end
|
38
|
+
|
39
|
+
sub_path_param_keys = param_keys_from(sub_path_definition)
|
40
|
+
query_params = params.delete_if do |key, value|
|
41
|
+
sub_path_param_keys.include?(key)
|
42
|
+
end
|
43
|
+
|
44
|
+
if query_params.empty?
|
45
|
+
full_path
|
46
|
+
else
|
47
|
+
query = build_query(query_params)
|
48
|
+
"#{full_path}?#{query}"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def base_path(params={})
|
53
|
+
path_from_definition(base_path_definition, params)
|
54
|
+
end
|
55
|
+
|
56
|
+
protected
|
57
|
+
|
58
|
+
def path_from_definition(definition, params={})
|
59
|
+
param_keys = param_keys_from(definition)
|
60
|
+
if param_keys.empty?
|
61
|
+
definition.dup
|
62
|
+
else
|
63
|
+
param_keys.each do |base_path_param|
|
64
|
+
unless params.include?(base_path_param.to_sym)
|
65
|
+
raise ArgumentError, "Expected #{base_path_param.inspect} to have a value"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
definition.split("/").map do |segment|
|
69
|
+
if param_key = segment_param_key(segment)
|
70
|
+
params[param_key]
|
71
|
+
else
|
72
|
+
segment
|
73
|
+
end
|
74
|
+
end.join("/")
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def param_keys_from(definition)
|
79
|
+
definition.split("/").find_all do |segment|
|
80
|
+
segment_param_key(segment)
|
81
|
+
end.map do |param|
|
82
|
+
param[1..-1].to_sym
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def segment_param_key(segment)
|
87
|
+
segment[0..0] == ':' ? segment[1..-1].to_sym : nil
|
88
|
+
end
|
89
|
+
|
90
|
+
def build_query(params)
|
91
|
+
params.to_a.inject([]) do |splatted_params, (key, value)|
|
92
|
+
[value].flatten.each do |value_in_param|
|
93
|
+
splatted_params << "#{URI.escape(key.to_s)}=#{URI.escape(value_in_param.to_s)}"
|
94
|
+
end
|
95
|
+
splatted_params
|
96
|
+
end.join("&")
|
97
|
+
end
|
98
|
+
|
99
|
+
def create_sinatra_handler
|
100
|
+
handlers = recorded_http_handlers
|
101
|
+
resource_class = self
|
102
|
+
Module.new do
|
103
|
+
(class << self; self; end).class_eval do
|
104
|
+
define_method(:registered) do |app|
|
105
|
+
handlers.each do |handler|
|
106
|
+
verb, relative_path, opts, block = handler
|
107
|
+
full_path = "#{resource_class.base_path_definition}/#{relative_path}".
|
108
|
+
gsub("//", "/").gsub(%r{^.+/$}) do |match|
|
109
|
+
match.gsub(%r{/$}, "")
|
110
|
+
end
|
111
|
+
app.send(verb, full_path, opts) do
|
112
|
+
resource_class.new(self).instance_eval(&block)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
attr_reader :app
|
122
|
+
|
123
|
+
def initialize(app)
|
124
|
+
@app = app
|
125
|
+
end
|
126
|
+
|
127
|
+
def method_missing(method_name, *args, &block)
|
128
|
+
if app.respond_to?(method_name)
|
129
|
+
app.send(method_name, *args, &block)
|
130
|
+
else
|
131
|
+
super
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module BeHttp
|
2
|
+
include Spec::Matchers
|
3
|
+
def be_http(status, headers, body)
|
4
|
+
SimpleMatcher.new(nil) do |given, matcher|
|
5
|
+
description = (<<-DESC).gsub(/^ +/, "")
|
6
|
+
be an http of
|
7
|
+
expected status: #{status.inspect}
|
8
|
+
actual status : #{given.status.inspect}
|
9
|
+
|
10
|
+
expected headers containing: #{headers.inspect}
|
11
|
+
actual headers : #{given.headers.inspect}
|
12
|
+
|
13
|
+
expected body containing: #{body.inspect}
|
14
|
+
actual body : #{given.body.inspect}
|
15
|
+
DESC
|
16
|
+
matcher.failure_message = description
|
17
|
+
matcher.negative_failure_message = "not #{description}"
|
18
|
+
|
19
|
+
passed = true
|
20
|
+
unless given.status == status
|
21
|
+
passed = false
|
22
|
+
end
|
23
|
+
unless headers.all?{|k, v| given.headers[k] == headers[k]}
|
24
|
+
passed = false
|
25
|
+
end
|
26
|
+
unless body.is_a?(Regexp) ? given.body =~ body : given.body.include?(body)
|
27
|
+
passed = false
|
28
|
+
end
|
29
|
+
passed
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,231 @@
|
|
1
|
+
require File.expand_path("#{File.dirname(__FILE__)}/../spec_helper")
|
2
|
+
|
3
|
+
module LuckyLuciano
|
4
|
+
module ResourceSpec
|
5
|
+
class Root < Resource
|
6
|
+
map "/"
|
7
|
+
end
|
8
|
+
|
9
|
+
class ResourceFixture < Resource
|
10
|
+
map "/foobar"
|
11
|
+
end
|
12
|
+
|
13
|
+
class ResourceFixtureWithSubPaths < Resource
|
14
|
+
map "/foobar"
|
15
|
+
|
16
|
+
get "/baz" do
|
17
|
+
"Response from /foobar/baz"
|
18
|
+
end
|
19
|
+
|
20
|
+
get "/users/:user_id" do
|
21
|
+
"User id is #{params[:user_id]}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class User < Resource
|
26
|
+
map "/users/:user_id"
|
27
|
+
|
28
|
+
get "/friends" do
|
29
|
+
"User #{params['user_id']} friends"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe Resource do
|
34
|
+
include ResourceSpec
|
35
|
+
|
36
|
+
before do
|
37
|
+
ResourceFixture.recorded_http_handlers.clear
|
38
|
+
end
|
39
|
+
|
40
|
+
macro("http verb") do |verb|
|
41
|
+
describe ".#{verb}" do
|
42
|
+
context "" do
|
43
|
+
before do
|
44
|
+
ResourceFixture.send(verb, "/") do
|
45
|
+
"He sleeps with the fishes"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
it "creates a route to #{verb.upcase} the given path that executes the given block" do
|
50
|
+
app.register(ResourceFixture.route_handler)
|
51
|
+
response = send(verb, "/foobar")
|
52
|
+
response.should be_http(
|
53
|
+
200,
|
54
|
+
{},
|
55
|
+
"He sleeps with the fishes"
|
56
|
+
)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context "when the base path is blank and the relative path is blank" do
|
61
|
+
before do
|
62
|
+
Root.send(verb, "") do
|
63
|
+
"Response from /"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
it "creates a route to /" do
|
68
|
+
app.register(Root.route_handler)
|
69
|
+
response = send(verb, "/")
|
70
|
+
response.should be_http(
|
71
|
+
200,
|
72
|
+
{},
|
73
|
+
"Response from /"
|
74
|
+
)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context "when the relative path does not have a leading slash" do
|
79
|
+
before do
|
80
|
+
ResourceFixtureWithSubPaths.send(verb, "no_leading_slash") do
|
81
|
+
"Response from /foobar/no_leading_slash"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
it "creates a route to #{verb.upcase} the given path that executes the given block" do
|
86
|
+
app.register(ResourceFixtureWithSubPaths.route_handler)
|
87
|
+
response = send(verb, "/foobar/no_leading_slash")
|
88
|
+
response.should be_http(
|
89
|
+
200,
|
90
|
+
{},
|
91
|
+
"Response from /foobar/no_leading_slash"
|
92
|
+
)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
|
97
|
+
it "does not respond to another type of http request" do
|
98
|
+
ResourceFixture.send(verb, "/") do
|
99
|
+
""
|
100
|
+
end
|
101
|
+
app.register(ResourceFixture.route_handler)
|
102
|
+
get("/foobar").status.should == 404 unless verb == "get"
|
103
|
+
put("/foobar").status.should == 404 unless verb == "put"
|
104
|
+
post("/foobar").status.should == 404 unless verb == "post"
|
105
|
+
delete("/foobar").status.should == 404 unless verb == "delete"
|
106
|
+
end
|
107
|
+
|
108
|
+
describe "Instance behavior" do
|
109
|
+
attr_reader :evaluation_target
|
110
|
+
before do
|
111
|
+
evaluation_target = nil
|
112
|
+
ResourceFixture.send(verb, "/") do
|
113
|
+
evaluation_target = self
|
114
|
+
""
|
115
|
+
end
|
116
|
+
app.register(ResourceFixture.route_handler)
|
117
|
+
|
118
|
+
send(verb, "/foobar")
|
119
|
+
@evaluation_target = evaluation_target
|
120
|
+
end
|
121
|
+
|
122
|
+
it "evaluates the block in as a Resource" do
|
123
|
+
evaluation_target.class.should == ResourceFixture
|
124
|
+
end
|
125
|
+
|
126
|
+
it "sets app to be the Sinatra context" do
|
127
|
+
evaluation_target.app.class.should == Sinatra::Application
|
128
|
+
end
|
129
|
+
|
130
|
+
it "delegates methods to the #app" do
|
131
|
+
return_value = nil
|
132
|
+
mock.proxy(evaluation_target.app).params {|val| return_value = val}
|
133
|
+
evaluation_target.params.should == return_value
|
134
|
+
end
|
135
|
+
|
136
|
+
context "when the #app does not respond to the method" do
|
137
|
+
it "raises a NoMethodError from the Resource's perspective" do
|
138
|
+
lambda do
|
139
|
+
evaluation_target.i_dont_exist
|
140
|
+
end.should raise_error(NoMethodError, /ResourceFixture/)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
send("http verb", "get")
|
149
|
+
send("http verb", "put")
|
150
|
+
send("http verb", "post")
|
151
|
+
send("http verb", "delete")
|
152
|
+
|
153
|
+
describe ".path" do
|
154
|
+
context "when passed nothing" do
|
155
|
+
it "returns the base_path" do
|
156
|
+
ResourceFixture.path.should == "/foobar"
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
context "when passed a sub path" do
|
161
|
+
it "merges the base_path into the sub path, regardless of a / in front" do
|
162
|
+
ResourceFixtureWithSubPaths.path("/baz").should == "/foobar/baz"
|
163
|
+
ResourceFixtureWithSubPaths.path("baz").should == "/foobar/baz"
|
164
|
+
end
|
165
|
+
|
166
|
+
context "when passed a multiple sub paths" do
|
167
|
+
it "joins the sub paths with '/'" do
|
168
|
+
ResourceFixtureWithSubPaths.path("users", 99).should == "/foobar/users/99"
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
context "when passed a hash as the last argument" do
|
173
|
+
context "when using a single path argument" do
|
174
|
+
it "creates url params from the hash" do
|
175
|
+
path = ResourceFixtureWithSubPaths.path(
|
176
|
+
"/users/:user_id", {:user_id => 99, :single_value_param => "single_value_param_value", 'multiple_value_param[]' => [1,2,3]}
|
177
|
+
)
|
178
|
+
uri = URI.parse(path)
|
179
|
+
uri.path.should == "/foobar/users/99"
|
180
|
+
query_parts = uri.query.split("&")
|
181
|
+
query_parts.should =~ [
|
182
|
+
"multiple_value_param[]=1",
|
183
|
+
"multiple_value_param[]=2",
|
184
|
+
"multiple_value_param[]=3",
|
185
|
+
"single_value_param=single_value_param_value",
|
186
|
+
]
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
context "when using multiple path arguments" do
|
191
|
+
it "creates url params from the hash" do
|
192
|
+
path = ResourceFixtureWithSubPaths.path(
|
193
|
+
"users", 99, {:single_value_param => "single_value_param_value", 'multiple_value_param[]' => [1,2,3]}
|
194
|
+
)
|
195
|
+
uri = URI.parse(path)
|
196
|
+
uri.path.should == "/foobar/users/99"
|
197
|
+
query_parts = uri.query.split("&")
|
198
|
+
query_parts.should =~ [
|
199
|
+
"multiple_value_param[]=1",
|
200
|
+
"multiple_value_param[]=2",
|
201
|
+
"multiple_value_param[]=3",
|
202
|
+
"single_value_param=single_value_param_value",
|
203
|
+
]
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
context "when the base_path contains a parameter" do
|
210
|
+
context "when not passed" do
|
211
|
+
it "raises an ArgumentError" do
|
212
|
+
lambda do
|
213
|
+
User.path
|
214
|
+
end.should raise_error(
|
215
|
+
ArgumentError,
|
216
|
+
%r{Expected :user_id to have a value}
|
217
|
+
)
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
context "when first argument is a hash" do
|
222
|
+
it "returns the full path with the base path param value" do
|
223
|
+
User.path("friends", :user_id => 99).should == "/users/99/friends"
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
end
|