rocketio 0.0.0 → 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -5
  3. data/.pryrc +2 -0
  4. data/.travis.yml +3 -0
  5. data/README.md +22 -5
  6. data/Rakefile +7 -1
  7. data/bin/console +14 -0
  8. data/bin/setup +7 -0
  9. data/lib/rocketio.rb +131 -3
  10. data/lib/rocketio/application.rb +31 -0
  11. data/lib/rocketio/controller.rb +288 -0
  12. data/lib/rocketio/controller/authentication.rb +141 -0
  13. data/lib/rocketio/controller/authorization.rb +53 -0
  14. data/lib/rocketio/controller/cookies.rb +59 -0
  15. data/lib/rocketio/controller/error_handlers.rb +89 -0
  16. data/lib/rocketio/controller/filters.rb +119 -0
  17. data/lib/rocketio/controller/flash.rb +21 -0
  18. data/lib/rocketio/controller/helpers.rb +438 -0
  19. data/lib/rocketio/controller/middleware.rb +32 -0
  20. data/lib/rocketio/controller/render.rb +148 -0
  21. data/lib/rocketio/controller/render/engine.rb +76 -0
  22. data/lib/rocketio/controller/render/layout.rb +27 -0
  23. data/lib/rocketio/controller/render/layouts.rb +85 -0
  24. data/lib/rocketio/controller/render/templates.rb +83 -0
  25. data/lib/rocketio/controller/request.rb +115 -0
  26. data/lib/rocketio/controller/response.rb +84 -0
  27. data/lib/rocketio/controller/sessions.rb +64 -0
  28. data/lib/rocketio/controller/token_auth.rb +118 -0
  29. data/lib/rocketio/controller/websocket.rb +21 -0
  30. data/lib/rocketio/error_templates/404.html +3 -0
  31. data/lib/rocketio/error_templates/409.html +7 -0
  32. data/lib/rocketio/error_templates/500.html +3 -0
  33. data/lib/rocketio/error_templates/501.html +6 -0
  34. data/lib/rocketio/error_templates/layout.html +1 -0
  35. data/lib/rocketio/exceptions.rb +4 -0
  36. data/lib/rocketio/router.rb +65 -0
  37. data/lib/rocketio/util.rb +122 -0
  38. data/lib/rocketio/version.rb +2 -2
  39. data/rocketio.gemspec +21 -17
  40. data/test/aliases_test.rb +54 -0
  41. data/test/authentication_test.rb +307 -0
  42. data/test/authorization_test.rb +91 -0
  43. data/test/cache_control_test.rb +268 -0
  44. data/test/content_type_test.rb +124 -0
  45. data/test/cookies_test.rb +49 -0
  46. data/test/error_handlers_test.rb +125 -0
  47. data/test/etag_test.rb +445 -0
  48. data/test/filters_test.rb +177 -0
  49. data/test/halt_test.rb +73 -0
  50. data/test/helpers_test.rb +171 -0
  51. data/test/middleware_test.rb +57 -0
  52. data/test/redirect_test.rb +135 -0
  53. data/test/render/engine_test.rb +71 -0
  54. data/test/render/get.erb +1 -0
  55. data/test/render/items.erb +1 -0
  56. data/test/render/layout.erb +1 -0
  57. data/test/render/layout_test.rb +104 -0
  58. data/test/render/layouts/master.erb +1 -0
  59. data/test/render/layouts_test.rb +145 -0
  60. data/test/render/master.erb +1 -0
  61. data/test/render/post.erb +1 -0
  62. data/test/render/put.erb +1 -0
  63. data/test/render/render_test.rb +101 -0
  64. data/test/render/setup.rb +14 -0
  65. data/test/render/templates/a/get.erb +1 -0
  66. data/test/render/templates/master.erb +1 -0
  67. data/test/render/templates_test.rb +146 -0
  68. data/test/request_test.rb +105 -0
  69. data/test/response_test.rb +119 -0
  70. data/test/routes_test.rb +70 -0
  71. data/test/sendfile_test.rb +209 -0
  72. data/test/sessions_test.rb +176 -0
  73. data/test/setup.rb +59 -0
  74. metadata +144 -9
  75. data/LICENSE.txt +0 -22
