js-test-server 0.2.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 (64) hide show
  1. data/CHANGES +31 -0
  2. data/Gemfile +17 -0
  3. data/README.markdown +9 -0
  4. data/Rakefile +63 -0
  5. data/bin/jasmine-server +9 -0
  6. data/bin/js-test-client +8 -0
  7. data/bin/js-test-server +9 -0
  8. data/bin/screw-unit-server +9 -0
  9. data/lib/js_test_server.rb +29 -0
  10. data/lib/js_test_server/client.rb +23 -0
  11. data/lib/js_test_server/client/runner.rb +129 -0
  12. data/lib/js_test_server/configuration.rb +69 -0
  13. data/lib/js_test_server/server.rb +14 -0
  14. data/lib/js_test_server/server/app.rb +10 -0
  15. data/lib/js_test_server/server/representations.rb +12 -0
  16. data/lib/js_test_server/server/representations/dir.html.rb +22 -0
  17. data/lib/js_test_server/server/representations/frameworks.rb +3 -0
  18. data/lib/js_test_server/server/representations/not_found.html.rb +13 -0
  19. data/lib/js_test_server/server/representations/page.html.rb +32 -0
  20. data/lib/js_test_server/server/representations/remote_control_subscriber.rb +17 -0
  21. data/lib/js_test_server/server/representations/suite.html.rb +54 -0
  22. data/lib/js_test_server/server/representations/suites.rb +6 -0
  23. data/lib/js_test_server/server/representations/suites/jasmine.html.rb +32 -0
  24. data/lib/js_test_server/server/representations/suites/screw_unit.html.rb +45 -0
  25. data/lib/js_test_server/server/resources.rb +14 -0
  26. data/lib/js_test_server/server/resources/file.rb +58 -0
  27. data/lib/js_test_server/server/resources/framework_file.rb +15 -0
  28. data/lib/js_test_server/server/resources/implementations_deprecation.rb +8 -0
  29. data/lib/js_test_server/server/resources/not_found.rb +25 -0
  30. data/lib/js_test_server/server/resources/remote_control.rb +80 -0
  31. data/lib/js_test_server/server/resources/resource.rb +12 -0
  32. data/lib/js_test_server/server/resources/spec_file.rb +47 -0
  33. data/lib/js_test_server/server/resources/web_root.rb +17 -0
  34. data/lib/js_test_server/server/runner.rb +62 -0
  35. data/scratch.rb +8 -0
  36. data/spec/frameworks/jasmine/cruise_config.rb +21 -0
  37. data/spec/frameworks/jasmine/spec/jasmine_helper.rb +44 -0
  38. data/spec/frameworks/jasmine/spec/jasmine_spec.rb +31 -0
  39. data/spec/functional/functional_spec_helper.rb +55 -0
  40. data/spec/functional/functional_spec_server_starter.rb +69 -0
  41. data/spec/functional/jasmine/jasmine_functional_spec.rb +27 -0
  42. data/spec/functional/screw-unit/screw_unit_functional_spec.rb +27 -0
  43. data/spec/functional_suite.rb +16 -0
  44. data/spec/spec_helpers/be_http.rb +32 -0
  45. data/spec/spec_helpers/example_group.rb +41 -0
  46. data/spec/spec_helpers/fake_deferrable.rb +3 -0
  47. data/spec/spec_helpers/fake_selenium_driver.rb +16 -0
  48. data/spec/spec_helpers/mock_session.rb +30 -0
  49. data/spec/spec_helpers/show_test_exceptions.rb +22 -0
  50. data/spec/spec_helpers/wait_for.rb +11 -0
  51. data/spec/spec_suite.rb +3 -0
  52. data/spec/unit/js_test_core/client/runner_spec.rb +198 -0
  53. data/spec/unit/js_test_core/configuration_spec.rb +44 -0
  54. data/spec/unit/js_test_core/resources/file_spec.rb +79 -0
  55. data/spec/unit/js_test_core/resources/framework_file_spec.rb +58 -0
  56. data/spec/unit/js_test_core/resources/implementations_deprecation_spec.rb +16 -0
  57. data/spec/unit/js_test_core/resources/not_found_spec.rb +49 -0
  58. data/spec/unit/js_test_core/resources/remote_control_spec.rb +117 -0
  59. data/spec/unit/js_test_core/resources/spec_file_spec.rb +147 -0
  60. data/spec/unit/js_test_core/resources/web_root_spec.rb +26 -0
  61. data/spec/unit/js_test_core/server/server_spec.rb +67 -0
  62. data/spec/unit/unit_spec_helper.rb +34 -0
  63. data/spec/unit_suite.rb +10 -0
  64. metadata +220 -0
