pivotal-screw-unit 0.4.0

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 (127) hide show
  1. data/CHANGES +21 -0
  2. data/README.markdown +354 -0
  3. data/Rakefile +39 -0
  4. data/VERSION.yml +4 -0
  5. data/bin/screw_unit +6 -0
  6. data/bin/screw_unit_server +10 -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 +94 -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/representations/spec.html.rb +117 -0
  34. data/lib/screw_unit/representations.rb +2 -0
  35. data/lib/screw_unit.rb +19 -0
  36. data/spec/functional/functional_spec.rb +25 -0
  37. data/spec/functional/functional_spec_helper.rb +34 -0
  38. data/spec/functional/functional_spec_server_starter.rb +63 -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_dir_spec.rb +39 -0
  42. data/spec/unit/js_test_core/specs/spec_file_spec.rb +35 -0
  43. data/spec/unit/unit_spec_helper.rb +119 -0
  44. data/spec/unit_suite.rb +10 -0
  45. data/vendor/js-test-core/CHANGES +25 -0
  46. data/vendor/js-test-core/README +12 -0
  47. data/vendor/js-test-core/Rakefile +73 -0
  48. data/vendor/js-test-core/lib/js_test_core/client.rb +129 -0
  49. data/vendor/js-test-core/lib/js_test_core/extensions/time.rb +6 -0
  50. data/vendor/js-test-core/lib/js_test_core/extensions.rb +3 -0
  51. data/vendor/js-test-core/lib/js_test_core/rack/commonlogger.rb +5 -0
  52. data/vendor/js-test-core/lib/js_test_core/rack.rb +2 -0
  53. data/vendor/js-test-core/lib/js_test_core/rails_server.rb +22 -0
  54. data/vendor/js-test-core/lib/js_test_core/representations/spec.html.rb +23 -0
  55. data/vendor/js-test-core/lib/js_test_core/representations.rb +9 -0
  56. data/vendor/js-test-core/lib/js_test_core/resources/dir.rb +67 -0
  57. data/vendor/js-test-core/lib/js_test_core/resources/file.rb +42 -0
  58. data/vendor/js-test-core/lib/js_test_core/resources/runner.rb +107 -0
  59. data/vendor/js-test-core/lib/js_test_core/resources/session.rb +44 -0
  60. data/vendor/js-test-core/lib/js_test_core/resources/session_finish.rb +17 -0
  61. data/vendor/js-test-core/lib/js_test_core/resources/specs/spec.rb +32 -0
  62. data/vendor/js-test-core/lib/js_test_core/resources/specs/spec_dir.rb +50 -0
  63. data/vendor/js-test-core/lib/js_test_core/resources/specs/spec_file.rb +21 -0
  64. data/vendor/js-test-core/lib/js_test_core/resources/web_root.rb +66 -0
  65. data/vendor/js-test-core/lib/js_test_core/resources.rb +17 -0
  66. data/vendor/js-test-core/lib/js_test_core/selenium/client/driver.rb +7 -0
  67. data/vendor/js-test-core/lib/js_test_core/selenium.rb +2 -0
  68. data/vendor/js-test-core/lib/js_test_core/selenium_server_configuration.rb +48 -0
  69. data/vendor/js-test-core/lib/js_test_core/server.rb +50 -0
  70. data/vendor/js-test-core/lib/js_test_core/thin/backends/js_test_core_server.rb +9 -0
  71. data/vendor/js-test-core/lib/js_test_core/thin/js_test_core_connection.rb +8 -0
  72. data/vendor/js-test-core/lib/js_test_core/thin.rb +3 -0
  73. data/vendor/js-test-core/lib/js_test_core.rb +41 -0
  74. data/vendor/js-test-core/spec/example_core/JsTestCore.css +0 -0
  75. data/vendor/js-test-core/spec/example_core/JsTestCore.js +0 -0
  76. data/vendor/js-test-core/spec/example_public/favicon.ico +0 -0
  77. data/vendor/js-test-core/spec/example_public/javascripts/foo.js +3 -0
  78. data/vendor/js-test-core/spec/example_public/javascripts/large_file.js +59 -0
  79. data/vendor/js-test-core/spec/example_public/javascripts/subdir/bar.js +1 -0
  80. data/vendor/js-test-core/spec/example_public/robots.txt +0 -0
  81. data/vendor/js-test-core/spec/example_public/stylesheets/example.css +3 -0
  82. data/vendor/js-test-core/spec/example_specs/custom_dir_and_suite/passing_spec.js +6 -0
  83. data/vendor/js-test-core/spec/example_specs/custom_dir_and_suite.html +9 -0
  84. data/vendor/js-test-core/spec/example_specs/custom_suite.html +8 -0
  85. data/vendor/js-test-core/spec/example_specs/failing_spec.js +5 -0
  86. data/vendor/js-test-core/spec/example_specs/foo/failing_spec.js +6 -0
  87. data/vendor/js-test-core/spec/example_specs/foo/passing_spec.js +6 -0
  88. data/vendor/js-test-core/spec/spec_suite.rb +2 -0
  89. data/vendor/js-test-core/spec/specs/failing_spec.js +0 -0
  90. data/vendor/js-test-core/spec/unit/js_test_core/client_spec.rb +192 -0
  91. data/vendor/js-test-core/spec/unit/js_test_core/rails_server_spec.rb +45 -0
  92. data/vendor/js-test-core/spec/unit/js_test_core/resources/dir_spec.rb +53 -0
  93. data/vendor/js-test-core/spec/unit/js_test_core/resources/file_not_found_spec.rb +16 -0
  94. data/vendor/js-test-core/spec/unit/js_test_core/resources/file_spec.rb +90 -0
  95. data/vendor/js-test-core/spec/unit/js_test_core/resources/runners/runner_spec.rb +303 -0
  96. data/vendor/js-test-core/spec/unit/js_test_core/resources/session_finish_spec.rb +79 -0
  97. data/vendor/js-test-core/spec/unit/js_test_core/resources/session_spec.rb +82 -0
  98. data/vendor/js-test-core/spec/unit/js_test_core/resources/specs/spec_dir_spec.rb +104 -0
  99. data/vendor/js-test-core/spec/unit/js_test_core/resources/specs/spec_file_spec.rb +41 -0
  100. data/vendor/js-test-core/spec/unit/js_test_core/resources/web_root_spec.rb +32 -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/js_test_core/server_spec.rb +117 -0
  103. data/vendor/js-test-core/spec/unit/thin/js_test_core_connection_spec.rb +6 -0
  104. data/vendor/js-test-core/spec/unit/unit_spec_helper.rb +161 -0
  105. data/vendor/js-test-core/spec/unit_suite.rb +10 -0
  106. data/vendor/js-test-core/vendor/thin-rest/CHANGES +2 -0
  107. data/vendor/js-test-core/vendor/thin-rest/README +0 -0
  108. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest/connection.rb +117 -0
  109. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest/extensions/object.rb +21 -0
  110. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest/extensions.rb +3 -0
  111. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest/representations/internal_error.html.rb +19 -0
  112. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest/representations/page.html.rb +41 -0
  113. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest/representations/resource_not_found.html.rb +18 -0
  114. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest/representations.rb +4 -0
  115. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest/resources/internal_error.rb +11 -0
  116. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest/resources/resource.rb +105 -0
  117. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest/resources/resource_not_found.rb +19 -0
  118. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest/resources.rb +4 -0
  119. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest/routing_error.rb +5 -0
  120. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest.rb +10 -0
  121. data/vendor/js-test-core/vendor/thin-rest/spec/spec_suite.rb +5 -0
  122. data/vendor/js-test-core/vendor/thin-rest/spec/thin_rest/connection_spec.rb +205 -0
  123. data/vendor/js-test-core/vendor/thin-rest/spec/thin_rest/resources/resource_not_found_spec.rb +16 -0
  124. data/vendor/js-test-core/vendor/thin-rest/spec/thin_rest/resources/resource_spec.rb +135 -0
  125. data/vendor/js-test-core/vendor/thin-rest/spec/thin_rest/resources/root_spec.rb +16 -0
  126. data/vendor/js-test-core/vendor/thin-rest/spec/thin_rest_spec_helper.rb +133 -0
  127. metadata +184 -0
