rocketio 0.0.0 → 0.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.
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