gin 1.1.2 → 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.
@@ -5,22 +5,22 @@ class MockApp < Gin::App
5
5
  layout "foo"
6
6
 
7
7
  def index
8
- view :bar, locals: {test_val: "LOCAL"}
8
+ view :bar, :locals => {:test_val => "LOCAL"}
9
9
  end
10
10
 
11
11
  def login
12
12
  set_cookie "foo_session", "12345",
13
- expires: Time.parse("Fri, 01 Jan 2100 00:00:00 -0000")
13
+ :expires => Time.parse("Fri, 01 Jan 2100 00:00:00 -0000")
14
14
  "OK"
15
15
  end
16
16
 
17
17
  def supercookie
18
18
  set_cookie "supercookie", "SUPER!",
19
- expires: Time.parse("Fri, 01 Jan 2100 00:00:00 -0000"),
20
- domain: "mockapp.com",
21
- path: "/",
22
- secure: true,
23
- httponly: true
19
+ :expires => Time.parse("Fri, 01 Jan 2100 00:00:00 -0000"),
20
+ :domain => "mockapp.com",
21
+ :path => "/",
22
+ :secure => true,
23
+ :httponly => true
24
24
  "OK"
25
25
  end
26
26
  end
@@ -4,6 +4,7 @@ require "stringio"
4
4
  class FooController < Gin::Controller;
5
5
  def index; "FOO"; end
6
6
  def create; end
7
+ def show id; "FOO ID = #{id}"; end
7
8
  def error; raise "Something bad happened"; end
8
9
  end
9
10
 
@@ -21,6 +22,13 @@ class FooApp < Gin::App
21
22
  get :index, "/"
22
23
  post :create, "/"
23
24
  get :error, "/error"
25
+ get :show, "/:id"
26
+ end
27
+
28
+ def call env
29
+ env['SERVER_NAME'] ||= 'foo.com'
30
+ env['SERVER_PORT'] ||= '80'
31
+ super
24
32
  end
25
33
 
26
34
  def reloaded?
@@ -71,6 +79,8 @@ end
71
79
 
72
80
 
73
81
  class AppTest < Test::Unit::TestCase
82
+ include Gin::Constants
83
+
74
84
  class NamespacedApp < Gin::App; end
75
85
 
76
86
  FOO_ROUTER = FooApp.router
@@ -122,6 +132,54 @@ class AppTest < Test::Unit::TestCase
122
132
  end
123
133
 
124
134
 
135
+ def test_hostname
136
+ FooApp.hostname 'example.com'
137
+ @app = FooApp.new
138
+
139
+ assert_equal 'example.com', FooApp.hostname
140
+ assert_equal 'example.com', @app.hostname
141
+ assert @app.send(:valid_host?,{})
142
+ end
143
+
144
+
145
+ def test_hostname_enforce
146
+ FooApp.hostname 'example.com', :enforce => true
147
+ @app = FooApp.new
148
+
149
+ assert_equal 'example.com', FooApp.hostname
150
+ assert_equal 'example.com', @app.hostname
151
+ assert !@app.send(:valid_host?,{'SERVER_NAME' => 'admin.example.com', 'SERVER_PORT' => '80'})
152
+ assert @app.send(:valid_host?,{'SERVER_NAME' => 'example.com', 'SERVER_PORT' => '443'})
153
+ assert @app.send(:valid_host?,{'SERVER_NAME' => 'example.com', 'SERVER_PORT' => '80'})
154
+ end
155
+
156
+
157
+ def test_hostname_enforce_port
158
+ FooApp.hostname 'example.com:80', :enforce => true
159
+ @app = FooApp.new
160
+
161
+ assert_equal 'example.com:80', FooApp.hostname
162
+ assert_equal 'example.com:80', @app.hostname
163
+ assert !@app.send(:valid_host?,{'SERVER_NAME' => 'admin.example.com', 'SERVER_PORT' => '80'})
164
+ assert !@app.send(:valid_host?,{'SERVER_NAME' => 'example.com', 'SERVER_PORT' => '443'})
165
+ assert @app.send(:valid_host?,{'SERVER_NAME' => 'example.com', 'SERVER_PORT' => '80'})
166
+ end
167
+
168
+
169
+ def test_hostname_enforce_regexp
170
+ FooApp.hostname 'admin.example.com',
171
+ :enforce => /^admin\.(example\.com|localhost)$/
172
+
173
+ @app = FooApp.new
174
+
175
+ assert_equal 'admin.example.com', FooApp.hostname
176
+ assert_equal 'admin.example.com', @app.hostname
177
+ assert !@app.send(:valid_host?,{'SERVER_NAME' => 'example.com'})
178
+ assert @app.send(:valid_host?,{'SERVER_NAME' => 'admin.example.com'})
179
+ assert @app.send(:valid_host?,{'SERVER_NAME' => 'admin.localhost'})
180
+ end
181
+
182
+
125
183
  def test_namespace
