js-test-server 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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