screw-unit 0.3.1

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 (112) hide show
  1. data/CHANGES +11 -0
  2. data/README.markdown +354 -0
  3. data/Rakefile +40 -0
  4. data/bin/screw_unit +6 -0
  5. data/bin/screw_unit_server +10 -0
  6. data/core/EXAMPLE.html +68 -0
  7. data/core/LICENSE +22 -0
  8. data/core/README.markdown +307 -0
  9. data/core/example/models/cat.js +5 -0
  10. data/core/example/models/man.js +17 -0
  11. data/core/example/spec/matchers/have.js +8 -0
  12. data/core/example/spec/models/cat_spec.js +31 -0
  13. data/core/example/spec/models/man_spec.js +34 -0
  14. data/core/example/spec/spec_helper.js +5 -0
  15. data/core/example/spec/suite.html +25 -0
  16. data/core/lib/jquery-1.2.6.js +3549 -0
  17. data/core/lib/jquery.fn.js +29 -0
  18. data/core/lib/jquery.print.js +109 -0
  19. data/core/lib/screw.assets.js +36 -0
  20. data/core/lib/screw.behaviors.js +91 -0
  21. data/core/lib/screw.builder.js +80 -0
  22. data/core/lib/screw.css +90 -0
  23. data/core/lib/screw.events.js +44 -0
  24. data/core/lib/screw.matchers.js +145 -0
  25. data/core/lib/screw.server.js +21 -0
  26. data/core/spec/behaviors_spec.js +178 -0
  27. data/core/spec/matchers_spec.js +237 -0
  28. data/core/spec/print_spec.js +152 -0
  29. data/core/spec/spec_helper.js +0 -0
  30. data/core/spec/suite.html +18 -0
  31. data/init.rb +0 -0
  32. data/lib/screw_unit.rb +26 -0
  33. data/lib/screw_unit/resources.rb +2 -0
  34. data/lib/screw_unit/resources/spec.rb +38 -0
  35. data/spec/functional/functional_spec.rb +25 -0
  36. data/spec/functional/functional_spec_helper.rb +55 -0
  37. data/spec/functional_suite.rb +10 -0
  38. data/spec/spec_suite.rb +3 -0
  39. data/spec/unit/js_test_core/specs/spec_dir_spec.rb +39 -0
  40. data/spec/unit/js_test_core/specs/spec_file_spec.rb +35 -0
  41. data/spec/unit/unit_spec_helper.rb +120 -0
  42. data/spec/unit_suite.rb +10 -0
  43. data/vendor/js-test-core/CHANGES +15 -0
  44. data/vendor/js-test-core/README +12 -0
  45. data/vendor/js-test-core/Rakefile +72 -0
  46. data/vendor/js-test-core/lib/js_test_core.rb +38 -0
  47. data/vendor/js-test-core/lib/js_test_core/client.rb +114 -0
  48. data/vendor/js-test-core/lib/js_test_core/extensions.rb +3 -0
  49. data/vendor/js-test-core/lib/js_test_core/extensions/time.rb +6 -0
  50. data/vendor/js-test-core/lib/js_test_core/rack.rb +2 -0
  51. data/vendor/js-test-core/lib/js_test_core/rack/commonlogger.rb +5 -0
  52. data/vendor/js-test-core/lib/js_test_core/rails_server.rb +22 -0
  53. data/vendor/js-test-core/lib/js_test_core/resources.rb +10 -0
  54. data/vendor/js-test-core/lib/js_test_core/resources/dir.rb +67 -0
  55. data/vendor/js-test-core/lib/js_test_core/resources/file.rb +49 -0
  56. data/vendor/js-test-core/lib/js_test_core/resources/file_not_found.rb +11 -0
  57. data/vendor/js-test-core/lib/js_test_core/resources/runner.rb +105 -0
  58. data/vendor/js-test-core/lib/js_test_core/resources/specs/spec_dir.rb +46 -0
  59. data/vendor/js-test-core/lib/js_test_core/resources/specs/spec_file.rb +17 -0
  60. data/vendor/js-test-core/lib/js_test_core/resources/suite.rb +40 -0
  61. data/vendor/js-test-core/lib/js_test_core/resources/suite_finish.rb +17 -0
  62. data/vendor/js-test-core/lib/js_test_core/resources/web_root.rb +63 -0
  63. data/vendor/js-test-core/lib/js_test_core/selenium.rb +2 -0
  64. data/vendor/js-test-core/lib/js_test_core/selenium/selenium_driver.rb +5 -0
  65. data/vendor/js-test-core/lib/js_test_core/selenium_server_configuration.rb +48 -0
  66. data/vendor/js-test-core/lib/js_test_core/server.rb +50 -0
  67. data/vendor/js-test-core/lib/js_test_core/thin.rb +3 -0
  68. data/vendor/js-test-core/lib/js_test_core/thin/backends/js_test_core_server.rb +9 -0
  69. data/vendor/js-test-core/lib/js_test_core/thin/js_test_core_connection.rb +8 -0
  70. data/vendor/js-test-core/spec/example_core/JsTestCore.css +0 -0
  71. data/vendor/js-test-core/spec/example_core/JsTestCore.js +0 -0
  72. data/vendor/js-test-core/spec/example_public/favicon.ico +0 -0
  73. data/vendor/js-test-core/spec/example_public/javascripts/foo.js +3 -0
  74. data/vendor/js-test-core/spec/example_public/javascripts/large_file.js +59 -0
  75. data/vendor/js-test-core/spec/example_public/javascripts/subdir/bar.js +1 -0
  76. data/vendor/js-test-core/spec/example_public/robots.txt +0 -0
  77. data/vendor/js-test-core/spec/example_public/stylesheets/example.css +3 -0
  78. data/vendor/js-test-core/spec/example_specs/failing_spec.js +5 -0
  79. data/vendor/js-test-core/spec/example_specs/foo/failing_spec.js +6 -0
  80. data/vendor/js-test-core/spec/example_specs/foo/passing_spec.js +6 -0
  81. data/vendor/js-test-core/spec/spec_suite.rb +2 -0
  82. data/vendor/js-test-core/spec/specs/failing_spec.js +0 -0
  83. data/vendor/js-test-core/spec/unit/js_test_core/client_spec.rb +166 -0
  84. data/vendor/js-test-core/spec/unit/js_test_core/rails_server_spec.rb +45 -0
  85. data/vendor/js-test-core/spec/unit/js_test_core/resources/dir_spec.rb +52 -0
  86. data/vendor/js-test-core/spec/unit/js_test_core/resources/file_not_found_spec.rb +16 -0
  87. data/vendor/js-test-core/spec/unit/js_test_core/resources/file_spec.rb +128 -0
  88. data/vendor/js-test-core/spec/unit/js_test_core/resources/runners/runner_spec.rb +283 -0
  89. data/vendor/js-test-core/spec/unit/js_test_core/resources/specs/spec_dir_spec.rb +105 -0
  90. data/vendor/js-test-core/spec/unit/js_test_core/resources/specs/spec_file_spec.rb +42 -0
  91. data/vendor/js-test-core/spec/unit/js_test_core/resources/suite_finish_spec.rb +82 -0
  92. data/vendor/js-test-core/spec/unit/js_test_core/resources/suite_spec.rb +86 -0
  93. data/vendor/js-test-core/spec/unit/js_test_core/resources/web_root_spec.rb +32 -0
  94. data/vendor/js-test-core/spec/unit/js_test_core/selenium_server_configuration_spec.rb +49 -0
  95. data/vendor/js-test-core/spec/unit/js_test_core/server_spec.rb +117 -0
  96. data/vendor/js-test-core/spec/unit/thin/js_test_core_connection_spec.rb +6 -0
  97. data/vendor/js-test-core/spec/unit/unit_spec_helper.rb +134 -0
  98. data/vendor/js-test-core/spec/unit_suite.rb +10 -0
  99. data/vendor/js-test-core/vendor/thin-rest/CHANGES +2 -0
  100. data/vendor/js-test-core/vendor/thin-rest/README +0 -0
  101. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest.rb +9 -0
  102. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest/connection.rb +116 -0
  103. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest/extensions.rb +3 -0
  104. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest/extensions/object.rb +21 -0
  105. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest/resource.rb +104 -0
  106. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest/resource_invalid.rb +4 -0
  107. data/vendor/js-test-core/vendor/thin-rest/lib/thin_rest/routing_error.rb +5 -0
  108. data/vendor/js-test-core/vendor/thin-rest/spec/spec_suite.rb +5 -0
  109. data/vendor/js-test-core/vendor/thin-rest/spec/thin_rest/connection_spec.rb +207 -0
  110. data/vendor/js-test-core/vendor/thin-rest/spec/thin_rest/resource_spec.rb +127 -0
  111. data/vendor/js-test-core/vendor/thin-rest/spec/thin_rest_spec_helper.rb +124 -0
  112. metadata +210 -0
@@ -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