126
184
  assert_nil FooApp.namespace
127
185
  assert_equal self.class, NamespacedApp.namespace
@@ -131,8 +189,8 @@ class AppTest < Test::Unit::TestCase
131
189
  def test_protection
132
190
  assert_equal false, FooApp.protection
133
191
 
134
- FooApp.protection(test: "thing")
135
- assert_equal({test:"thing"}, FooApp.protection)
192
+ FooApp.protection(:test => "thing")
193
+ assert_equal({:test =>"thing"}, FooApp.protection)
136
194
 
137
195
  FooApp.protection false
138
196
  assert_equal false, FooApp.protection
@@ -174,8 +232,8 @@ class AppTest < Test::Unit::TestCase
174
232
  def test_sessions
175
233
  assert_equal false, FooApp.sessions
176
234
 
177
- FooApp.sessions(test: "thing")
178
- assert_equal({test:"thing"}, FooApp.sessions)
235
+ FooApp.sessions(:test => "thing")
236
+ assert_equal({:test =>"thing"}, FooApp.sessions)
179
237
 
180
238
  FooApp.sessions false
181
239
  assert_equal false, FooApp.sessions
@@ -313,7 +371,7 @@ class AppTest < Test::Unit::TestCase
313
371
 
314
372
  def test_template_for
315
373
  FooApp.default_template Tilt::ERBTemplate, "erb"
316
- @app = FooApp.new root_dir: "./test/app"
374
+ @app = FooApp.new :root_dir => "./test/app"
317
375
  template = @app.template_for "./test/app/layouts/foo"
318
376
 
319
377
  assert Tilt::ERBTemplate === template
@@ -322,14 +380,14 @@ class AppTest < Test::Unit::TestCase
322
380
 
323
381
 
324
382
  def test_template_for_invalid
325
- @app = FooApp.new root_dir: "./test/app"
383
+ @app = FooApp.new :root_dir => "./test/app"
326
384
  template = @app.template_for "./test/app/layouts/ugh"
327
385
  assert_nil template
328
386
  end
329
387
 
330
388
 
331
389
  def test_template_files
332
- @app = FooApp.new root_dir: "./test/app"
390
+ @app = FooApp.new :root_dir => "./test/app"
333
391
 
334
392
  files = @app.template_files "./test/app/layouts/foo"
335
393
  assert_equal ["./test/app/layouts/foo.erb"], files
@@ -351,16 +409,97 @@ class AppTest < Test::Unit::TestCase
351
409
  assert_equal [FooMiddleware, :foo, :bar], FooApp.middleware[0]
352
410
  assert !FooMiddleware.called?
353
411
 
354
- myapp = FooApp.new logger: @error_io
412
+ myapp = FooApp.new :logger => @error_io
355
413
  myapp.call({'rack.input' => "", 'PATH_INFO' => '/foo', 'REQUEST_METHOD' => 'GET'})
356
414
  assert FooMiddleware.called?
357
415
 
358
416
  FooMiddleware.reset!
359
- myapp.dispatch({'rack.input' => "", 'PATH_INFO' => '/foo', 'REQUEST_METHOD' => 'GET'}, FooController, :index)
417
+ myapp.dispatch('rack.input' => "", 'PATH_INFO' => '/foo',
418
+ 'REQUEST_METHOD' => 'GET', GIN_TARGET => [FooController, :index])
360
419
  assert !FooMiddleware.called?
361
420
  end
362
421
 
363
422
 