@@ -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,41 @@
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
+ include WaitFor
19
+ attr_reader :framework_path, :spec_path, :root_path, :server, :connection
20
+ before(:all) do
21
+ dir = File.dirname(__FILE__)
22
+ @framework_path = File.expand_path("#{LIBRARY_ROOT_DIR}/spec/example_framework")
23
+ @spec_path = File.expand_path("#{LIBRARY_ROOT_DIR}/spec/example_spec")
24
+ @root_path = File.expand_path("#{LIBRARY_ROOT_DIR}/spec/example_root")
25
+ stub(Thread).start.yields
26
+ end
27
+
28
+ before(:each) do
29
+ JsTestServer::Configuration.instance.spec_path = spec_path
30
+ JsTestServer::Configuration.instance.root_path = root_path
31
+ JsTestServer::Configuration.instance.framework_path = framework_path
32
+ end
33
+
34
+ after(:each) do
35
+ JsTestServer::Server::Resources::RemoteControl.queue = nil
36
+ end
37
+
38
+ def app
39
+ Sinatra::Application
40
+ end
41
+ end
@@ -0,0 +1,3 @@
1
+ class FakeDeferrable
2
+ include EventMachine::Deferrable
3
+ end
@@ -0,0 +1,16 @@
1
+ class FakeSeleniumDriver
2
+ def initialize
3
+ end
4
+
5
+ def start
6
+ end
7
+
8
+ def get_eval(js)
9
+ end
10
+
11
+ def stop
12
+ end
13
+
14
+ def open(url)
15
+ end
16
+ end
@@ -0,0 +1,30 @@
1
+ class Rack::MockSession
2
+ attr_writer :last_response
3
+
4
+ def last_response
5
+ @last_response
6
+ end
7
+ end
8
+
9
+ class Rack::Test::Session
10
+ class << self
11
+ def http_action_with_async_catch(method_name)
12
+ alias_method "#{method_name}_without_async_catch", method_name
13
+ class_eval((<<-RUBY), __FILE__, __LINE__)
14
+ def #{method_name}_with_async_catch(*args, &block)
15
+ catch(:async) {return #{method_name}_without_async_catch(*args, &block)}
16
+ nil
17
+ end
18
+ RUBY
19
+ alias_method method_name, "#{method_name}_with_async_catch"
20
+ end
21
+ end
22
+
23
+ def_delegators :@rack_mock_session, :last_response=
24
+
25
+ http_action_with_async_catch :get
26
+ http_action_with_async_catch :put
27
+ http_action_with_async_catch :post
28
+ http_action_with_async_catch :delete
29
+ end
30
+
@@ -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
@@ -0,0 +1,11 @@
1
+ module WaitFor
2
+ extend self
3
+ def wait_for(time=5)
4
+ Timeout.timeout(time) do
5
+ loop do
6
+ value = yield
7
+ return value if value
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ dir = File.dirname(__FILE__)
2
+ raise "Unit Suite Failure" unless system(%Q|ruby #{dir}/unit_suite.rb|)
3
+ raise "Functional Suite Failure" unless system(%Q|ruby #{dir}/functional_suite.rb|)
@@ -0,0 +1,198 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../unit_spec_helper")
2
+
3
+ module JsTestServer
4
+ module Client
5
+ describe Runner do
6
+ describe '.run' do
7
+ attr_reader :stdout, :request
8
+ before do
9
+ @stdout = StringIO.new
10
+ Runner.const_set(:STDOUT, stdout)
11
+ stub.instance_of(Runner).sleep
12
+ end
13
+
14
+ after do
15
+ Runner.__send__(:remove_const, :STDOUT)
16
+ end
17
+
18
+ describe "#start" do
19
+ attr_reader :driver, :browser_host, :spec_url, :selenium_browser_start_command, :selenium_host, :selenium_port
20
+
21
+ context "with default runner parameters" do
22
+ before do
23
+ @driver = FakeSeleniumDriver.new
24
+
25
+ expected_selenium_client_params = {
26
+ :host => "0.0.0.0", :port => 4444, :browser => "*firefox", :url => "http://localhost:8080"
27
+ }
28
+
29
+ mock.proxy(Selenium::Client::Driver).new(expected_selenium_client_params) do
30
+ driver
31
+ end
32
+ end
33
+
34
+ context "when the suite fails" do
35
+ it "returns false" do
36
+ mock.proxy(driver).start.ordered
37
+ mock.proxy(driver).open("/specs").ordered
38
+
39
+ mock.strong(driver).get_eval("window.JsTestServer.status()") do
40
+ {"runner_state" => RUNNING_RUNNER_STATE, "console" => ""}.to_json
41
+ end
42
+
43
+ mock.strong(driver).get_eval("window.JsTestServer.status()") do
44
+ {"runner_state" => RUNNING_RUNNER_STATE, "console" => ".."}.to_json
45
+ end
46
+
47
+ mock.strong(driver).get_eval("window.JsTestServer.status()") do
48
+ {"runner_state" => RUNNING_RUNNER_STATE, "console" => "...F."}.to_json
49
+ end
50
+
51
+ mock.strong(driver).get_eval("window.JsTestServer.status()") do
52
+ {"runner_state" => FAILED_RUNNER_STATE, "console" => "...F..\n\nFailure\n/specs/foo_spec.js"}.to_json
53
+ end
54
+
55
+ Runner.run.should be_false
56
+ end
57
+ end
58
+
59
+ context "when the suite passes" do
60
+ it "returns true" do
61
+ mock.proxy(driver).start.ordered
62
+ mock.proxy(driver).open("/specs").ordered
63
+
64
+ mock.strong(driver).get_eval("window.JsTestServer.status()") do
65
+ {"runner_state" => RUNNING_RUNNER_STATE, "console" => ""}.to_json
66
+ end
67
+
68
+ mock.strong(driver).get_eval("window.JsTestServer.status()") do
69
+ {"runner_state" => RUNNING_RUNNER_STATE, "console" => ".."}.to_json
70
+ end
71
+
72
+ mock.strong(driver).get_eval("window.JsTestServer.status()") do
73
+ {"runner_state" => RUNNING_RUNNER_STATE, "console" => "....."}.to_json
74
+ end
75
+
76
+ mock.strong(driver).get_eval("window.JsTestServer.status()") do
77
+ {"runner_state" => PASSED_RUNNER_STATE, "console" => "......\n\nPassed"}.to_json
78
+ end
79
+
80
+ Runner.run.should be_true
81
+ end
82
+ end
83
+ end
84
+
85
+ describe "with overridden runner parameters" do
86
+ it "allows overrides for :host, :port, :browser, and :url" do
87
+ driver = FakeSeleniumDriver.new
88
+
89
+ host = "myhost"
90
+ port = 9999
91
+ browser = "*iexplore"
92
+ spec_url = "http://myspechost:7777/specs/path"
93
+ expected_selenium_client_params = {
94
+ :host => host, :port => port, :browser => browser, :url => "http://myspechost:7777"
95
+ }
96
+ mock.proxy(Selenium::Client::Driver).new(expected_selenium_client_params) do
97
+ driver
98
+ end
99
+
100
+ mock.proxy(driver).start.ordered
101
+ mock.proxy(driver).open("/specs/path").ordered
102
+
103
+ mock.strong(driver).get_eval("window.JsTestServer.status()") do
104
+ {"runner_state" => RUNNING_RUNNER_STATE, "console" => ""}.to_json
105
+ end
106
+
107
+ mock.strong(driver).get_eval("window.JsTestServer.status()") do
108
+ {"runner_state" => RUNNING_RUNNER_STATE, "console" => ".."}.to_json
109
+ end
110
+
111
+ mock.strong(driver).get_eval("window.JsTestServer.status()") do
112
+ {"runner_state" => RUNNING_RUNNER_STATE, "console" => "....."}.to_json
113
+ end
114
+
115
+ mock.strong(driver).get_eval("window.JsTestServer.status()") do
116
+ {"runner_state" => PASSED_RUNNER_STATE, "console" => "......\n\nPassed"}.to_json
117
+ end
118
+
119
+ Runner.run(:selenium_host => host, :selenium_port => port, :selenium_browser => browser, :spec_url => spec_url).
120
+ should be_true
121
+ end
122
+ end
123
+ end
124
+ end
125
+
126
+ describe ".run_argv" do
127
+ attr_reader :request, :response
128
+ before do
129
+ stub(Runner).puts
130
+ end
131
+
132
+ context "when passed-in Hash contains :selenium_browser" do
133
+ it "passes the spec_url as a post parameter" do
134
+ selenium_browser = '*iexplore'
135
+ mock(Runner).run(satisfy do |params|
136
+ default_params.merge(:selenium_browser => selenium_browser).
137
+ to_set.subset?(params.to_set)
138
+ end)
139
+ client = Runner.run_argv(['--selenium-browser', selenium_browser])
140
+ end
141
+ end
142
+
143
+ context "when passed-in Hash contains :spec_url" do
144
+ it "passes the spec_url as a post parameter" do
145
+ spec_url = 'http://foobar.com/foo'
146
+ mock(Runner).run(satisfy do |params|
147
+ default_params.merge(:spec_url => spec_url).
148
+ to_set.subset?(params.to_set)
149
+ end)
150
+ client = Runner.run_argv(['--spec-url', spec_url])
151
+ end
152
+ end
153
+
154
+ context "when passed-in Hash contains :selenium_host" do
155
+ it "passes the selenium_host as a post parameter" do
156
+ selenium_host = 'test-runner'
157
+ mock(Runner).run(satisfy do |params|
158
+ default_params.merge(:selenium_host => selenium_host).
159
+ to_set.subset?(params.to_set)
160
+ end)
161
+ client = Runner.run_argv(['--selenium-host', selenium_host])
162
+ end
163
+ end
164
+
165
+ context "when passed-in Hash contains :selenium_port" do
166
+ it "passes the selenium_port as a post parameter" do
167
+ selenium_port = 5000
168
+ mock(Runner).run(satisfy do |params|
169
+ default_params.merge(:selenium_port => selenium_port).
170
+ to_set.subset?(params.to_set)
171
+ end)
172
+ client = Runner.run_argv(['--selenium-port', selenium_port.to_s])
173
+ end
174
+ end
175
+
176
+ context "when passed-in Hash contains :timeout" do
177
+ it "passes the timeout as a post parameter" do
178
+ mock(Runner).run(satisfy do |params|
179
+ default_params.merge(:timeout => 5).
180
+ to_set.subset?(params.to_set)
181
+ end)
182
+ client = Runner.run_argv(['--timeout', "5"])
183
+ end
184
+ end
185
+
186
+ def default_params
187
+ {
188
+ :selenium_browser => "*firefox",
189
+ :selenium_host => "0.0.0.0",
190
+ :selenium_port => 4444,
191
+ :spec_url => "http://localhost:8080/specs",
192
+ :timeout => 60
193
+ }
194
+ end
195
+ end
196
+ end
197
+ end
198
+ end
@@ -0,0 +1,44 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../unit_spec_helper")
2
+
3
+ module JsTestServer
4
+ describe Configuration do
5
+ attr_reader :result
6
+
7
+ before do
8
+ @result = ""
9
+ end
10
+
11
+ describe "#spec_path" do
12
+ it "returns the Dir " do
13
+ Configuration.spec_path.should == spec_path
14
+ end
15
+ end
16
+
17
+ describe "#spec_path" do
18
+ it "returns the absolute path of the specs root directory" do
19
+ Configuration.spec_path.should == spec_path
20
+ end
21
+ end
22
+
23
+ describe "#root_path" do
24
+ it "returns the expanded path of the public path" do
25
+ Configuration.root_path.should == root_path
26
+ end
27
+ end
28
+
29
+ describe "#framework_path" do
30
+ it "returns the expanded path to the JsTestServer core directory" do
31
+ Configuration.framework_path.should == framework_path
32
+ end
33
+ end
34
+
35
+ describe "#root_url" do
36
+ it "returns the url of the site's root" do
37
+ configuration = Configuration.new
38
+ configuration.host = "localhost"
39
+ configuration.port = 9999
40
+ configuration.root_url.should == "http://localhost:9999"
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,79 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../unit_spec_helper")
2
+
3
+ module JsTestServer::Server::Resources
4
+ describe File do
5
+ describe "Files" do
6
+ describe "GET /stylesheets/example.css" do
7
+ it "returns the example.css file content as a css file" do
8
+ path = "#{root_path}/stylesheets/example.css"
9
+ response = get("/stylesheets/example.css")
10
+ response.should be_http(
11
+ 200,
12
+ {
13
+ 'Content-Length' => ::File.size(path).to_s,
14
+ 'Content-Type' => "text/css",
15
+ 'Last-Modified' => ::File.mtime(path).rfc822
16
+ },
17
+ ::File.read(path)
18
+ )
19
+ end
20
+ end
21
+
22
+ describe "GET /javascripts/foo.js" do
23
+ it "returns the foo.js file content as a javascript file" do
24
+ path = "#{root_path}/javascripts/foo.js"
25
+ response = get("/javascripts/foo.js")
26
+ response.should be_http(
27
+ 200,
28
+ {
29
+ 'Content-Length' => ::File.size(path).to_s,
30
+ 'Content-Type' => "text/javascript",
31
+ 'Last-Modified' => ::File.mtime(path).rfc822
32
+ },
33
+ ::File.read(path)
34
+ )
35
+ end
36
+ end
37
+
38
+ describe "GET /javascripts/subdir/bar.js - Subdirectory" do
39
+ it "returns the subdir/bar.js file content as a javascript file" do
40
+ path = "#{root_path}/javascripts/subdir/bar.js"
41
+ response = get("/javascripts/subdir/bar.js")
42
+ response.should be_http(
43
+ 200,
44
+ {
45
+ 'Content-Length' => ::File.size(path).to_s,
46
+ 'Content-Type' => "text/javascript",
47
+ 'Last-Modified' => ::File.mtime(path).rfc822
48
+ },
49
+ ::File.read(path)
50
+ )
51
+ end
52
+ end
53
+ end
54
+
55
+ describe "Directories" do
56
+ describe "GET /stylesheets - Top level directory" do
57
+ it "returns a page with a of files in the directory" do
58
+ response = get("/stylesheets")
59
+ response.should be_http(
60
+ 200,
61
+ {},
62
+ %r(<a href="/stylesheets/example.css">example.css</a>)
63
+ )
64
+ end
65
+ end
66
+
67
+ describe "GET /javascripts/subdir - Subdirectory" do
68
+ it "returns a page with a of files in the directory" do
69
+ response = get("/javascripts/subdir")
70
+ response.should be_http(
71
+ 200,
72
+ {},
73
+ %r(<a href="/javascripts/subdir/bar.js">bar.js</a>)
74
+ )
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end