js_test_core 0.1.1 → 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 (48) hide show
  1. data/CHANGES +11 -0
  2. data/Rakefile +1 -1
  3. data/lib/js_test_core.rb +10 -2
  4. data/lib/js_test_core/client.rb +85 -18
  5. data/lib/js_test_core/extensions.rb +3 -0
  6. data/lib/js_test_core/extensions/time.rb +6 -0
  7. data/lib/js_test_core/resources.rb +4 -4
  8. data/lib/js_test_core/resources/dir.rb +22 -7
  9. data/lib/js_test_core/resources/file.rb +24 -16
  10. data/lib/js_test_core/resources/file_not_found.rb +11 -0
  11. data/lib/js_test_core/resources/runner.rb +107 -0
  12. data/lib/js_test_core/resources/session.rb +44 -0
  13. data/lib/js_test_core/resources/session_finish.rb +17 -0
  14. data/lib/js_test_core/resources/specs/spec_dir.rb +10 -14
  15. data/lib/js_test_core/resources/specs/spec_file.rb +1 -1
  16. data/lib/js_test_core/resources/web_root.rb +51 -39
  17. data/lib/js_test_core/selenium_server_configuration.rb +48 -0
  18. data/lib/js_test_core/server.rb +3 -64
  19. data/lib/js_test_core/thin/js_test_core_connection.rb +4 -38
  20. data/spec/unit/js_test_core/client_spec.rb +167 -0
  21. data/spec/unit/{js_spec → js_test_core}/rails_server_spec.rb +0 -0
  22. data/spec/unit/js_test_core/resources/dir_spec.rb +52 -0
  23. data/spec/unit/js_test_core/resources/file_not_found_spec.rb +16 -0
  24. data/spec/unit/js_test_core/resources/file_spec.rb +90 -0
  25. data/spec/unit/js_test_core/resources/runners/runner_spec.rb +303 -0
  26. data/spec/unit/js_test_core/resources/session_finish_spec.rb +79 -0
  27. data/spec/unit/js_test_core/resources/session_spec.rb +82 -0
  28. data/spec/unit/js_test_core/resources/specs/spec_dir_spec.rb +105 -0
  29. data/spec/unit/{js_spec → js_test_core}/resources/specs/spec_file_spec.rb +5 -5
  30. data/spec/unit/js_test_core/resources/web_root_spec.rb +32 -0
  31. data/spec/unit/js_test_core/selenium_server_configuration_spec.rb +49 -0
  32. data/spec/unit/{js_spec → js_test_core}/server_spec.rb +18 -32
  33. data/spec/unit/thin/js_test_core_connection_spec.rb +0 -86
  34. data/spec/unit/unit_spec_helper.rb +58 -22
  35. metadata +39 -33
  36. data/lib/js_test_core/resources/runners.rb +0 -15
  37. data/lib/js_test_core/resources/runners/firefox_runner.rb +0 -73
  38. data/lib/js_test_core/resources/suite.rb +0 -24
  39. data/lib/js_test_core/resources/suite_finish.rb +0 -19
  40. data/spec/unit/js_spec/client_spec.rb +0 -137
  41. data/spec/unit/js_spec/resources/dir_spec.rb +0 -42
  42. data/spec/unit/js_spec/resources/file_spec.rb +0 -88
  43. data/spec/unit/js_spec/resources/runner_spec.rb +0 -24
  44. data/spec/unit/js_spec/resources/runners/firefox_runner_spec.rb +0 -161
  45. data/spec/unit/js_spec/resources/specs/spec_dir_spec.rb +0 -79
  46. data/spec/unit/js_spec/resources/suite_finish_spec.rb +0 -94
  47. data/spec/unit/js_spec/resources/suite_spec.rb +0 -44
  48. data/spec/unit/js_spec/resources/web_root_spec.rb +0 -67