423
+ def test_rewrite_env
424
+ time = Time.now
425
+ env = {'rack.input' => 'id=foo', 'PATH_INFO' => '/foobar', 'REQUEST_METHOD' => 'GET',
426
+ 'REMOTE_ADDR' => '127.0.0.1', GIN_RELOADED => true, GIN_TIMESTAMP => time,
427
+ GIN_TARGET => [FooController, :index]}
428
+
429
+ expected_env = env.dup
430
+ expected_env.delete(GIN_TARGET)
431
+ expected_env['REQUEST_METHOD'] = 'POST'
432
+ expected_env['PATH_INFO'] = '/foo'
433
+ expected_env['QUERY_STRING'] = nil
434
+
435
+ assert_equal expected_env, @app.rewrite_env(env, FooController, :create)
436
+
437
+ assert_raises Gin::RouterError do
438
+ @app.rewrite_env(env, FooController, :bad_action)
439
+ end
440
+
441
+ assert_raises Gin::Router::PathArgumentError do
442
+ @app.rewrite_env(env, FooController, :show)
443
+ end
444
+
445
+ expected_env['REQUEST_METHOD'] = 'GET'
446
+ expected_env['PATH_INFO'] = '/foo/123'
447
+ expected_env['QUERY_STRING'] = 'blah=456'
448
+
449
+ assert_equal expected_env,
450
+ @app.rewrite_env(env, FooController, :show, {:id => 123, :blah => 456}, 'REQUEST_METHOD' => 'POST')
451
+ end
452
+
453
+
454
+ def test_rewrite_env_custom_path
455
+ time = Time.now
456
+ env = {'rack.input' => 'id=foo', 'PATH_INFO' => '/foobar', 'REQUEST_METHOD' => 'GET',
457
+ 'REMOTE_ADDR' => '127.0.0.1', GIN_RELOADED => true, GIN_TIMESTAMP => time,
458
+ GIN_TARGET => [FooController, :index]}
459
+
460
+ expected_env = env.dup
461
+ expected_env.delete(GIN_TARGET)
462
+ expected_env['REQUEST_METHOD'] = 'POST'
463
+ expected_env['PATH_INFO'] = '/foo'
464
+ expected_env['QUERY_STRING'] = nil
465
+
466
+ assert_equal expected_env, @app.rewrite_env(env, '/foo', {}, 'REQUEST_METHOD' => 'POST')
467
+ assert_raises Gin::Router::PathArgumentError do
468
+ @app.rewrite_env(env, '/foo/:id', {}, 'REQUEST_METHOD' => 'POST')
469
+ end
470
+
471
+ expected_env['PATH_INFO'] = '/foo/123'
472
+ expected_env['QUERY_STRING'] = 'blah=456'
473
+
474
+ assert_equal expected_env,
475
+ @app.rewrite_env(env, '/foo/:id', {:id => 123, :blah => 456}, 'REQUEST_METHOD' => 'POST')
476
+ end
477
+
478
+
479
+ def test_rewrite
480
+ env = {'rack.input' => 'id=foo', 'PATH_INFO' => '/foobar', 'REQUEST_METHOD' => 'GET',
481
+ 'REMOTE_ADDR' => '127.0.0.1'}
482
+
483
+ resp = @app.rewrite!(env, FooController, :show, :id => 123)
484
+ @app.logger.rewind
485
+
486
+ assert_equal ["FOO ID = 123"], resp[2]
487
+ assert_equal "[REWRITE] GET /foobar -> GET /foo/123\n", @app.logger.readline
488
+ end
489
+
490
+
491
+ def test_rewrite_path
492
+ env = {'rack.input' => 'id=foo', 'PATH_INFO' => '/foobar', 'REQUEST_METHOD' => 'GET',
493
+ 'REMOTE_ADDR' => '127.0.0.1'}
494
+
495
+ resp = @app.rewrite!(env, '/other/path/:id', {:id => 123}, 'REQUEST_METHOD' => 'PUT')
496
+ @app.logger.rewind
497
+
498
+ assert_equal 404, resp[0]
499
+ assert_equal "[REWRITE] GET /foobar -> PUT /other/path/123\n", @app.logger.readline
500
+ end
501
+
502
+
364
503
  def test_call_reload
365
504
  FooApp.autoreload true