@@ -0,0 +1,135 @@
1
+ # Copyright (c) 2007, 2008, 2009 Blake Mizerany
2
+ # Copyright (c) 2010, 2011, 2012, 2013, 2014 Konstantin Haase
3
+ # Copyright (c) 2015 Slee Woo
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person
6
+ # obtaining a copy of this software and associated documentation
7
+ # files (the "Software"), to deal in the Software without
8
+ # restriction, including without limitation the rights to use,
9
+ # copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ # copies of the Software, and to permit persons to whom the
11
+ # Software is furnished to do so, subject to the following
12
+ # conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be
15
+ # included in all copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19
+ # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21
+ # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22
+ # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24
+ # OTHER DEALINGS IN THE SOFTWARE.
25
+
26
+ require 'setup'
27
+
28
+ spec :Redirect do
29
+ before do
30
+ app mock_controller {
31
+ define_method(:get) { redirect '/foo' }
32
+ define_method(:post) { redirect '/foo' }
33
+ }
34
+ env.clear
35
+ end
36
+
37
+ it 'uses a 302 by default' do
38
+ get
39
+ assert(last_response.status) == 302
40
+ assert(last_response.body) == ''
41
+ assert(last_response['Location']) == 'http://rack.radar/foo'
42
+ end
43
+
44
+ it 'uses 301 for permanent redirects' do
45
+ app mock_controller {
46
+ define_method(:get) { permanent_redirect '/foo' }
47
+ }
48
+
49
+ get
50
+ assert(last_response.status) == 301
51
+ assert(last_response.body) == ''
52
+ assert(last_response['Location']) == 'http://rack.radar/foo'
53
+ end
54
+
55
+ it 'redirects back to request.referer when passed back' do
56
+ app mock_controller(:try_redirect) {
57
+ define_method(:get) { redirect back }
58
+ }
59
+
60
+ env['HTTP_REFERER'] = '/foo'
61
+ get '/try_redirect'
62
+ assert(last_response.status) == 302
63
+ assert(last_response['Location']) == 'http://rack.radar/foo'
64
+ end
65
+
66
+ it 'redirects using a non-standard HTTP port' do
67
+ env['HTTP_HOST'] = nil
68
+ env['SERVER_PORT'] = '81'
69
+ get
70
+ assert(last_response['Location']) == 'http://rack.radar:81/foo'
71
+ end
72
+
73
+ it 'redirects using a non-standard HTTPS port' do
74
+ env['HTTP_HOST'] = nil
75
+ env['SERVER_PORT'] = '444'
76
+ get
77
+ assert(last_response['Location']) == 'http://rack.radar:444/foo'
78
+ end
79
+
80
+ it 'uses 303 for post requests if request is HTTP 1.1' do
81
+ env['HTTP_VERSION'] = 'HTTP/1.1'
82
+ post
83
+ assert(last_response.status) == 303
84
+ assert(last_response.body) == ''
85
+ assert(last_response['Location']) == 'http://rack.radar/foo'
86
+ end
87
+
88
+ it 'uses 302 for post requests if request is HTTP 1.0' do
89
+ env['HTTP_VERSION'] = 'HTTP/1.0'
90
+ post
91
+ assert(last_response.status) == 302
92
+ assert(last_response.body) == ''
93
+ assert(last_response['Location']) == 'http://rack.radar/foo'
94
+ end
95
+
96
+ it 'works behind a reverse proxy' do
97
+ env['HTTP_X_FORWARDED_HOST'] = 'example.com'
98
+ env['SERVER_PORT'] = '8080'
99
+ get
100
+ assert(last_response['Location']) == 'http://example.com/foo'
101
+ end
102
+
103
+ it 'accepts absolute URIs' do
104
+ app mock_controller {
105
+ define_method(:get) {redirect 'http://google.com'}
106
+ }
107
+
108
+ get
109
+ assert(last_response.status) == 302
110
+ assert(last_response.body) == ''
111
+ assert(last_response['Location']) == 'http://google.com'
112
+ end
113
+
114
+ it 'accepts absolute URIs with a different schema' do
115
+ app mock_controller {
116
+ define_method(:get) {redirect 'mailto:jsmith@example.com'}
117
+ }
118
+
119
+ get
120
+ assert(last_response.status) == 302
121
+ assert(last_response.body) == ''
122
+ assert(last_response['Location']) == 'mailto:jsmith@example.com'
123
+ end
124
+
125
+ it 'accepts a URI object instead of a String' do
126
+ app mock_controller {
127
+ define_method(:get) {redirect URI.parse('http://sinatrarb.com')}
128
+ }
129
+
130
+ get
131
+ assert(last_response.status) == 302
132
+ assert(last_response.body) == ''
133
+ assert(last_response['Location']) == 'http://sinatrarb.com'
134
+ end
135
+ end
@@ -0,0 +1,71 @@
1
+ require 'setup'
2
+
3
+ spec :engine do
4
+ it 'inherits engine from superclass' do
5
+ a = mock_controller {
6
+ engine :Slim
7
+ }
8
+ b = mock_controller(a) {
9
+ }
10
+ assert(b.initialize_controller.engine) == [:SlimTemplate, []]
11
+ end
12
+
13
+ it 'overrides engine inherited from superclass' do
14
+ a = mock_controller {
15
+ engine :Slim
16
+ }
17
+ b = mock_controller(a) {
18
+ engine :Turbo
19
+ }
20
+ assert(b.initialize_controller.engine) == [:TurboTemplate, []]
21
+ end
22
+
23
+ it 'can use include to override engine inherited from superclass' do
24
+ a = mock_controller {
25
+ engine :Slim
26
+ }
27
+ b = mock_controller(a) {
28
+ engine :Turbo
29
+ }
30
+ c = mock_controller(a) {
31
+ inherit :engine, from: b
32
+ }
33
+ assert(c.initialize_controller.engine) == [:TurboTemplate, []]
34
+ end
35
+
36
+ it 'uses a block (that runs at instance level) to define engine' do
37
+ app mock_controller {
38
+ engine {@x = 'x'; :Slim}
39
+ def get; engine[0].to_s + @x end
40
+ }
41
+ get
42
+ assert(last_response.body) == 'SlimTemplatex'
43
+ end
44
+
45
+ it 'can accept engine options when a block used' do
46
+ c = mock_controller {
47
+ engine {[:Slim, {pretty_print: true}]}
48
+ }
49
+ e,o = c.allocate.engine
50
+ assert(e) == :SlimTemplate
51
+ assert(o) == [{pretty_print: true}]
52
+ end
53
+
54
+ it 'uses inherited engine if given block returns no engine' do
55
+ a = mock_controller {
56
+ engine :Slim
57
+ }
58
+ b = mock_controller(a) {
59
+ engine {
60
+ :ERB if env['IAMABOT']
61
+ }
62
+ def get; engine[0].to_s end
63
+ }
64
+ app b
65
+ get
66
+ assert(last_response.body) == 'SlimTemplate'
67
+ env['IAMABOT'] = true
68
+ get
69
+ assert(last_response.body) == 'ERBTemplate'
70
+ end
71
+ end
@@ -0,0 +1 @@
1
+ <%= url %>
@@ -0,0 +1 @@
1
+ items
@@ -0,0 +1 @@
1
+ =<%= yield %>=
@@ -0,0 +1,104 @@
1
+ require 'setup'
2
+
3
+ spec :Views do
4
+ context :layouts do
5
+ it 'inherits layout from superclass' do
6
+ a = mock_controller {
7
+ layout :master
8
+ }
9
+ b = mock_controller(a) {
10
+ }
11
+ assert(b.initialize_controller.layout) == :master
12
+ end
13
+
14
+ it 'overrides layout inherited from superclass' do
15
+ a = mock_controller {
16
+ layout :master
17
+ }
18
+ b = mock_controller(a) {
19
+ layout :baster
20
+ }
21
+ assert(b.initialize_controller.layout) == :baster
22
+ end
23
+
24
+ it 'can use `inherit` to override layout inherited from superclass' do
25
+ a = mock_controller {
26
+ layout :master
27
+ }
28
+ b = mock_controller(a) {
29
+ layout :baster
30
+ }
31
+ c = mock_controller(a) {
32
+ inherit :layout, from: b
33
+ }
34
+ assert(c.initialize_controller.layout) == :baster
35
+ end
36
+
37
+ it 'renders without layout if no default layout set' do
38
+ app mock_controller {
39
+ def get; render; end
40
+ }
41
+ get
42
+ assert(last_response).is_ok_with_body('/')
43
+ end
44
+
45
+ it 'renders without layout if default layout set to false' do
46
+ app mock_controller {
47
+ layout false
48
+ def get; render; end
49
+ }
50
+ get
51
+ assert(last_response).is_ok_with_body('/')
52
+ end
53
+
54
+ it 'renders without layout if layout option set to nil or false' do
55
+ app mock_controller {
56
+ layout :layout
57
+ def var; @var end
58
+ def get; render(layout: nil); end
59
+ def post; @var = 'x'; render(layout: false); end
60
+ def put; @var = 'y'; render; end
61
+ }
62
+ get
63
+ assert(last_response).is_ok_with_body('/')
64
+ post
65
+ assert(last_response).is_ok_with_body('x')
66
+ put
67
+ assert(last_response).is_ok_with_body("=y=\n")
68
+ end
69
+
70
+ it 'renders with a defined layout' do
71
+ app mock_controller {
72
+ define_layout(:master) {'=<%= yield %>='}
73
+ layout :master
74
+ def get; render; end
75
+ }
76
+ get
77
+ assert(last_response).is_ok_with_body('=/=')
78
+ end
79
+
80
+ it 'prefers defined layouts over files' do
81
+ app mock_controller {
82
+ define_layout(:layout) {'-<%= yield %>-'}
83
+ layout :layout
84
+ def get; render; end
85
+ }
86
+ get
87
+ assert(last_response).is_ok_with_body('-/-')
88
+ end
89
+
90
+ it 'prefers explicit layouts over implicit ones' do
91
+ app mock_controller {
92
+ define_layout(:x) {'x<%= yield %>'}
93
+ define_layout(:y) {'y<%= yield %>'}
94
+ layout :x
95
+ def get; render {''}; end
96
+ def post; render(layout: :y) {''}; end
97
+ }
98
+ get
99
+ assert(last_response).is_ok_with_body('x')
100
+ post
101
+ assert(last_response).is_ok_with_body('y')
102
+ end
103
+ end
104
+ end
@@ -0,0 +1 @@
1
+ outside <%= yield %> layout
@@ -0,0 +1,145 @@
1
+ require 'setup'
2
+
3
+ spec :layouts do
4
+ context :compositing do
5
+ it 'inherits layouts from superclass' do
6
+ a = mock_controller {
7
+ define_layout(:a) {'a'}
8
+ }
9
+ b = mock_controller(a) {
10
+ }.initialize_controller
11
+ assert(b.__send__ b.layouts[:a]) == 'a'
12
+ end
13
+
14
+ it 'complements layouts inherited from superclass' do
15
+ a = mock_controller {
16
+ define_layout(:a) {'a'}
17
+ }
18
+ b = mock_controller(a) {
19
+ define_layout(:b) {'b'}
20
+ }.initialize_controller
21
+ assert(b.__send__ b.layouts[:a]) == 'a'
22
+ assert(b.__send__ b.layouts[:b]) == 'b'
23
+ end
24
+
25
+ it 'overrides layouts inherited from superclass' do
26
+ a = mock_controller {
27
+ define_layout(:x) {'a'}
28
+ }
29
+ b = mock_controller(a) {
30
+ define_layout(:x) {'b'}
31
+ }.initialize_controller
32
+ assert(b.__send__ b.layouts[:x]) == 'b'
33
+ end
34
+
35
+ test '`inherit` overrides layouts inherited from superclass' do
36
+ a = mock_controller {
37
+ define_layout(:x) {'a'}
38
+ }
39
+ b = mock_controller(a) {
40
+ define_layout(:x) {'b'}
41
+ }
42
+ c = mock_controller(a) {
43
+ inherit :layouts, from: b
44
+ }.initialize_controller
45
+ assert(c.__send__ c.layouts[:x]) == 'b'
46
+ end
47
+
48
+ test '`inherit` complements layouts inherited from superclass' do
49
+ a = mock_controller {
50
+ define_layout(:a) {'a'}
51
+ }
52
+ b = mock_controller(a) {
53
+ define_layout(:b) {'b'}
54
+ }
55
+ c = mock_controller(a) {
56
+ inherit :layouts, from: b
57
+ }.initialize_controller
58
+ assert(c.__send__ c.layouts[:a]) == 'a'
59
+ assert(c.__send__ c.layouts[:b]) == 'b'
60
+ end
61
+
62
+ test '`inherit` overrides defined layouts' do
63
+ a = mock_controller {
64
+ define_layout(:x) {'a'}
65
+ }
66
+ b = mock_controller {
67
+ define_layout(:x) {'b'}
68
+ inherit :layouts, from: a
69
+ }.initialize_controller
70
+ assert(b.__send__ b.layouts[:x]) == 'a'
71
+ end
72
+
73
+ test '`inherit` complements defined layouts' do
74
+ a = mock_controller {
75
+ define_layout(:a) {'a'}
76
+ }
77
+ b = mock_controller {
78
+ define_layout(:b) {'b'}
79
+ inherit :layouts, from: a
80
+ }.initialize_controller
81
+ assert(b.__send__ b.layouts[:a]) == 'a'
82
+ assert(b.__send__ b.layouts[:b]) == 'b'
83
+ end
84
+
85
+ it 'overrides layouts inherited via `inherit`' do
86
+ a = mock_controller {
87
+ define_layout(:x) {'a'}
88
+ }
89
+ b = mock_controller {
90
+ inherit :layouts, from: a
91
+ define_layout(:x) {'b'}
92
+ }.initialize_controller
93
+ assert(b.__send__ b.layouts[:x]) == 'b'
94
+ end
95
+ end
96
+
97
+ context :rendering do
98
+ it 'uses a file with same name if only name given' do
99
+ c = mock_controller {
100
+ define_layout :master
101
+ }.initialize_controller
102
+ assert(c.render_layout(:master) {'yo'}) == "master yo layout\n"
103
+ end
104
+
105
+ it 'raises a TemplateError if there is no file with same name' do
106
+ layout = rand.to_s
107
+ c = mock_controller {
108
+ define_layout layout
109
+ }.initialize_controller
110
+ assert {c.render_layout(layout) {}}.raise RocketIO::TemplateError
111
+ end
112
+
113
+ it 'uses given file - file resides in controller dirname' do
114
+ c = mock_controller {
115
+ define_layout :master, file: :layout
116
+ }.initialize_controller
117
+ assert(c.render_layout(:master) {'yo'}) == "=yo=\n"
118
+ end
119
+
120
+ it 'uses given file - file resides outside controller dirname' do
121
+ c = mock_controller {
122
+ define_layout :master, file: './layouts/master'
123
+ }.initialize_controller
124
+ assert(c.render_layout(:master) {'yo'}) == "outside yo layout\n"
125
+ end
126
+
127
+ it 'accepts a block for given file' do
128
+ c = mock_controller {
129
+ define_layout :master, file: -> {@outside ? './layouts/master' : :master}
130
+ }.initialize_controller
131
+ assert(c.render_layout(:master) {'yo'}) == "master yo layout\n"
132
+ c.instance_variable_set(:@outside, true)
133
+ assert(c.render_layout(:master) {'yo'}) == "outside yo layout\n"
134
+ end
135
+
136
+ it 'accepts a block and uses returned value as layout without searching for file' do
137
+ c = mock_controller {
138
+ define_layout(:master) {@admin ? ':<%= yield %>:' : '|<%= yield %>|'}
139
+ }.initialize_controller
140
+ assert(c.render_layout(:master) {'yo'}) == "|yo|"
141
+ c.instance_variable_set(:@admin, true)
142
+ assert(c.render_layout(:master) {'yo'}) == ":yo:"
143
+ end
144
+ end
145
+ end