@@ -0,0 +1,79 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../unit_spec_helper")
2
+
3
+ module JsTestCore
4
+ module Resources
5
+ describe SessionFinish do
6
+ attr_reader :stdout
7
+ before do
8
+ @stdout = StringIO.new
9
+ SessionFinish.const_set(:STDOUT, stdout)
10
+ end
11
+
12
+ after do
13
+ SessionFinish.__send__(:remove_const, :STDOUT)
14
+ end
15
+
16
+
17
+ describe "POST /session/finish" do
18
+ context "when session_id cookie is not set" do
19
+ it "writes the body of the request to stdout" do
20
+ stub(connection).send_head
21
+ stub(connection).send_body
22
+
23
+ text = "The text in the POST body"
24
+ body = "text=#{text}"
25
+ connection.receive_data("POST /session/finish HTTP/1.1\r\nHost: _\r\nContent-Length: #{body.length}\r\n\r\n#{body}")
26
+ stdout.string.should == "#{text}\n"
27
+ end
28
+
29
+ it "sends an empty body" do
30
+ text = "The text in the POST body"
31
+ body = "text=#{text}"
32
+
33
+ mock(connection).send_head
34
+ mock(connection).send_body("")
35
+ connection.receive_data("POST /session/finish HTTP/1.1\r\nHost: _\r\nContent-Length: #{body.length}\r\n\r\n#{body}")
36
+ end
37
+ end
38
+
39
+ context "when session_id cookie is set'" do
40
+ attr_reader :session_id, :driver
41
+ before do
42
+ @session_id = FakeSeleniumDriver::SESSION_ID
43
+ @driver = FakeSeleniumDriver.new
44
+ stub(Selenium::SeleniumDriver).new('localhost', 4444, '*firefox', 'http://0.0.0.0:8080') do
45
+ driver
46
+ end
47
+
48
+ firefox_connection = Thin::JsTestCoreConnection.new(Guid.new)
49
+ stub(firefox_connection).send_head
50
+ stub(firefox_connection).send_body
51
+ stub(firefox_connection).close_connection
52
+ firefox_connection.receive_data("POST /runners/firefox HTTP/1.1\r\nHost: _\r\n\r\n")
53
+ end
54
+
55
+ it "calls Runner.finalize" do
56
+ text = "The text in the POST body"
57
+ body = "text=#{text}"
58
+ stub(connection).send_head
59
+ stub(connection).send_body
60
+ mock.proxy(Runner).finalize(session_id.to_s, text)
61
+ mock(driver).stop
62
+ stub(connection).close_connection
63
+
64
+ connection.receive_data("POST /session/finish HTTP/1.1\r\nCookie: session_id=#{session_id}\r\nHost: _\r\nContent-Length: #{body.length}\r\n\r\n#{body}")
65
+ end
66
+
67
+ it "responds with a blank body" do
68
+ stub(driver).stop
69
+ stub(connection).close_connection
70
+
71
+ mock(connection).send_head
72
+ mock(connection).send_body("")
73
+ connection.receive_data("POST /session/finish HTTP/1.1\r\nCookie: session_id=#{session_id}\r\nHost: _\r\nContent-Length: 0\r\n\r\n")
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,82 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../unit_spec_helper")
2
+
3
+ module JsTestCore
4
+ module Resources
5
+ describe Session do
6
+ describe "GET /sessions/:session_id" do
7
+ attr_reader :driver, :session_id
8
+
9
+ context "when there is no Runner with the :session_id" do
10
+ it "responds with a 404" do
11
+ session_id = "invalid_session_id"
12
+ Runner.find(session_id).should be_nil
13
+
14
+ mock(connection).send_head(404)
15
+ mock(connection).send_body("")
16
+
17
+ connection.receive_data("GET /sessions/#{session_id} HTTP/1.1\r\nHost: _\r\n\r\n")
18
+ end
19
+ end
20
+
21
+ context "when there is a Runner with the :session_id" do
22
+ attr_reader :session_runner
23
+ before do
24
+ @driver = FakeSeleniumDriver.new
25
+ @session_id = FakeSeleniumDriver::SESSION_ID
26
+ stub(Selenium::SeleniumDriver).new('localhost', 4444, '*firefox', 'http://0.0.0.0:8080') do
27
+ driver
28
+ end
29
+
30
+ connection_that_starts_firefox = create_connection
31
+ stub(connection_that_starts_firefox).send_head
32
+ stub(connection_that_starts_firefox).send_body
33
+ connection_that_starts_firefox.receive_data("POST /runners/firefox HTTP/1.1\r\nHost: _\r\nContent-Length: 0\r\n\r\n")
34
+ @session_runner = Runner.find(session_id)
35
+ session_runner.should be_running
36
+ end
37
+
38
+ context "when a Runner with the :session_id is running" do
39
+ it "responds with a 200 and status=running" do
40
+ mock(connection).send_head
41
+ mock(connection).send_body("status=#{Resources::Session::RUNNING}")
42
+
43
+ connection.receive_data("GET /sessions/#{session_id} HTTP/1.1\r\nHost: _\r\n\r\n")
44
+ end
45
+ end
46
+
47
+ context "when a Runner with the :session_id has completed" do
48
+ context "when the session has a status of 'success'" do
49
+ before do
50
+ session_runner.finalize("")
51
+ session_runner.should be_successful
52
+ end
53
+
54
+ it "responds with a 200 and status=success" do
55
+ mock(connection).send_head
56
+ mock(connection).send_body("status=#{Resources::Session::SUCCESSFUL_COMPLETION}")
57
+
58
+ connection.receive_data("GET /sessions/#{session_id} HTTP/1.1\r\nHost: _\r\n\r\n")
59
+ end
60
+ end
61
+
62
+ context "when the session has a status of 'failure'" do
63
+ attr_reader :reason
64
+ before do
65
+ @reason = "Failure stuff"
66
+ session_runner.finalize(reason)
67
+ session_runner.should be_failed
68
+ end
69
+
70
+ it "responds with a 200 and status=failure and reason" do
71
+ mock(connection).send_head
72
+ mock(connection).send_body("status=#{Resources::Session::FAILURE_COMPLETION}&reason=#{reason}")
73
+
74
+ connection.receive_data("GET /sessions/#{session_id} HTTP/1.1\r\nHost: _\r\n\r\n")
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,105 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../../unit_spec_helper")
2
+
3
+ module JsTestCore
4
+ module Resources
5
+ module Specs
6
+ describe SpecDir do
7
+ attr_reader :dir, :absolute_path, :relative_path
8
+ before do
9
+ @absolute_path = spec_root_path
10
+ @relative_path = "/specs"
11
+ @dir = Resources::Specs::SpecDir.new(:connection => connection, :absolute_path => absolute_path, :relative_path => relative_path)
12
+ end
13
+
14
+ describe "#locate" do
15
+ context "when passed the name with an extension" do
16
+ context "when file exists" do
17
+ it "returns a Resources::File representing it" do
18
+ file = dir.locate("failing_spec.js")
19
+ file.relative_path.should == "/specs/failing_spec.js"
20
+ file.absolute_path.should == "#{spec_root_path}/failing_spec.js"
21
+ end
22
+ end
23
+
24
+ context "when file does not exist" do
25
+ it "raises error" do
26
+ lambda { dir.locate("nonexistent.js") }.should raise_error
27
+ end
28
+ end
29
+ end
30
+
31
+ context "when passed a name without an extension" do
32
+ context "when name corresponds to a subdirectory" do
33
+ it "returns a DirectoryRunner for the directory" do
34
+ subdir = dir.locate("foo")
35
+ subdir.should == spec_dir("/foo")
36
+ end
37
+ end
38
+
39
+ context "when name corresponds to a .js file" do
40
+ it "returns a SpecFile for the .js file" do
41
+ spec_file_name = "failing_spec"
42
+ subdir = dir.locate(spec_file_name)
43
+ subdir.should == JsTestCore::Resources::Specs::SpecFile.new(
44
+ :connection => connection,
45
+ :absolute_path => "#{spec_root_path}/#{spec_file_name}.js",
46
+ :relative_path => "/specs/#{spec_file_name}.js"
47
+ )
48
+ end
49
+ end
50
+
51
+ context "when name does not correspond to a .js file or directory" do
52
+ it "raises an error" do
53
+ lambda do
54
+ dir.locate("nonexistent")
55
+ end.should raise_error
56
+ end
57
+ end
58
+ end
59
+ end
60
+
61
+ describe "#get" do
62
+ attr_reader :request, :response
63
+ before do
64
+ @request = Rack::Request.new( Rack::MockRequest.env_for('/core') )
65
+ @response = Rack::Response.new
66
+ end
67
+
68
+ it "raises NotImplementedError" do
69
+ lambda do
70
+ dir.get
71
+ end.should raise_error(NotImplementedError)
72
+ end
73
+
74
+ it "can be overridden from a Module without needing to redefine the #get method" do
75
+ spec_dir_class = Resources::Specs::SpecDir.clone
76
+ mod = Module.new do
77
+ def get
78
+ end
79
+ end
80
+ spec_dir_class.class_eval do
81
+ include mod
82
+ end
83
+ @dir = spec_dir_class.new(:connection => connection, :absolute_path => absolute_path, :relative_path => relative_path)
84
+
85
+ lambda do
86
+ dir.get
87
+ end.should_not raise_error
88
+ end
89
+ end
90
+
91
+ describe "GET /" do
92
+ context "when WebRoot.dispatch_specs has been invoked" do
93
+ it "renders a home page" do
94
+ WebRoot.dispatch_specs
95
+ mock(connection).send_head(200, :Location => '/specs')
96
+ mock(connection).send_body(is_a(String))
97
+
98
+ connection.receive_data("GET / HTTP/1.1\r\nHost: _\r\n\r\n")
99
+ end
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
@@ -8,7 +8,7 @@ module JsTestCore
8
8
  before do