366
505
  myapp = FooApp.new @error_io
@@ -393,6 +532,116 @@ class AppTest < Test::Unit::TestCase
393
532
  end
394
533
 
395
534
 
535
+ def test_call_host
536
+ env = {'rack.input' => "", 'PATH_INFO' => '/foo', 'REQUEST_METHOD' => 'GET',
537
+ 'SERVER_NAME' => 'foo.com', 'SERVER_PORT' => '80'}
538
+ FooApp.hostname 'example.com'
539
+ @app = FooApp.new
540
+ resp = @app.call env
541
+
542
+ assert_equal 200, resp[0]
543
+ assert_equal 'example.com:80', resp[1]['Host']
544
+ end
545
+
546
+
547
+ def test_call_validate_host
548
+ env = {'rack.input' => "", 'PATH_INFO' => '/foo', 'REQUEST_METHOD' => 'GET',
549
+ 'SERVER_NAME' => 'foo.com', 'SERVER_PORT' => '80'}
550
+ FooApp.hostname 'example.com', :enforce => true
551
+ @app = FooApp.new
552
+ resp = @app.call env
553
+
554
+ assert_equal 400, resp[0]
555
+ assert_equal 'example.com:80', resp[1]['Host']
556
+ assert resp[2][0].include?("No route for host &#39;foo.com:80&#39;")
557
+
558
+ env['SERVER_NAME'] = 'example.com'
559
+ resp = @app.call env
560
+
561
+ assert_equal 200, resp[0]
562
+ assert_equal 'example.com:80', resp[1]['Host']
563
+ end
564
+
565
+
566
+ def test_call_validate_host_regexp
567
+ env = {'rack.input' => "", 'PATH_INFO' => '/foo', 'REQUEST_METHOD' => 'GET',
568
+ 'SERVER_NAME' => 'foo.com', 'SERVER_PORT' => '80'}
569
+ FooApp.hostname 'admin.example.com', :enforce => /^admin\.(example\.com|localhost)$/
570
+ @app = FooApp.new
571
+ resp = @app.call env
572
+
573
+ assert_equal 400, resp[0]
574
+ assert_equal 'admin.example.com:80', resp[1]['Host']
575
+ assert resp[2][0].include?("No route for host &#39;foo.com:80&#39;")
576
+
577
+ env['SERVER_NAME'] = 'admin.example.com'
578
+ env['SERVER_PORT'] = '443'
579
+ resp = @app.call env
580
+
581
+ assert_equal 200, resp[0]
582
+ assert_equal 'admin.example.com:443', resp[1]['Host']
583
+ end
584
+
585
+
586
+ def test_call_validate_host_and_port
587
+ env = {'rack.input' => "", 'PATH_INFO' => '/foo', 'REQUEST_METHOD' => 'GET',
588
+ 'SERVER_NAME' => 'example.com', 'SERVER_PORT' => '80'}
589
+ FooApp.hostname 'example.com:443', :enforce => true
590
+ @app = FooApp.new
591
+ resp = @app.call env
592
+
593
+ assert_equal 400, resp[0]
594
+ assert_equal 'example.com:80', resp[1]['Host']
595
+ assert resp[2][0].include?("No route for host &#39;example.com:80&#39;")
596
+
597
+ env['SERVER_PORT'] = '443'
598
+ resp = @app.call env
599
+
600
+ assert_equal 200, resp[0]
601
+ assert_equal 'example.com:443', resp[1]['Host']
602
+ end
603
+
604
+
605
+ def test_call_validate_host_static
606
+ env = {'rack.input' => "", 'PATH_INFO' => '/gin.css', 'REQUEST_METHOD' => 'GET',
607
+ 'SERVER_NAME' => 'foo.com', 'SERVER_PORT' => '80'}
608
+ FooApp.hostname 'example.com', :enforce => true
609
+ @app = FooApp.new
610
+ resp = @app.call env
611
+
612
+ assert_equal 400, resp[0]
613
+ assert_equal 'example.com:80', resp[1]['Host']
614
+ assert resp[2][0].include?("No route for host &#39;foo.com:80&#39;")
615
+
616
+ env['SERVER_NAME'] = 'example.com'
617
+ resp = @app.call env
618
+
619
+ assert_equal 200, resp[0]
620
+ assert_equal 'example.com:80', resp[1]['Host']
621
+ end
622
+
623
+
624
+ def test_call_validate_host_rack_app
625
+ env = {'rack.input' => "", 'PATH_INFO' => '/gin.css', 'REQUEST_METHOD' => 'GET',
626
+ 'SERVER_NAME' => 'foo.com', 'SERVER_PORT' => '80'}
627
+
628
+ FooApp.hostname 'example.com', :enforce => true
629
+
630
+ expected = [200, {'Content-Length'=>"5", 'Host' => 'foo.com:80'}, "AHOY!"]
631
+ myapp = lambda{|_| expected }
632
+ @app = FooApp.new myapp
633
+ resp = @app.call env
634
+
635
+ assert_equal expected, resp
636
+
637
+ env['SERVER_NAME'] = 'example.com'
638
+ resp = @app.call env
639
+
640
+ assert_equal 200, resp[0]
641
+ assert_equal 'example.com:80', resp[1]['Host']
642
+ assert resp[2].is_a?(File)
643
+ end
644
+
396
645
 