@@ -0,0 +1,21 @@
1
+ module JsTestCore
2
+ module Resources
3
+ module Specs
4
+ class SpecFile < ::JsTestCore::Resources::File
5
+ include Spec
6
+
7
+ def get
8
+ if ::File.exists?(absolute_path) && ::File.extname(absolute_path) != ".js"
9
+ super
10
+ else
11
+ get_generated_spec
12
+ end
13
+ end
14
+
15
+ def spec_files
16
+ [self]
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,66 @@
1
+ module JsTestCore
2
+ module Resources
3
+ class WebRoot < Resources::Resource
4
+ route "" do |env, name|
5
+ self
6
+ end
7
+ route "core" do |env, name|
8
+ Resources::Dir.new(env.merge(
9
+ :absolute_path => JsTestCore::Server.core_path,
10
+ :relative_path => "/core"
11
+ ))
12
+ end
13
+ route "implementations" do |env, name|
14
+ Resources::Dir.new(env.merge(
15
+ :absolute_path => JsTestCore::Server.implementation_root_path,
16
+ :relative_path => "/implementations"
17
+ ))
18
+ end
19
+ route "sessions", "JsTestCore::Resources::Session::Collection"
20
+ route "session" do |env, name|
21
+ Session.new(env.merge(:id => rack_request.cookies["session_id"]))
22
+ end
23
+ route "runners", "JsTestCore::Resources::Runner::Collection"
24
+ route "specs" do |env, name|
25
+ if self.class.dispatch_strategy == :specs
26
+ Resources::Specs::SpecDir.new(env.merge(
27
+ :absolute_path => JsTestCore::Server.spec_root_path,
28
+ :relative_path => "/specs"
29
+ ))
30
+ else
31
+ Resources::ResourceNotFound.new(env.merge(:name => name))
32
+ end
33
+ end
34
+ route ANY do |env, name|
35
+ potential_file_in_public_path = "#{public_path}/#{name}"
36
+ if ::File.directory?(potential_file_in_public_path)
37
+ Resources::Dir.new(env.merge(
38
+ :absolute_path => potential_file_in_public_path,
39
+ :relative_path => "/#{name}"
40
+ ))
41
+ elsif ::File.exists?(potential_file_in_public_path)
42
+ Resources::File.new(env.merge(
43
+ :absolute_path => potential_file_in_public_path,
44
+ :relative_path => "/#{name}"
45
+ ))
46
+ else
47
+ Resources::ResourceNotFound.new(env.merge(:name => name))
48
+ end
49
+ end
50
+
51
+ class << self
52
+ attr_accessor :dispatch_strategy
53
+ def dispatch_specs
54
+ self.dispatch_strategy = :specs
55
+ end
56
+ end
57
+
58
+ property :public_path
59
+
60
+ def get
61
+ connection.send_head(200, :Location => "/#{self.class.dispatch_strategy}")
62
+ connection.send_body("<html><head></head><body>Welcome to the Js Test Server. Click the following link to run you <a href=/specs>spec suite</a>.</body></html>")
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,17 @@
1
+ dir = File.dirname(__FILE__)
2
+
3
+ module JsTestCore
4
+ module Resources
5
+ include ThinRest::Resources
6
+ end
7
+ end
8
+
9
+ require "#{dir}/resources/runner"
10
+ require "#{dir}/resources/file"
11
+ require "#{dir}/resources/dir"
12
+ require "#{dir}/resources/specs/spec"
13
+ require "#{dir}/resources/specs/spec_file"
14
+ require "#{dir}/resources/specs/spec_dir"
15
+ require "#{dir}/resources/web_root"
16
+ require "#{dir}/resources/session"
17
+ require "#{dir}/resources/session_finish"
@@ -0,0 +1,7 @@
1
+ module Selenium
2
+ module Client
3
+ Driver.class_eval do
4
+ attr_reader :session_id
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,2 @@
1
+ dir = File.dirname(__FILE__)
2
+ require "#{dir}/selenium/client/driver"
@@ -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,50 @@
1
+ module JsTestCore
2
+ class Server
3
+ class << self
4
+ attr_accessor :instance
5
+
6
+ def run(spec_root_path, implementation_root_path, public_path, server_options = {})
7
+ server_options[:Host] ||= DEFAULT_HOST
8
+ server_options[:Port] ||= DEFAULT_PORT
9
+ @instance = new(spec_root_path, implementation_root_path, public_path, server_options[:Host], server_options[:Port])
10
+ instance.run server_options
11
+ end
12
+
13
+ def spec_root_path; instance.spec_root_path; end
14
+ def implementation_root_path; instance.implementation_root_path; end
15
+ def public_path; instance.public_path; end
16
+ def core_path; instance.core_path; end
17
+ def request; instance.request; end
18
+ def response; instance.response; end
19
+ def root_url; instance.root_url; end
20
+ end
21
+
22
+ attr_reader :host, :port, :spec_root_path, :implementation_root_path, :public_path
23
+
24
+ def initialize(spec_root_path, implementation_root_path, public_path, host=DEFAULT_HOST, port=DEFAULT_PORT)
25
+ dir = ::File.dirname(__FILE__)
26
+ @spec_root_path = ::File.expand_path(spec_root_path)
27
+ @implementation_root_path = ::File.expand_path(implementation_root_path)
28
+ @public_path = ::File.expand_path(public_path)
29
+ @host = host
30
+ @port = port
31
+ end
32
+
33
+ def run(options)
34
+ server = ::Thin::Server.new(options[:Host], options[:Port]) do
35
+ use Rack::CommonLogger
36
+ end
37
+ server.backend = ::Thin::Backends::JsTestCoreServer.new(options[:Host], options[:Port])
38
+ server.backend.server = server
39
+ server.start!
40
+ end
41
+
42
+ def root_url
43
+ "http://#{host}:#{port}"
44
+ end
45
+
46
+ def core_path
47
+ JsTestCore.core_path
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,9 @@
1
+ module Thin
2
+ module Backends
3
+ class JsTestCoreServer < TcpServer
4
+ def connect
5
+ @signature = EventMachine.start_server(@host, @port, JsTestCoreConnection, &method(:initialize_connection))
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,8 @@
1
+ module Thin
2
+ class JsTestCoreConnection < ThinRest::Connection
3
+ protected
4
+ def root_resource
5
+ ::JsTestCore::Resources::WebRoot.new(:connection => self, :public_path => ::JsTestCore::Server.public_path)
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,3 @@
1
+ dir = File.dirname(__FILE__)
2
+ require "#{dir}/thin/js_test_core_connection"
3
+ require "#{dir}/thin/backends/js_test_core_server"
@@ -0,0 +1,41 @@
1
+ require "rubygems"
2
+ gem "thin", ">=0.8.0"
3
+ gem "selenium-client"
4
+
5
+ dir = File.dirname(__FILE__)
6
+ $LOAD_PATH.unshift File.expand_path("#{dir}/../vendor/thin-rest/lib")
7
+ require "thin_rest"
8
+
9
+ # This causes errors to be printed to STDOUT.
10
+ Thin::Logging.silent = false
11
+ Thin::Logging.debug = true
12
+
13
+ require "fileutils"
14
+ require "tmpdir"
15
+ require "timeout"
16
+ require "cgi"
17
+ require "net/http"
18
+ require "selenium/client"
19
+ require "optparse"
20
+ require "erector"
21
+
22
+ require "#{dir}/js_test_core/extensions"
23
+ require "#{dir}/js_test_core/thin"
24
+ require "#{dir}/js_test_core/rack"
25
+ require "#{dir}/js_test_core/resources"
26
+ require "#{dir}/js_test_core/representations"
27
+ require "#{dir}/js_test_core/selenium"
28
+
29
+ require "#{dir}/js_test_core/client"
30
+ require "#{dir}/js_test_core/selenium_server_configuration"
31
+ require "#{dir}/js_test_core/server"
32
+ require "#{dir}/js_test_core/rails_server"
33
+
34
+ module JsTestCore
35
+ DEFAULT_HOST = "0.0.0.0"
36
+ DEFAULT_PORT = 8080
37
+
38
+ class << self
39
+ attr_accessor :core_path
40
+ end
41
+ end
@@ -0,0 +1,3 @@
1
+ var Foo = {
2
+ value: true
3
+ }
@@ -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,3 @@
1
+ h1 {
2
+ text-align: center;
3
+ }
@@ -0,0 +1,6 @@
1
+ require("/implementations/foo");
2
+ describe("A passing spec", {
3
+ 'passes': function() {
4
+ value_of(Foo.value).should_be(true);
5
+ }
6
+ })
@@ -0,0 +1,9 @@
1
+ <html>
2
+ <head>
3
+ <title>Custom Dir and Suite</title>
4
+ <script type="text/javascript" src="/specs/custom_dir_and_suite/passing_spec.js" />
5
+ </head>
6
+ <body>
7
+
8
+ </body>
9
+ </html>
@@ -0,0 +1,8 @@
1
+ <html>
2
+ <head>
3
+ <title>Custom Suite</title>
4
+ </head>
5
+ <body>
6
+
7
+ </body>
8
+ </html>
@@ -0,0 +1,5 @@
1
+ describe("A failing spec", {
2
+ 'fails': function() {
3
+ value_of(true).should_be(false);
4
+ }
5
+ })
@@ -0,0 +1,6 @@
1
+ require("/implementations/foo");
2
+ describe("A failing spec in foo", {
3
+ 'fails': function() {
4
+ value_of(Foo.value).should_be(false);
5
+ }
6
+ })
@@ -0,0 +1,6 @@
1
+ require("/implementations/foo");
2
+ describe("A passing spec", {
3
+ 'passes': function() {
4
+ value_of(Foo.value).should_be(true);
5
+ }
6
+ })
@@ -0,0 +1,2 @@
1
+ dir = File.dirname(__FILE__)
2
+ raise "Failure" unless system(%Q|ruby #{dir}/unit_suite.rb|)
File without changes
@@ -0,0 +1,192 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../unit_spec_helper")
2
+
3
+ module JsTestCore
4
+ describe Client do
5
+ describe '.run' 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
26
+ before do
27
+ mock_post_to_runner("*firefox")
28
+ mock_polling_returns([running_status, running_status, success_status])
29
+ end
30
+
31
+ it "reports success" do
32
+ Client.run
33
+ stdout.string.strip.should == "SUCCESS"
34
+ end
35
+
36
+ it "returns true" do
37
+ Client.run.should be_true
38
+ end
39
+ end
40
+
41
+ context "when the Session run ends in 'failure'" do
42
+ attr_reader :failure_reason
43
+ before do
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)
53
+ end
54
+
55
+ it "returns false" do
56
+ Client.run.should be_false
57
+ end
58
+
59
+ it "reports the reason for failure"
60
+ end
61
+
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("/sessions/my_session_id") do
66
+ stub(session_response = Object.new).code {"404"}
67
+ session_response
68
+ end
69
+ lambda {Client.run}.should raise_error(Client::SessionNotFound)
70
+ end
71
+ end
72
+
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)
78
+ end
79
+ end
80
+
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)
87
+ end
88
+ end
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("/runners", "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("/sessions/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::Session::RUNNING}"
116
+ end
117
+
118
+ def success_status
119
+ "status=#{Resources::Session::SUCCESSFUL_COMPLETION}"
120
+ end
121
+
122
+ def failure_status(reason)
123
+ "status=#{Resources::Session::FAILURE_COMPLETION}&reason=#{reason}"
124
+ end
125
+ end
126
+
127
+ describe ".run_argv" do
128
+ attr_reader :request, :response
129
+ before do
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])
138
+ end
139
+ end
140
+
141
+ context "when passed-in Hash contains :spec_url" do
142
+ it "passes the spec_url as a post parameter" do
143
+ spec_url = 'http://foobar.com/foo'
144
+ mock(Client).run(:spec_url => spec_url)
145
+ client = Client.run_argv(['--spec_url', spec_url])
146
+ end
147
+ end
148
+
149
+ context "when passed-in Hash contains :selenium_host" do
150
+ it "passes the selenium_host as a post parameter" do
151
+ selenium_host = 'test-runner'
152
+ mock(Client).run(:selenium_host => selenium_host)
153
+ client = Client.run_argv(['--selenium_host', selenium_host])
154
+ end
155
+ end
156
+
157
+ context "when passed-in Hash contains :selenium_port" do
158
+ it "passes the selenium_port as a post parameter" do
159
+ selenium_port = "5000"
160
+ mock(Client).run(:selenium_port => selenium_port)
161
+ client = Client.run_argv(['--selenium_port', selenium_port])
162
+ end
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
190
+ end
191
+ end
192
+ end