js_spec 0.3.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. data/CHANGES +3 -0
  2. data/Rakefile +3 -2
  3. data/vendor/js-test-core/CHANGES +15 -0
  4. data/vendor/js-test-core/README +12 -0
  5. data/vendor/js-test-core/Rakefile +72 -0
  6. data/vendor/js-test-core/lib/js_test_core.rb +38 -0
  7. data/vendor/js-test-core/lib/js_test_core/client.rb +114 -0
  8. data/vendor/js-test-core/lib/js_test_core/extensions.rb +3 -0
  9. data/vendor/js-test-core/lib/js_test_core/extensions/time.rb +6 -0
  10. data/vendor/js-test-core/lib/js_test_core/rack.rb +2 -0
  11. data/vendor/js-test-core/lib/js_test_core/rack/commonlogger.rb +5 -0
  12. data/vendor/js-test-core/lib/js_test_core/rails_server.rb +22 -0
  13. data/vendor/js-test-core/lib/js_test_core/resources.rb +10 -0
  14. data/vendor/js-test-core/lib/js_test_core/resources/dir.rb +67 -0
  15. data/vendor/js-test-core/lib/js_test_core/resources/file.rb +40 -0
  16. data/vendor/js-test-core/lib/js_test_core/resources/file_not_found.rb +11 -0
  17. data/vendor/js-test-core/lib/js_test_core/resources/runner.rb +105 -0
  18. data/vendor/js-test-core/lib/js_test_core/resources/specs/spec_dir.rb +46 -0
  19. data/vendor/js-test-core/lib/js_test_core/resources/specs/spec_file.rb +17 -0
  20. data/vendor/js-test-core/lib/js_test_core/resources/suite.rb +40 -0
  21. data/vendor/js-test-core/lib/js_test_core/resources/suite_finish.rb +17 -0
  22. data/vendor/js-test-core/lib/js_test_core/resources/web_root.rb +63 -0
  23. data/vendor/js-test-core/lib/js_test_core/selenium.rb +2 -0
  24. data/vendor/js-test-core/lib/js_test_core/selenium/selenium_driver.rb +5 -0
  25. data/vendor/js-test-core/lib/js_test_core/selenium_server_configuration.rb +48 -0
  26. data/vendor/js-test-core/lib/js_test_core/server.rb +50 -0
  27. data/vendor/js-test-core/lib/js_test_core/thin.rb +3 -0
  28. data/vendor/js-test-core/lib/js_test_core/thin/backends/js_test_core_server.rb +9 -0
  29. data/vendor/js-test-core/lib/js_test_core/thin/js_test_core_connection.rb +8 -0
  30. data/vendor/js-test-core/spec/example_core/JsTestCore.css +0 -0
  31. data/vendor/js-test-core/spec/example_core/JsTestCore.js +0 -0
  32. data/vendor/js-test-core/spec/example_public/favicon.ico +0 -0
  33. data/vendor/js-test-core/spec/example_public/javascripts/foo.js +3 -0
  34. data/vendor/js-test-core/spec/example_public/javascripts/large_file.js +59 -0
  35. data/vendor/js-test-core/spec/example_public/javascripts/subdir/bar.js +1 -0
  36. data/vendor/js-test-core/spec/example_public/robots.txt +0 -0
  37. data/vendor/js-test-core/spec/example_public/stylesheets/example.css +3 -0
  38. data/vendor/js-test-core/spec/example_specs/failing_spec.js +5 -0
  39. data/vendor/js-test-core/spec/example_specs/foo/failing_spec.js +6 -0
  40. data/vendor/js-test-core/spec/example_specs/foo/passing_spec.js +6 -0
  41. data/vendor/js-test-core/spec/spec_suite.rb +2 -0
  42. data/vendor/js-test-core/spec/specs/failing_spec.js +0 -0
  43. data/vendor/js-test-core/spec/unit/js_test_core/client_spec.rb +166 -0
  44. data/vendor/js-test-core/spec/unit/js_test_core/rails_server_spec.rb +45 -0
  45. data/vendor/js-test-core/spec/unit/js_test_core/resources/dir_spec.rb +52 -0
  46. data/vendor/js-test-core/spec/unit/js_test_core/resources/file_not_found_spec.rb +16 -0
  47. data/vendor/js-test-core/spec/unit/js_test_core/resources/file_spec.rb +90 -0
  48. data/vendor/js-test-core/spec/unit/js_test_core/resources/runners/runner_spec.rb +283 -0
  49. data/vendor/js-test-core/spec/unit/js_test_core/resources/specs/spec_dir_spec.rb +105 -0
  50. data/vendor/js-test-core/spec/unit/js_test_core/resources/specs/spec_file_spec.rb +42 -0
  51. data/vendor/js-test-core/spec/unit/js_test_core/resources/suite_finish_spec.rb +82 -0
  52. data/vendor/js-test-core/spec/unit/js_test_core/resources/suite_spec.rb +86 -0
  53. data/vendor/js-test-core/spec/unit/js_test_core/resources/web_root_spec.rb +32 -0
  54. data/vendor/js-test-core/spec/unit/js_test_core/selenium_server_configuration_spec.rb +49 -0
  55. data/vendor/js-test-core/spec/unit/js_test_core/server_spec.rb +117 -0
  56. data/vendor/js-test-core/spec/unit/thin/js_test_core_connection_spec.rb +6 -0
  57. data/vendor/js-test-core/spec/unit/unit_spec_helper.rb +134 -0
  58. data/vendor/js-test-core/spec/unit_suite.rb +10 -0
  59. data/vendor/js-test-core/vendor/thin-rest/CHANGES +2 -0
  60. data/vendor/js-test-core/vendor/thin-rest/README +0 -0
  61. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest.rb +9 -0
  62. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest/connection.rb +116 -0
  63. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest/extensions.rb +3 -0
  64. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest/extensions/object.rb +21 -0
  65. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest/resource.rb +104 -0
  66. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest/resource_invalid.rb +4 -0
  67. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest/routing_error.rb +5 -0
  68. data/vendor/js-test-core/vendor/thin-rest/spec/spec_suite.rb +5 -0
  69. data/vendor/js-test-core/vendor/thin-rest/spec/thin_rest/connection_spec.rb +207 -0
  70. data/vendor/js-test-core/vendor/thin-rest/spec/thin_rest/resource_spec.rb +127 -0
  71. data/vendor/js-test-core/vendor/thin-rest/spec/thin_rest_spec_helper.rb +124 -0
  72. metadata +120 -17
