js_test_core 0.1.1 → 0.2.0

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