deas 0.0.2 → 0.1.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.
@@ -0,0 +1,203 @@
1
+ require 'assert'
2
+ require 'deas/logger'
3
+ require 'deas/route'
4
+ require 'deas/server'
5
+ require 'logger'
6
+
7
+ class Deas::Server
8
+
9
+ class BaseTests < Assert::Context
10
+ desc "Deas::Server"
11
+ setup do
12
+ @old_configuration = Deas::Server.configuration.dup
13
+ new_configuration = Deas::Server::Configuration.new
14
+ Deas::Server.instance.tap do |s|
15
+ s.instance_variable_set("@configuration", new_configuration)
16
+ end
17
+ end
18
+ teardown do
19
+ Deas::Server.instance.tap do |s|
20
+ s.instance_variable_set("@configuration", @old_configuration)
21
+ end
22
+ end
23
+ subject{ Deas::Server }
24
+
25
+ should have_instance_methods :configuration, :init, :view_handler_ns,
26
+ :get, :post, :put, :patch, :delete, :route
27
+
28
+ should "be a singleton" do
29
+ assert_includes Singleton, subject.included_modules
30
+ end
31
+
32
+ should "allow setting it's configuration options" do
33
+ config = subject.configuration
34
+
35
+ subject.env 'staging'
36
+ assert_equal 'staging', config.env
37
+
38
+ subject.root '/path/to/root'
39
+ assert_equal '/path/to/root', config.root.to_s
40
+
41
+ subject.public_folder '/path/to/public'
42
+ assert_equal '/path/to/public', config.public_folder.to_s
43
+
44
+ subject.views_folder '/path/to/views'
45
+ assert_equal '/path/to/views', config.views_folder.to_s
46
+
47
+ subject.dump_errors true
48
+ assert_equal true, config.dump_errors
49
+
50
+ subject.method_override false
51
+ assert_equal false, config.method_override
52
+
53
+ subject.sessions false
54
+ assert_equal false, config.sessions
55
+
56
+ subject.show_exceptions true
57
+ assert_equal true, config.show_exceptions
58
+
59
+ subject.static_files false
60
+ assert_equal false, config.static_files
61
+
62
+ stdout_logger = Logger.new(STDOUT)
63
+ subject.logger stdout_logger
64
+ assert_equal stdout_logger, config.logger
65
+
66
+ init_proc = proc{ }
67
+ subject.init(&init_proc)
68
+ assert_equal init_proc, config.init_proc
69
+ end
70
+
71
+ should "add a GET route using #get" do
72
+ subject.get('/assets', 'ListAssets')
73
+
74
+ route = subject.configuration.routes[0]
75
+ assert_instance_of Deas::Route, route
76
+ assert_equal :get, route.method
77
+ assert_equal '/assets', route.path
78
+ assert_equal 'ListAssets', route.handler_class_name
79
+ end
80
+
81
+ should "add a POST route using #post" do
82
+ subject.post('/assets', 'CreateAsset')
83
+
84
+ route = subject.configuration.routes[0]
85
+ assert_instance_of Deas::Route, route
86
+ assert_equal :post, route.method
87
+ assert_equal '/assets', route.path
88
+ assert_equal 'CreateAsset', route.handler_class_name
89
+ end
90
+
91
+ should "add a PUT route using #put" do
92
+ subject.put('/assets/:id', 'UpdateAsset')
93
+
94
+ route = subject.configuration.routes[0]
95
+ assert_instance_of Deas::Route, route
96
+ assert_equal :put, route.method
97
+ assert_equal '/assets/:id', route.path
98
+ assert_equal 'UpdateAsset', route.handler_class_name
99
+ end
100
+
101
+ should "add a PATCH route using #patch" do
102
+ subject.patch('/assets/:id', 'UpdateAsset')
103
+
104
+ route = subject.configuration.routes[0]
105
+ assert_instance_of Deas::Route, route
106
+ assert_equal :patch, route.method
107
+ assert_equal '/assets/:id', route.path
108
+ assert_equal 'UpdateAsset', route.handler_class_name
109
+ end
110
+
111
+ should "add a DELETE route using #delete" do
112
+ subject.delete('/assets/:id', 'DeleteAsset')
113
+
114
+ route = subject.configuration.routes[0]
115
+ assert_instance_of Deas::Route, route
116
+ assert_equal :delete, route.method
117
+ assert_equal '/assets/:id', route.path
118
+ assert_equal 'DeleteAsset', route.handler_class_name
119
+ end
120
+
121
+ should "allow defining any kind of route using #route" do
122
+ subject.route(:options, '/get_info', 'GetInfo')
123
+
124
+ route = subject.configuration.routes[0]
125
+ assert_instance_of Deas::Route, route
126
+ assert_equal :options, route.method
127
+ assert_equal '/get_info', route.path
128
+ assert_equal 'GetInfo', route.handler_class_name
129
+ end
130
+
131
+ should "set a namespace with #view_handler_ns and " \
132
+ "use it when defining routes" do
133
+ subject.view_handler_ns 'MyStuff'
134
+ assert_equal 'MyStuff', subject.configuration.view_handler_ns
135
+
136
+ # should use the ns
137
+ subject.route(:get, '/ns_test', 'NsTest')
138
+ route = subject.configuration.routes.last
139
+ assert_equal 'MyStuff::NsTest', route.handler_class_name
140
+
141
+ # should ignore the ns when the leading colons are present
142
+ subject.route(:post, '/no_ns_test', '::NoNsTest')
143
+ route = subject.configuration.routes.last
144
+ assert_equal '::NoNsTest', route.handler_class_name
145
+ end
146
+
147
+ end
148
+
149
+ class ConfigurationTests < BaseTests
150
+ desc "Configuration"
151
+ setup do
152
+ @configuration = Deas::Server::Configuration.new
153
+ end
154
+ subject{ @configuration }
155
+
156
+ should have_instance_methods :env, :root, :app_file, :public_folder,
157
+ :views_folder, :dump_errors, :method_override, :sessions, :static_files,
158
+ :init_proc, :logger, :routes, :view_handler_ns, :show_exceptions
159
+
160
+ should "default the env to 'development'" do
161
+ assert_equal 'development', subject.env
162
+ end
163
+
164
+ should "default the root to the routes file's folder" do
165
+ expected_root = File.expand_path('..', Deas.config.routes_file)
166
+ assert_equal expected_root, subject.root.to_s
167
+ end
168
+
169
+ should "default the app file to the routes file" do
170
+ assert_equal Deas.config.routes_file.to_s, subject.app_file.to_s
171
+ end
172
+
173
+ should "default the public folder based on the root" do
174
+ expected_root = File.expand_path('..', Deas.config.routes_file)
175
+ expected_public_folder = File.join(expected_root, 'public')
176
+ assert_equal expected_public_folder, subject.public_folder.to_s
177
+ end
178
+
179
+ should "default the views folder based on the root" do
180
+ expected_root = File.expand_path('..', Deas.config.routes_file)
181
+ expected_views_folder = File.join(expected_root, 'views')
182
+ assert_equal expected_views_folder, subject.views_folder.to_s
183
+ end
184
+
185
+ should "default the Sinatra flags" do
186
+ assert_equal false, subject.dump_errors
187
+ assert_equal true, subject.method_override
188
+ assert_equal false, subject.show_exceptions
189
+ assert_equal true, subject.sessions
190
+ assert_equal true, subject.static_files
191
+ end
192
+
193
+ should "default the logger to a NullLogger" do
194
+ assert_instance_of Deas::NullLogger, subject.logger
195
+ end
196
+
197
+ should "default routes to an empty array" do
198
+ assert_equal [], subject.routes
199
+ end
200
+
201
+ end
202
+
203
+ end
@@ -0,0 +1,70 @@
1
+ require 'assert'
2
+ require 'deas/route'
3
+ require 'deas/server'
4
+ require 'deas/sinatra_app'
5
+ require 'sinatra/base'
6
+ require 'test/support/view_handlers'
7
+
8
+ module Deas::SinatraApp
9
+
10
+ class BaseTests < Assert::Context
11
+ desc "Deas::SinatraApp"
12
+ setup do
13
+ @route = Deas::Route.new(:get, '/something', 'TestViewHandler')
14
+ @configuration = Deas::Server::Configuration.new.tap do |c|
15
+ c.env = 'staging'
16
+ c.root = 'path/to/somewhere'
17
+ c.dump_errors = true
18
+ c.method_override = false
19
+ c.sessions = false
20
+ c.show_exceptions = true
21
+ c.static = true
22
+ c.routes = [ @route ]
23
+ end
24
+ @sinatra_app = Deas::SinatraApp.new(@configuration)
25
+ end
26
+ subject{ @sinatra_app }
27
+
28
+ should "be a kind of Sinatra::Base" do
29
+ assert_equal Sinatra::Base, subject.superclass
30
+ end
31
+
32
+ should "call init procs when initialized" do
33
+ initialized = false
34
+ @configuration.init_proc = proc{ initialized = true }
35
+ @sinatra_app = Deas::SinatraApp.new(@configuration)
36
+
37
+ assert_equal true, initialized
38
+ end
39
+
40
+ should "call constantize! on all routes" do
41
+ assert_equal TestViewHandler, @route.handler_class
42
+ end
43
+
44
+ should "have it's configuration set based on the server configuration" do
45
+ subject.settings do |settings|
46
+ assert_equal 'staging', settings.env
47
+ assert_equal 'path/to/somewhere', settings.root
48
+ assert_equal @configuration.app_file, settings.app_file
49
+ assert_equal 'path/to/somewhere/public', settings.public_folder
50
+ assert_equal 'path/to/somewhere/views', settings.views
51
+ assert_equal true, settings.dump_errors
52
+ assert_equal false, settings.logging
53
+ assert_equal false, settings.method_override
54
+ assert_equal false, settings.sessions
55
+ assert_equal true, settings.show_exceptions
56
+ assert_equal true, settings.static_files
57
+ assert_equal @configuration.logger, settings.deas_logger
58
+ end
59
+ end
60
+
61
+ should "define Sinatra routes for every route in the configuration" do
62
+ get_routes = subject.routes[@route.method.to_s.upcase] || []
63
+ sinatra_route = get_routes.detect{|route| route[0].match(@route.path) }
64
+
65
+ assert_not_nil sinatra_route
66
+ end
67
+
68
+ end
69
+
70
+ end
@@ -0,0 +1,103 @@
1
+ require 'assert'
2
+ require 'deas/sinatra_runner'
3
+ require 'deas/template'
4
+ require 'test/support/fake_app'
5
+ require 'test/support/view_handlers'
6
+
7
+ class Deas::SinatraRunner
8
+
9
+ class BaseTests < Assert::Context
10
+ desc "Deas::SinatraRunner"
11
+ setup do
12
+ @fake_sinatra_call = FakeApp.new
13
+ @runner = Deas::SinatraRunner.new(FlagViewHandler, @fake_sinatra_call)
14
+ end
15
+ subject{ @runner }
16
+
17
+ should have_instance_methods :run, :request, :response, :params, :logger,
18
+ :halt, :render, :session, :redirect, :redirect_to
19
+
20
+ should "return the sinatra_call's request with #request" do
21
+ assert_equal @fake_sinatra_call.request, subject.request
22
+ end
23
+
24
+ should "return the sinatra_call's response with #response" do
25
+ assert_equal @fake_sinatra_call.response, subject.response
26
+ end
27
+
28
+ should "return the sinatra_call's params with #params" do
29
+ assert_equal @fake_sinatra_call.params, subject.params
30
+ end
31
+
32
+ should "return the sinatra_call's session with #session" do
33
+ assert_equal @fake_sinatra_call.session, subject.session
34
+ end
35
+
36
+ should "return the sinatra_call's settings logger with #logger" do
37
+ assert_equal @fake_sinatra_call.settings.deas_logger, subject.logger
38
+ end
39
+
40
+ should "call the sinatra_call's halt with #halt" do
41
+ return_value = catch(:halt){ subject.halt('test') }
42
+ assert_equal [ 'test' ], return_value
43
+ end
44
+
45
+ should "call the sinatra_call's erb method with #render" do
46
+ return_value = subject.render('index')
47
+
48
+ assert_equal :web, return_value[0]
49
+ assert_equal :index, return_value[2]
50
+
51
+ options = return_value[3]
52
+ assert_instance_of Deas::Template::RenderScope, options[:scope]
53
+
54
+ expected_locals = { :view => subject.instance_variable_get("@handler") }
55
+ assert_equal(expected_locals, options[:locals])
56
+ end
57
+
58
+ should "call the sinatra_call's redirect method with #redirect" do
59
+ return_value = catch(:halt){ subject.redirect('http://google.com') }
60
+ expected = [ 302, { 'Location' => 'http://google.com' } ]
61
+
62
+ assert_equal expected, return_value
63
+ end
64
+
65
+ should "call the sinatra_call's redirect and to methods with #redirect_to" do
66
+ return_value = catch(:halt){ subject.redirect_to('/somewhere') }
67
+ expected = [ 302, { 'Location' => "http://test.local/somewhere" } ]
68
+
69
+ assert_equal expected, return_value
70
+ end
71
+
72
+ should "not throw an exception with the setup or teardown methods" do
73
+ assert_nothing_raised{ subject.setup }
74
+ assert_nothing_raised{ subject.teardown }
75
+ end
76
+
77
+ end
78
+
79
+ class RunTests < BaseTests
80
+ desc "run"
81
+ setup do
82
+ @return_value = @runner.run
83
+ @handler = @runner.instance_variable_get("@handler")
84
+ end
85
+ subject{ @handler }
86
+
87
+ should "run the before and after hooks" do
88
+ assert_equal true, subject.before_hook_called
89
+ assert_equal true, subject.after_hook_called
90
+ end
91
+
92
+ should "run the handler's init and run" do
93
+ assert_equal true, subject.init_bang_called
94
+ assert_equal true, subject.run_bang_called
95
+ end
96
+
97
+ should "return the handler's run! return value" do
98
+ assert_equal true, @return_value
99
+ end
100
+
101
+ end
102
+
103
+ end
@@ -0,0 +1,150 @@
1
+ require 'assert'
2
+ require 'deas/template'
3
+ require 'test/support/fake_app'
4
+
5
+ class Deas::Template
6
+
7
+ class BaseTests < Assert::Context
8
+ desc "Deas::Template"
9
+ setup do
10
+ @fake_sinatra_call = FakeApp.new
11
+ @template = Deas::Template.new(@fake_sinatra_call, 'users/index')
12
+ end
13
+ subject{ @template }
14
+
15
+ should have_instance_methods :name, :options, :render
16
+ should have_class_methods :helpers
17
+
18
+ should "symbolize it's name" do
19
+ assert_equal :"users/index", subject.name
20
+ end
21
+
22
+ should "set it's scope option to a empty Module" do
23
+ assert_instance_of Deas::Template::RenderScope, subject.options[:scope]
24
+ end
25
+
26
+ should "call the sinatra_call's `erb` method with #render" do
27
+ return_value = subject.render
28
+
29
+ assert_equal subject.name, return_value[0]
30
+ assert_equal subject.options, return_value[1]
31
+ end
32
+
33
+ should "include modules on the RenderScope using helpers class method" do
34
+ helper_module = Module.new
35
+ Deas::Template.helpers(helper_module)
36
+
37
+ included_modules = Deas::Template::RenderScope.included_modules
38
+ assert_includes helper_module, included_modules
39
+ end
40
+
41
+ end
42
+
43
+ class WithLayoutsTests < BaseTests
44
+ desc "with layouts"
45
+ setup do
46
+ @template = Deas::Template.new(@fake_sinatra_call, 'users/index', {
47
+ :layout => [ 'layouts/web', 'layouts/search' ]
48
+ })
49
+ end
50
+
51
+ should "call the engine's `erb` method for each layout, " \
52
+ "in the `layout` option" do
53
+ return_value = subject.render
54
+
55
+ # the return_value is a one-dimensional array of all the render args
56
+ # used in order. Thus the, 0, 2, 4 nature of the indexes.
57
+ assert_equal :"layouts/web", return_value[0]
58
+ assert_equal :"layouts/search", return_value[2]
59
+ assert_equal :"users/index", return_value[4]
60
+ end
61
+
62
+ end
63
+
64
+ class RenderScopeTests < Assert::Context
65
+ desc "Deas::Template::RenderScope"
66
+ setup do
67
+ @fake_sinatra_call = FakeApp.new
68
+ @render_scope = Deas::Template::RenderScope.new(@fake_sinatra_call)
69
+ end
70
+ subject{ @render_scope }
71
+
72
+ should have_instance_methods :partial, :escape_html, :h, :escape_url, :u,
73
+ :render
74
+
75
+ should "call the sinatra_call's erb method with #partial" do
76
+ return_value = subject.partial('part', :something => true)
77
+
78
+ assert_equal :_part, return_value[0]
79
+
80
+ expected_options = return_value[1]
81
+ assert_instance_of Deas::Template::RenderScope, expected_options[:scope]
82
+
83
+ expected_locals = { :something => true }
84
+ assert_equal(expected_locals, expected_options[:locals])
85
+ end
86
+
87
+ should "call the sinatra_call's erb method with #render" do
88
+ return_value = subject.render('my_template', {
89
+ :views => '/path/to/templates',
90
+ :locals => {
91
+ :something => true
92
+ }
93
+ })
94
+
95
+ assert_equal :my_template, return_value[0]
96
+
97
+ expected_options = return_value[1]
98
+ assert_instance_of Deas::Template::RenderScope, expected_options[:scope]
99
+
100
+ expected_locals = { :something => true }
101
+ assert_equal(expected_locals, expected_options[:locals])
102
+ end
103
+
104
+ should "escape html with #h or #escape_html" do
105
+ return_value = subject.escape_html("<strong></strong>")
106
+ assert_equal "&lt;strong&gt;&lt;&#x2F;strong&gt;", return_value
107
+
108
+ return_value = subject.h("<strong></strong>")
109
+ assert_equal "&lt;strong&gt;&lt;&#x2F;strong&gt;", return_value
110
+ end
111
+
112
+ should "escape urls with #u or #escape_url" do
113
+ return_value = subject.escape_url("/path/to/somewhere")
114
+ assert_equal "%2Fpath%2Fto%2Fsomewhere", return_value
115
+
116
+ return_value = subject.u("/path/to/somewhere")
117
+ assert_equal "%2Fpath%2Fto%2Fsomewhere", return_value
118
+ end
119
+
120
+ end
121
+
122
+ end
123
+
124
+ class Deas::Partial
125
+
126
+ class BaseTests < Assert::Context
127
+ desc "Deas::Partial"
128
+ setup do
129
+ @fake_sinatra_call = FakeApp.new
130
+ @partial = Deas::Partial.new(@fake_sinatra_call, 'users/index/listing', {
131
+ :user => 'Joe Test'
132
+ })
133
+ end
134
+ subject{ @partial }
135
+
136
+ should "be a kind of Deas::Template" do
137
+ assert_kind_of Deas::Template, subject
138
+ end
139
+
140
+ should "add an underscore to it's template's basename" do
141
+ assert_equal :"users/index/_listing", subject.name
142
+ end
143
+
144
+ should "set it's locals option" do
145
+ assert_equal({ :user => 'Joe Test' }, subject.options[:locals])
146
+ end
147
+
148
+ end
149
+
150
+ end
@@ -0,0 +1,96 @@
1
+ require 'assert'
2
+ require 'deas/test_helpers'
3
+ require 'deas/view_handler'
4
+ require 'test/support/view_handlers'
5
+
6
+ module Deas::ViewHandler
7
+
8
+ class BaseTests < Assert::Context
9
+ include Deas::TestHelpers
10
+
11
+ desc "Deas::ViewHandler"
12
+ setup do
13
+ @handler = test_runner(TestViewHandler).handler
14
+ end
15
+ subject{ @handler }
16
+
17
+ should have_instance_methods :init, :init!, :run, :run!
18
+ should have_class_methods :before, :before_callbacks, :after,
19
+ :after_callbacks, :layout, :layouts
20
+
21
+ should "raise a NotImplementedError if run! is not overwritten" do
22
+ assert_raises(NotImplementedError){ subject.run! }
23
+ end
24
+
25
+ should "store procs in #before_callbacks with #before" do
26
+ before_proc = proc{ }
27
+ TestViewHandler.before(&before_proc)
28
+
29
+ assert_includes before_proc, TestViewHandler.before_callbacks
30
+ end
31
+
32
+ should "store procs in #after_callbacks with #after" do
33
+ after_proc = proc{ }
34
+ TestViewHandler.after(&after_proc)
35
+
36
+ assert_includes after_proc, TestViewHandler.after_callbacks
37
+ end
38
+
39
+ should "allow specifying the layouts using #layout or #layouts" do
40
+ handler_class = Class.new{ include Deas::ViewHandler }
41
+
42
+ handler_class.layout 'layouts/app'
43
+ assert_equal [ 'layouts/app' ], handler_class.layouts
44
+
45
+ handler_class.layouts 'layouts/web', 'layouts/search'
46
+ assert_equal [ 'layouts/web', 'layouts/search' ], handler_class.layouts
47
+ end
48
+
49
+ end
50
+
51
+ class WithMethodFlagsTests < BaseTests
52
+ setup do
53
+ @handler = test_runner(FlagViewHandler).handler
54
+ end
55
+
56
+ should "have called `init!` and it's callbacks" do
57
+ assert_equal true, subject.before_init_called
58
+ assert_equal true, subject.init_bang_called
59
+ assert_equal true, subject.after_init_called
60
+ end
61
+
62
+ should "not have called `run!` or it's callbacks when initialized" do
63
+ assert_nil subject.before_run_called
64
+ assert_nil subject.run_bang_called
65
+ assert_nil subject.after_run_called
66
+ end
67
+
68
+ should "call `run!` and it's callbacks when it's `run`" do
69
+ subject.run
70
+
71
+ assert_equal true, subject.before_run_called
72
+ assert_equal true, subject.run_bang_called
73
+ assert_equal true, subject.after_run_called
74
+ end
75
+
76
+ end
77
+
78
+ class HaltTests < BaseTests
79
+ desc "halt"
80
+
81
+ should "return a response with the status code and the passed data" do
82
+ runner = test_runner(HaltViewHandler, :params => {
83
+ 'code' => 200,
84
+ 'headers' => { 'Content-Type' => 'text/plain' },
85
+ 'body' => 'test halting'
86
+ })
87
+ runner.run
88
+
89
+ assert_equal 200, runner.return_value[0]
90
+ assert_equal({ 'Content-Type' => 'text/plain' }, runner.return_value[1])
91
+ assert_equal 'test halting', runner.return_value[2]
92
+ end
93
+
94
+ end
95
+
96
+ end