honkster-js-test-server 0.2.9
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 +40 -0
- data/Gemfile +21 -0
- data/Gemfile.lock +60 -0
- data/README.markdown +9 -0
- data/Rakefile +67 -0
- data/bin/jasmine-server +9 -0
- data/bin/js-test-client +8 -0
- data/bin/js-test-server +9 -0
- data/bin/screw-unit-server +9 -0
- data/lib/js_test_server.rb +29 -0
- data/lib/js_test_server/client.rb +23 -0
- data/lib/js_test_server/client/runner.rb +130 -0
- data/lib/js_test_server/configuration.rb +69 -0
- data/lib/js_test_server/server.rb +14 -0
- data/lib/js_test_server/server/app.rb +10 -0
- data/lib/js_test_server/server/resources.rb +14 -0
- data/lib/js_test_server/server/resources/file.rb +58 -0
- data/lib/js_test_server/server/resources/framework_file.rb +15 -0
- data/lib/js_test_server/server/resources/implementations_deprecation.rb +8 -0
- data/lib/js_test_server/server/resources/not_found.rb +25 -0
- data/lib/js_test_server/server/resources/remote_control.rb +80 -0
- data/lib/js_test_server/server/resources/resource.rb +12 -0
- data/lib/js_test_server/server/resources/spec_file.rb +47 -0
- data/lib/js_test_server/server/resources/web_root.rb +17 -0
- data/lib/js_test_server/server/runner.rb +77 -0
- data/lib/js_test_server/server/standalone.ru +1 -0
- data/lib/js_test_server/server/views.rb +12 -0
- data/lib/js_test_server/server/views/dir.html.rb +22 -0
- data/lib/js_test_server/server/views/frameworks.rb +3 -0
- data/lib/js_test_server/server/views/not_found.html.rb +13 -0
- data/lib/js_test_server/server/views/page.html.rb +40 -0
- data/lib/js_test_server/server/views/remote_control_subscriber.rb +17 -0
- data/lib/js_test_server/server/views/suite.html.rb +54 -0
- data/lib/js_test_server/server/views/suites.rb +6 -0
- data/lib/js_test_server/server/views/suites/jasmine.html.rb +30 -0
- data/lib/js_test_server/server/views/suites/screw_unit.html.rb +44 -0
- data/public/js_test_server.js +565 -0
- data/public/js_test_server/jasmine_driver.js +63 -0
- data/public/js_test_server/remote_control.js +28 -0
- data/public/js_test_server/screw_unit_driver.js +31 -0
- data/scratch.rb +8 -0
- data/spec/frameworks/jasmine/cruise_config.rb +21 -0
- data/spec/frameworks/jasmine/spec/jasmine_helper.rb +44 -0
- data/spec/frameworks/jasmine/spec/jasmine_spec.rb +31 -0
- data/spec/functional/functional_spec_helper.rb +55 -0
- data/spec/functional/functional_spec_server_starter.rb +69 -0
- data/spec/functional/jasmine/jasmine_functional_spec.rb +27 -0
- data/spec/functional/screw-unit/screw_unit_functional_spec.rb +27 -0
- data/spec/functional_suite.rb +16 -0
- data/spec/spec_helpers/be_http.rb +32 -0
- data/spec/spec_helpers/example_group.rb +41 -0
- data/spec/spec_helpers/fake_deferrable.rb +3 -0
- data/spec/spec_helpers/fake_selenium_driver.rb +16 -0
- data/spec/spec_helpers/mock_session.rb +30 -0
- data/spec/spec_helpers/show_test_exceptions.rb +22 -0
- data/spec/spec_helpers/wait_for.rb +11 -0
- data/spec/spec_suite.rb +3 -0
- data/spec/unit/js_test_core/client/runner_spec.rb +198 -0
- data/spec/unit/js_test_core/configuration_spec.rb +44 -0
- data/spec/unit/js_test_core/resources/file_spec.rb +79 -0
- data/spec/unit/js_test_core/resources/framework_file_spec.rb +58 -0
- data/spec/unit/js_test_core/resources/implementations_deprecation_spec.rb +16 -0
- data/spec/unit/js_test_core/resources/not_found_spec.rb +49 -0
- data/spec/unit/js_test_core/resources/remote_control_spec.rb +117 -0
- data/spec/unit/js_test_core/resources/spec_file_spec.rb +147 -0
- data/spec/unit/js_test_core/resources/web_root_spec.rb +26 -0
- data/spec/unit/js_test_core/server/server_spec.rb +103 -0
- data/spec/unit/unit_spec_helper.rb +34 -0
- data/spec/unit_suite.rb +10 -0
- data/vendor/lucky-luciano/lib/lucky_luciano.rb +5 -0
- data/vendor/lucky-luciano/lib/lucky_luciano/resource.rb +142 -0
- data/vendor/lucky-luciano/lib/lucky_luciano/resource/path.rb +24 -0
- data/vendor/lucky-luciano/lib/lucky_luciano/rspec.rb +4 -0
- data/vendor/lucky-luciano/lib/lucky_luciano/rspec/be_http.rb +32 -0
- data/vendor/lucky-luciano/spec/lucky_luciano/resource_spec.rb +276 -0
- data/vendor/lucky-luciano/spec/spec_helper.rb +48 -0
- data/vendor/lucky-luciano/spec/spec_suite.rb +4 -0
- metadata +146 -0
@@ -0,0 +1,34 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "spec"
|
3
|
+
require "spec/autorun"
|
4
|
+
require "rack/test"
|
5
|
+
require "rr"
|
6
|
+
ARGV.push("-b", "--format", "nested")
|
7
|
+
|
8
|
+
dir = File.dirname(__FILE__)
|
9
|
+
LIBRARY_ROOT_DIR = File.expand_path("#{dir}/../..")
|
10
|
+
$LOAD_PATH.unshift File.expand_path("#{LIBRARY_ROOT_DIR}/lib")
|
11
|
+
require "js_test_server"
|
12
|
+
require "nokogiri"
|
13
|
+
require "guid"
|
14
|
+
require "thin"
|
15
|
+
require "js_test_server"
|
16
|
+
require "#{LIBRARY_ROOT_DIR}/spec/spec_helpers/be_http"
|
17
|
+
require "#{LIBRARY_ROOT_DIR}/spec/spec_helpers/wait_for"
|
18
|
+
require "#{LIBRARY_ROOT_DIR}/spec/spec_helpers/example_group"
|
19
|
+
require "#{LIBRARY_ROOT_DIR}/spec/spec_helpers/fake_selenium_driver"
|
20
|
+
require "#{LIBRARY_ROOT_DIR}/spec/spec_helpers/show_test_exceptions"
|
21
|
+
require "#{LIBRARY_ROOT_DIR}/spec/spec_helpers/fake_deferrable"
|
22
|
+
require "#{LIBRARY_ROOT_DIR}/spec/spec_helpers/mock_session"
|
23
|
+
|
24
|
+
Spec::Runner.configure do |config|
|
25
|
+
config.mock_with RR::Adapters::Rspec
|
26
|
+
end
|
27
|
+
|
28
|
+
Sinatra::Application.use ShowTestExceptions
|
29
|
+
Sinatra::Application.set :raise_errors, true
|
30
|
+
Sinatra::Application.set :show_exceptions, false
|
31
|
+
JsTestServer::Server::App.set :raise_errors, true
|
32
|
+
JsTestServer::Server::App.set :show_exceptions, false
|
33
|
+
|
34
|
+
Sinatra::Application.use(JsTestServer::Server::App)
|
data/spec/unit_suite.rb
ADDED
@@ -0,0 +1,142 @@
|
|
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 [](sub_path=nil)
|
27
|
+
Path.new(self, sub_path)
|
28
|
+
end
|
29
|
+
|
30
|
+
def path(*sub_paths)
|
31
|
+
params = sub_paths.last.is_a?(Hash) ? sub_paths.pop : {}
|
32
|
+
|
33
|
+
sub_path_definition = sub_paths.join("/")
|
34
|
+
|
35
|
+
full_path = normalize_seperators("#{base_path(params)}/#{path_from_definition(sub_path_definition, params)}").gsub(/\/$/, "")
|
36
|
+
|
37
|
+
base_path_param_keys = param_keys_from(base_path_definition)
|
38
|
+
query_params = params.delete_if do |key, value|
|
39
|
+
base_path_param_keys.include?(key)
|
40
|
+
end
|
41
|
+
|
42
|
+
sub_path_param_keys = param_keys_from(sub_path_definition)
|
43
|
+
query_params = params.delete_if do |key, value|
|
44
|
+
sub_path_param_keys.include?(key)
|
45
|
+
end
|
46
|
+
|
47
|
+
if query_params.empty?
|
48
|
+
full_path
|
49
|
+
else
|
50
|
+
query = build_query(query_params)
|
51
|
+
"#{full_path}?#{query}"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def base_path(params={})
|
56
|
+
path_from_definition(base_path_definition, params)
|
57
|
+
end
|
58
|
+
|
59
|
+
def normalize_seperators(url)
|
60
|
+
url.gsub(Regexp.new("//+"), '/')
|
61
|
+
end
|
62
|
+
|
63
|
+
protected
|
64
|
+
|
65
|
+
def path_from_definition(definition, params={})
|
66
|
+
param_keys = param_keys_from(definition)
|
67
|
+
if param_keys.empty?
|
68
|
+
definition.dup
|
69
|
+
else
|
70
|
+
param_keys.each do |base_path_param|
|
71
|
+
unless params.include?(base_path_param.to_sym)
|
72
|
+
raise ArgumentError, "Expected #{base_path_param.inspect} to have a value"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
definition.split("/").map do |segment|
|
76
|
+
if param_key = segment_param_key(segment)
|
77
|
+
params[param_key]
|
78
|
+
else
|
79
|
+
segment
|
80
|
+
end
|
81
|
+
end.join("/")
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def param_keys_from(definition)
|
86
|
+
definition.split("/").find_all do |segment|
|
87
|
+
segment_param_key(segment)
|
88
|
+
end.map do |param|
|
89
|
+
param[1..-1].to_sym
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def segment_param_key(segment)
|
94
|
+
segment[0..0] == ':' ? segment[1..-1].to_sym : nil
|
95
|
+
end
|
96
|
+
|
97
|
+
def build_query(params)
|
98
|
+
params.to_a.inject([]) do |splatted_params, (key, value)|
|
99
|
+
[value].flatten.each do |value_in_param|
|
100
|
+
splatted_params << "#{URI.escape(key.to_s)}=#{URI.escape(value_in_param.to_s)}"
|
101
|
+
end
|
102
|
+
splatted_params
|
103
|
+
end.join("&")
|
104
|
+
end
|
105
|
+
|
106
|
+
def create_sinatra_handler
|
107
|
+
resource_class = self
|
108
|
+
Module.new do
|
109
|
+
(class << self; self; end).class_eval do
|
110
|
+
define_method(:registered) do |app|
|
111
|
+
resource_class.recorded_http_handlers.each do |handler|
|
112
|
+
verb, relative_path, opts, block = handler
|
113
|
+
full_path = resource_class.normalize_seperators(
|
114
|
+
"#{resource_class.base_path_definition}/#{relative_path}"
|
115
|
+
).gsub(%r{^.+/$}) do |match|
|
116
|
+
match.gsub(%r{/$}, "")
|
117
|
+
end
|
118
|
+
app.send(verb, full_path, opts) do
|
119
|
+
resource_class.new(self).instance_eval(&block)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
attr_reader :app
|
129
|
+
|
130
|
+
def initialize(app)
|
131
|
+
@app = app
|
132
|
+
end
|
133
|
+
|
134
|
+
def method_missing(method_name, *args, &block)
|
135
|
+
if app.respond_to?(method_name)
|
136
|
+
app.send(method_name, *args, &block)
|
137
|
+
else
|
138
|
+
super
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class LuckyLuciano::Resource::Path
|
2
|
+
attr_reader :resource, :sub_paths
|
3
|
+
def initialize(resource, *sub_paths)
|
4
|
+
@resource = resource
|
5
|
+
@sub_paths = sub_paths
|
6
|
+
end
|
7
|
+
|
8
|
+
def =~(other)
|
9
|
+
to_s =~ other
|
10
|
+
end
|
11
|
+
|
12
|
+
def [](*additional_sub_paths)
|
13
|
+
sub_paths.push(*additional_sub_paths)
|
14
|
+
self
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_s
|
18
|
+
resource.path(*sub_paths)
|
19
|
+
end
|
20
|
+
|
21
|
+
def ==(other)
|
22
|
+
to_s == other.to_s
|
23
|
+
end
|
24
|
+
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,276 @@
|
|
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( 200, {}, "He sleeps with the fishes" )
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context "when the base path is blank and the relative path is blank" do
|
57
|
+
before do
|
58
|
+
Root.send(verb, "") do
|
59
|
+
"Response from /"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
it "creates a route to /" do
|
64
|
+
app.register(Root.route_handler)
|
65
|
+
response = send(verb, "/")
|
66
|
+
response.should be_http( 200, {}, "Response from /" )
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context "when the relative path does not have a leading slash" do
|
71
|
+
before do
|
72
|
+
ResourceFixtureWithSubPaths.send(verb, "no_leading_slash") do
|
73
|
+
"Response from /foobar/no_leading_slash"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
it "creates a route to #{verb.upcase} the given path that executes the given block" do
|
78
|
+
app.register(ResourceFixtureWithSubPaths.route_handler)
|
79
|
+
response = send(verb, "/foobar/no_leading_slash")
|
80
|
+
response.should be_http( 200, {}, "Response from /foobar/no_leading_slash" )
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
it "does not respond to another type of http request" do
|
86
|
+
ResourceFixture.send(verb, "/") do
|
87
|
+
""
|
88
|
+
end
|
89
|
+
app.register(ResourceFixture.route_handler)
|
90
|
+
get("/foobar").status.should == 404 unless verb == "get"
|
91
|
+
put("/foobar").status.should == 404 unless verb == "put"
|
92
|
+
post("/foobar").status.should == 404 unless verb == "post"
|
93
|
+
delete("/foobar").status.should == 404 unless verb == "delete"
|
94
|
+
end
|
95
|
+
|
96
|
+
describe "Instance behavior" do
|
97
|
+
attr_reader :evaluation_target
|
98
|
+
before do
|
99
|
+
evaluation_target = nil
|
100
|
+
ResourceFixture.send(verb, "/") do
|
101
|
+
evaluation_target = self
|
102
|
+
""
|
103
|
+
end
|
104
|
+
app.register(ResourceFixture.route_handler)
|
105
|
+
|
106
|
+
send(verb, "/foobar")
|
107
|
+
@evaluation_target = evaluation_target
|
108
|
+
end
|
109
|
+
|
110
|
+
it "evaluates the block in as a Resource" do
|
111
|
+
evaluation_target.class.should == ResourceFixture
|
112
|
+
end
|
113
|
+
|
114
|
+
it "sets app to be the Sinatra context" do
|
115
|
+
evaluation_target.app.class.should == Sinatra::Application
|
116
|
+
end
|
117
|
+
|
118
|
+
it "delegates methods to the #app" do
|
119
|
+
return_value = nil
|
120
|
+
mock.proxy(evaluation_target.app).params {|val| return_value = val}
|
121
|
+
evaluation_target.params.should == return_value
|
122
|
+
end
|
123
|
+
|
124
|
+
context "when the #app does not respond to the method" do
|
125
|
+
it "raises a NoMethodError from the Resource's perspective" do
|
126
|
+
lambda do
|
127
|
+
evaluation_target.i_dont_exist
|
128
|
+
end.should raise_error(NoMethodError, /ResourceFixture/)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
send("http verb", "get")
|
137
|
+
send("http verb", "put")
|
138
|
+
send("http verb", "post")
|
139
|
+
send("http verb", "delete")
|
140
|
+
|
141
|
+
describe ".[][]" do
|
142
|
+
context "when passed nothing" do
|
143
|
+
it "returns the base_path" do
|
144
|
+
ResourceFixture[].should == "/foobar"
|
145
|
+
ResourceFixture[][].should == "/foobar"
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
context "when passed a sub path" do
|
150
|
+
it "merges the base_path into the sub path, regardless of a / in front" do
|
151
|
+
ResourceFixtureWithSubPaths["/baz"].to_s.should == "/foobar/baz"
|
152
|
+
ResourceFixtureWithSubPaths["baz"].to_s.should == "/foobar/baz"
|
153
|
+
end
|
154
|
+
|
155
|
+
context "when passed a multiple sub paths" do
|
156
|
+
it "joins the sub paths with '/'" do
|
157
|
+
ResourceFixtureWithSubPaths["users"][99].should == "/foobar/users/99"
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
context "when passed a hash as the last argument" do
|
162
|
+
context "when using a single path argument" do
|
163
|
+
it "creates url params from the hash" do
|
164
|
+
path = ResourceFixtureWithSubPaths["/users/:user_id"][:user_id => 99, :single_value_param => "single_value_param_value", 'multiple_value_param[]' => [1,2,3]]
|
165
|
+
path.should be_url("/foobar/users/99", [
|
166
|
+
"multiple_value_param[]=1",
|
167
|
+
"multiple_value_param[]=2",
|
168
|
+
"multiple_value_param[]=3",
|
169
|
+
"single_value_param=single_value_param_value",
|
170
|
+
])
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
context "when using multiple path arguments" do
|
175
|
+
it "creates url params from the hash" do
|
176
|
+
path = ResourceFixtureWithSubPaths["users"][99][:single_value_param => "single_value_param_value", 'multiple_value_param[]' => [1,2,3]]
|
177
|
+
path.should be_url("/foobar/users/99", [
|
178
|
+
"multiple_value_param[]=1",
|
179
|
+
"multiple_value_param[]=2",
|
180
|
+
"multiple_value_param[]=3",
|
181
|
+
"single_value_param=single_value_param_value",
|
182
|
+
])
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
def be_url(expected_path, expected_query_parts)
|
187
|
+
Spec::Matchers::SimpleMatcher.new("match url") do |actual|
|
188
|
+
uri = URI.parse(actual.to_s)
|
189
|
+
uri.path.should == expected_path
|
190
|
+
query_parts = uri.query.split("&")
|
191
|
+
query_parts.should =~ expected_query_parts
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
describe ".path" do
|
199
|
+
context "when passed nothing" do
|
200
|
+
it "returns the base_path" do
|
201
|
+
ResourceFixture.path.should == "/foobar"
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
context "when passed a sub path" do
|
206
|
+
it "merges the base_path into the sub path, regardless of a / in front" do
|
207
|
+
ResourceFixtureWithSubPaths.path("/baz").should == "/foobar/baz"
|
208
|
+
ResourceFixtureWithSubPaths.path("baz").should == "/foobar/baz"
|
209
|
+
end
|
210
|
+
|
211
|
+
context "when passed a multiple sub paths" do
|
212
|
+
it "joins the sub paths with '/'" do
|
213
|
+
ResourceFixtureWithSubPaths.path("users", 99).should == "/foobar/users/99"
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
context "when passed a hash as the last argument" do
|
218
|
+
context "when using a single path argument" do
|
219
|
+
it "creates url params from the hash" do
|
220
|
+
path = ResourceFixtureWithSubPaths.path(
|
221
|
+
"/users/:user_id", {:user_id => 99, :single_value_param => "single_value_param_value", 'multiple_value_param[]' => [1,2,3]}
|
222
|
+
)
|
223
|
+
uri = URI.parse(path)
|
224
|
+
uri.path.should == "/foobar/users/99"
|
225
|
+
query_parts = uri.query.split("&")
|
226
|
+
query_parts.should =~ [
|
227
|
+
"multiple_value_param[]=1",
|
228
|
+
"multiple_value_param[]=2",
|
229
|
+
"multiple_value_param[]=3",
|
230
|
+
"single_value_param=single_value_param_value",
|
231
|
+
]
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
context "when using multiple path arguments" do
|
236
|
+
it "creates url params from the hash" do
|
237
|
+
path = ResourceFixtureWithSubPaths.path(
|
238
|
+
"users", 99, {:single_value_param => "single_value_param_value", 'multiple_value_param[]' => [1,2,3]}
|
239
|
+
)
|
240
|
+
uri = URI.parse(path)
|
241
|
+
uri.path.should == "/foobar/users/99"
|
242
|
+
query_parts = uri.query.split("&")
|
243
|
+
query_parts.should =~ [
|
244
|
+
"multiple_value_param[]=1",
|
245
|
+
"multiple_value_param[]=2",
|
246
|
+
"multiple_value_param[]=3",
|
247
|
+
"single_value_param=single_value_param_value",
|
248
|
+
]
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
context "when the base_path contains a parameter" do
|
255
|
+
context "when not passed" do
|
256
|
+
it "raises an ArgumentError" do
|
257
|
+
lambda do
|
258
|
+
User.path
|
259
|
+
end.should raise_error(
|
260
|
+
ArgumentError,
|
261
|
+
%r{Expected :user_id to have a value}
|
262
|
+
)
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
context "when first argument is a hash" do
|
267
|
+
it "returns the full path with the base path param value" do
|
268
|
+
User.path("friends", :user_id => 99).should == "/users/99/friends"
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
end
|