screw-unit-server 0.3.0 → 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 (124) hide show
  1. data/CHANGES +23 -1
  2. data/README.markdown +10 -3
  3. data/Rakefile +27 -55
  4. data/VERSION.yml +4 -0
  5. data/bin/screw_unit_server +14 -4
  6. data/core/CHANGES +10 -0
  7. data/core/EXAMPLE.html +4 -4
  8. data/core/README.markdown +7 -7
  9. data/core/example/models/man.js +2 -2
  10. data/core/example/spec/suite.html +1 -1
  11. data/core/lib/jquery-1.3.2.js +4376 -0
  12. data/core/lib/jquery.fn.js +2 -1
  13. data/core/lib/jquery.print.js +13 -12
  14. data/core/lib/screw.behaviors.js +11 -9
  15. data/core/lib/screw.builder.js +26 -11
  16. data/core/lib/screw.css +2 -2
  17. data/core/lib/screw.events.js +11 -4
  18. data/core/lib/screw.matchers.js +192 -13
  19. data/core/spec/behaviors_spec.js +11 -1
  20. data/core/spec/matchers_spec.js +288 -9
  21. data/core/spec/print_spec.js +47 -8
  22. data/core/spec/suite.html +2 -1
  23. data/core/spec/with_screw_context_spec.js +9 -0
  24. data/lib/screw_unit.rb +13 -16
  25. data/lib/screw_unit/representations.rb +2 -0
  26. data/lib/screw_unit/representations/spec.html.rb +117 -0
  27. data/spec/functional/functional_spec.rb +14 -3
  28. data/spec/functional/functional_spec_helper.rb +22 -34
  29. data/spec/functional/functional_spec_server_starter.rb +68 -0
  30. data/spec/unit/js_test_core/specs/spec_file_spec.rb +45 -20
  31. data/spec/unit/unit_spec_helper.rb +24 -93
  32. data/vendor/js-test-core/CHANGES +19 -0
  33. data/vendor/js-test-core/Rakefile +2 -1
  34. data/vendor/js-test-core/lib/js_test_core.rb +26 -10
  35. data/vendor/js-test-core/lib/js_test_core/app.rb +12 -0
  36. data/vendor/js-test-core/lib/js_test_core/client.rb +97 -18
  37. data/vendor/js-test-core/lib/js_test_core/configuration.rb +35 -0
  38. data/vendor/js-test-core/lib/js_test_core/extensions.rb +3 -0
  39. data/vendor/js-test-core/lib/js_test_core/extensions/selenium/client/driver.rb +7 -0
  40. data/vendor/js-test-core/lib/js_test_core/extensions/time.rb +6 -0
  41. data/vendor/js-test-core/lib/js_test_core/models.rb +8 -0
  42. data/vendor/js-test-core/lib/js_test_core/models/selenium_session.rb +80 -0
  43. data/vendor/js-test-core/lib/js_test_core/representations.rb +11 -0
  44. data/vendor/js-test-core/lib/js_test_core/representations/dir.html.rb +24 -0
  45. data/vendor/js-test-core/lib/js_test_core/representations/not_found.html.rb +15 -0
  46. data/vendor/js-test-core/lib/js_test_core/representations/page.html.rb +41 -0
  47. data/vendor/js-test-core/lib/js_test_core/representations/spec.html.rb +24 -0
  48. data/vendor/js-test-core/lib/js_test_core/resources.rb +13 -8
  49. data/vendor/js-test-core/lib/js_test_core/resources/core_file.rb +19 -0
  50. data/vendor/js-test-core/lib/js_test_core/resources/file.rb +44 -14
  51. data/vendor/js-test-core/lib/js_test_core/resources/implementations_deprecation.rb +12 -0
  52. data/vendor/js-test-core/lib/js_test_core/resources/not_found.rb +35 -0
  53. data/vendor/js-test-core/lib/js_test_core/resources/resource.rb +16 -0
  54. data/vendor/js-test-core/lib/js_test_core/resources/selenium_session.rb +104 -0
  55. data/vendor/js-test-core/lib/js_test_core/resources/spec_file.rb +63 -0
  56. data/vendor/js-test-core/lib/js_test_core/resources/web_root.rb +5 -56
  57. data/vendor/js-test-core/lib/js_test_core/selenium_server_configuration.rb +48 -0
  58. data/vendor/js-test-core/spec/example_core/subdir/SubDirFile.js +0 -0
  59. data/vendor/js-test-core/spec/example_public/javascripts/large_file.js +59 -0
  60. data/vendor/js-test-core/spec/example_public/javascripts/subdir/bar.js +1 -0
  61. data/vendor/js-test-core/spec/example_specs/custom_dir_and_suite/passing_spec.js +6 -0
  62. data/vendor/js-test-core/spec/example_specs/custom_suite.html +8 -0
  63. data/vendor/js-test-core/spec/example_specs/foo/failing_spec.js +1 -1
  64. data/vendor/js-test-core/spec/example_specs/foo/passing_spec.js +1 -1
  65. data/vendor/js-test-core/spec/spec_helpers/be_http.rb +32 -0
  66. data/vendor/js-test-core/spec/spec_helpers/example_group.rb +36 -0
  67. data/vendor/js-test-core/spec/spec_helpers/fake_selenium_driver.rb +27 -0
  68. data/vendor/js-test-core/spec/spec_helpers/show_test_exceptions.rb +22 -0
  69. data/vendor/js-test-core/spec/unit/js_test_core/client_spec.rb +140 -85
  70. data/vendor/js-test-core/spec/unit/js_test_core/configuration_spec.rb +44 -0
  71. data/vendor/js-test-core/spec/unit/js_test_core/models/selenium_session_spec.rb +85 -0
  72. data/vendor/js-test-core/spec/unit/js_test_core/resources/core_file_spec.rb +60 -0
  73. data/vendor/js-test-core/spec/unit/js_test_core/resources/file_spec.rb +61 -68
  74. data/vendor/js-test-core/spec/unit/js_test_core/resources/implementations_deprecation_spec.rb +18 -0
  75. data/vendor/js-test-core/spec/unit/js_test_core/resources/not_found_spec.rb +51 -0
  76. data/vendor/js-test-core/spec/unit/js_test_core/resources/selenium_session_spec.rb +362 -0
  77. data/vendor/js-test-core/spec/unit/js_test_core/resources/spec_file_spec.rb +120 -0
  78. data/vendor/js-test-core/spec/unit/js_test_core/resources/web_root_spec.rb +14 -89
  79. data/vendor/js-test-core/spec/unit/js_test_core/selenium_server_configuration_spec.rb +49 -0
  80. data/vendor/js-test-core/spec/unit/unit_spec_helper.rb +16 -113
  81. data/vendor/js-test-core/vendor/lucky-luciano/README.markdown +7 -0
  82. data/vendor/js-test-core/vendor/lucky-luciano/lib/lucky_luciano.rb +4 -0
  83. data/vendor/js-test-core/vendor/lucky-luciano/lib/lucky_luciano/resource.rb +135 -0
  84. data/vendor/js-test-core/vendor/lucky-luciano/lib/lucky_luciano/rspec.rb +4 -0
  85. data/vendor/js-test-core/vendor/lucky-luciano/lib/lucky_luciano/rspec/be_http.rb +32 -0
  86. data/vendor/js-test-core/vendor/lucky-luciano/spec/lucky_luciano/resource_spec.rb +231 -0
  87. data/vendor/js-test-core/vendor/lucky-luciano/spec/spec_helper.rb +48 -0
  88. data/vendor/js-test-core/vendor/lucky-luciano/spec/spec_suite.rb +4 -0
  89. metadata +143 -129
  90. data/core/TODO +0 -2
  91. data/core/lib/jquery-1.2.3.js +0 -3408
  92. data/core/lib/screw.assets.js +0 -36
  93. data/core/lib/screw.server.js +0 -21
  94. data/lib/screw_unit/resources.rb +0 -2
  95. data/lib/screw_unit/resources/spec.rb +0 -37
  96. data/spec/unit/js_test_core/specs/spec_dir_spec.rb +0 -43
  97. data/vendor/js-test-core/lib/js_test_core/rack.rb +0 -2
  98. data/vendor/js-test-core/lib/js_test_core/rack/commonlogger.rb +0 -5
  99. data/vendor/js-test-core/lib/js_test_core/rails_server.rb +0 -22
  100. data/vendor/js-test-core/lib/js_test_core/resources/dir.rb +0 -52
  101. data/vendor/js-test-core/lib/js_test_core/resources/file_not_found.rb +0 -15
  102. data/vendor/js-test-core/lib/js_test_core/resources/runners.rb +0 -15
  103. data/vendor/js-test-core/lib/js_test_core/resources/runners/firefox_runner.rb +0 -75
  104. data/vendor/js-test-core/lib/js_test_core/resources/specs/spec_dir.rb +0 -50
  105. data/vendor/js-test-core/lib/js_test_core/resources/specs/spec_file.rb +0 -17
  106. data/vendor/js-test-core/lib/js_test_core/resources/suite.rb +0 -24
  107. data/vendor/js-test-core/lib/js_test_core/resources/suite_finish.rb +0 -19
  108. data/vendor/js-test-core/lib/js_test_core/selenium.rb +0 -2
  109. data/vendor/js-test-core/lib/js_test_core/selenium/selenium_driver.rb +0 -5
  110. data/vendor/js-test-core/lib/js_test_core/server.rb +0 -111
  111. data/vendor/js-test-core/lib/js_test_core/thin.rb +0 -3
  112. data/vendor/js-test-core/lib/js_test_core/thin/backends/js_test_core_server.rb +0 -9
  113. data/vendor/js-test-core/lib/js_test_core/thin/js_test_core_connection.rb +0 -42
  114. data/vendor/js-test-core/spec/unit/js_test_core/rails_server_spec.rb +0 -45
  115. data/vendor/js-test-core/spec/unit/js_test_core/resources/dir_spec.rb +0 -42
  116. data/vendor/js-test-core/spec/unit/js_test_core/resources/file_not_found_spec.rb +0 -26
  117. data/vendor/js-test-core/spec/unit/js_test_core/resources/runner_spec.rb +0 -24
  118. data/vendor/js-test-core/spec/unit/js_test_core/resources/runners/firefox_runner_spec.rb +0 -197
  119. data/vendor/js-test-core/spec/unit/js_test_core/resources/specs/spec_dir_spec.rb +0 -79
  120. data/vendor/js-test-core/spec/unit/js_test_core/resources/specs/spec_file_spec.rb +0 -42
  121. data/vendor/js-test-core/spec/unit/js_test_core/resources/suite_finish_spec.rb +0 -94
  122. data/vendor/js-test-core/spec/unit/js_test_core/resources/suite_spec.rb +0 -44
  123. data/vendor/js-test-core/spec/unit/js_test_core/server_spec.rb +0 -131
  124. data/vendor/js-test-core/spec/unit/thin/js_test_core_connection_spec.rb +0 -92