9
9
  @absolute_path = "#{spec_root_path}/failing_spec.js"
10
10
  @relative_path = "/specs/failing_spec.js"
11
- @file = Resources::Specs::SpecFile.new(absolute_path, relative_path)
11
+ @file = Resources::Specs::SpecFile.new(:connection => connection, :absolute_path => absolute_path, :relative_path => relative_path)
12
12
  @request = Rack::Request.new( Rack::MockRequest.env_for(relative_path) )
13
13
  @response = Rack::Response.new
14
14
  end
@@ -16,23 +16,23 @@ module JsTestCore
16
16
  describe "#get" do
17
17
  it "raises NotImplementedError" do
18
18
  lambda do
19
- file.get(request, response)
19
+ file.get
20
20
  end.should raise_error(NotImplementedError)
21
21
  end
22
22
 
23
23
  it "can be overridden from a Module without needing to redefine the #get method" do
24
24
  spec_file_class = Resources::Specs::SpecFile.clone
25
25
  mod = Module.new do
26
- def get(request, response)
26
+ def get
27
27
  end
28
28
  end
29
29
  spec_file_class.class_eval do
30
30
  include mod
31
31
  end
32
- @file = spec_file_class.new(absolute_path, relative_path)
32
+ @file = spec_file_class.new(:connection => connection, :absolute_path => absolute_path, :relative_path => relative_path)
33
33
 
