pivotal-screw-unit-server 0.5.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (112) hide show
  1. data/CHANGES +27 -0
  2. data/README.markdown +354 -0
  3. data/Rakefile +42 -0
  4. data/VERSION.yml +4 -0
  5. data/bin/screw_unit +6 -0
  6. data/bin/screw_unit_server +20 -0
  7. data/core/CHANGES +10 -0
  8. data/core/EXAMPLE.html +68 -0
  9. data/core/LICENSE +22 -0
  10. data/core/README.markdown +307 -0
  11. data/core/example/models/cat.js +5 -0
  12. data/core/example/models/man.js +17 -0
  13. data/core/example/spec/matchers/have.js +8 -0
  14. data/core/example/spec/models/cat_spec.js +31 -0
  15. data/core/example/spec/models/man_spec.js +34 -0
  16. data/core/example/spec/spec_helper.js +5 -0
  17. data/core/example/spec/suite.html +25 -0
  18. data/core/lib/jquery-1.3.2.js +4376 -0
  19. data/core/lib/jquery.fn.js +30 -0
  20. data/core/lib/jquery.print.js +109 -0
  21. data/core/lib/screw.behaviors.js +93 -0
  22. data/core/lib/screw.builder.js +95 -0
  23. data/core/lib/screw.css +90 -0
  24. data/core/lib/screw.events.js +45 -0
  25. data/core/lib/screw.matchers.js +244 -0
  26. data/core/spec/behaviors_spec.js +188 -0
  27. data/core/spec/matchers_spec.js +372 -0
  28. data/core/spec/print_spec.js +158 -0
  29. data/core/spec/spec_helper.js +0 -0
  30. data/core/spec/suite.html +19 -0
  31. data/core/spec/with_screw_context_spec.js +9 -0
  32. data/init.rb +0 -0
  33. data/lib/screw_unit.rb +23 -0
  34. data/lib/screw_unit/representations.rb +2 -0
  35. data/lib/screw_unit/representations/spec.html.rb +117 -0
  36. data/spec/functional/functional_spec.rb +25 -0
  37. data/spec/functional/functional_spec_helper.rb +43 -0
  38. data/spec/functional/functional_spec_server_starter.rb +68 -0
  39. data/spec/functional_suite.rb +10 -0
  40. data/spec/spec_suite.rb +3 -0
  41. data/spec/unit/js_test_core/specs/spec_file_spec.rb +68 -0
  42. data/spec/unit/unit_spec_helper.rb +51 -0
  43. data/spec/unit_suite.rb +10 -0
  44. data/vendor/js-test-core/CHANGES +28 -0
  45. data/vendor/js-test-core/README +12 -0
  46. data/vendor/js-test-core/Rakefile +73 -0
  47. data/vendor/js-test-core/lib/js_test_core.rb +46 -0
  48. data/vendor/js-test-core/lib/js_test_core/app.rb +12 -0
  49. data/vendor/js-test-core/lib/js_test_core/client.rb +129 -0
  50. data/vendor/js-test-core/lib/js_test_core/configuration.rb +35 -0
  51. data/vendor/js-test-core/lib/js_test_core/extensions.rb +3 -0
  52. data/vendor/js-test-core/lib/js_test_core/extensions/selenium/client/driver.rb +7 -0
  53. data/vendor/js-test-core/lib/js_test_core/extensions/time.rb +6 -0
  54. data/vendor/js-test-core/lib/js_test_core/models.rb +8 -0
  55. data/vendor/js-test-core/lib/js_test_core/models/selenium_session.rb +80 -0
  56. data/vendor/js-test-core/lib/js_test_core/representations.rb +11 -0
  57. data/vendor/js-test-core/lib/js_test_core/representations/dir.html.rb +24 -0
  58. data/vendor/js-test-core/lib/js_test_core/representations/not_found.html.rb +15 -0
  59. data/vendor/js-test-core/lib/js_test_core/representations/page.html.rb +41 -0
  60. data/vendor/js-test-core/lib/js_test_core/representations/spec.html.rb +24 -0
  61. data/vendor/js-test-core/lib/js_test_core/resources.rb +16 -0
  62. data/vendor/js-test-core/lib/js_test_core/resources/core_file.rb +19 -0
  63. data/vendor/js-test-core/lib/js_test_core/resources/file.rb +62 -0
  64. data/vendor/js-test-core/lib/js_test_core/resources/implementations_deprecation.rb +12 -0
  65. data/vendor/js-test-core/lib/js_test_core/resources/not_found.rb +35 -0
  66. data/vendor/js-test-core/lib/js_test_core/resources/resource.rb +16 -0
  67. data/vendor/js-test-core/lib/js_test_core/resources/selenium_session.rb +104 -0
  68. data/vendor/js-test-core/lib/js_test_core/resources/spec_file.rb +63 -0
  69. data/vendor/js-test-core/lib/js_test_core/resources/web_root.rb +11 -0
  70. data/vendor/js-test-core/lib/js_test_core/selenium_server_configuration.rb +48 -0
  71. data/vendor/js-test-core/spec/example_core/JsTestCore.css +0 -0
  72. data/vendor/js-test-core/spec/example_core/JsTestCore.js +0 -0
  73. data/vendor/js-test-core/spec/example_core/subdir/SubDirFile.js +0 -0
  74. data/vendor/js-test-core/spec/example_public/favicon.ico +0 -0
  75. data/vendor/js-test-core/spec/example_public/javascripts/foo.js +3 -0
  76. data/vendor/js-test-core/spec/example_public/javascripts/large_file.js +59 -0
  77. data/vendor/js-test-core/spec/example_public/javascripts/subdir/bar.js +1 -0
  78. data/vendor/js-test-core/spec/example_public/robots.txt +0 -0
  79. data/vendor/js-test-core/spec/example_public/stylesheets/example.css +3 -0
  80. data/vendor/js-test-core/spec/example_specs/custom_dir_and_suite/passing_spec.js +6 -0
  81. data/vendor/js-test-core/spec/example_specs/custom_suite.html +8 -0
  82. data/vendor/js-test-core/spec/example_specs/failing_spec.js +5 -0
  83. data/vendor/js-test-core/spec/example_specs/foo/failing_spec.js +6 -0
  84. data/vendor/js-test-core/spec/example_specs/foo/passing_spec.js +6 -0
  85. data/vendor/js-test-core/spec/spec_helpers/be_http.rb +32 -0
  86. data/vendor/js-test-core/spec/spec_helpers/example_group.rb +36 -0
  87. data/vendor/js-test-core/spec/spec_helpers/fake_selenium_driver.rb +27 -0
  88. data/vendor/js-test-core/spec/spec_helpers/show_test_exceptions.rb +22 -0
  89. data/vendor/js-test-core/spec/spec_suite.rb +2 -0
  90. data/vendor/js-test-core/spec/specs/failing_spec.js +0 -0
  91. data/vendor/js-test-core/spec/unit/js_test_core/client_spec.rb +192 -0
  92. data/vendor/js-test-core/spec/unit/js_test_core/configuration_spec.rb +44 -0
  93. data/vendor/js-test-core/spec/unit/js_test_core/models/selenium_session_spec.rb +85 -0
  94. data/vendor/js-test-core/spec/unit/js_test_core/resources/core_file_spec.rb +60 -0
  95. data/vendor/js-test-core/spec/unit/js_test_core/resources/file_spec.rb +81 -0
  96. data/vendor/js-test-core/spec/unit/js_test_core/resources/implementations_deprecation_spec.rb +18 -0
  97. data/vendor/js-test-core/spec/unit/js_test_core/resources/not_found_spec.rb +51 -0
  98. data/vendor/js-test-core/spec/unit/js_test_core/resources/selenium_session_spec.rb +362 -0
  99. data/vendor/js-test-core/spec/unit/js_test_core/resources/spec_file_spec.rb +120 -0
  100. data/vendor/js-test-core/spec/unit/js_test_core/resources/web_root_spec.rb +28 -0
  101. data/vendor/js-test-core/spec/unit/js_test_core/selenium_server_configuration_spec.rb +49 -0
  102. data/vendor/js-test-core/spec/unit/unit_spec_helper.rb +28 -0
  103. data/vendor/js-test-core/spec/unit_suite.rb +10 -0
  104. data/vendor/js-test-core/vendor/lucky-luciano/README.markdown +7 -0
  105. data/vendor/js-test-core/vendor/lucky-luciano/lib/lucky_luciano.rb +4 -0
  106. data/vendor/js-test-core/vendor/lucky-luciano/lib/lucky_luciano/resource.rb +135 -0
  107. data/vendor/js-test-core/vendor/lucky-luciano/lib/lucky_luciano/rspec.rb +4 -0
  108. data/vendor/js-test-core/vendor/lucky-luciano/lib/lucky_luciano/rspec/be_http.rb +32 -0
  109. data/vendor/js-test-core/vendor/lucky-luciano/spec/lucky_luciano/resource_spec.rb +231 -0
  110. data/vendor/js-test-core/vendor/lucky-luciano/spec/spec_helper.rb +48 -0
  111. data/vendor/js-test-core/vendor/lucky-luciano/spec/spec_suite.rb +4 -0
  112. metadata +198 -0