397
646
  def test_call!
398
647
  resp = @app.call! 'rack.input' => "",
@@ -409,7 +658,7 @@ class AppTest < Test::Unit::TestCase
409
658
  FooApp.environment 'test'
410
659
  env = {'rack.input' => "", 'PATH_INFO' => '/foo', 'REQUEST_METHOD' => 'GET'}
411
660
 
412
- resp = @app.dispatch env, FooController, :index
661
+ resp = @app.dispatch env.merge(GIN_TARGET => [FooController, :index])
413
662
  assert_equal 200, resp[0]
414
663
  assert_equal "3", resp[1]['Content-Length']
415
664
  assert_equal 'text/html;charset=UTF-8', resp[1]['Content-Type']
@@ -422,7 +671,7 @@ class AppTest < Test::Unit::TestCase
422
671
  @app = FooApp.new
423
672
  env = {'rack.input' => "", 'PATH_INFO' => '/foo', 'REQUEST_METHOD' => 'GET'}
424
673
 
425
- resp = @app.dispatch env, FooController, :bad
674
+ resp = @app.dispatch env.merge(GIN_TARGET => [FooController, :bad])
426
675
  assert_equal 404, resp[0]
427
676
  assert_equal "288", resp[1]['Content-Length']
428
677
  assert_equal 'text/html;charset=UTF-8', resp[1]['Content-Type']
@@ -435,13 +684,13 @@ class AppTest < Test::Unit::TestCase
435
684
  @app = FooApp.new
436
685
  env = {'rack.input' => "", 'PATH_INFO' => '/foo', 'REQUEST_METHOD' => 'GET'}
437
686
 
438
- resp = @app.dispatch env, FooController, nil
687
+ resp = @app.dispatch env.merge(GIN_TARGET => [FooController, nil])
439
688
  assert_equal 404, resp[0]
440
689
  assert_equal "288", resp[1]['Content-Length']
441
690
  assert_equal 'text/html;charset=UTF-8', resp[1]['Content-Type']
442
691
  assert_equal @app.asset("404.html"), resp[2].path
443
692
 
444
- msg = "[ERROR] Gin::NotFound: No route exists for: GET /foo"
693
+ msg = "[ERROR] Gin::NotFound: No action exists for: GET /foo"
445
694
  @error_io.rewind
446
695
  assert @error_io.read.include?(msg)
447
696
  end
@@ -451,7 +700,7 @@ class AppTest < Test::Unit::TestCase
451
700
  FooApp.environment 'test'
452
701
  @app = FooApp.new
453
702
  env = {'rack.input' => "", 'PATH_INFO' => '/bad', 'REQUEST_METHOD' => 'GET'}
454
- resp = @app.dispatch env, FooController, :error
703
+ resp = @app.dispatch env.merge(GIN_TARGET => [FooController, :error])
455
704
 
456
705
  assert_equal 500, resp[0]
457
706
  assert_equal @app.asset("500.html"), resp[2].path
@@ -496,7 +745,7 @@ class AppTest < Test::Unit::TestCase
496
745
  env = {'rack.input' => "", 'PATH_INFO' => '/bad', 'REQUEST_METHOD' => 'GET'}