@@ -0,0 +1,9 @@
1
+ require "rubygems"
2
+ require "thin"
3
+
4
+ dir = File.dirname(__FILE__)
5
+ require "#{dir}/thin_rest/connection"
6
+ require "#{dir}/thin_rest/resource"
7
+ require "#{dir}/thin_rest/resource_invalid"
8
+ require "#{dir}/thin_rest/routing_error"
9
+ require "#{dir}/thin_rest/extensions"
@@ -0,0 +1,116 @@
1
+ module ThinRest
2
+ class Connection < Thin::Connection
3
+ attr_reader :resource, :rack_request
4
+
5
+ def process
6
+ guard_against_errors do
7
+ method = rack_request.request_method.downcase.to_sym
8
+ @resource = get_resource
9
+ resource.send(method)
10
+ end
11
+ end
12
+
13
+ def rack_request
14
+ @rack_request ||= Rack::Request.new(@request.env)
15
+ end
16
+
17
+ def send_head(status=200, additional_parameters={})
18
+ send_data(head(status, additional_parameters))
19
+ end
20
+
21
+ def head(status, additional_parameters)
22
+ parameters = {}
23
+ parameters['Connection'] = "close" unless request.persistent?
24
+ parameters.merge!(additional_parameters)
25
+ head_output = parameters.inject("HTTP/1.1 #{status} OK\r\nServer: Thin Rest Server\r\n") do |header, parameter|
26
+ header << "#{parameter[0]}: #{parameter[1]}\r\n"
27
+ end
28
+ if additional_parameters[:'Content-Length'] || additional_parameters['Content-Length']
29
+ head_output << "\r\n"
30
+ end
31
+ head_output
32
+ end
33
+
34
+ def send_body(data)
35
+ terminate_after_sending do
36
+ send_data("Content-Length: #{data.length}\r\n\r\n")
37
+ send_data(data)
38
+ end
39
+ end
40
+
41
+ def terminate_after_sending
42
+ yield
43
+ unless request.persistent?
44
+ close_connection_after_writing
45
+ end
46
+ ensure
47
+ terminate_request
48
+ end
49
+
50
+ def unbind
51
+ super
52
+ resource.unbind if resource
53
+ rescue Exception => e
54
+ handle_error e
55
+ end
56
+
57
+ def terminate_request
58
+ persistent = persistent?
59
+ @resource = nil
60
+ @rack_request = nil
61
+ @request.close rescue nil
62
+ @response.close rescue nil
63
+
64
+ # Prepare the connection for another request if the client
65
+ # supports HTTP pipelining (persistent connection).
66
+ if persistent
67
+ post_init
68
+ end
69
+ end
70
+
71
+ def persistent?
72
+ request.persistent?
73
+ end
74
+
75
+ def handle_error(error)
76
+ log_error error
77
+ close_connection rescue nil
78
+ rescue Exception => unexpected_error
79
+ log_error unexpected_error
80
+ end
81
+
82
+ protected
83
+ def guard_against_errors
84
+ yield
85
+ rescue RoutingError => e
86
+ handle_error e
87
+ rescue Exception => e
88
+ wrapped_error = Exception.new("Error in #{rack_request.path_info} : #{e.message}")
89
+ wrapped_error.set_backtrace(e.backtrace)
90
+ handle_error wrapped_error
91
+ end
92
+
93
+ def get_resource
94
+ path_parts.inject(root_resource) do |resource, child_resource_name|
95
+ resource.locate(child_resource_name)
96
+ end
97
+ end
98
+
99
+ def root_resource
100
+ raise NotImplementedError
101
+ end
102
+
103
+ def path_parts
104
+ rack_request.path_info.split('/').reject { |part| part == "" }
105
+ end
106
+
107
+ def error_message(e)
108
+ output = "Error in Connection#receive_line\n"
109
+ output << "#{e.message}\n"
110
+ output << e.backtrace.join("\n\t")
111
+ output << "\n\nResource was:\n\t"
112
+ output << "#{resource.inspect}\n"
113
+ output
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,3 @@
1
+ Dir["#{File.dirname(__FILE__)}/extensions/*.rb"].each do |file|
2
+ require file
3
+ end
@@ -0,0 +1,21 @@
1
+ # From Mauricio Fernandez.
2
+ class Object
3
+ module InstanceExecHelper; end
4
+ include InstanceExecHelper
5
+ def instance_exec(*args, &block)
6
+ begin
7
+ old_critical, Thread.critical = Thread.critical, true
8
+ n = 0
9
+ n += 1 while respond_to?(mname="__instance_exec#{n}")
10
+ InstanceExecHelper.module_eval{ define_method(mname, &block) }
11
+ ensure
12
+ Thread.critical = old_critical
13
+ end
14
+ begin
15
+ ret = send(mname, *args)
16
+ ensure
17
+ InstanceExecHelper.module_eval{ remove_method(mname) } rescue nil
18
+ end
19
+ ret
20
+ end
21
+ end
@@ -0,0 +1,104 @@
1
+ module ThinRest
2
+ class Resource
3
+ class << self
4
+ def property(*names)
5
+ names.each do |name|
6
+ my_properties << name.to_sym
7
+
8
+ define_method name do
9
+ env[name]
10
+ end
11
+
12
+ define_method "#{name}=" do |new_value|
13
+ env[name] = new_value
14
+ end
15
+ end
16
+ end
17
+
18
+ def properties
19
+ if superclass.respond_to?(:properties)
20
+ superclass.properties | my_properties
21
+ else
22
+ my_properties
23
+ end
24
+ end
25
+
26
+ def route(name, resource_type_name=nil, &block)
27
+ routes[name] = block || lambda do |env, name|
28
+ resource_type = resource_type_name.split('::').inject(Object) do |mod, next_mod_name|
29
+ mod.const_get(next_mod_name)
30
+ end
31
+ resource_type.new(env)
32
+ end
33
+ end
34
+
35
+ def routes
36
+ @routes ||= {}
37
+ end
38
+
39
+ protected
40
+ def my_properties
41
+ @my_properties ||= []
42
+ end
43
+
44
+ def handle_dequeue_and_process_error(command, error)
45
+ if command.connection
46
+ command.connection.handle_error error
47
+ else
48
+ super
49
+ end
50
+ end
51
+ end
52
+ ANY = Object.new
53
+
54
+ property :connection
55
+ attr_reader :env
56
+
57
+ def initialize(env={})
58
+ @env = env
59
+ env.each do |name, value|
60
+ if self.class.properties.include?(name.to_sym)
61
+ instance_variable_set("@#{name}", value)
62
+ end
63
+ end
64
+ after_initialize
65
+ end
66
+
67
+ def request; connection.request; end
68
+ def response; connection.response; end
69
+ def rack_request; connection.rack_request; end
70
+
71
+ def get
72
+ connection.send_head
73
+ connection.send_body(do_get || "")
74
+ end
75
+
76
+ def post
77
+ connection.send_head
78
+ connection.send_body(do_post || "")
79
+ end
80
+
81
+ def put
82
+ connection.send_head
83
+ connection.send_body(do_put || "")
84
+ end
85
+
86
+ def delete
87
+ connection.send_head
88
+ connection.send_body(do_delete || "")
89
+ end
90
+
91
+ def locate(name)
92
+ route_handler = self.class.routes[name] || self.class.routes[ANY]
93
+ raise RoutingError, "Invalid route: #{connection.rack_request.path_info} ; name: #{name}" unless route_handler
94
+ instance_exec(env, name, &route_handler)
95
+ end
96
+
97
+ def unbind
98
+ end
99
+
100
+ protected
101
+ def after_initialize
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,4 @@
1
+ module ThinRest
2
+ class ResourceInvalid < StandardError
3
+ end
4
+ end
@@ -0,0 +1,5 @@
1
+ module ThinRest
2
+ class RoutingError < RuntimeError
3
+
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ dir = File.dirname(__FILE__)
2
+ Dir["#{dir}/**/*_spec.rb"].each do |file|
3
+ # puts "require '#{file}'"
4
+ require file
5
+ end
@@ -0,0 +1,207 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../thin_rest_spec_helper")
2
+
3
+ module ThinRest
4
+ describe Connection do
5
+ attr_reader :connection
6
+
7
+ describe "#process" do
8
+ attr_reader :result
9
+ before do
10
+ @connection = create_connection
11
+ stub(connection).socket_address {'0.0.0.0'}
12
+
13
+ @result = ""
14
+ stub(EventMachine).send_data do |signature, data, data_length|
15
+ result << data
16
+ end
17
+ end
18
+
19
+ context "when the call is successful" do
20
+ context "when the request has Connection: close" do
21
+ it "sends the response to the socket with a Connection: close response header" do
22
+ mock(connection).close_connection_after_writing
23
+ connection.receive_data "GET /subresource HTTP/1.1\r\nConnection: close\r\nHost: _\r\n\r\n"
24
+ result.should include("GET response")
25
+ result.should include("Connection: close")
26
+ end
27
+
28
+ it "closes the connection" do
29
+ mock(connection).close_connection_after_writing
30
+ connection.receive_data "GET /subresource HTTP/1.1\r\nConnection: close\r\nHost: _\r\n\r\n"
31
+ end
32
+ end
33
+
34
+ context "when the request does not have Connection: close" do
35
+ it "sends the response to the socket without a Connection: close response header" do
36
+ connection.receive_data "GET /subresource HTTP/1.1\r\nHost: _\r\n\r\n"
37
+ result.should include("GET response")
38
+ result.should_not include("Connection: close")
39
+ end
40
+
41
+ it "does not close the connection" do
42
+ dont_allow(connection).close_connection_after_writing
43
+ connection.receive_data "GET /subresource HTTP/1.1\r\nHost: _\r\n\r\n"
44
+ end
45
+
46
+ context "when a second request is made" do
47
+ it "sends the response for the second request and not for the first request" do
48
+ connection.receive_data "GET /subresource HTTP/1.1\r\nHost: _\r\n\r\n"
49
+ result.should include("GET response")
50
+ result.should_not include("Another GET response")
51
+
52
+ connection.receive_data "GET /another_subresource HTTP/1.1\r\nHost: _\r\n\r\n"
53
+ result.should include("Another GET response")
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ context "when the call raises an error" do
60
+ it "logs the error and closes the connection" do
61
+ error = nil
62
+ mock(connection).log_error(is_a(Exception)) do |error_arg|
63
+ error = error_arg
64
+ end
65
+ mock(connection).close_connection
66
+
67
+ connection.receive_data "GET /error_subresource HTTP/1.1\r\nHost: _\r\n\r\n"
68
+ error.message.should =~ Regexp.new("/error_subresource")
69
+ end
70
+ end
71
+ end
72
+
73
+ describe "#send_head" do
74
+ before do
75
+ @connection = create_connection
76
+ stub(EventMachine).close_connection
77
+ end
78
+
79
+ context "when passed no arguments" do
80
+ it "responds with a 200 HTTP header excluding the Content-Length" do
81
+ expected_header = "HTTP/1.1 200 OK\r\nServer: Thin Rest Server\r\n"
82
+ mock(EventMachine).send_data( connection.signature, expected_header, expected_header.length ) {expected_header.length}
83
+ connection.send_head
84
+ end
85
+ end
86
+
87
+ context "when passed 301" do
88
+ it "responds with a 301 HTTP header excluding the Content-Length" do
89
+ expected_header = "HTTP/1.1 301 OK\r\nServer: Thin Rest Server\r\n"
90
+ mock(EventMachine).send_data( connection.signature, expected_header, expected_header.length ) {expected_header.length}
91
+ connection.send_head(301)
92
+ end
93
+ end
94
+
95
+ context "when passed additional parameters" do
96
+ it "responds with the additional parameters in the header" do
97
+ expected_header = "HTTP/1.1 301 OK\r\nServer: Thin Rest Server\r\nLocation: http://google.com\r\n"
98
+ mock(EventMachine).send_data( connection.signature, expected_header, expected_header.length ) {expected_header.length}
99
+ connection.send_head(301, :Location => "http://google.com")
100
+ end
101
+
102
+ context "when not passed Content-length" do
103
+ it 'does not end with \r\n\r\n' do
104
+ expected_header = "HTTP/1.1 301 OK\r\nServer: Thin Rest Server\r\nLocation: http://google.com\r\n"
105
+ mock(EventMachine).send_data( connection.signature, expected_header, expected_header.length ) {expected_header.length}
106
+ connection.send_head(301, :Location => "http://google.com")
107
+ end
108
+ end
109
+
110
+ context "when passed Content-Length" do
111
+ it 'when passed a Symbol representation of Content-Length ends with \r\n\r\n' do
112
+ expected_header = "HTTP/1.1 301 OK\r\nServer: Thin Rest Server\r\nContent-Length: 10\r\n\r\n"
113
+ mock(EventMachine).send_data( connection.signature, expected_header, expected_header.length ) {expected_header.length}
114
+ connection.send_head(301, :'Content-Length' => 10)
115
+ end
116
+
117
+ it 'when passed a String representation of Content-Length ends with \r\n\r\n' do
118
+ expected_header = "HTTP/1.1 301 OK\r\nServer: Thin Rest Server\r\nContent-Length: 10\r\n\r\n"
119
+ mock(EventMachine).send_data( connection.signature, expected_header, expected_header.length ) {expected_header.length}
120
+ connection.send_head(301, 'Content-Length' => 10)
121
+ end
122
+ end
123
+ end
124
+ end
125
+
126
+ describe "#send_body" do
127
+ before do
128
+ @connection = create_connection
129
+ stub(EventMachine).close_connection
130
+ end
131
+
132
+ it "responds with Content-Length and the body" do
133
+ data = "The data"
134
+ header = "Content-Length: #{data.length}\r\n\r\n"
135
+
136
+ mock(EventMachine).send_data( connection.signature, header, header.length ) {header.length}
137
+ mock(EventMachine).send_data( connection.signature, data, data.length ) {data.length}
138
+
139
+ connection.send_body data
140
+ end
141
+ end
142
+
143
+ describe "#unbind" do
144
+ attr_reader :game_session
145
+
146
+ before do
147
+ stub_send_data
148
+ stub(EventMachine).close_connection
149
+ @connection = create_connection
150
+ params = "param_1=1&param_2=2"
151
+ body = "#{params}\r\n"
152
+ connection.receive_data("POST /subresource HTTP/1.1\r\nHost: _\r\n\r\n#{body}")
153
+ end
154
+
155
+ it "calls connection_finished on the backend to protect against memory leaks" do
156
+ mock(connection.backend).connection_finished(connection)
157
+ connection.unbind
158
+ end
159
+
160
+ it "does not send data or add a timer of any type" do
161
+ dont_allow(EventMachine).send_data
162
+ dont_allow(EventMachine).add_timer
163
+
164
+ connection.unbind
165
+ end
166
+ end
167
+
168
+ describe "#handle_error" do
169
+ before do
170
+ @connection = create_connection
171
+ Thin::Logging.silent = true
172
+ end
173
+
174
+ it "logs the error" do
175
+ error = RuntimeError.new("Unexpected Error")
176
+ stub(error).backtrace(caller)
177
+
178
+ stub(connection).warn
179
+ mock.proxy(connection).log_error(error)
180
+ mock.proxy(connection).log_error(anything)
181
+
182
+ connection.handle_error(error)
183
+ end
184
+ end
185
+
186
+ describe "#persistent?" do
187
+ before do
188
+ @connection = create_connection
189
+ stub(connection).socket_address {'0.0.0.0'}
190
+ end
191
+
192
+ context "when #request.persistent? is true" do
193
+ it "returns true" do
194
+ stub(connection.request).persistent? {true}
195
+ connection.should be_persistent
196
+ end
197
+ end
198
+
199
+ context "when #request.persistent? is false" do
200
+ it "returns false" do
201
+ stub(connection.request).persistent? {false}
202
+ connection.should_not be_persistent
203
+ end
204
+ end
205
+ end
206
+ end
207
+ end