aldebaran 1.0.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.
- data/.gitignore +13 -0
- data/.travis.yml +16 -0
- data/.yardopts +4 -0
- data/AUTHORS +4 -0
- data/Gemfile +77 -0
- data/KNOWN_ISSUES +5 -0
- data/LICENSE +22 -0
- data/README.rdoc +1900 -0
- data/Rakefile +175 -0
- data/aldebaran.gemspec +19 -0
- data/lib/aldebaran.rb +7 -0
- data/lib/aldebaran/base.rb +1600 -0
- data/lib/aldebaran/images/404.png +0 -0
- data/lib/aldebaran/images/500.png +0 -0
- data/lib/aldebaran/main.rb +28 -0
- data/lib/aldebaran/showexceptions.rb +340 -0
- data/lib/aldebaran/version.rb +3 -0
- data/test/aldebaran_test.rb +17 -0
- data/test/base_test.rb +160 -0
- data/test/builder_test.rb +95 -0
- data/test/coffee_test.rb +92 -0
- data/test/contest.rb +98 -0
- data/test/creole_test.rb +65 -0
- data/test/delegator_test.rb +162 -0
- data/test/encoding_test.rb +20 -0
- data/test/erb_test.rb +104 -0
- data/test/extensions_test.rb +100 -0
- data/test/filter_test.rb +397 -0
- data/test/haml_test.rb +101 -0
- data/test/helper.rb +115 -0
- data/test/helpers_test.rb +1192 -0
- data/test/less_test.rb +67 -0
- data/test/liquid_test.rb +59 -0
- data/test/mapped_error_test.rb +259 -0
- data/test/markaby_test.rb +80 -0
- data/test/markdown_test.rb +81 -0
- data/test/middleware_test.rb +68 -0
- data/test/nokogiri_test.rb +69 -0
- data/test/public/favicon.ico +0 -0
- data/test/radius_test.rb +59 -0
- data/test/rdoc_test.rb +65 -0
- data/test/readme_test.rb +136 -0
- data/test/request_test.rb +45 -0
- data/test/response_test.rb +61 -0
- data/test/result_test.rb +98 -0
- data/test/route_added_hook_test.rb +59 -0
- data/test/routing_test.rb +1096 -0
- data/test/sass_test.rb +115 -0
- data/test/scss_test.rb +88 -0
- data/test/server_test.rb +48 -0
- data/test/settings_test.rb +493 -0
- data/test/slim_test.rb +98 -0
- data/test/static_test.rb +178 -0
- data/test/streaming_test.rb +100 -0
- data/test/templates_test.rb +298 -0
- data/test/textile_test.rb +65 -0
- data/test/views/a/in_a.str +1 -0
- data/test/views/ascii.erb +2 -0
- data/test/views/b/in_b.str +1 -0
- data/test/views/calc.html.erb +1 -0
- data/test/views/error.builder +3 -0
- data/test/views/error.erb +3 -0
- data/test/views/error.haml +3 -0
- data/test/views/error.sass +2 -0
- data/test/views/explicitly_nested.str +1 -0
- data/test/views/foo/hello.test +1 -0
- data/test/views/hello.builder +1 -0
- data/test/views/hello.coffee +1 -0
- data/test/views/hello.creole +1 -0
- data/test/views/hello.erb +1 -0
- data/test/views/hello.haml +1 -0
- data/test/views/hello.less +5 -0
- data/test/views/hello.liquid +1 -0
- data/test/views/hello.mab +1 -0
- data/test/views/hello.md +1 -0
- data/test/views/hello.nokogiri +1 -0
- data/test/views/hello.radius +1 -0
- data/test/views/hello.rdoc +1 -0
- data/test/views/hello.sass +2 -0
- data/test/views/hello.scss +3 -0
- data/test/views/hello.slim +1 -0
- data/test/views/hello.str +1 -0
- data/test/views/hello.test +1 -0
- data/test/views/hello.textile +1 -0
- data/test/views/layout2.builder +3 -0
- data/test/views/layout2.erb +2 -0
- data/test/views/layout2.haml +2 -0
- data/test/views/layout2.liquid +2 -0
- data/test/views/layout2.mab +2 -0
- data/test/views/layout2.nokogiri +3 -0
- data/test/views/layout2.radius +2 -0
- data/test/views/layout2.slim +3 -0
- data/test/views/layout2.str +2 -0
- data/test/views/layout2.test +1 -0
- data/test/views/nested.str +1 -0
- data/test/views/utf8.erb +2 -0
- metadata +231 -0
data/test/less_test.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
require File.expand_path('../helper', __FILE__)
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'less'
|
5
|
+
|
6
|
+
class LessTest < Test::Unit::TestCase
|
7
|
+
def less_app(options = {}, &block)
|
8
|
+
mock_app {
|
9
|
+
set :views, File.dirname(__FILE__) + '/views'
|
10
|
+
set options
|
11
|
+
get '/', &block
|
12
|
+
}
|
13
|
+
get '/'
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'renders inline Less strings' do
|
17
|
+
less_app { less "@white_color: #fff; #main { background-color: @white_color }" }
|
18
|
+
assert ok?
|
19
|
+
assert_equal "#main { background-color: #ffffff; }\n", body
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'defaults content type to css' do
|
23
|
+
less_app { less "@white_color: #fff; #main { background-color: @white_color }" }
|
24
|
+
assert ok?
|
25
|
+
assert_equal "text/css;charset=utf-8", response['Content-Type']
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'defaults allows setting content type per route' do
|
29
|
+
less_app do
|
30
|
+
content_type :html
|
31
|
+
less "@white_color: #fff; #main { background-color: @white_color }"
|
32
|
+
end
|
33
|
+
assert ok?
|
34
|
+
assert_equal "text/html;charset=utf-8", response['Content-Type']
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'defaults allows setting content type globally' do
|
38
|
+
less_app(:less => { :content_type => 'html' }) do
|
39
|
+
less "@white_color: #fff; #main { background-color: @white_color }"
|
40
|
+
end
|
41
|
+
assert ok?
|
42
|
+
assert_equal "text/html;charset=utf-8", response['Content-Type']
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'renders .less files in views path' do
|
46
|
+
less_app { less :hello }
|
47
|
+
assert ok?
|
48
|
+
assert_equal "#main { background-color: #ffffff; }\n", body
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'ignores the layout option' do
|
52
|
+
less_app { less :hello, :layout => :layout2 }
|
53
|
+
assert ok?
|
54
|
+
assert_equal "#main { background-color: #ffffff; }\n", body
|
55
|
+
end
|
56
|
+
|
57
|
+
it "raises error if template not found" do
|
58
|
+
mock_app {
|
59
|
+
get('/') { less :no_such_template }
|
60
|
+
}
|
61
|
+
assert_raise(Errno::ENOENT) { get('/') }
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
rescue LoadError
|
66
|
+
warn "#{$!.to_s}: skipping less tests"
|
67
|
+
end
|
data/test/liquid_test.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
require File.expand_path('../helper', __FILE__)
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'liquid'
|
5
|
+
|
6
|
+
class LiquidTest < Test::Unit::TestCase
|
7
|
+
def liquid_app(&block)
|
8
|
+
mock_app do
|
9
|
+
set :views, File.dirname(__FILE__) + '/views'
|
10
|
+
get '/', &block
|
11
|
+
end
|
12
|
+
get '/'
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'renders inline liquid strings' do
|
16
|
+
liquid_app { liquid '<h1>Hiya</h1>' }
|
17
|
+
assert ok?
|
18
|
+
assert_equal "<h1>Hiya</h1>", body
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'renders .liquid files in views path' do
|
22
|
+
liquid_app { liquid :hello }
|
23
|
+
assert ok?
|
24
|
+
assert_equal "<h1>Hello From Liquid</h1>\n", body
|
25
|
+
end
|
26
|
+
|
27
|
+
it "renders with inline layouts" do
|
28
|
+
mock_app do
|
29
|
+
layout { "<h1>THIS. IS. {{ yield }}</h1>" }
|
30
|
+
get('/') { liquid '<EM>SPARTA</EM>' }
|
31
|
+
end
|
32
|
+
get '/'
|
33
|
+
assert ok?
|
34
|
+
assert_equal "<h1>THIS. IS. <EM>SPARTA</EM></h1>", body
|
35
|
+
end
|
36
|
+
|
37
|
+
it "renders with file layouts" do
|
38
|
+
liquid_app { liquid 'Hello World', :layout => :layout2 }
|
39
|
+
assert ok?
|
40
|
+
assert_equal "<h1>Liquid Layout!</h1>\n<p>Hello World</p>\n", body
|
41
|
+
end
|
42
|
+
|
43
|
+
it "raises error if template not found" do
|
44
|
+
mock_app { get('/') { liquid :no_such_template } }
|
45
|
+
assert_raise(Errno::ENOENT) { get('/') }
|
46
|
+
end
|
47
|
+
|
48
|
+
it "allows passing locals" do
|
49
|
+
liquid_app do
|
50
|
+
liquid '{{ value }}', :locals => { :value => 'foo' }
|
51
|
+
end
|
52
|
+
assert ok?
|
53
|
+
assert_equal 'foo', body
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
rescue LoadError
|
58
|
+
warn "#{$!.to_s}: skipping liquid tests"
|
59
|
+
end
|
@@ -0,0 +1,259 @@
|
|
1
|
+
require File.expand_path('../helper', __FILE__)
|
2
|
+
|
3
|
+
class FooError < RuntimeError
|
4
|
+
end
|
5
|
+
|
6
|
+
class FooNotFound < aldebaran::NotFound
|
7
|
+
end
|
8
|
+
|
9
|
+
class FooSpecialError < RuntimeError
|
10
|
+
def code; 501 end
|
11
|
+
end
|
12
|
+
|
13
|
+
class MappedErrorTest < Test::Unit::TestCase
|
14
|
+
def test_default
|
15
|
+
assert true
|
16
|
+
end
|
17
|
+
|
18
|
+
describe 'Exception Mappings' do
|
19
|
+
it 'invokes handlers registered with ::error when raised' do
|
20
|
+
mock_app {
|
21
|
+
set :raise_errors, false
|
22
|
+
error(FooError) { 'Foo!' }
|
23
|
+
get '/' do
|
24
|
+
raise FooError
|
25
|
+
end
|
26
|
+
}
|
27
|
+
get '/'
|
28
|
+
assert_equal 500, status
|
29
|
+
assert_equal 'Foo!', body
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'passes the exception object to the error handler' do
|
33
|
+
mock_app do
|
34
|
+
set :raise_errors, false
|
35
|
+
error(FooError) { |e| assert_equal(FooError, e.class) }
|
36
|
+
get('/') { raise FooError }
|
37
|
+
end
|
38
|
+
get('/')
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'uses the Exception handler if no matching handler found' do
|
42
|
+
mock_app {
|
43
|
+
set :raise_errors, false
|
44
|
+
error(Exception) { 'Exception!' }
|
45
|
+
get '/' do
|
46
|
+
raise FooError
|
47
|
+
end
|
48
|
+
}
|
49
|
+
|
50
|
+
get '/'
|
51
|
+
assert_equal 500, status
|
52
|
+
assert_equal 'Exception!', body
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'walks down inheritance chain for errors' do
|
56
|
+
mock_app {
|
57
|
+
set :raise_errors, false
|
58
|
+
error(RuntimeError) { 'Exception!' }
|
59
|
+
get '/' do
|
60
|
+
raise FooError
|
61
|
+
end
|
62
|
+
}
|
63
|
+
|
64
|
+
get '/'
|
65
|
+
assert_equal 500, status
|
66
|
+
assert_equal 'Exception!', body
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'favors subclass handler over superclass handler if available' do
|
70
|
+
mock_app {
|
71
|
+
set :raise_errors, false
|
72
|
+
error(Exception) { 'Exception!' }
|
73
|
+
error(FooError) { 'FooError!' }
|
74
|
+
error(RuntimeError) { 'Exception!' }
|
75
|
+
get '/' do
|
76
|
+
raise FooError
|
77
|
+
end
|
78
|
+
}
|
79
|
+
|
80
|
+
get '/'
|
81
|
+
assert_equal 500, status
|
82
|
+
assert_equal 'FooError!', body
|
83
|
+
end
|
84
|
+
|
85
|
+
it "sets env['aldebaran.error'] to the rescued exception" do
|
86
|
+
mock_app {
|
87
|
+
set :raise_errors, false
|
88
|
+
error(FooError) {
|
89
|
+
assert env.include?('aldebaran.error')
|
90
|
+
assert env['aldebaran.error'].kind_of?(FooError)
|
91
|
+
'looks good'
|
92
|
+
}
|
93
|
+
get '/' do
|
94
|
+
raise FooError
|
95
|
+
end
|
96
|
+
}
|
97
|
+
get '/'
|
98
|
+
assert_equal 'looks good', body
|
99
|
+
end
|
100
|
+
|
101
|
+
it "raises errors from the app when raise_errors set and no handler defined" do
|
102
|
+
mock_app {
|
103
|
+
set :raise_errors, true
|
104
|
+
get '/' do
|
105
|
+
raise FooError
|
106
|
+
end
|
107
|
+
}
|
108
|
+
assert_raise(FooError) { get '/' }
|
109
|
+
end
|
110
|
+
|
111
|
+
it "calls error handlers before raising errors even when raise_errors is set" do
|
112
|
+
mock_app {
|
113
|
+
set :raise_errors, true
|
114
|
+
error(FooError) { "she's there." }
|
115
|
+
get '/' do
|
116
|
+
raise FooError
|
117
|
+
end
|
118
|
+
}
|
119
|
+
assert_nothing_raised { get '/' }
|
120
|
+
assert_equal 500, status
|
121
|
+
end
|
122
|
+
|
123
|
+
it "never raises aldebaran::NotFound beyond the application" do
|
124
|
+
mock_app(aldebaran::Application) { get('/') { raise aldebaran::NotFound }}
|
125
|
+
assert_nothing_raised { get '/' }
|
126
|
+
assert_equal 404, status
|
127
|
+
end
|
128
|
+
|
129
|
+
it "cascades for subclasses of aldebaran::NotFound" do
|
130
|
+
mock_app {
|
131
|
+
set :raise_errors, true
|
132
|
+
error(FooNotFound) { "foo! not found." }
|
133
|
+
get '/' do
|
134
|
+
raise FooNotFound
|
135
|
+
end
|
136
|
+
}
|
137
|
+
assert_nothing_raised { get '/' }
|
138
|
+
assert_equal 404, status
|
139
|
+
assert_equal 'foo! not found.', body
|
140
|
+
end
|
141
|
+
|
142
|
+
it 'has a not_found method for backwards compatibility' do
|
143
|
+
mock_app {
|
144
|
+
not_found do
|
145
|
+
"Lost, are we?"
|
146
|
+
end
|
147
|
+
}
|
148
|
+
|
149
|
+
get '/test'
|
150
|
+
assert_equal 404, status
|
151
|
+
assert_equal "Lost, are we?", body
|
152
|
+
end
|
153
|
+
|
154
|
+
it 'inherits error mappings from base class' do
|
155
|
+
base = Class.new(aldebaran::Base)
|
156
|
+
base.error(FooError) { 'base class' }
|
157
|
+
|
158
|
+
mock_app(base) {
|
159
|
+
set :raise_errors, false
|
160
|
+
get '/' do
|
161
|
+
raise FooError
|
162
|
+
end
|
163
|
+
}
|
164
|
+
|
165
|
+
get '/'
|
166
|
+
assert_equal 'base class', body
|
167
|
+
end
|
168
|
+
|
169
|
+
it 'overrides error mappings in base class' do
|
170
|
+
base = Class.new(aldebaran::Base)
|
171
|
+
base.error(FooError) { 'base class' }
|
172
|
+
|
173
|
+
mock_app(base) {
|
174
|
+
set :raise_errors, false
|
175
|
+
error(FooError) { 'subclass' }
|
176
|
+
get '/' do
|
177
|
+
raise FooError
|
178
|
+
end
|
179
|
+
}
|
180
|
+
|
181
|
+
get '/'
|
182
|
+
assert_equal 'subclass', body
|
183
|
+
end
|
184
|
+
|
185
|
+
it 'honors Exception#code if present' do
|
186
|
+
mock_app do
|
187
|
+
set :raise_errors, false
|
188
|
+
error(501) { 'Foo!' }
|
189
|
+
get('/') { raise FooSpecialError }
|
190
|
+
end
|
191
|
+
get '/'
|
192
|
+
assert_equal 501, status
|
193
|
+
assert_equal 'Foo!', body
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
describe 'Custom Error Pages' do
|
198
|
+
it 'allows numeric status code mappings to be registered with ::error' do
|
199
|
+
mock_app {
|
200
|
+
set :raise_errors, false
|
201
|
+
error(500) { 'Foo!' }
|
202
|
+
get '/' do
|
203
|
+
[500, {}, 'Internal Foo Error']
|
204
|
+
end
|
205
|
+
}
|
206
|
+
get '/'
|
207
|
+
assert_equal 500, status
|
208
|
+
assert_equal 'Foo!', body
|
209
|
+
end
|
210
|
+
|
211
|
+
it 'allows ranges of status code mappings to be registered with :error' do
|
212
|
+
mock_app {
|
213
|
+
set :raise_errors, false
|
214
|
+
error(500..550) { "Error: #{response.status}" }
|
215
|
+
get '/' do
|
216
|
+
[507, {}, 'A very special error']
|
217
|
+
end
|
218
|
+
}
|
219
|
+
get '/'
|
220
|
+
assert_equal 507, status
|
221
|
+
assert_equal 'Error: 507', body
|
222
|
+
end
|
223
|
+
|
224
|
+
it 'allows passing more than one range' do
|
225
|
+
mock_app {
|
226
|
+
set :raise_errors, false
|
227
|
+
error(409..411, 503..509) { "Error: #{response.status}" }
|
228
|
+
get '/' do
|
229
|
+
[507, {}, 'A very special error']
|
230
|
+
end
|
231
|
+
}
|
232
|
+
get '/'
|
233
|
+
assert_equal 507, status
|
234
|
+
assert_equal 'Error: 507', body
|
235
|
+
end
|
236
|
+
|
237
|
+
class FooError < RuntimeError
|
238
|
+
end
|
239
|
+
|
240
|
+
it 'runs after exception mappings and overwrites body' do
|
241
|
+
mock_app {
|
242
|
+
set :raise_errors, false
|
243
|
+
error FooError do
|
244
|
+
response.status = 502
|
245
|
+
'from exception mapping'
|
246
|
+
end
|
247
|
+
error(500) { 'from 500 handler' }
|
248
|
+
error(502) { 'from custom error page' }
|
249
|
+
|
250
|
+
get '/' do
|
251
|
+
raise FooError
|
252
|
+
end
|
253
|
+
}
|
254
|
+
get '/'
|
255
|
+
assert_equal 502, status
|
256
|
+
assert_equal 'from custom error page', body
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require File.expand_path('../helper', __FILE__)
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'markaby'
|
5
|
+
|
6
|
+
class MarkabyTest < Test::Unit::TestCase
|
7
|
+
def markaby_app(&block)
|
8
|
+
mock_app do
|
9
|
+
set :views, File.dirname(__FILE__) + '/views'
|
10
|
+
get '/', &block
|
11
|
+
end
|
12
|
+
get '/'
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'renders inline markaby strings' do
|
16
|
+
markaby_app { markaby 'h1 "Hiya"' }
|
17
|
+
assert ok?
|
18
|
+
assert_equal "<h1>Hiya</h1>", body
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'renders .markaby files in views path' do
|
22
|
+
markaby_app { markaby :hello }
|
23
|
+
assert ok?
|
24
|
+
assert_equal "<h1>Hello From Markaby</h1>", body
|
25
|
+
end
|
26
|
+
|
27
|
+
it "renders with inline layouts" do
|
28
|
+
mock_app do
|
29
|
+
layout { 'h1 { text "THIS. IS. "; yield }' }
|
30
|
+
get('/') { markaby 'em "SPARTA"' }
|
31
|
+
end
|
32
|
+
get '/'
|
33
|
+
assert ok?
|
34
|
+
assert_equal "<h1>THIS. IS. <em>SPARTA</em></h1>", body
|
35
|
+
end
|
36
|
+
|
37
|
+
it "renders with file layouts" do
|
38
|
+
markaby_app { markaby 'text "Hello World"', :layout => :layout2 }
|
39
|
+
assert ok?
|
40
|
+
assert_equal "<h1>Markaby Layout!</h1><p>Hello World</p>", body
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'renders inline markaby blocks' do
|
44
|
+
markaby_app { markaby { h1 'Hiya' } }
|
45
|
+
assert ok?
|
46
|
+
assert_equal "<h1>Hiya</h1>", body
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'renders inline markaby blocks with inline layouts' do
|
50
|
+
markaby_app do
|
51
|
+
settings.layout { 'h1 { text "THIS. IS. "; yield }' }
|
52
|
+
markaby { em 'SPARTA' }
|
53
|
+
end
|
54
|
+
assert ok?
|
55
|
+
assert_equal "<h1>THIS. IS. <em>SPARTA</em></h1>", body
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'renders inline markaby blocks with file layouts' do
|
59
|
+
markaby_app { markaby(:layout => :layout2) { text "Hello World" } }
|
60
|
+
assert ok?
|
61
|
+
assert_equal "<h1>Markaby Layout!</h1><p>Hello World</p>", body
|
62
|
+
end
|
63
|
+
|
64
|
+
it "raises error if template not found" do
|
65
|
+
mock_app { get('/') { markaby :no_such_template } }
|
66
|
+
assert_raise(Errno::ENOENT) { get('/') }
|
67
|
+
end
|
68
|
+
|
69
|
+
it "allows passing locals" do
|
70
|
+
markaby_app do
|
71
|
+
markaby 'text value', :locals => { :value => 'foo' }
|
72
|
+
end
|
73
|
+
assert ok?
|
74
|
+
assert_equal 'foo', body
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
rescue LoadError
|
79
|
+
warn "#{$!.to_s}: skipping markaby tests"
|
80
|
+
end
|