pivotal-screw-unit-server 0.5.3

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 +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