sinatra 1.1.4 → 1.2.0
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/AUTHORS +5 -1
- data/CHANGES +47 -2
- data/Gemfile +53 -0
- data/README.de.rdoc +732 -85
- data/README.es.rdoc +725 -75
- data/README.fr.rdoc +29 -16
- data/README.hu.rdoc +4 -4
- data/README.jp.rdoc +29 -16
- data/README.pt-br.rdoc +6 -6
- data/README.rdoc +664 -91
- data/README.ru.rdoc +257 -75
- data/README.zh.rdoc +889 -111
- data/Rakefile +7 -32
- data/lib/sinatra/base.rb +133 -66
- data/lib/sinatra/showexceptions.rb +25 -0
- data/sinatra.gemspec +10 -18
- data/test/builder_test.rb +6 -0
- data/test/coffee_test.rb +1 -1
- data/test/encoding_test.rb +4 -3
- data/test/erubis_test.rb +6 -0
- data/test/filter_test.rb +105 -1
- data/test/haml_test.rb +2 -1
- data/test/helper.rb +2 -0
- data/test/helpers_test.rb +105 -13
- data/test/less_test.rb +6 -0
- data/test/liquid_test.rb +2 -1
- data/test/markaby_test.rb +23 -1
- data/test/markdown_test.rb +3 -2
- data/test/nokogiri_test.rb +2 -1
- data/test/radius_test.rb +3 -2
- data/test/rdoc_test.rb +3 -2
- data/test/routing_test.rb +38 -1
- data/test/sass_test.rb +1 -1
- data/test/scss_test.rb +1 -1
- data/test/slim_test.rb +98 -0
- data/test/templates_test.rb +53 -0
- data/test/textile_test.rb +2 -1
- data/test/views/a/in_a.str +1 -0
- data/test/views/{ascii.haml → ascii.erb} +1 -1
- data/test/views/b/in_b.str +1 -0
- data/test/views/hello.slim +1 -0
- data/test/views/layout2.slim +3 -0
- data/test/views/{utf8.haml → utf8.erb} +1 -1
- metadata +42 -161
data/test/filter_test.rb
CHANGED
|
@@ -274,7 +274,7 @@ class AfterFilterTest < Test::Unit::TestCase
|
|
|
274
274
|
get '/foo/bar'
|
|
275
275
|
assert_equal subpath, 'bar'
|
|
276
276
|
end
|
|
277
|
-
|
|
277
|
+
|
|
278
278
|
it 'is possible to access url params from the route param' do
|
|
279
279
|
ran = false
|
|
280
280
|
mock_app do
|
|
@@ -287,4 +287,108 @@ class AfterFilterTest < Test::Unit::TestCase
|
|
|
287
287
|
get '/foo/bar'
|
|
288
288
|
assert ran
|
|
289
289
|
end
|
|
290
|
+
|
|
291
|
+
it 'is possible to apply host_name conditions to before filters with no path' do
|
|
292
|
+
ran = false
|
|
293
|
+
mock_app do
|
|
294
|
+
before(:host_name => 'example.com') { ran = true }
|
|
295
|
+
get('/') { 'welcome' }
|
|
296
|
+
end
|
|
297
|
+
get '/', {}, { 'HTTP_HOST' => 'example.org' }
|
|
298
|
+
assert !ran
|
|
299
|
+
get '/', {}, { 'HTTP_HOST' => 'example.com' }
|
|
300
|
+
assert ran
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
it 'is possible to apply host_name conditions to before filters with a path' do
|
|
304
|
+
ran = false
|
|
305
|
+
mock_app do
|
|
306
|
+
before('/foo', :host_name => 'example.com') { ran = true }
|
|
307
|
+
get('/') { 'welcome' }
|
|
308
|
+
end
|
|
309
|
+
get '/', {}, { 'HTTP_HOST' => 'example.com' }
|
|
310
|
+
assert !ran
|
|
311
|
+
get '/foo', {}, { 'HTTP_HOST' => 'example.org' }
|
|
312
|
+
assert !ran
|
|
313
|
+
get '/foo', {}, { 'HTTP_HOST' => 'example.com' }
|
|
314
|
+
assert ran
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
it 'is possible to apply host_name conditions to after filters with no path' do
|
|
318
|
+
ran = false
|
|
319
|
+
mock_app do
|
|
320
|
+
after(:host_name => 'example.com') { ran = true }
|
|
321
|
+
get('/') { 'welcome' }
|
|
322
|
+
end
|
|
323
|
+
get '/', {}, { 'HTTP_HOST' => 'example.org' }
|
|
324
|
+
assert !ran
|
|
325
|
+
get '/', {}, { 'HTTP_HOST' => 'example.com' }
|
|
326
|
+
assert ran
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
it 'is possible to apply host_name conditions to after filters with a path' do
|
|
330
|
+
ran = false
|
|
331
|
+
mock_app do
|
|
332
|
+
after('/foo', :host_name => 'example.com') { ran = true }
|
|
333
|
+
get('/') { 'welcome' }
|
|
334
|
+
end
|
|
335
|
+
get '/', {}, { 'HTTP_HOST' => 'example.com' }
|
|
336
|
+
assert !ran
|
|
337
|
+
get '/foo', {}, { 'HTTP_HOST' => 'example.org' }
|
|
338
|
+
assert !ran
|
|
339
|
+
get '/foo', {}, { 'HTTP_HOST' => 'example.com' }
|
|
340
|
+
assert ran
|
|
341
|
+
end
|
|
342
|
+
|
|
343
|
+
it 'is possible to apply user_agent conditions to before filters with no path' do
|
|
344
|
+
ran = false
|
|
345
|
+
mock_app do
|
|
346
|
+
before(:user_agent => /foo/) { ran = true }
|
|
347
|
+
get('/') { 'welcome' }
|
|
348
|
+
end
|
|
349
|
+
get '/', {}, { 'HTTP_USER_AGENT' => 'bar' }
|
|
350
|
+
assert !ran
|
|
351
|
+
get '/', {}, { 'HTTP_USER_AGENT' => 'foo' }
|
|
352
|
+
assert ran
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
it 'is possible to apply user_agent conditions to before filters with a path' do
|
|
356
|
+
ran = false
|
|
357
|
+
mock_app do
|
|
358
|
+
before('/foo', :user_agent => /foo/) { ran = true }
|
|
359
|
+
get('/') { 'welcome' }
|
|
360
|
+
end
|
|
361
|
+
get '/', {}, { 'HTTP_USER_AGENT' => 'foo' }
|
|
362
|
+
assert !ran
|
|
363
|
+
get '/foo', {}, { 'HTTP_USER_AGENT' => 'bar' }
|
|
364
|
+
assert !ran
|
|
365
|
+
get '/foo', {}, { 'HTTP_USER_AGENT' => 'foo' }
|
|
366
|
+
assert ran
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
it 'is possible to apply user_agent conditions to after filters with no path' do
|
|
370
|
+
ran = false
|
|
371
|
+
mock_app do
|
|
372
|
+
after(:user_agent => /foo/) { ran = true }
|
|
373
|
+
get('/') { 'welcome' }
|
|
374
|
+
end
|
|
375
|
+
get '/', {}, { 'HTTP_USER_AGENT' => 'bar' }
|
|
376
|
+
assert !ran
|
|
377
|
+
get '/', {}, { 'HTTP_USER_AGENT' => 'foo' }
|
|
378
|
+
assert ran
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
it 'is possible to apply user_agent conditions to before filters with a path' do
|
|
382
|
+
ran = false
|
|
383
|
+
mock_app do
|
|
384
|
+
after('/foo', :user_agent => /foo/) { ran = true }
|
|
385
|
+
get('/') { 'welcome' }
|
|
386
|
+
end
|
|
387
|
+
get '/', {}, { 'HTTP_USER_AGENT' => 'foo' }
|
|
388
|
+
assert !ran
|
|
389
|
+
get '/foo', {}, { 'HTTP_USER_AGENT' => 'bar' }
|
|
390
|
+
assert !ran
|
|
391
|
+
get '/foo', {}, { 'HTTP_USER_AGENT' => 'foo' }
|
|
392
|
+
assert ran
|
|
393
|
+
end
|
|
290
394
|
end
|
data/test/haml_test.rb
CHANGED
data/test/helper.rb
CHANGED
data/test/helpers_test.rb
CHANGED
|
@@ -111,6 +111,18 @@ class HelpersTest < Test::Unit::TestCase
|
|
|
111
111
|
response = request.get('/', 'SERVER_PORT' => '444')
|
|
112
112
|
assert_equal 'http://example.org:444/foo', response['Location']
|
|
113
113
|
end
|
|
114
|
+
|
|
115
|
+
it 'works behind a reverse proxy' do
|
|
116
|
+
mock_app do
|
|
117
|
+
get '/' do
|
|
118
|
+
redirect '/foo'
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
request = Rack::MockRequest.new(@app)
|
|
123
|
+
response = request.get('/', 'HTTP_X_FORWARDED_HOST' => 'example.com', 'SERVER_PORT' => '8080')
|
|
124
|
+
assert_equal 'http://example.com/foo', response['Location']
|
|
125
|
+
end
|
|
114
126
|
end
|
|
115
127
|
|
|
116
128
|
describe 'error' do
|
|
@@ -419,6 +431,13 @@ class HelpersTest < Test::Unit::TestCase
|
|
|
419
431
|
assert_equal File.mtime(@file).httpdate, response['Last-Modified']
|
|
420
432
|
end
|
|
421
433
|
|
|
434
|
+
it 'allows passing in a differen Last-Modified response header with :last_modified' do
|
|
435
|
+
time = Time.now
|
|
436
|
+
send_file_app :last_modified => time
|
|
437
|
+
get '/file.txt'
|
|
438
|
+
assert_equal time.httpdate, response['Last-Modified']
|
|
439
|
+
end
|
|
440
|
+
|
|
422
441
|
it "returns a 404 when not found" do
|
|
423
442
|
mock_app {
|
|
424
443
|
get '/' do
|
|
@@ -441,6 +460,12 @@ class HelpersTest < Test::Unit::TestCase
|
|
|
441
460
|
assert_equal 'attachment; filename="file.txt"', response['Content-Disposition']
|
|
442
461
|
end
|
|
443
462
|
|
|
463
|
+
it "sets the Content-Disposition header when :disposition set to 'inline'" do
|
|
464
|
+
send_file_app :disposition => 'inline'
|
|
465
|
+
get '/file.txt'
|
|
466
|
+
assert_equal 'inline', response['Content-Disposition']
|
|
467
|
+
end
|
|
468
|
+
|
|
444
469
|
it "sets the Content-Disposition header when :filename provided" do
|
|
445
470
|
send_file_app :filename => 'foo.txt'
|
|
446
471
|
get '/file.txt'
|
|
@@ -482,39 +507,67 @@ class HelpersTest < Test::Unit::TestCase
|
|
|
482
507
|
|
|
483
508
|
describe 'cache_control' do
|
|
484
509
|
setup do
|
|
485
|
-
mock_app
|
|
486
|
-
get '/' do
|
|
510
|
+
mock_app do
|
|
511
|
+
get '/foo' do
|
|
487
512
|
cache_control :public, :no_cache, :max_age => 60.0
|
|
488
513
|
'Hello World'
|
|
489
514
|
end
|
|
490
|
-
|
|
515
|
+
|
|
516
|
+
get '/bar' do
|
|
517
|
+
cache_control :public, :no_cache
|
|
518
|
+
'Hello World'
|
|
519
|
+
end
|
|
520
|
+
end
|
|
491
521
|
end
|
|
492
522
|
|
|
493
523
|
it 'sets the Cache-Control header' do
|
|
494
|
-
get '/'
|
|
524
|
+
get '/foo'
|
|
495
525
|
assert_equal ['public', 'no-cache', 'max-age=60'], response['Cache-Control'].split(', ')
|
|
496
526
|
end
|
|
527
|
+
|
|
528
|
+
it 'last argument does not have to be a hash' do
|
|
529
|
+
get '/bar'
|
|
530
|
+
assert_equal ['public', 'no-cache'], response['Cache-Control'].split(', ')
|
|
531
|
+
end
|
|
497
532
|
end
|
|
498
533
|
|
|
499
534
|
describe 'expires' do
|
|
500
535
|
setup do
|
|
501
|
-
mock_app
|
|
502
|
-
get '/' do
|
|
536
|
+
mock_app do
|
|
537
|
+
get '/foo' do
|
|
503
538
|
expires 60, :public, :no_cache
|
|
504
539
|
'Hello World'
|
|
505
540
|
end
|
|
506
|
-
|
|
541
|
+
|
|
542
|
+
get '/bar' do
|
|
543
|
+
expires Time.now
|
|
544
|
+
end
|
|
545
|
+
|
|
546
|
+
get '/baz' do
|
|
547
|
+
expires Time.at(0)
|
|
548
|
+
end
|
|
549
|
+
end
|
|
507
550
|
end
|
|
508
551
|
|
|
509
552
|
it 'sets the Cache-Control header' do
|
|
510
|
-
get '/'
|
|
553
|
+
get '/foo'
|
|
511
554
|
assert_equal ['public', 'no-cache', 'max-age=60'], response['Cache-Control'].split(', ')
|
|
512
555
|
end
|
|
513
556
|
|
|
514
557
|
it 'sets the Expires header' do
|
|
515
|
-
get '/'
|
|
558
|
+
get '/foo'
|
|
559
|
+
assert_not_nil response['Expires']
|
|
560
|
+
end
|
|
561
|
+
|
|
562
|
+
it 'allows passing time objects' do
|
|
563
|
+
get '/bar'
|
|
516
564
|
assert_not_nil response['Expires']
|
|
517
565
|
end
|
|
566
|
+
|
|
567
|
+
it 'allows passing time objects' do
|
|
568
|
+
get '/baz'
|
|
569
|
+
assert_equal 'Thu, 01 Jan 1970 00:00:00 GMT', response['Expires']
|
|
570
|
+
end
|
|
518
571
|
end
|
|
519
572
|
|
|
520
573
|
describe 'last_modified' do
|
|
@@ -527,17 +580,18 @@ class HelpersTest < Test::Unit::TestCase
|
|
|
527
580
|
assert ! response['Last-Modified']
|
|
528
581
|
end
|
|
529
582
|
|
|
530
|
-
[Time, DateTime
|
|
531
|
-
|
|
583
|
+
[Time.now, DateTime.now, Date.today, Time.now.to_i,
|
|
584
|
+
Struct.new(:to_time).new(Time.now) ].each do |last_modified_time|
|
|
585
|
+
describe "with #{last_modified_time.class.name}" do
|
|
532
586
|
setup do
|
|
533
|
-
last_modified_time = klass.now
|
|
534
587
|
mock_app do
|
|
535
588
|
get '/' do
|
|
536
589
|
last_modified last_modified_time
|
|
537
590
|
'Boo!'
|
|
538
591
|
end
|
|
539
592
|
end
|
|
540
|
-
|
|
593
|
+
wrapper = Object.new.extend Sinatra::Helpers
|
|
594
|
+
@last_modified_time = wrapper.send :time_for, last_modified_time
|
|
541
595
|
end
|
|
542
596
|
|
|
543
597
|
# fixes strange missing test error when running complete test suite.
|
|
@@ -687,6 +741,44 @@ class HelpersTest < Test::Unit::TestCase
|
|
|
687
741
|
end
|
|
688
742
|
end
|
|
689
743
|
|
|
744
|
+
describe 'uri' do
|
|
745
|
+
it 'generates absolute urls' do
|
|
746
|
+
mock_app { get('/') { uri }}
|
|
747
|
+
get '/'
|
|
748
|
+
assert_equal 'http://example.org/', body
|
|
749
|
+
end
|
|
750
|
+
|
|
751
|
+
it 'includes path_info' do
|
|
752
|
+
mock_app { get('/:name') { uri }}
|
|
753
|
+
get '/foo'
|
|
754
|
+
assert_equal 'http://example.org/foo', body
|
|
755
|
+
end
|
|
756
|
+
|
|
757
|
+
it 'allows passing an alternative to path_info' do
|
|
758
|
+
mock_app { get('/:name') { uri '/bar' }}
|
|
759
|
+
get '/foo'
|
|
760
|
+
assert_equal 'http://example.org/bar', body
|
|
761
|
+
end
|
|
762
|
+
|
|
763
|
+
it 'includes script_name' do
|
|
764
|
+
mock_app { get('/:name') { uri '/bar' }}
|
|
765
|
+
get '/foo', {}, { "SCRIPT_NAME" => '/foo' }
|
|
766
|
+
assert_equal 'http://example.org/foo/bar', body
|
|
767
|
+
end
|
|
768
|
+
|
|
769
|
+
it 'is aliased to #url' do
|
|
770
|
+
mock_app { get('/') { url }}
|
|
771
|
+
get '/'
|
|
772
|
+
assert_equal 'http://example.org/', body
|
|
773
|
+
end
|
|
774
|
+
|
|
775
|
+
it 'is aliased to #to' do
|
|
776
|
+
mock_app { get('/') { to }}
|
|
777
|
+
get '/'
|
|
778
|
+
assert_equal 'http://example.org/', body
|
|
779
|
+
end
|
|
780
|
+
end
|
|
781
|
+
|
|
690
782
|
module ::HelperOne; def one; '1'; end; end
|
|
691
783
|
module ::HelperTwo; def two; '2'; end; end
|
|
692
784
|
|
data/test/less_test.rb
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
require File.dirname(__FILE__) + '/helper'
|
|
2
|
+
|
|
3
|
+
begin
|
|
2
4
|
require 'less'
|
|
3
5
|
|
|
4
6
|
class LessTest < Test::Unit::TestCase
|
|
@@ -59,3 +61,7 @@ class LessTest < Test::Unit::TestCase
|
|
|
59
61
|
assert_raise(Errno::ENOENT) { get('/') }
|
|
60
62
|
end
|
|
61
63
|
end
|
|
64
|
+
|
|
65
|
+
rescue LoadError
|
|
66
|
+
warn "#{$!.to_s}: skipping less tests"
|
|
67
|
+
end
|
data/test/liquid_test.rb
CHANGED
data/test/markaby_test.rb
CHANGED
|
@@ -40,6 +40,27 @@ class MarkabyTest < Test::Unit::TestCase
|
|
|
40
40
|
assert_equal "<h1>Markaby Layout!</h1><p>Hello World</p>", body
|
|
41
41
|
end
|
|
42
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
|
+
|
|
43
64
|
it "raises error if template not found" do
|
|
44
65
|
mock_app { get('/') { markaby :no_such_template } }
|
|
45
66
|
assert_raise(Errno::ENOENT) { get('/') }
|
|
@@ -53,6 +74,7 @@ class MarkabyTest < Test::Unit::TestCase
|
|
|
53
74
|
assert_equal 'foo', body
|
|
54
75
|
end
|
|
55
76
|
end
|
|
56
|
-
|
|
77
|
+
|
|
78
|
+
rescue LoadError
|
|
57
79
|
warn "#{$!.to_s}: skipping markaby tests"
|
|
58
80
|
end
|
data/test/markdown_test.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
require File.dirname(__FILE__) + '/helper'
|
|
2
2
|
|
|
3
3
|
begin
|
|
4
|
-
fail "rdiscount not available" if defined? JRuby
|
|
4
|
+
fail LoadError, "rdiscount not available" if defined? JRuby
|
|
5
5
|
require 'rdiscount'
|
|
6
6
|
|
|
7
7
|
class MarkdownTest < Test::Unit::TestCase
|
|
@@ -30,6 +30,7 @@ class MarkdownTest < Test::Unit::TestCase
|
|
|
30
30
|
assert_raise(Errno::ENOENT) { get('/') }
|
|
31
31
|
end
|
|
32
32
|
end
|
|
33
|
-
|
|
33
|
+
|
|
34
|
+
rescue LoadError
|
|
34
35
|
warn "#{$!.to_s}: skipping markdown tests"
|
|
35
36
|
end
|
data/test/nokogiri_test.rb
CHANGED
data/test/radius_test.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
require File.dirname(__FILE__) + '/helper'
|
|
2
2
|
|
|
3
3
|
begin
|
|
4
|
-
fail 'Radius broken on 1.9.' if RUBY_VERSION >= '1.9.1'
|
|
4
|
+
fail LoadError, 'Radius broken on 1.9.' if RUBY_VERSION >= '1.9.1'
|
|
5
5
|
require 'radius'
|
|
6
6
|
|
|
7
7
|
class RadiusTest < Test::Unit::TestCase
|
|
@@ -54,6 +54,7 @@ class RadiusTest < Test::Unit::TestCase
|
|
|
54
54
|
assert_equal 'foo', body
|
|
55
55
|
end
|
|
56
56
|
end
|
|
57
|
-
|
|
57
|
+
|
|
58
|
+
rescue LoadError
|
|
58
59
|
warn "#{$!.to_s}: skipping radius tests"
|
|
59
60
|
end
|
data/test/rdoc_test.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
require File.dirname(__FILE__) + '/helper'
|
|
2
2
|
|
|
3
3
|
begin
|
|
4
|
-
require 'rdoc'
|
|
4
|
+
require 'rdoc/markup/to_html'
|
|
5
5
|
|
|
6
6
|
class RdocTest < Test::Unit::TestCase
|
|
7
7
|
def rdoc_app(&block)
|
|
@@ -29,6 +29,7 @@ class RdocTest < Test::Unit::TestCase
|
|
|
29
29
|
assert_raise(Errno::ENOENT) { get('/') }
|
|
30
30
|
end
|
|
31
31
|
end
|
|
32
|
-
|
|
32
|
+
|
|
33
|
+
rescue LoadError
|
|
33
34
|
warn "#{$!.to_s}: skipping rdoc tests"
|
|
34
35
|
end
|
data/test/routing_test.rb
CHANGED
|
@@ -23,7 +23,7 @@ class RegexpLookAlike
|
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
class RoutingTest < Test::Unit::TestCase
|
|
26
|
-
%w[get put post delete].each do |verb|
|
|
26
|
+
%w[get put post delete options].each do |verb|
|
|
27
27
|
it "defines #{verb.upcase} request handlers with #{verb}" do
|
|
28
28
|
mock_app {
|
|
29
29
|
send verb, '/hello' do
|
|
@@ -179,6 +179,38 @@ class RoutingTest < Test::Unit::TestCase
|
|
|
179
179
|
assert_equal "foo=;bar=", body
|
|
180
180
|
end
|
|
181
181
|
|
|
182
|
+
it "supports named captures like %r{/hello/(?<person>[^/?#]+)} on Ruby >= 1.9" do
|
|
183
|
+
next if RUBY_VERSION < '1.9'
|
|
184
|
+
mock_app {
|
|
185
|
+
get Regexp.new('/hello/(?<person>[^/?#]+)') do
|
|
186
|
+
"Hello #{params['person']}"
|
|
187
|
+
end
|
|
188
|
+
}
|
|
189
|
+
get '/hello/Frank'
|
|
190
|
+
assert_equal 'Hello Frank', body
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
it "supports optional named captures like %r{/page(?<format>.[^/?#]+)?} on Ruby >= 1.9" do
|
|
194
|
+
next if RUBY_VERSION < '1.9'
|
|
195
|
+
mock_app {
|
|
196
|
+
get Regexp.new('/page(?<format>.[^/?#]+)?') do
|
|
197
|
+
"format=#{params[:format]}"
|
|
198
|
+
end
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
get '/page.html'
|
|
202
|
+
assert ok?
|
|
203
|
+
assert_equal "format=.html", body
|
|
204
|
+
|
|
205
|
+
get '/page.xml'
|
|
206
|
+
assert ok?
|
|
207
|
+
assert_equal "format=.xml", body
|
|
208
|
+
|
|
209
|
+
get '/page'
|
|
210
|
+
assert ok?
|
|
211
|
+
assert_equal "format=", body
|
|
212
|
+
end
|
|
213
|
+
|
|
182
214
|
it "supports single splat params like /*" do
|
|
183
215
|
mock_app {
|
|
184
216
|
get '/*' do
|
|
@@ -746,6 +778,11 @@ class RoutingTest < Test::Unit::TestCase
|
|
|
746
778
|
end
|
|
747
779
|
|
|
748
780
|
it 'raises an ArgumentError with block arity > 1 and too many values' do
|
|
781
|
+
if RUBY_ENGINE == "rbx"
|
|
782
|
+
$stderr.puts "\npending test: #{__method__}, #{__FILE__}:#{__LINE__} "
|
|
783
|
+
next
|
|
784
|
+
end
|
|
785
|
+
|
|
749
786
|
mock_app {
|
|
750
787
|
get '/:foo/:bar/:baz' do |foo, bar|
|
|
751
788
|
'quux'
|
data/test/sass_test.rb
CHANGED
data/test/scss_test.rb
CHANGED
data/test/slim_test.rb
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
|
2
|
+
|
|
3
|
+
begin
|
|
4
|
+
require 'slim'
|
|
5
|
+
|
|
6
|
+
class SlimTest < Test::Unit::TestCase
|
|
7
|
+
def slim_app(&block)
|
|
8
|
+
mock_app {
|
|
9
|
+
set :views, File.dirname(__FILE__) + '/views'
|
|
10
|
+
get '/', &block
|
|
11
|
+
}
|
|
12
|
+
get '/'
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it 'renders inline slim strings' do
|
|
16
|
+
slim_app { slim "h1 Hiya\n" }
|
|
17
|
+
assert ok?
|
|
18
|
+
assert_equal "<h1>Hiya</h1>", body
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it 'renders .slim files in views path' do
|
|
22
|
+
slim_app { slim :hello }
|
|
23
|
+
assert ok?
|
|
24
|
+
assert_equal "<h1>Hello From Slim</h1>", body
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "renders with inline layouts" do
|
|
28
|
+
mock_app {
|
|
29
|
+
layout { %(h1\n | THIS. IS. \n == yield.upcase ) }
|
|
30
|
+
get('/') { slim 'em Sparta' }
|
|
31
|
+
}
|
|
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
|
+
slim_app {
|
|
39
|
+
slim '| Hello World', :layout => :layout2
|
|
40
|
+
}
|
|
41
|
+
assert ok?
|
|
42
|
+
assert_equal "<h1>Slim Layout!</h1><p>Hello World</p>", body
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it "raises error if template not found" do
|
|
46
|
+
mock_app {
|
|
47
|
+
get('/') { slim :no_such_template }
|
|
48
|
+
}
|
|
49
|
+
assert_raise(Errno::ENOENT) { get('/') }
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
HTML4_DOCTYPE = "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">"
|
|
53
|
+
|
|
54
|
+
it "passes slim options to the slim engine" do
|
|
55
|
+
mock_app {
|
|
56
|
+
get '/' do
|
|
57
|
+
slim "! doctype html\nh1 Hello World", :format => :html4
|
|
58
|
+
end
|
|
59
|
+
}
|
|
60
|
+
get '/'
|
|
61
|
+
assert ok?
|
|
62
|
+
assert_equal "#{HTML4_DOCTYPE}<h1>Hello World</h1>", body
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it "passes default slim options to the slim engine" do
|
|
66
|
+
mock_app {
|
|
67
|
+
set :slim, {:format => :html4}
|
|
68
|
+
get '/' do
|
|
69
|
+
slim "! doctype html\nh1 Hello World"
|
|
70
|
+
end
|
|
71
|
+
}
|
|
72
|
+
get '/'
|
|
73
|
+
assert ok?
|
|
74
|
+
assert_equal "#{HTML4_DOCTYPE}<h1>Hello World</h1>", body
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it "merges the default slim options with the overrides and passes them to the slim engine" do
|
|
78
|
+
mock_app {
|
|
79
|
+
set :slim, {:format => :html4}
|
|
80
|
+
get '/' do
|
|
81
|
+
slim "! doctype html\nh1.header Hello World"
|
|
82
|
+
end
|
|
83
|
+
get '/html5' do
|
|
84
|
+
slim "! doctype html\nh1.header Hello World", :format => :html5
|
|
85
|
+
end
|
|
86
|
+
}
|
|
87
|
+
get '/'
|
|
88
|
+
assert ok?
|
|
89
|
+
assert_match(/^#{HTML4_DOCTYPE}/, body)
|
|
90
|
+
get '/html5'
|
|
91
|
+
assert ok?
|
|
92
|
+
assert_equal "<!DOCTYPE html><h1 class=\"header\">Hello World</h1>", body
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
rescue LoadError
|
|
97
|
+
warn "#{$!.to_s}: skipping slim tests"
|
|
98
|
+
end
|