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,3 @@
1
+ h1 {
2
+ text-align: center;
3
+ }
@@ -0,0 +1,5 @@
1
+ describe("A failing spec", {
2
+ 'fails': function() {
3
+ value_of(true).should_be(false);
4
+ }
5
+ })
@@ -0,0 +1,6 @@
1
+ require("/implementations/foo");
2
+ describe("A failing spec in foo", {
3
+ 'fails': function() {
4
+ value_of(Foo.value).should_be(false);
5
+ }
6
+ })
@@ -0,0 +1,6 @@
1
+ require("/implementations/foo");
2
+ describe("A passing spec", {
3
+ 'passes': function() {
4
+ value_of(Foo.value).should_be(true);
5
+ }
6
+ })
@@ -0,0 +1,2 @@
1
+ dir = File.dirname(__FILE__)
2
+ raise "Failure" unless system(%Q|ruby #{dir}/unit_suite.rb|)
@@ -0,0 +1,166 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../unit_spec_helper")
2
+
3
+ module JsTestCore
4
+ describe Client do
5
+ describe '.run' do
6
+ attr_reader :stdout, :request
7
+ before do
8
+ @stdout = StringIO.new
9
+ Client.const_set(:STDOUT, stdout)
10
+ @request = "http request"
11
+ mock(Net::HTTP).start(DEFAULT_HOST, DEFAULT_PORT).yields(request)
12
+ end
13
+
14
+ after do
15
+ Client.__send__(:remove_const, :STDOUT)
16
+ end
17
+
18
+ it "tells the server to start a suite run in Firefox and polls the status of the suite until the suite is complete" do
19
+ mock_post_to_runner("*firefox")
20
+ mock_polling_returns([running_status, running_status, success_status])
21
+ Client.run
22
+ end
23
+
24
+ context "when the Suite run ends in 'success'" do
25
+ before do
26
+ mock_post_to_runner("*firefox")
27
+ mock_polling_returns([running_status, running_status, success_status])
28
+ end
29
+
30
+ it "reports success" do
31
+ Client.run
32
+ stdout.string.strip.should == "SUCCESS"
33
+ end
34
+
35
+ it "returns true" do
36
+ Client.run.should be_true
37
+ end
38
+ end
39
+
40
+ context "when the Suite run ends in 'failure'" do
41
+ attr_reader :failure_reason
42
+ before do
43
+ mock_post_to_runner("*firefox")
44
+ @failure_reason = "I have a failed test"
45
+ mock_polling_returns([running_status, running_status, failure_status(failure_reason)])
46
+ end
47
+
48
+ it "reports failure and reason" do
49
+ Client.run
50
+ stdout.string.strip.should include("FAILURE")
51
+ stdout.string.strip.should include(failure_reason)
52
+ end
53
+
54
+ it "returns false" do
55
+ Client.run.should be_false
56
+ end
57
+
58
+ it "reports the reason for failure"
59
+ end
60
+
61
+ context "when the Suite is not found" do
62
+ it "raises a SuiteNotFound error" do
63
+ mock_post_to_runner("*firefox")
64
+ mock(request).get("/suites/my_suite_id") do
65
+ stub(suite_response = Object.new).code {"404"}
66
+ suite_response
67
+ end
68
+ lambda {Client.run}.should raise_error(Client::SuiteNotFound)
69
+ end
70
+ end
71
+
72
+ context "when the Suite run ends in with invalid status" do
73
+ it "raises an InvalidStatusResponse" do
74
+ mock_post_to_runner("*firefox")
75
+ mock_polling_returns([running_status, running_status, "status=this is an unexpected status result"])
76
+ lambda {Client.run}.should raise_error(Client::InvalidStatusResponse)
77
+ end
78
+ end
79
+
80
+ def mock_post_to_runner(selenium_browser_start_command)
81
+ mock(start_suite_response = Object.new).body {"suite_id=my_suite_id"}
82
+ mock(request).post("/runners", "selenium_browser_start_command=#{CGI.escape(selenium_browser_start_command)}&selenium_host=localhost&selenium_port=4444") do
83
+ start_suite_response
84
+ end
85
+ end
86
+
87
+ def mock_polling_returns(suite_statuses=[])
88
+ mock(request).get("/suites/my_suite_id") do
89
+ stub(suite_response = Object.new).body {suite_statuses.shift}
90
+ stub(suite_response).code {"200"}
91
+ suite_response
92
+ end.times(suite_statuses.length)
93
+ end
94
+
95
+ def running_status
96
+ "status=#{Resources::Suite::RUNNING}"
97
+ end
98
+
99
+ def success_status
100
+ "status=#{Resources::Suite::SUCCESSFUL_COMPLETION}"
101
+ end
102
+
103
+ def failure_status(reason)
104
+ "status=#{Resources::Suite::FAILURE_COMPLETION}&reason=#{reason}"
105
+ end
106
+ end
107
+
108
+ describe ".run_argv" do
109
+ attr_reader :request, :response
110
+ before do
111
+ stub(Client).puts
112
+ end
113
+
114
+ describe "when passed in Hash contains :selenium_browser_start_command" do
115
+ it "passes the spec_url as a post parameter" do
116
+ selenium_browser_start_command = '*iexplore'
117
+ mock(Client).run(:selenium_browser_start_command => selenium_browser_start_command)
118
+ client = Client.run_argv(['--selenium_browser_start_command', selenium_browser_start_command])
119
+ end
120
+ end
121
+
122
+ describe "when passed in Hash contains :spec_url" do
123
+ it "passes the spec_url as a post parameter" do
124
+ spec_url = 'http://foobar.com/foo'
125
+ mock(Client).run(:spec_url => spec_url)
126
+ client = Client.run_argv(['--spec_url', spec_url])
127
+ end
128
+ end
129
+
130
+ describe "when passed in Hash contains :selenium_host" do
131
+ it "passes the selenium_host as a post parameter" do
132
+ selenium_host = 'test-runner'
133
+ mock(Client).run(:selenium_host => selenium_host)
134
+ client = Client.run_argv(['--selenium_host', selenium_host])
135
+ end
136
+ end
137
+
138
+ describe "when passed in Hash contains :selenium_port" do
139
+ it "passes the selenium_port as a post parameter" do
140
+ selenium_port = "5000"
141
+ mock(Client).run(:selenium_port => selenium_port)
142
+ client = Client.run_argv(['--selenium_port', selenium_port])
143
+ end
144
+ end
145
+ end
146
+
147
+ describe '#parts_from_query' do
148
+ attr_reader :client
149
+ before do
150
+ @client = Client.new(params_does_not_matter = {})
151
+ end
152
+
153
+ it "parses empty query into an empty hash" do
154
+ client.parts_from_query("").should == {}
155
+ end
156
+
157
+ it "parses a single key value pair into a single-element hash" do
158
+ client.parts_from_query("foo=bar").should == {'foo' => 'bar'}
159
+ end
160
+
161
+ it "parses a multiple key value pairs into a multi-element hash" do
162
+ client.parts_from_query("foo=bar&baz=quux").should == {'foo' => 'bar', 'baz' => 'quux'}
163
+ end
164
+ end
165
+ end
166
+ end
@@ -0,0 +1,45 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../unit_spec_helper")
2
+
3
+ module JsTestCore
4
+ describe RailsServer do
5
+ it "subclasses Server" do
6
+ RailsServer.superclass.should == Server
7
+ end
8
+
9
+ describe ".run" do
10
+ attr_reader :rails_root
11
+ before do
12
+ @rails_root = "/rails/root"
13
+ Server.instance = nil
14
+ end
15
+
16
+ it "initializes the RailsServer and runs the Thin Handler and sets Server.instance to the RailsServer instance" do
17
+ host = DEFAULT_HOST
18
+ port = DEFAULT_PORT
19
+ server_instance = nil
20
+ mock.proxy(RailsServer).new(
21
+ rails_root,
22
+ host,
23
+ port
24
+ ) do |new_instance|
25
+ server_instance = new_instance
26
+ end
27
+
28
+ mock(EventMachine).run.yields
29
+ mock(EventMachine).start_server(host, port, ::Thin::JsTestCoreConnection)
30
+ RailsServer.run(rails_root)
31
+ Server.instance.should == server_instance
32
+ end
33
+ end
34
+
35
+ describe "#initialize" do
36
+ it "sets the server paths based on the passed in rails root" do
37
+ rails_root = "/rails/root"
38
+ server = RailsServer.new(rails_root)
39
+ server.spec_root_path.should == "#{rails_root}/spec/javascripts"
40
+ server.implementation_root_path.should == "#{rails_root}/public/javascripts"
41
+ server.public_path.should == "#{rails_root}/public"
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,52 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../unit_spec_helper")
2
+
3
+ module JsTestCore
4
+ module Resources
5
+ describe Dir do
6
+ attr_reader :dir, :absolute_path, :relative_path
7
+
8
+ describe "GET /stylesheets - Top level directory" do
9
+ it "returns a page with a of files in the directory" do
10
+ mock(connection).send_head()
11
+ mock(connection).send_body(%r(<a href="example.css">example.css</a>))
12
+
13
+ connection.receive_data("GET /stylesheets HTTP/1.1\r\nHost: _\r\n\r\n")
14
+ end
15
+ end
16
+
17
+ describe "GET /javascripts/subdir - Subdirectory" do
18
+ it "returns a page with a of files in the directory" do
19
+ mock(connection).send_head()
20
+ mock(connection).send_body(%r(<a href="bar.js">bar.js</a>))
21
+
22
+ connection.receive_data("GET /javascripts/subdir HTTP/1.1\r\nHost: _\r\n\r\n")
23
+ end
24
+ end
25
+
26
+ describe "GET /javascripts/i_dont_exist - FileNotFound" do
27
+ it "returns a 404 error" do
28
+ mock(connection).send_head(404)
29
+ mock(connection).send_body("")
30
+
31
+ connection.receive_data("GET /javascripts/i_dont_exist HTTP/1.1\r\nHost: _\r\n\r\n")
32
+ end
33
+ end
34
+
35
+ describe "#glob" do
36
+ before do
37
+ @absolute_path = spec_root_path
38
+ @relative_path = "/specs"
39
+ @dir = Resources::Dir.new(:connection => connection, :absolute_path => absolute_path, :relative_path => relative_path)
40
+ end
41
+
42
+ it "returns an array of matching Files under this directory with the correct relative paths" do
43
+ globbed_files = dir.glob("/**/*_spec.js")
44
+ globbed_files.size.should == 3
45
+ globbed_files.should contain_spec_file_with_correct_paths("/failing_spec.js")
46
+ globbed_files.should contain_spec_file_with_correct_paths("/foo/failing_spec.js")
47
+ globbed_files.should contain_spec_file_with_correct_paths("/foo/passing_spec.js")
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,16 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../unit_spec_helper")
2
+
3
+ module JsTestCore
4
+ module Resources
5
+ describe FileNotFound do
6
+ describe "GET /invalid_path" do
7
+ it "returns a page with a of files in the directory" do
8
+ mock(connection).send_head(404)
9
+ mock(connection).send_body("")
10
+
11
+ connection.receive_data("GET /invalid_path HTTP/1.1\r\nHost: _\r\n\r\n")
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,128 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../unit_spec_helper")
2
+
3
+ module JsTestCore
4
+ module Resources
5
+ describe File do
6
+ before do
7
+ WebRoot.dispatch_specs
8
+ stub_send_data
9
+ stub(EventMachine).close_connection
10
+ end
11
+
12
+ describe "GET" do
13
+ context "when If-Modified-Since header is == the File's mtime" do
14
+ it "returns a 304 response with Content-Length: 0 and Last-Modified: File.mtime" do
15
+ path = "#{public_path}/stylesheets/example.css"
16
+ mock(connection).send_head(304, 'Content-Type' => "text/css", 'Content-Length' => 0, 'Last-Modified' => ::File.mtime(path).rfc822)
17
+ connection.receive_data("GET /stylesheets/example.css HTTP/1.1\r\nHost: _\r\nIf-Modified-Since: #{::File.mtime(path).rfc822}\r\n\r\n")
18
+
19
+ path_2 = "#{public_path}/javascripts/foo.js"
20
+ mock(connection).send_head(304, 'Content-Type' => "text/javascript", 'Content-Length' => 0, 'Last-Modified' => ::File.mtime(path_2).rfc822)
21
+ connection.receive_data("GET /javascripts/foo.js HTTP/1.1\r\nHost: _\r\nIf-Modified-Since: #{::File.mtime(path_2).rfc822}\r\n\r\n")
22
+ end
23
+ end
24
+
25
+ context "when If-Modified-Since header is > the File's mtime" do
26
+ it "returns a 304 response with Content-Length: 0 and Last-Modified: File.mtime" do
27
+ path = "#{public_path}/stylesheets/example.css"
28
+ mock(connection).send_head(304, 'Content-Type' => "text/css", 'Content-Length' => 0, 'Last-Modified' => ::File.mtime(path).rfc822)
29
+ connection.receive_data("GET /stylesheets/example.css HTTP/1.1\r\nHost: _\r\nIf-Modified-Since: #{(::File.mtime(path) + 10).rfc822}\r\n\r\n")
30
+
31
+ path_2 = "#{public_path}/javascripts/foo.js"
32
+ mock(connection).send_head(304, 'Content-Type' => "text/javascript", 'Content-Length' => 0, 'Last-Modified' => ::File.mtime(path_2).rfc822)
33
+ connection.receive_data("GET /javascripts/foo.js HTTP/1.1\r\nHost: _\r\nIf-Modified-Since: #{(::File.mtime(path_2) + 10).rfc822}\r\n\r\n")
34
+ end
35
+ end
36
+
37
+ context "when If-Modified-Since header is < the File's mtime" do
38
+ it "returns a 200 response with the file's contents" do
39
+ path = "#{public_path}/stylesheets/example.css"
40
+ mock(connection).send_head(200, 'Content-Type' => "text/css", 'Content-Length' => ::File.size(path), 'Last-Modified' => ::File.mtime(path).rfc822)
41
+ mock(connection).send_data(::File.read(path))
42
+ connection.receive_data("GET /stylesheets/example.css HTTP/1.1\r\nHost: _\r\nIf-Modified-Since: #{(::File.mtime(path) - 10).rfc822}\r\n\r\n")
43
+
44
+ path_2 = "#{public_path}/javascripts/foo.js"
45
+ mock(connection).send_head(200, 'Content-Type' => "text/javascript", 'Content-Length' => ::File.size(path_2), 'Last-Modified' => ::File.mtime(path_2).rfc822)
46
+ mock(connection).send_data(::File.read(path_2))
47
+ connection.receive_data("GET /javascripts/foo.js HTTP/1.1\r\nHost: _\r\nIf-Modified-Since: #{(::File.mtime(path_2) - 10).rfc822}\r\n\r\n")
48
+ end
49
+ end
50
+
51
+ describe "GET /stylesheets/example.css" do
52
+ it "returns a page with a of files in the directory" do
53
+ path = "#{public_path}/stylesheets/example.css"
54
+ mock(connection).send_head(200, 'Content-Type' => "text/css", 'Content-Length' => ::File.size(path), 'Last-Modified' => ::File.mtime(path).rfc822)
55
+ mock(connection).send_data(::File.read(path))
56
+
57
+ connection.receive_data("GET /stylesheets/example.css HTTP/1.1\r\nHost: _\r\n\r\n")
58
+ end
59
+ end
60
+
61
+ describe "GET /implementations/foo.js" do
62
+ it "returns a page with a of files in the directory" do
63
+ path = "#{public_path}/javascripts/foo.js"
64
+ mock(connection).send_head(200, 'Content-Type' => "text/javascript", 'Content-Length' => ::File.size(path), 'Last-Modified' => ::File.mtime(path).rfc822)
65
+ mock(connection).send_data(::File.read(path))
66
+
67
+ connection.receive_data("GET /implementations/foo.js HTTP/1.1\r\nHost: _\r\n\r\n")
68
+ end
69
+ end
70
+
71
+ describe "GET /javascripts/subdir/bar.js - Subdirectory" do
72
+ it "returns a page with a of files in the directory" do
73
+ path = "#{public_path}/javascripts/subdir/bar.js"
74
+ mock(connection).send_head(200, 'Content-Type' => "text/javascript", 'Content-Length' => ::File.size(path), 'Last-Modified' => ::File.mtime(path).rfc822)
75
+ mock(connection).send_data(::File.read(path))
76
+
77
+ connection.receive_data("GET /javascripts/subdir/bar.js HTTP/1.1\r\nHost: _\r\n\r\n")
78
+ end
79
+ end
80
+
81
+ describe "GET /implementations/large_file.js - Large files" do
82
+ it "returns a page in 1024 byte chunks" do
83
+ chunk_count = 0
84
+ path = "#{public_path}/javascripts/large_file.js"
85
+ mock(connection).send_head(200, 'Content-Type' => "text/javascript", 'Content-Length' => ::File.size(path), 'Last-Modified' => ::File.mtime(path).rfc822)
86
+ ::File.open(path) do |file|
87
+ while !file.eof?
88
+ chunk_count += 1
89
+ mock(connection).send_data(file.read(1024))
90
+ end
91
+ end
92
+
93
+ chunk_count.should == (::File.size(path) / 1024.0).ceil.to_i
94
+ connection.receive_data("GET /javascripts/large_file.js HTTP/1.1\r\nHost: _\r\n\r\n")
95
+ end
96
+ end
97
+ end
98
+
99
+
100
+ describe "==" do
101
+ attr_reader :file, :absolute_path, :relative_path
102
+
103
+ before do
104
+ @absolute_path = "#{implementation_root_path}/foo.js"
105
+ @relative_path = "/implementations/foo.js"
106
+ @file = Resources::File.new(
107
+ :connection => connection,
108
+ :absolute_path => absolute_path,
109
+ :relative_path => relative_path
110
+ )
111
+ end
112
+
113
+ it "returns true when passed a file with the same absolute and relative paths" do
114
+ file.should == Resources::File.new(:absolute_path => absolute_path, :relative_path => relative_path)
115
+ end
116
+
117
+ it "returns false when passed a file with a different absolute or relative path" do
118
+ file.should_not == Resources::File.new(:absolute_path => absolute_path, :relative_path => "bogus")
119
+ file.should_not == Resources::File.new(:absolute_path => "bogus", :relative_path => relative_path)
120
+ end
121
+
122
+ it "when passed a Dir, returns false because File is not a Dir" do
123
+ file.should_not == Resources::Dir.new(:absolute_path => absolute_path, :relative_path => relative_path)
124
+ end
125
+ end
126
+ end
127
+ end
128
+ end