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.
Files changed (112) hide show
  1. data/CHANGES +27 -0
  2. data/README.markdown +354 -0
  3. data/Rakefile +42 -0
  4. data/VERSION.yml +4 -0
  5. data/bin/screw_unit +6 -0
  6. data/bin/screw_unit_server +20 -0
  7. data/core/CHANGES +10 -0
  8. data/core/EXAMPLE.html +68 -0
  9. data/core/LICENSE +22 -0
  10. data/core/README.markdown +307 -0
  11. data/core/example/models/cat.js +5 -0
  12. data/core/example/models/man.js +17 -0
  13. data/core/example/spec/matchers/have.js +8 -0
  14. data/core/example/spec/models/cat_spec.js +31 -0
  15. data/core/example/spec/models/man_spec.js +34 -0
  16. data/core/example/spec/spec_helper.js +5 -0
  17. data/core/example/spec/suite.html +25 -0
  18. data/core/lib/jquery-1.3.2.js +4376 -0
  19. data/core/lib/jquery.fn.js +30 -0
  20. data/core/lib/jquery.print.js +109 -0
  21. data/core/lib/screw.behaviors.js +93 -0
  22. data/core/lib/screw.builder.js +95 -0
  23. data/core/lib/screw.css +90 -0
  24. data/core/lib/screw.events.js +45 -0
  25. data/core/lib/screw.matchers.js +244 -0
  26. data/core/spec/behaviors_spec.js +188 -0
  27. data/core/spec/matchers_spec.js +372 -0
  28. data/core/spec/print_spec.js +158 -0
  29. data/core/spec/spec_helper.js +0 -0
  30. data/core/spec/suite.html +19 -0
  31. data/core/spec/with_screw_context_spec.js +9 -0
  32. data/init.rb +0 -0
  33. data/lib/screw_unit.rb +23 -0
  34. data/lib/screw_unit/representations.rb +2 -0
  35. data/lib/screw_unit/representations/spec.html.rb +117 -0
  36. data/spec/functional/functional_spec.rb +25 -0
  37. data/spec/functional/functional_spec_helper.rb +43 -0
  38. data/spec/functional/functional_spec_server_starter.rb +68 -0
  39. data/spec/functional_suite.rb +10 -0
  40. data/spec/spec_suite.rb +3 -0
  41. data/spec/unit/js_test_core/specs/spec_file_spec.rb +68 -0
  42. data/spec/unit/unit_spec_helper.rb +51 -0
  43. data/spec/unit_suite.rb +10 -0
  44. data/vendor/js-test-core/CHANGES +28 -0
  45. data/vendor/js-test-core/README +12 -0
  46. data/vendor/js-test-core/Rakefile +73 -0
  47. data/vendor/js-test-core/lib/js_test_core.rb +46 -0
  48. data/vendor/js-test-core/lib/js_test_core/app.rb +12 -0
  49. data/vendor/js-test-core/lib/js_test_core/client.rb +129 -0
  50. data/vendor/js-test-core/lib/js_test_core/configuration.rb +35 -0
  51. data/vendor/js-test-core/lib/js_test_core/extensions.rb +3 -0
  52. data/vendor/js-test-core/lib/js_test_core/extensions/selenium/client/driver.rb +7 -0
  53. data/vendor/js-test-core/lib/js_test_core/extensions/time.rb +6 -0
  54. data/vendor/js-test-core/lib/js_test_core/models.rb +8 -0
  55. data/vendor/js-test-core/lib/js_test_core/models/selenium_session.rb +80 -0
  56. data/vendor/js-test-core/lib/js_test_core/representations.rb +11 -0
  57. data/vendor/js-test-core/lib/js_test_core/representations/dir.html.rb +24 -0
  58. data/vendor/js-test-core/lib/js_test_core/representations/not_found.html.rb +15 -0
  59. data/vendor/js-test-core/lib/js_test_core/representations/page.html.rb +41 -0
  60. data/vendor/js-test-core/lib/js_test_core/representations/spec.html.rb +24 -0
  61. data/vendor/js-test-core/lib/js_test_core/resources.rb +16 -0
  62. data/vendor/js-test-core/lib/js_test_core/resources/core_file.rb +19 -0
  63. data/vendor/js-test-core/lib/js_test_core/resources/file.rb +62 -0
  64. data/vendor/js-test-core/lib/js_test_core/resources/implementations_deprecation.rb +12 -0
  65. data/vendor/js-test-core/lib/js_test_core/resources/not_found.rb +35 -0
  66. data/vendor/js-test-core/lib/js_test_core/resources/resource.rb +16 -0
  67. data/vendor/js-test-core/lib/js_test_core/resources/selenium_session.rb +104 -0
  68. data/vendor/js-test-core/lib/js_test_core/resources/spec_file.rb +63 -0
  69. data/vendor/js-test-core/lib/js_test_core/resources/web_root.rb +11 -0
  70. data/vendor/js-test-core/lib/js_test_core/selenium_server_configuration.rb +48 -0
  71. data/vendor/js-test-core/spec/example_core/JsTestCore.css +0 -0
  72. data/vendor/js-test-core/spec/example_core/JsTestCore.js +0 -0
  73. data/vendor/js-test-core/spec/example_core/subdir/SubDirFile.js +0 -0
  74. data/vendor/js-test-core/spec/example_public/favicon.ico +0 -0
  75. data/vendor/js-test-core/spec/example_public/javascripts/foo.js +3 -0
  76. data/vendor/js-test-core/spec/example_public/javascripts/large_file.js +59 -0
  77. data/vendor/js-test-core/spec/example_public/javascripts/subdir/bar.js +1 -0
  78. data/vendor/js-test-core/spec/example_public/robots.txt +0 -0
  79. data/vendor/js-test-core/spec/example_public/stylesheets/example.css +3 -0
  80. data/vendor/js-test-core/spec/example_specs/custom_dir_and_suite/passing_spec.js +6 -0
  81. data/vendor/js-test-core/spec/example_specs/custom_suite.html +8 -0
  82. data/vendor/js-test-core/spec/example_specs/failing_spec.js +5 -0
  83. data/vendor/js-test-core/spec/example_specs/foo/failing_spec.js +6 -0
  84. data/vendor/js-test-core/spec/example_specs/foo/passing_spec.js +6 -0
  85. data/vendor/js-test-core/spec/spec_helpers/be_http.rb +32 -0
  86. data/vendor/js-test-core/spec/spec_helpers/example_group.rb +36 -0
  87. data/vendor/js-test-core/spec/spec_helpers/fake_selenium_driver.rb +27 -0
  88. data/vendor/js-test-core/spec/spec_helpers/show_test_exceptions.rb +22 -0
  89. data/vendor/js-test-core/spec/spec_suite.rb +2 -0
  90. data/vendor/js-test-core/spec/specs/failing_spec.js +0 -0
  91. data/vendor/js-test-core/spec/unit/js_test_core/client_spec.rb +192 -0
  92. data/vendor/js-test-core/spec/unit/js_test_core/configuration_spec.rb +44 -0
  93. data/vendor/js-test-core/spec/unit/js_test_core/models/selenium_session_spec.rb +85 -0
  94. data/vendor/js-test-core/spec/unit/js_test_core/resources/core_file_spec.rb +60 -0
  95. data/vendor/js-test-core/spec/unit/js_test_core/resources/file_spec.rb +81 -0
  96. data/vendor/js-test-core/spec/unit/js_test_core/resources/implementations_deprecation_spec.rb +18 -0
  97. data/vendor/js-test-core/spec/unit/js_test_core/resources/not_found_spec.rb +51 -0
  98. data/vendor/js-test-core/spec/unit/js_test_core/resources/selenium_session_spec.rb +362 -0
  99. data/vendor/js-test-core/spec/unit/js_test_core/resources/spec_file_spec.rb +120 -0
  100. data/vendor/js-test-core/spec/unit/js_test_core/resources/web_root_spec.rb +28 -0
  101. data/vendor/js-test-core/spec/unit/js_test_core/selenium_server_configuration_spec.rb +49 -0
  102. data/vendor/js-test-core/spec/unit/unit_spec_helper.rb +28 -0
  103. data/vendor/js-test-core/spec/unit_suite.rb +10 -0
  104. data/vendor/js-test-core/vendor/lucky-luciano/README.markdown +7 -0
  105. data/vendor/js-test-core/vendor/lucky-luciano/lib/lucky_luciano.rb +4 -0
  106. data/vendor/js-test-core/vendor/lucky-luciano/lib/lucky_luciano/resource.rb +135 -0
  107. data/vendor/js-test-core/vendor/lucky-luciano/lib/lucky_luciano/rspec.rb +4 -0
  108. data/vendor/js-test-core/vendor/lucky-luciano/lib/lucky_luciano/rspec/be_http.rb +32 -0
  109. data/vendor/js-test-core/vendor/lucky-luciano/spec/lucky_luciano/resource_spec.rb +231 -0
  110. data/vendor/js-test-core/vendor/lucky-luciano/spec/spec_helper.rb +48 -0
  111. data/vendor/js-test-core/vendor/lucky-luciano/spec/spec_suite.rb +4 -0
  112. 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,10 @@
1
+ class UnitSuite
2
+ def run
3
+ dir = File.dirname(__FILE__)
4
+ Dir["#{dir}/unit/**/*_spec.rb"].each do |file|
5
+ require file
6
+ end
7
+ end
8
+ end
9
+
10
+ UnitSuite.new.run
@@ -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,4 @@
1
+ require "sinatra/base"
2
+
3
+ dir = File.dirname(__FILE__)
4
+ require "#{dir}/lucky_luciano/resource"
@@ -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,4 @@
1
+ dir = File.dirname(__FILE__)
2
+ Dir["#{dir}/rspec/**/*.rb"].each do |file|
3
+ require file
4
+ 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