@@ -0,0 +1,22 @@
1
+ class ShowTestExceptions
2
+ attr_reader :app
3
+
4
+ def initialize(app)
5
+ @app = app
6
+ end
7
+
8
+ def call(env)
9
+ app.call(env)
10
+ rescue StandardError, LoadError, SyntaxError => e
11
+ body = [
12
+ e.message,
13
+ e.backtrace.join("\n\t")
14
+ ].join("\n")
15
+ [
16
+ 500,
17
+ {"Content-Type" => "text",
18
+ "Content-Length" => body.size.to_s},
19
+ body
20
+ ]
21
+ end
22
+ end
@@ -0,0 +1,2 @@
1
+ dir = File.dirname(__FILE__)
2
+ raise "Failure" unless system(%Q|ruby #{dir}/unit_suite.rb|)
File without changes
@@ -0,0 +1,192 @@
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
+ stub.instance_of(Client).sleep
13
+ end
14
+
15
+ after do
16
+ Client.__send__(:remove_const, :STDOUT)
17
+ end
18
+
19
+ it "tells the server to start a session run in Firefox and polls the status of the session until the session is complete" do
20
+ mock_post_to_runner("*firefox")
21
+ mock_polling_returns([running_status, running_status, success_status])
22
+ Client.run
23
+ end
24
+
25
+ context "when the Session run ends in 'success'" do
26
+ before do
27
+ mock_post_to_runner("*firefox")
28
+ mock_polling_returns([running_status, running_status, success_status])
29
+ end
30
+
31
+ it "reports success" do
32
+ Client.run
33
+ stdout.string.strip.should == "SUCCESS"
34
+ end
35
+
36
+ it "returns true" do
37
+ Client.run.should be_true
38
+ end
39
+ end
40
+
41
+ context "when the Session run ends in 'failure'" do
42
+ attr_reader :failure_reason
43
+ before do
44
+ mock_post_to_runner("*firefox")
45
+ @failure_reason = "I have a failed test"
46
+ mock_polling_returns([running_status, running_status, failure_status(failure_reason)])
47
+ end
48
+
49
+ it "reports failure and reason" do
50
+ Client.run
51
+ stdout.string.strip.should include("FAILURE")
52
+ stdout.string.strip.should include(failure_reason)
53
+ end
54
+
55
+ it "returns false" do
56
+ Client.run.should be_false
57
+ end
58
+
59
+ it "reports the reason for failure"
60
+ end
61
+
62
+ context "when the Session is not found" do
63
+ it "raises a SessionNotFound error" do
64
+ mock_post_to_runner("*firefox")
65
+ mock(request).get(Resources::SeleniumSession.path(":session_id", :session_id => "my_session_id")) do
66
+ stub(session_response = Object.new).code {"404"}
67
+ session_response
68
+ end
69
+ lambda {Client.run}.should raise_error(Client::SessionNotFound)
70
+ end
71
+ end
72
+
73
+ context "when the Session run ends in with invalid status" do
74
+ it "raises an InvalidStatusResponse" do
75
+ mock_post_to_runner("*firefox")
76
+ mock_polling_returns([running_status, running_status, "status=this is an unexpected status result"])
77
+ lambda {Client.run}.should raise_error(Client::InvalidStatusResponse)
78
+ end
79
+ end
80
+
81
+ context "when passed-in a timeout" do
82
+ it "wraps a timeout around the run" do
83
+ mock.proxy(Timeout).timeout(5)
84
+ mock_post_to_runner("*firefox")
85
+ mock_polling_returns([running_status, running_status, success_status])
86
+ Client.run(:timeout => 5)
87
+ end
88
+ end
89
+
90
+ context "when not passed-in a timeout" do
91
+ it "does not wrap a timeout around the run" do
92
+ dont_allow(Timeout).timeout
93
+ mock_post_to_runner("*firefox")
94
+ mock_polling_returns([running_status, running_status, success_status])
95
+ Client.run
96
+ end
97
+ end
98
+
99
+ def mock_post_to_runner(selenium_browser_start_command)
100
+ mock(start_session_response = Object.new).body {"session_id=my_session_id"}
101
+ mock(request).post(Resources::SeleniumSession.path, "selenium_browser_start_command=#{CGI.escape(selenium_browser_start_command)}&selenium_host=localhost&selenium_port=4444") do
102
+ start_session_response
103
+ end
104
+ end
105
+
106
+ def mock_polling_returns(session_statuses=[])
107
+ mock(request).get(Resources::SeleniumSession.path(":session_id", :session_id => "my_session_id")) do
108
+ stub(session_response = Object.new).body {session_statuses.shift}
109
+ stub(session_response).code {"200"}
110
+ session_response
111
+ end.times(session_statuses.length)
112
+ end
113
+
114
+ def running_status
115
+ "status=#{Resources::SeleniumSession::RUNNING}"
116
+ end
117
+
118
+ def success_status
119
+ "status=#{Resources::SeleniumSession::SUCCESSFUL_COMPLETION}"
120
+ end
121
+
122
+ def failure_status(reason)
123
+ "status=#{Resources::SeleniumSession::FAILURE_COMPLETION}&reason=#{reason}"
124
+ end
125
+ end
126
+
127
+ describe ".run_argv" do
128
+ attr_reader :request, :response
129
+ before do
130
+ stub(Client).puts
131
+ end
132
+
133
+ context "when passed-in Hash contains :selenium_browser_start_command" do
134
+ it "passes the spec_url as a post parameter" do
135
+ selenium_browser_start_command = '*iexplore'
136
+ mock(Client).run(:selenium_browser_start_command => selenium_browser_start_command)
137
+ client = Client.run_argv(['--selenium_browser_start_command', selenium_browser_start_command])
138
+ end
139
+ end
140
+
141
+ context "when passed-in Hash contains :spec_url" do
142
+ it "passes the spec_url as a post parameter" do
143
+ spec_url = 'http://foobar.com/foo'
144
+ mock(Client).run(:spec_url => spec_url)
145
+ client = Client.run_argv(['--spec_url', spec_url])
146
+ end
147
+ end
148
+
149
+ context "when passed-in Hash contains :selenium_host" do
150
+ it "passes the selenium_host as a post parameter" do
151
+ selenium_host = 'test-runner'
152
+ mock(Client).run(:selenium_host => selenium_host)
153
+ client = Client.run_argv(['--selenium_host', selenium_host])
154
+ end
155
+ end
156
+
157
+ context "when passed-in Hash contains :selenium_port" do
158
+ it "passes the selenium_port as a post parameter" do
159
+ selenium_port = "5000"
160
+ mock(Client).run(:selenium_port => selenium_port)
161
+ client = Client.run_argv(['--selenium_port', selenium_port])
162
+ end
163
+ end
164
+
165
+ context "when passed-in Hash contains :timeout" do
166
+ it "passes the timeout as a post parameter" do
167
+ mock(Client).run(:timeout => 5)
168
+ client = Client.run_argv(['--timeout', "5"])
169
+ end
170
+ end
171
+ end
172
+
173
+ describe '#parts_from_query' do
174
+ attr_reader :client
175
+ before do
176
+ @client = Client.new(params_does_not_matter = {})
177
+ end
178
+
179
+ it "parses empty query into an empty hash" do
180
+ client.parts_from_query("").should == {}
181
+ end
182
+
183
+ it "parses a single key value pair into a single-element hash" do
184
+ client.parts_from_query("foo=bar").should == {'foo' => 'bar'}
185
+ end
186
+
187
+ it "parses a multiple key value pairs into a multi-element hash" do
188
+ client.parts_from_query("foo=bar&baz=quux").should == {'foo' => 'bar', 'baz' => 'quux'}
189
+ end
190
+ end
191
+ end
192
+ end
@@ -0,0 +1,44 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../unit_spec_helper")
2
+
3
+ module JsTestCore
4
+ describe Configuration do
5
+ attr_reader :result
6
+
7
+ before do
8
+ @result = ""
9
+ end
10
+
11
+ describe ".spec_root" do
12
+ it "returns the Dir " do
13
+ Configuration.spec_root_path.should == spec_root_path
14
+ end
15
+ end
16
+
17
+ describe ".spec_root_path" do
18
+ it "returns the absolute path of the specs root directory" do
19
+ Configuration.spec_root_path.should == spec_root_path
20
+ end
21
+ end
22
+
23
+ describe ".public_path" do
24
+ it "returns the expanded path of the public path" do
25
+ Configuration.public_path.should == public_path
26
+ end
27
+ end
28
+
29
+ describe ".core_path" do
30
+ it "returns the expanded path to the JsTestCore core directory" do
31
+ Configuration.core_path.should == core_path
32
+ end
33
+ end
34
+
35
+ describe "#root_url" do
36
+ it "returns the url of the site's root" do
37
+ server = Configuration.new
38
+ server.host = "localhost"
39
+ server.port = 9999
40
+ server.root_url.should == "http://localhost:9999"
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,85 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../unit_spec_helper")
2
+
3
+ module JsTestCore
4
+ module Models
5
+ describe SeleniumSession do
6
+ attr_reader :driver, :session_id, :selenium_session
7
+
8
+ before do
9
+ @driver = FakeSeleniumDriver.new
10
+ @selenium_session = SeleniumSession.new(:spec_url => "http://localhost:8080/specs")
11
+ stub(selenium_session).driver {driver}
12
+ driver.start
13
+ @session_id = driver.session_id
14
+ SeleniumSession.register(selenium_session)
15
+ end
16
+
17
+ describe ".find" do
18
+ context "when passed an id for which there is a corresponding selenium_session" do
19
+ it "returns the selenium_session" do
20
+ SeleniumSession.find(session_id).should == selenium_session
21
+ end
22
+ end
23
+
24
+ context "when passed an id for which there is no corresponding selenium_session" do
25
+ it "returns nil" do
26
+ invalid_id = "666666666666666"
27
+ SeleniumSession.find(invalid_id).should be_nil
28
+ end
29
+ end
30
+ end
31
+
32
+ describe "#running?" do
33
+ context "when the driver#session_started? is true" do
34
+ it "returns true" do
35
+ driver.session_started?.should be_true
36
+ selenium_session.should be_running
37
+ end
38
+ end
39
+
40
+ context "when the driver#session_started? is false" do
41
+ it "returns false" do
42
+ driver.stop
43
+ driver.session_started?.should be_false
44
+ selenium_session.should_not be_running
45
+ end
46
+ end
47
+ end
48
+
49
+ describe "#finalize" do
50
+ attr_reader :selenium_session
51
+
52
+ before do
53
+ mock.proxy(driver).stop
54
+ end
55
+
56
+ it "kills the browser and stores the #run_result" do
57
+ run_result = "The session run result"
58
+ selenium_session.finish(run_result)
59
+ selenium_session.run_result.should == run_result
60
+ end
61
+
62
+ it "sets #run_result" do
63
+ selenium_session.finish("the result")
64
+ selenium_session.run_result.should == "the result"
65
+ end
66
+
67
+ context "when passed an empty string" do
68
+ it "causes #successful? to be true" do
69
+ selenium_session.finish("")
70
+ selenium_session.should be_successful
71
+ selenium_session.should_not be_failed
72
+ end
73
+ end
74
+
75
+ context "when passed a non-empty string" do
76
+ it "causes #successful? to be false" do
77
+ selenium_session.finish("A bunch of error stuff")
78
+ selenium_session.should_not be_successful
79
+ selenium_session.should be_failed
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,60 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../unit_spec_helper")
2
+
3
+ module JsTestCore
4
+ module Resources
5
+ describe CoreFile do
6
+ describe "Files" do
7
+ describe "GET /core/JsTestCore.js" do
8
+ it "renders the JsTestCore.js file, which lives in the core framework directory" do
9
+ absolute_path = "#{core_path}/JsTestCore.js"
10
+
11
+ response = get(CoreFile.path("JsTestCore.js"))
12
+ response.should be_http(
13
+ 200,
14
+ {
15
+ "Content-Type" => "text/javascript",
16
+ "Last-Modified" => ::File.mtime(absolute_path).rfc822
17
+ },
18
+ ::File.read(absolute_path)
19
+ )
20
+ end
21
+ end
22
+ end
23
+
24
+ describe "Directories" do
25
+ macro "returns a page with the files in the root core directory" do |relative_path|
26
+ it "returns a page with the files in the root core directory" do
27
+ response = get(CoreFile.path(relative_path))
28
+ response.should be_http(
29
+ 200,
30
+ {},
31
+ ""
32
+ )
33
+ doc = Nokogiri::HTML(response.body)
34
+ links = doc.search("a").map {|script| script["href"]}
35
+ links.should include("/core/JsTestCore.js")
36
+ links.should include("/core/JsTestCore.css")
37
+ links.should include("/core/subdir")
38
+ end
39
+ end
40
+ describe "GET /core" do
41
+ send("returns a page with the files in the root core directory", "")
42
+ end
43
+ describe "GET /core/" do
44
+ send("returns a page with the files in the root core directory", "/")
45
+ end
46
+
47
+ describe "GET /core/subdir" do
48
+ it "returns a page with the files in the directory" do
49
+ response = get(CoreFile.path("subdir"))
50
+ response.should be_http(
51
+ 200,
52
+ {},
53
+ %r(<a href="/core/subdir/SubDirFile.js">SubDirFile.js</a>)
54
+ )
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,81 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../unit_spec_helper")
2
+
3
+ module JsTestCore
4
+ module Resources
5
+ describe File do
6
+ describe "Files" do
7
+ describe "GET /stylesheets/example.css" do
8
+ it "returns the example.css file content as a css file" do
9
+ path = "#{public_path}/stylesheets/example.css"
10
+ response = get("/stylesheets/example.css")
11
+ response.should be_http(
12
+ 200,
13
+ {
14
+ 'Content-Length' => ::File.size(path).to_s,
15
+ 'Content-Type' => "text/css",
16
+ 'Last-Modified' => ::File.mtime(path).rfc822
17
+ },
18
+ ::File.read(path)
19
+ )
20
+ end
21
+ end
22
+
23
+ describe "GET /javascripts/foo.js" do
24
+ it "returns the foo.js file content as a javascript file" do
25
+ path = "#{public_path}/javascripts/foo.js"
26
+ response = get("/javascripts/foo.js")
27
+ response.should be_http(
28
+ 200,
29
+ {
30
+ 'Content-Length' => ::File.size(path).to_s,
31
+ 'Content-Type' => "text/javascript",
32
+ 'Last-Modified' => ::File.mtime(path).rfc822
33
+ },
34
+ ::File.read(path)
35
+ )
36
+ end
37
+ end
38
+
39
+ describe "GET /javascripts/subdir/bar.js - Subdirectory" do
40
+ it "returns the subdir/bar.js file content as a javascript file" do
41
+ path = "#{public_path}/javascripts/subdir/bar.js"
42
+ response = get("/javascripts/subdir/bar.js")
43
+ response.should be_http(
44
+ 200,
45
+ {
46
+ 'Content-Length' => ::File.size(path).to_s,
47
+ 'Content-Type' => "text/javascript",
48
+ 'Last-Modified' => ::File.mtime(path).rfc822
49
+ },
50
+ ::File.read(path)
51
+ )
52
+ end
53
+ end
54
+ end
55
+
56
+ describe "Directories" do
57
+ describe "GET /stylesheets - Top level directory" do
58
+ it "returns a page with a of files in the directory" do
59
+ response = get("/stylesheets")
60
+ response.should be_http(
61
+ 200,
62
+ {},
63
+ %r(<a href="/stylesheets/example.css">example.css</a>)
64
+ )
65
+ end
66
+ end
67
+
68
+ describe "GET /javascripts/subdir - Subdirectory" do
69
+ it "returns a page with a of files in the directory" do
70
+ response = get("/javascripts/subdir")
71
+ response.should be_http(
72
+ 200,
73
+ {},
74
+ %r(<a href="/javascripts/subdir/bar.js">bar.js</a>)
75
+ )
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end