34
34
  lambda do
35
- file.get(request, response)
35
+ file.get
36
36
  end.should_not raise_error
37
37
  end
38
38
  end
@@ -0,0 +1,32 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../unit_spec_helper")
2
+
3
+ module JsTestCore
4
+ module Resources
5
+ describe WebRoot do
6
+ attr_reader :web_root
7
+ before(:each) do
8
+ @web_root = WebRoot.new(:connection => connection, :public_path => public_path)
9
+ end
10
+
11
+ describe "GET /stylesheets" do
12
+ it "returns a page with a of files in the directory" do
13
+ mock(connection).send_head()
14
+ mock(connection).send_body(Regexp.new('<a href="example.css">example.css</a>'))
15
+
16
+ connection.receive_data("GET /stylesheets HTTP/1.1\r\nHost: _\r\n\r\n")
17
+ end
18
+ end
19
+
20
+ describe "GET /stylesheets/example.css" do
21
+ it "returns a page with a of files in the directory" do
22
+ path = "#{public_path}/stylesheets/example.css"
23
+ mock(connection).send_head(200, 'Content-Type' => "text/css", 'Content-Length' => ::File.size(path), 'Last-Modified' => ::File.mtime(path).rfc822)
24
+ mock(connection).send_data(::File.read(path))
25
+ stub(EventMachine).close_connection
26
+
27
+ connection.receive_data("GET /stylesheets/example.css HTTP/1.1\r\nHost: _\r\n\r\n")
28
+ end
29
+ end
30
+ end
31
+ end
32
+ 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
@@ -12,24 +12,6 @@ module JsTestCore
12
12
  stub(EventMachine).close_connection