@@ -0,0 +1,48 @@
1
+ module JsTestCore
2
+ class SeleniumServerConfiguration
3
+ attr_reader :parameters
4
+
5
+ class << self
6
+ def query_string_from(*args, &block)
7
+ new(*args, &block).query_string
8
+ end
9
+ end
10
+
11
+ def initialize(parameters={})
12
+ @parameters = parameters
13
+ end
14
+
15
+
16
+ def query_string
17
+ parts = [selenium_browser_start_command, selenium_host, selenium_port]
18
+ parts << spec_url if url
19
+ parts.join('&')
20
+ end
21
+
22
+ private
23
+
24
+ def selenium_browser_start_command
25
+ "selenium_browser_start_command=#{parameter_or_default_for(:selenium_browser_start_command, '*firefox')}"
26
+ end
27
+
28
+ def selenium_host
29
+ "selenium_host=#{parameter_or_default_for(:selenium_host, 'localhost')}"
30
+ end
31
+
32
+ def selenium_port
33
+ "selenium_port=#{parameter_or_default_for(:selenium_port, 4444)}"
34
+ end
35
+
36
+ def spec_url
37
+ "spec_url=#{url}"
38
+ end
39
+
40
+ def url
41
+ parameters[:spec_url]
42
+ end
43
+
44
+ def parameter_or_default_for(parameter_name, default = nil)
45
+ CGI.escape((parameters[parameter_name] || default).to_s)
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,59 @@
1
+ //////////////////////////////////////////////
2
+ //////////////////////////////////////////////
3
+ //////////////////////////////////////////////
4
+ //////////////////////////////////////////////
5
+ //////////////////////////////////////////////
6
+ //////////////////////////////////////////////
7
+ //////////////////////////////////////////////
8
+ //////////////////////////////////////////////
9
+ //////////////////////////////////////////////
10
+ //////////////////////////////////////////////
11
+ //////////////////////////////////////////////
12
+ //////////////////////////////////////////////
13
+ //////////////////////////////////////////////
14
+ //////////////////////////////////////////////
15
+ //////////////////////////////////////////////
16
+ //////////////////////////////////////////////
17
+ //////////////////////////////////////////////
18
+ //////////////////////////////////////////////
19
+ //////////////////////////////////////////////
20
+ //////////////////////////////////////////////
21
+ //////////////////////////////////////////////
22
+ //////////////////////////////////////////////
23
+ //////////////////////////////////////////////
24
+ //////////////////////////////////////////////
25
+ //////////////////////////////////////////////
26
+ //////////////////////////////////////////////
27
+ //////////////////////////////////////////////
28
+ //////////////////////////////////////////////
29
+ //////////////////////////////////////////////
30
+ //////////////////////////////////////////////
31
+ //////////////////////////////////////////////
32
+ //////////////////////////////////////////////
33
+ //////////////////////////////////////////////
34
+ //////////////////////////////////////////////
35
+ //////////////////////////////////////////////
36
+ //////////////////////////////////////////////
37
+ //////////////////////////////////////////////
38
+ //////////////////////////////////////////////
39
+ //////////////////////////////////////////////
40
+ //////////////////////////////////////////////
41
+ //////////////////////////////////////////////
42
+ //////////////////////////////////////////////
43
+ //////////////////////////////////////////////
44
+ //////////////////////////////////////////////
45
+ //////////////////////////////////////////////
46
+ //////////////////////////////////////////////
47
+ //////////////////////////////////////////////
48
+ //////////////////////////////////////////////
49
+ //////////////////////////////////////////////
50
+ //////////////////////////////////////////////
51
+ //////////////////////////////////////////////
52
+ //////////////////////////////////////////////
53
+ //////////////////////////////////////////////
54
+ //////////////////////////////////////////////
55
+ //////////////////////////////////////////////
56
+ //////////////////////////////////////////////
57
+ //////////////////////////////////////////////
58
+ //////////////////////////////////////////////
59
+ //////////////////////////////////////////////
@@ -0,0 +1,6 @@
1
+ require("/javascripts/foo");
2
+ describe("A passing spec", {
3
+ 'passes': function() {
4
+ value_of(Foo.value).should_be(true);
5
+ }
6
+ })
@@ -0,0 +1,8 @@
1
+ <html>
2
+ <head>
3
+ <title>Custom Suite</title>
4
+ </head>
5
+ <body>
6
+
7
+ </body>
8
+ </html>
@@ -1,4 +1,4 @@
1
- require("/implementations/foo");
1
+ require("/javascripts/foo");
2
2
  describe("A failing spec in foo", {
3
3
  'fails': function() {
4
4
  value_of(Foo.value).should_be(false);
@@ -1,4 +1,4 @@
1
- require("/implementations/foo");
1
+ require("/javascripts/foo");
2
2
  describe("A passing spec", {
3
3
  'passes': function() {
4
4
  value_of(Foo.value).should_be(true);
@@ -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,36 @@
1
+ class Spec::ExampleGroup
2
+ class << self
3
+ def macro(name, &block)
4
+ eigen do
5
+ define_method(name, &block)
6
+ end
7
+ end
8
+
9
+ def eigen(&block)
10
+ eigen_class = (class << self; self; end)
11
+ eigen_class.class_eval(&block)
12
+ eigen_class
13
+ end
14
+ end
15
+
16
+ include Rack::Test::Methods
17
+ include BeHttp
18
+ attr_reader :core_path, :spec_root_path, :public_path, :server, :connection
19
+ before(:all) do
20
+ dir = File.dirname(__FILE__)
21
+ @core_path = File.expand_path("#{LIBRARY_ROOT_DIR}/spec/example_core")
22
+ @spec_root_path = File.expand_path("#{LIBRARY_ROOT_DIR}/spec/example_specs")
23
+ @public_path = File.expand_path("#{LIBRARY_ROOT_DIR}/spec/example_public")
24
+ stub(Thread).start.yields
25
+ end
26
+
27
+ before(:each) do
28
+ JsTestCore::Configuration.instance.spec_root_path = spec_root_path
29
+ JsTestCore::Configuration.instance.public_path = public_path
30
+ JsTestCore::Configuration.instance.core_path = core_path
31
+ end
32
+
33
+ def app
34
+ Sinatra::Application
35
+ end
36
+ end
@@ -0,0 +1,27 @@
1
+ class FakeSeleniumDriver
2
+ SESSION_ID = "DEADBEEF"
3
+ attr_reader :session_id
4
+
5
+ def initialize
6
+ @session_id = nil
7
+ end
8
+
9
+ def start
10
+ @session_id = SESSION_ID
11
+ end
12
+
13
+ def stop
14
+ @session_id = nil
15
+ end
16
+
17
+ def open(url)
18
+ end
19
+
20
+ def create_cookie(key_value, options="")
21
+
22
+ end
23
+
24
+ def session_started?
25
+ !!@session_id
26
+ end
27
+ end
@@ -0,0 +1,22 @@
1
+ class ShowTestExceptions
2
+ attr_reader :app
3
+
4
+ def initialize(app)
5
+ @app = app
6
+ end
7
+
8
+ def call(env)
9
+ app.call(env)
10
+ rescue StandardError, LoadError, SyntaxError => e
11
+ body = [
12
+ e.message,
13
+ e.backtrace.join("\n\t")
14
+ ].join("\n")
15
+ [
16
+ 500,
17
+ {"Content-Type" => "text",
18
+ "Content-Length" => body.size.to_s},
19
+ body
20
+ ]
21
+ end
22
+ end
@@ -3,135 +3,190 @@ require File.expand_path("#{File.dirname(__FILE__)}/../unit_spec_helper")
3
3
  module JsTestCore
4
4
  describe Client do
5
5
  describe '.run' do
6
- describe 'when successful' do
6
+ attr_reader :stdout, :request
7
+ before do
8
+ @stdout = StringIO.new
9
+ Client.const_set(:STDOUT, stdout)
10
+ @request = "http request"
11
+ mock(Net::HTTP).start(DEFAULT_HOST, DEFAULT_PORT).yields(request)
12
+ stub.instance_of(Client).sleep
13
+ end
14
+
15
+ after do
16
+ Client.__send__(:remove_const, :STDOUT)
17
+ end
18
+
19
+ it "tells the server to start a session run in Firefox and polls the status of the session until the session is complete" do
20
+ mock_post_to_runner("*firefox")
21
+ mock_polling_returns([running_status, running_status, success_status])
22
+ Client.run
23
+ end
24
+
25
+ context "when the Session run ends in 'success'" do
7
26
  before do
8
- request = Object.new
9
- mock(request).post("/runners/firefox", "selenium_host=localhost&selenium_port=4444")
10
- response = Object.new
11
- mock(response).body {""}
12
- mock(Net::HTTP).start(DEFAULT_HOST, DEFAULT_PORT).yields(request) {response}
13
- stub(Client).puts
27
+ mock_post_to_runner("*firefox")
28
+ mock_polling_returns([running_status, running_status, success_status])
14
29
  end
15
30
 
16
- it "returns true" do
17
- Client.run.should be_true
31
+ it "reports success" do
32
+ Client.run
33
+ stdout.string.strip.should == "SUCCESS"
18
34
  end
19
35
 
20
- it "prints 'SUCCESS'" do
21
- mock(Client).puts("SUCCESS")
22
- Client.run
36
+ it "returns true" do
37
+ Client.run.should be_true
23
38
  end
24
39
  end
25
40
 
26
- describe 'when unsuccessful' do
41
+ context "when the Session run ends in 'failure'" do
42
+ attr_reader :failure_reason
27
43
  before do
28
- request = Object.new
29
- mock(request).post("/runners/firefox", "selenium_host=localhost&selenium_port=4444")
30
- response = Object.new
31
- mock(response).body {"the failure message"}
32
- mock(Net::HTTP).start(DEFAULT_HOST, DEFAULT_PORT).yields(request) {response}
33
- stub(Client).puts
44
+ mock_post_to_runner("*firefox")
45
+ @failure_reason = "I have a failed test"
46
+ mock_polling_returns([running_status, running_status, failure_status(failure_reason)])
47
+ end
48
+
49
+ it "reports failure and reason" do
50
+ Client.run
51
+ stdout.string.strip.should include("FAILURE")
52
+ stdout.string.strip.should include(failure_reason)
34
53
  end
35
54
 
36
55
  it "returns false" do
37
56
  Client.run.should be_false
38
57
  end
39
58
 
40
- it "prints 'FAILURE' and the error message(s)" do
41
- mock(Client).puts("FAILURE")
42
- mock(Client).puts("the failure message")
43
- Client.run
44
- end
59
+ it "reports the reason for failure"
45
60
  end
46
61
 
47
- describe "arguments" do
48
- attr_reader :request, :response
49
- before do
50
- @request = Object.new
51
- @response = Object.new
52
- mock(response).body {""}
53
- mock(Net::HTTP).start(DEFAULT_HOST, DEFAULT_PORT).yields(request) {response}
54
- stub(Client).puts
55
- end
56
-
57
- describe "when passed a custom spec_url" do
58
- it "passes the spec_url as a post parameter" do
59
- spec_url = 'http://foobar.com/foo'
60
- mock(request).post(
61
- "/runners/firefox",
62
- "selenium_host=localhost&selenium_port=4444&spec_url=#{CGI.escape(spec_url)}"
63
- )
64
- Client.run(:spec_url => spec_url)
62
+ context "when the Session is not found" do
63
+ it "raises a SessionNotFound error" do
64
+ mock_post_to_runner("*firefox")
65
+ mock(request).get(Resources::SeleniumSession.path(":session_id", :session_id => "my_session_id")) do
66
+ stub(session_response = Object.new).code {"404"}
67
+ session_response
65
68
  end
69
+ lambda {Client.run}.should raise_error(Client::SessionNotFound)
66
70
  end
71
+ end
67
72
 
68
- describe "when passed a custom selenium host" do
69
- it "passes the selenium_host as a post parameter" do
70
- selenium_host = 'test-runner'
71
- mock(request).post(
72
- "/runners/firefox",
73
- "selenium_host=test-runner&selenium_port=4444"
74
- )
75
- Client.run(:selenium_host => selenium_host)
76
- end
73
+ context "when the Session run ends in with invalid status" do
74
+ it "raises an InvalidStatusResponse" do
75
+ mock_post_to_runner("*firefox")
76
+ mock_polling_returns([running_status, running_status, "status=this is an unexpected status result"])
77
+ lambda {Client.run}.should raise_error(Client::InvalidStatusResponse)
77
78
  end
79
+ end
78
80
 
79
- describe "when passed a custom selenium port" do
80
- it "passes the selenium_port as a post parameter" do
81
- selenium_port = 5000
82
- mock(request).post(
83
- "/runners/firefox",
84
- "selenium_host=localhost&selenium_port=5000"
85
- )
86
- Client.run(:selenium_port => selenium_port)
87
- end
81
+ context "when passed-in a timeout" do
82
+ it "wraps a timeout around the run" do
83
+ mock.proxy(Timeout).timeout(5)
84
+ mock_post_to_runner("*firefox")
85
+ mock_polling_returns([running_status, running_status, success_status])
86
+ Client.run(:timeout => 5)
88
87
  end
89
88
  end
90
89
 
90
+ context "when not passed-in a timeout" do
91
+ it "does not wrap a timeout around the run" do
92
+ dont_allow(Timeout).timeout
93
+ mock_post_to_runner("*firefox")
94
+ mock_polling_returns([running_status, running_status, success_status])
95
+ Client.run
96
+ end
97
+ end
98
+
99
+ def mock_post_to_runner(selenium_browser_start_command)
100
+ mock(start_session_response = Object.new).body {"session_id=my_session_id"}
101
+ mock(request).post(Resources::SeleniumSession.path, "selenium_browser_start_command=#{CGI.escape(selenium_browser_start_command)}&selenium_host=localhost&selenium_port=4444") do
102
+ start_session_response
103
+ end
104
+ end
105
+
106
+ def mock_polling_returns(session_statuses=[])
107
+ mock(request).get(Resources::SeleniumSession.path(":session_id", :session_id => "my_session_id")) do
108
+ stub(session_response = Object.new).body {session_statuses.shift}
109
+ stub(session_response).code {"200"}
110
+ session_response
111
+ end.times(session_statuses.length)
112
+ end
113
+
114
+ def running_status
115
+ "status=#{Resources::SeleniumSession::RUNNING}"
116
+ end
117
+
118
+ def success_status
119
+ "status=#{Resources::SeleniumSession::SUCCESSFUL_COMPLETION}"
120
+ end
121
+
122
+ def failure_status(reason)
123
+ "status=#{Resources::SeleniumSession::FAILURE_COMPLETION}&reason=#{reason}"
124
+ end
91
125
  end
92
-
126
+
93
127
  describe ".run_argv" do
94
128
  attr_reader :request, :response
95
129
  before do
96
- @request = Object.new
97
- @response = Object.new
98
- mock(response).body {""}
99
- mock(Net::HTTP).start(DEFAULT_HOST, DEFAULT_PORT).yields(request) {response}
100
- stub(Client).puts
130
+ stub(Client).puts
131
+ end
132
+
133
+ context "when passed-in Hash contains :selenium_browser_start_command" do
134
+ it "passes the spec_url as a post parameter" do
135
+ selenium_browser_start_command = '*iexplore'
136
+ mock(Client).run(:selenium_browser_start_command => selenium_browser_start_command)
137
+ client = Client.run_argv(['--selenium_browser_start_command', selenium_browser_start_command])
101
138
  end
139
+ end
102
140
 
103
- describe "when passed a custom spec_url" do
141
+ context "when passed-in Hash contains :spec_url" do
104
142
  it "passes the spec_url as a post parameter" do
105
143
  spec_url = 'http://foobar.com/foo'
106
- mock(request).post(
107
- "/runners/firefox",
108
- "selenium_host=localhost&selenium_port=4444&spec_url=#{CGI.escape(spec_url)}"
109
- )
110
- Client.run_argv(['--spec_url', spec_url])
144
+ mock(Client).run(:spec_url => spec_url)
145
+ client = Client.run_argv(['--spec_url', spec_url])
111
146
  end
112
147
  end
113
148
 
114
- describe "when passed a custom selenium host" do
149
+ context "when passed-in Hash contains :selenium_host" do
115
150
  it "passes the selenium_host as a post parameter" do
116
151
  selenium_host = 'test-runner'
117
- mock(request).post(
118
- "/runners/firefox",
119
- "selenium_host=test-runner&selenium_port=4444"
120
- )
121
- Client.run_argv(['--selenium_host', selenium_host])
152
+ mock(Client).run(:selenium_host => selenium_host)
153
+ client = Client.run_argv(['--selenium_host', selenium_host])
122
154
  end
123
155
  end
124
156
 
125
- describe "when passed a custom selenium port" do
157
+ context "when passed-in Hash contains :selenium_port" do
126
158
  it "passes the selenium_port as a post parameter" do
127
- selenium_port = 5000
128
- mock(request).post(
129
- "/runners/firefox",
130
- "selenium_host=localhost&selenium_port=5000"
131
- )
132
- Client.run_argv(['--selenium_port', selenium_port.to_s])
159
+ selenium_port = "5000"
160
+ mock(Client).run(:selenium_port => selenium_port)
161
+ client = Client.run_argv(['--selenium_port', selenium_port])
133
162
  end
134
163
  end
164
+
165
+ context "when passed-in Hash contains :timeout" do
166
+ it "passes the timeout as a post parameter" do
167
+ mock(Client).run(:timeout => 5)
168
+ client = Client.run_argv(['--timeout', "5"])
169
+ end
170
+ end
171
+ end
172
+
173
+ describe '#parts_from_query' do
174
+ attr_reader :client
175
+ before do
176
+ @client = Client.new(params_does_not_matter = {})
177
+ end
178
+
179
+ it "parses empty query into an empty hash" do
180
+ client.parts_from_query("").should == {}
181
+ end
182
+
183
+ it "parses a single key value pair into a single-element hash" do
184
+ client.parts_from_query("foo=bar").should == {'foo' => 'bar'}
185
+ end
186
+
187
+ it "parses a multiple key value pairs into a multi-element hash" do
188
+ client.parts_from_query("foo=bar&baz=quux").should == {'foo' => 'bar', 'baz' => 'quux'}
189
+ end
135
190
  end
136
191
  end
137
192
  end