497
746
  err = ArgumentError.new("Unexpected Argument")
498
747
 
499
- resp = @app.handle_error ArgumentError.new("Unexpected Argument"), env
748
+ resp = @app.handle_error err, env
500
749
  assert_equal 500, resp[0]
501
750
  assert_equal File.read(@app.asset("500.html")), resp[2].read
502
751
  assert_equal({"Content-Type"=>"text/html;charset=UTF-8", "Content-Length"=>"348"}, resp[1])
@@ -663,14 +912,14 @@ class AppTest < Test::Unit::TestCase
663
912
 
664
913
 
665
914
  def test_init_missing_routes
666
- assert_raises Gin::App::RouterError do
915
+ assert_raises Gin::RouterError do
667
916
  MissingRouteApp.new
668
917
  end
669
918
  end
670
919
 
671
920
 
672
921
  def test_init_extra_routes
673
- assert_raises Gin::App::RouterError do
922
+ assert_raises Gin::RouterError do
674
923
  ExtraRouteApp.new
675
924
  end
676
925
  end
@@ -7,6 +7,15 @@ class CacheTest < Test::Unit::TestCase
7
7
  end
8
8
 
9
9
 
10
+ def test_clear
11
+ @cache[:foo] = "blah"
12
+ assert @cache[:foo]
13
+
14
+ @cache.clear
15
+ assert_nil @cache[:foo]
16
+ end
17
+
18
+
10
19
  def test_write_timeout
11
20
  assert_equal 0.05, @cache.write_timeout
12
21
  @cache.write_timeout = 0.1
@@ -15,20 +24,79 @@ class CacheTest < Test::Unit::TestCase
15
24
  end
16
25
 
17
26
 
18
- def test_write_thread_safe
27
+ # This test only valid for non-GC Ruby implementations
28
+ def test_readwrite_thread_safe
19
29
  @cache[:num] = 0
20
- @mutex = Mutex.new
21
30
  @num = 0
22
31
 
23
32
  threads = []
24
- 30.times do
25
- threads << Thread.new{ @cache[:num] += 1 }
33
+ 15.times do
34
+ threads << Thread.new{ @cache[:num] = Thread.current.object_id }
35
+ end
36
+ 15.times do
37
+ threads << Thread.new{ assert @cache[:num] }
38
+ end
39
+ threads.each do |t|
40
+ t.join
41
+ end
42
+ end
43
+
44
+
45
+ def test_increase
46
+ assert_equal 1, @cache.increase(:num)
47
+ assert_equal 1, @cache[:num]
48
+
49
+ @cache.increase(:num, 0.2)
50
+ assert_equal 1.2, @cache[:num]
51
+ end
52
+
53
+
54
+ def test_increase_invalid
55
+ @cache[:num] = "foo"
56
+ assert_nil @cache.increase(:num)
57
+ assert_equal "foo", @cache[:num]
58
+ end
59
+
60
+
61
+ def test_decrease
62
+ @cache.decrease(:num)
63
+ assert_equal -1, @cache[:num]
64
+
65
+ @cache.decrease(:num, 0.2)
66
+ assert_equal -1.2, @cache[:num]
67
+ end
68
+
69
+
70
+ def test_decrease_invalid
71
+ @cache[:num] = "foo"
72
+ assert_nil @cache.decrease(:num)
73
+ assert_equal "foo", @cache[:num]
74
+ end
75
+
76
+
77
+ def test_increase_thread_safe
78
+ threads = []
79
+ 15.times do
80
+ threads << Thread.new{ @cache.increase(:num) }
81
+ end
82
+ threads.each do |t|
83
+ t.join
84
+ end
85
+
86
+ assert_equal 15, @cache[:num]
87
+ end
88
+
89
+
90
+ def test_decrease_thread_safe
91
+ threads = []
92
+ 15.times do
93
+ threads << Thread.new{ @cache.decrease(:num) }
26
94
  end
27
95
  threads.each do |t|
28
96
  t.join
29
97
  end
30
98
 
31
- assert_equal 30, @cache[:num]
99
+ assert_equal -15, @cache[:num]
32
100
  end
33
101
 
34
102