13
13
  end
14
14
 
15
- describe "HTTP GET" do
16
- specify "'/core/JsTestCore.js', returns the contents of the file" do
17
- response = get("/core/JsTestCore.js")
18
- response.body.should == ::File.read("#{Server.core_path}/JsTestCore.js")
19
- end
20
-
21
- specify "'/stylesheets/example.css', returns the contents of the file" do
22
- response = get("/stylesheets/example.css")
23
- response.body.should == ::File.read("#{Server.public_path}/stylesheets/example.css")
24
- end
25
-
26
- specify "'/invalid/path', shows the full invalid path in the error message" do
27
- lambda do
28
- get("/invalid/path")
29
- end.should raise_error(Exception, Regexp.new("/invalid/path"))
30
- end
31
- end
32
-
33
15
  describe ".run" do
34
16
  attr_reader :server_instance
35
17
  before do
@@ -100,24 +82,28 @@ module JsTestCore
100
82
  end
101
83
 
102
84
  it "shows the full request path in the error message" do
103
- lambda do
104
- get('/somedir')
105
- end.should raise_error(Exception, Regexp.new("/somedir"))
85
+ error = nil
86
+ mock(connection).log_error(is_a(Exception)) do |error_arg|
87
+ error = error_arg
88
+ end
89
+
90
+ get('/somedir')
91
+ error.message.should =~ Regexp.new("/somedir")
106
92
  end
107
93
 
108
94
  it "uses the backtrace from where the original error was raised" do
109
- no_error = true
110
- begin
111
- get('/somedir')
112
- rescue Exception => e
113
- no_error = false
114
- top_of_backtrace = e.backtrace.first.split(":")
115
- backtrace_file = ::File.expand_path(top_of_backtrace[0])
116
- backtrace_line = Integer(top_of_backtrace[1])
117
- backtrace_file.should == __FILE__
118
- backtrace_line.should == top_line_of_backtrace
95
+ error = nil
96
+ mock(connection).log_error(is_a(Exception)) do |error_arg|
97
+ error = error_arg
119
98
  end
120
- raise "There should have been an error" if no_error
99
+
100
+ get('/somedir')
101
+ no_error = false
102
+ top_of_backtrace = error.backtrace.first.split(":")
103
+ backtrace_file = ::File.expand_path(top_of_backtrace[0])
104
+ backtrace_line = Integer(top_of_backtrace[1])
105
+ backtrace_file.should == __FILE__
106
+ backtrace_line.should == top_line_of_backtrace
121
107
  end
122
108
  end
123
109
  end