deas 0.38.0 → 0.39.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/Gemfile +2 -1
  2. data/{LICENSE.txt → LICENSE} +0 -0
  3. data/deas.gemspec +4 -3
  4. data/lib/deas/deas_runner.rb +17 -12
  5. data/lib/deas/handler_proxy.rb +14 -8
  6. data/lib/deas/redirect_proxy.rb +12 -12
  7. data/lib/deas/runner.rb +169 -19
  8. data/lib/deas/server.rb +14 -10
  9. data/lib/deas/template_source.rb +2 -2
  10. data/lib/deas/test_runner.rb +59 -60
  11. data/lib/deas/version.rb +1 -1
  12. data/lib/deas/view_handler.rb +55 -30
  13. data/test/support/empty_view_handler.rb +7 -0
  14. data/test/support/factory.rb +5 -0
  15. data/test/support/fake_request.rb +29 -0
  16. data/test/support/fake_sinatra_call.rb +11 -16
  17. data/test/support/file1.txt +1 -0
  18. data/test/support/file2.txt +1 -0
  19. data/test/support/routes.rb +7 -7
  20. data/test/support/show.html +0 -0
  21. data/test/support/show.json +0 -0
  22. data/test/system/{rack_tests.rb → deas_tests.rb} +19 -14
  23. data/test/unit/deas_runner_tests.rb +209 -20
  24. data/test/unit/handler_proxy_tests.rb +27 -19
  25. data/test/unit/redirect_proxy_tests.rb +32 -33
  26. data/test/unit/respond_with_proxy_tests.rb +1 -2
  27. data/test/unit/route_proxy_tests.rb +1 -1
  28. data/test/unit/route_tests.rb +1 -1
  29. data/test/unit/router_tests.rb +5 -5
  30. data/test/unit/runner_tests.rb +619 -76
  31. data/test/unit/server_tests.rb +6 -1
  32. data/test/unit/sinatra_app_tests.rb +1 -1
  33. data/test/unit/test_runner_tests.rb +377 -106
  34. data/test/unit/url_tests.rb +1 -1
  35. data/test/unit/view_handler_tests.rb +325 -182
  36. metadata +43 -24
  37. data/lib/deas/sinatra_runner.rb +0 -55
  38. data/lib/deas/test_helpers.rb +0 -23
  39. data/test/support/view_handlers.rb +0 -83
  40. data/test/unit/sinatra_runner_tests.rb +0 -79
  41. data/test/unit/test_helpers_tests.rb +0 -53
@@ -5,100 +5,99 @@ require 'deas/view_handler'
5
5
 
6
6
  module Deas
7
7
 
8
- InvalidServiceHandlerError = Class.new(StandardError)
8
+ InvalidViewHandlerError = Class.new(StandardError)
9
9
 
10
10
  class TestRunner < Runner
11
11
 
12
- attr_reader :response_value
12
+ attr_reader :content_type_args
13
13
 
14
14
  def initialize(handler_class, args = nil)
15
15
  if !handler_class.include?(Deas::ViewHandler)
16
- raise InvalidServiceHandlerError, "#{handler_class.inspect} is not a"\
17
- " Deas::ServiceHandler"
16
+ raise InvalidViewHandlerError, "#{handler_class.inspect} is not a " \
17
+ "Deas::ViewHandler"
18
18
  end
19
19
 
20
- args = (args || {}).dup
20
+ @run_return_value = nil
21
+ @content_type_args = nil
22
+ @halted = false
23
+
24
+ a = (args || {}).dup
21
25
  super(handler_class, {
22
- :request => args.delete(:request),
23
- :response => args.delete(:response),
24
- :session => args.delete(:session),
25
- :params => NormalizedParams.new(args.delete(:params) || {}).value,
26
- :logger => args.delete(:logger),
27
- :router => args.delete(:router),
28
- :template_source => args.delete(:template_source)
26
+ :logger => a.delete(:logger),
27
+ :router => a.delete(:router),
28
+ :template_source => a.delete(:template_source),
29
+ :request => a.delete(:request),
30
+ :session => a.delete(:session),
31
+ :params => NormalizedParams.new(a.delete(:params) || {}).value
29
32
  })
30
- args.each{|key, value| self.handler.send("#{key}=", value) }
33
+ a.each{|key, value| self.handler.send("#{key}=", value) }
31
34
 
32
- @response_value = catch(:halt){ self.handler.init; nil }
35
+ catch(:halt){ self.handler.deas_init }
33
36
  end
34
37
 
38
+ def halted?; @halted; end
39
+
35
40
  def run
36
- @response_value ||= catch(:halt){ self.handler.run }
41
+ catch(:halt){ self.handler.deas_run } if !self.halted?
42
+ @run_return_value
37
43
  end
38
44
 
39
- # Helpers
45
+ # helpers
40
46
 
41
- def halt(*args)
42
- throw(:halt, HaltArgs.new(args))
47
+ def content_type(extname, params = nil)
48
+ @content_type_args = ContentTypeArgs.new(extname, params)
49
+ super
43
50
  end
44
51
 
45
- class HaltArgs < Struct.new(:body, :headers, :status)
46
- def initialize(args)
47
- super(*[
48
- !args.last.kind_of?(::Hash) && !args.last.kind_of?(::Integer) ? args.pop : nil,
49
- args.last.kind_of?(::Hash) ? args.pop : nil,
50
- args.first.kind_of?(::Integer) ? args.first : nil
51
- ])
52
- end
52
+ def halt(*args)
53
+ @halted = true
54
+ @run_return_value ||= HaltArgs.new(args)
55
+ super
53
56
  end
54
57
 
55
- def redirect(path, *halt_args)
56
- throw(:halt, RedirectArgs.new(path, halt_args))
58
+ def redirect(location, *halt_args)
59
+ @run_return_value ||= RedirectArgs.new(location, HaltArgs.new(halt_args))
60
+ super
57
61
  end
58
62
 
59
- class RedirectArgs < Struct.new(:path, :halt_args)
60
- def redirect?; true; end
63
+ def send_file(file_path, opts = nil)
64
+ @run_return_value ||= SendFileArgs.new(file_path, opts)
65
+ super
61
66
  end
62
67
 
63
- def content_type(*args)
64
- return @content_type if args.empty?
65
- opts, value = [
66
- args.last.kind_of?(Hash) ? args.pop : {},
67
- args.last
68
- ]
69
- @content_type = ContentTypeArgs.new(value, opts)
68
+ def source_render(source, template_name, locals = nil)
69
+ @run_return_value ||= RenderArgs.new(source, template_name, locals)
70
+ super
70
71
  end
71
- ContentTypeArgs = Struct.new(:value, :opts)
72
72
 
73
- def status(*args)
74
- return @status if args.empty?
75
- value = args.last
76
- @status = StatusArgs.new(value)
73
+ def source_partial(source, template_name, locals = nil)
74
+ # partials don't interact with the response body so they shouldn't affect
75
+ # the run return value (like renders do). Render the markup and discard
76
+ # it to test the template. Return the render args so you can test the
77
+ # expected partials were rendered.
78
+ super
79
+ RenderArgs.new(source, template_name, locals)
77
80
  end
78
- StatusArgs = Struct.new(:value)
79
81
 
80
- def headers(*args)
81
- return @headers if args.empty?
82
- value = args.last
83
- @headers = HeadersArgs.new(value)
84
- end
85
- HeadersArgs = Struct.new(:value)
82
+ ContentTypeArgs = Struct.new(:extname, :params)
86
83
 
87
- def send_file(file_path, options = nil, &block)
88
- SendFileArgs.new(file_path, options, block)
84
+ class HaltArgs < Struct.new(:status, :headers, :body)
85
+ def initialize(args)
86
+ a = args.dup
87
+ super(*[
88
+ a.first.instance_of?(::Fixnum) ? a.shift : nil,
89
+ a.first.kind_of?(::Hash) ? a.shift : nil,
90
+ a.first.respond_to?(:each) ? a.shift : nil
91
+ ])
92
+ end
89
93
  end
90
- SendFileArgs = Struct.new(:file_path, :options, :block)
91
94
 
92
- def source_render(source, template_name, locals = nil)
93
- super # render the markup and discard it
94
- RenderArgs.new(source, template_name, locals)
95
+ class RedirectArgs < Struct.new(:location, :halt_args)
96
+ def redirect?; true; end
95
97
  end
96
- RenderArgs = Struct.new(:source, :template_name, :locals)
97
98
 
98
- def source_partial(source, template_name, locals = nil)
99
- super # render the markup and discard it
100
- RenderArgs.new(source, template_name, locals)
101
- end
99
+ SendFileArgs = Struct.new(:file_path, :opts)
100
+ RenderArgs = Struct.new(:source, :template_name, :locals)
102
101
 
103
102
  class NormalizedParams < Deas::Runner::NormalizedParams
104
103
  def file_type?(value)
@@ -1,3 +1,3 @@
1
1
  module Deas
2
- VERSION = "0.38.0"
2
+ VERSION = "0.39.0"
3
3
  end
@@ -1,14 +1,14 @@
1
+ require 'much-plugin'
1
2
  require 'deas/runner'
2
3
 
3
4
  module Deas
4
5
 
5
6
  module ViewHandler
7
+ include MuchPlugin
6
8
 
7
- def self.included(klass)
8
- klass.class_eval do
9
- extend ClassMethods
10
- include InstanceMethods
11
- end
9
+ plugin_included do
10
+ extend ClassMethods
11
+ include InstanceMethods
12
12
  end
13
13
 
14
14
  module InstanceMethods
@@ -17,30 +17,35 @@ module Deas
17
17
  @deas_runner = runner
18
18
  end
19
19
 
20
- def init
21
- run_callback 'before_init'
20
+ def deas_init
21
+ self.deas_run_callback 'before_init'
22
22
  self.init!
23
- run_callback 'after_init'
23
+ self.deas_run_callback 'after_init'
24
24
  end
25
25
 
26
26
  def init!
27
27
  end
28
28
 
29
- def run
30
- run_callback 'before_run'
29
+ def deas_run
30
+ self.deas_run_callback 'before_run'
31
31
  data = self.run!
32
- run_callback 'after_run'
32
+ self.deas_run_callback 'after_run'
33
33
  data
34
34
  end
35
35
 
36
36
  def run!
37
- raise NotImplementedError
38
37
  end
39
38
 
40
39
  def layouts
41
40
  self.class.layouts.map{ |proc| self.instance_eval(&proc) }
42
41
  end
43
42
 
43
+ def deas_run_callback(callback)
44
+ (self.class.send("#{callback}_callbacks") || []).each do |callback|
45
+ self.instance_eval(&callback)
46
+ end
47
+ end
48
+
44
49
  def inspect
45
50
  reference = '0x0%x' % (self.object_id << 1)
46
51
  "#<#{self.class}:#{reference} @request=#{request.inspect}>"
@@ -54,31 +59,29 @@ module Deas
54
59
 
55
60
  # Helpers
56
61
 
57
- def halt(*args); @deas_runner.halt(*args); end
58
- def redirect(*args); @deas_runner.redirect(*args); end
59
- def content_type(*args); @deas_runner.content_type(*args); end
62
+ # utils
63
+ def logger; @deas_runner.logger; end
64
+ def router; @deas_runner.router; end
65
+
66
+ # request
67
+ def request; @deas_runner.request; end
68
+ def session; @deas_runner.session; end
69
+ def params; @deas_runner.params; end
70
+
71
+ # response
60
72
  def status(*args); @deas_runner.status(*args); end
61
73
  def headers(*args); @deas_runner.headers(*args); end
74
+ def body(*args); @deas_runner.body(*args); end
75
+ def content_type(*args); @deas_runner.content_type(*args); end
76
+ def halt(*args); @deas_runner.halt(*args); end
77
+ def redirect(*args); @deas_runner.redirect(*args); end
78
+ def send_file(*args); @deas_runner.send_file(*args); end
62
79
 
80
+ # rendering
63
81
  def render(*args, &block); @deas_runner.render(*args, &block); end
64
82
  def source_render(*args, &block); @deas_runner.source_render(*args, &block); end
65
83
  def partial(*args, &block); @deas_runner.partial(*args, &block); end
66
84
  def source_partial(*args, &block); @deas_runner.source_partial(*args, &block); end
67
- def send_file(*args, &block); @deas_runner.send_file(*args, &block); end
68
-
69
- # TODO: make these public when built using the test helpers
70
- def logger; @deas_runner.logger; end
71
- def router; @deas_runner.router; end
72
- def request; @deas_runner.request; end
73
- def response; @deas_runner.response; end
74
- def params; @deas_runner.params; end
75
- def session; @deas_runner.session; end
76
-
77
- def run_callback(callback)
78
- (self.class.send("#{callback}_callbacks") || []).each do |callback|
79
- self.instance_eval(&callback)
80
- end
81
- end
82
85
 
83
86
  end
84
87
 
@@ -106,6 +109,7 @@ module Deas
106
109
  def after_init(&block); self.after_init_callbacks << block; end
107
110
  def before_run(&block); self.before_run_callbacks << block; end
108
111
  def after_run(&block); self.after_run_callbacks << block; end
112
+
109
113
  def prepend_before(&block); self.before_callbacks.unshift(block); end
110
114
  def prepend_after(&block); self.after_callbacks.unshift(block); end
111
115
  def prepend_before_init(&block); self.before_init_callbacks.unshift(block); end
@@ -115,6 +119,27 @@ module Deas
115
119
 
116
120
  end
117
121
 
122
+ module TestHelpers
123
+
124
+ def self.included(klass)
125
+ require 'rack/request'
126
+ require 'rack/response'
127
+ require 'deas/test_runner'
128
+ end
129
+
130
+ def test_runner(handler_class, args = nil)
131
+ args ||= {}
132
+ args[:request] ||= Rack::Request.new({})
133
+ args[:session] ||= args[:request].session
134
+ TestRunner.new(handler_class, args)
135
+ end
136
+
137
+ def test_handler(handler_class, args = nil)
138
+ test_runner(handler_class, args).handler
139
+ end
140
+
141
+ end
142
+
118
143
  end
119
144
 
120
145
  end
@@ -0,0 +1,7 @@
1
+ require 'deas/template_source'
2
+ require 'deas/view_handler'
3
+
4
+ class EmptyViewHandler
5
+ include Deas::ViewHandler
6
+
7
+ end
@@ -3,6 +3,7 @@ require 'deas/logger'
3
3
  require 'deas/router'
4
4
  require 'deas/server_data'
5
5
  require 'deas/template_source'
6
+ require 'test/support/fake_request'
6
7
  require 'test/support/fake_sinatra_call'
7
8
 
8
9
  module Factory
@@ -25,6 +26,10 @@ module Factory
25
26
  }.merge(opts || {}))
26
27
  end
27
28
 
29
+ def self.request(args = nil)
30
+ FakeRequest.new(args)
31
+ end
32
+
28
33
  def self.sinatra_call(settings = nil)
29
34
  FakeSinatraCall.new(settings)
30
35
  end
@@ -0,0 +1,29 @@
1
+ require 'ostruct'
2
+
3
+ class FakeRequest < Struct.new(:http_method, :path, :params, :session, :env)
4
+ alias :request_method :http_method
5
+
6
+ attr_reader :logging_msgs
7
+
8
+ def initialize(args = nil)
9
+ args ||= {}
10
+ super(*[
11
+ args[:http_method] || 'GET',
12
+ args[:path] || Factory.path,
13
+ args[:params] || {},
14
+ args[:session] || OpenStruct.new,
15
+ args[:env] || {}
16
+ ])
17
+
18
+ self.env.merge!({
19
+ 'rack.url_scheme' => Factory.boolean ? 'http' : 'https',
20
+ 'HTTP_HOST' => "#{Factory.string}.#{Factory.string}",
21
+
22
+ 'deas.logging' => Proc.new do |msg|
23
+ @logging_msgs ||= []
24
+ @logging_msgs.push(msg)
25
+ end
26
+ })
27
+ end
28
+
29
+ end
@@ -1,4 +1,4 @@
1
- require 'ostruct'
1
+ require 'test/support/fake_request'
2
2
 
3
3
  class FakeSinatraCall
4
4
 
@@ -9,8 +9,8 @@ class FakeSinatraCall
9
9
  attr_accessor :settings
10
10
 
11
11
  def initialize(settings = nil)
12
- @request = FakeRequest.new('GET','/something', {}, OpenStruct.new)
13
- @response = FakeResponse.new(Factory.integer, {}, [Factory.text])
12
+ @request = FakeRequest.new
13
+ @response = FakeResponse.new
14
14
  @session = @request.session
15
15
  @params = @request.params
16
16
  @logger = Deas::NullLogger.new
@@ -69,18 +69,13 @@ class FakeSinatraCall
69
69
 
70
70
  end
71
71
 
72
- class FakeRequest < Struct.new(:http_method, :path, :params, :session)
73
- alias :request_method :http_method
74
-
75
- attr_reader :logging_msgs
76
-
77
- def env
78
- @env ||= {
79
- 'deas.logging' => Proc.new do |msg|
80
- @logging_msgs ||= []
81
- @logging_msgs.push(msg)
82
- end
83
- }
72
+ class FakeResponse < Struct.new(:status, :headers, :body)
73
+ def initialize(args = nil)
74
+ args ||= {}
75
+ super(*[
76
+ args[:status] || Factory.integer,
77
+ args[:headers] || {},
78
+ args[:body] || [Factory.text]
79
+ ])
84
80
  end
85
81
  end
86
- FakeResponse = Struct.new(:status, :headers, :body)
@@ -0,0 +1 @@
1
+ this is just a file to use in send file tests.
@@ -0,0 +1 @@
1
+ this is just another file to use in send file tests.
@@ -59,7 +59,7 @@ class DeasDevServer
59
59
 
60
60
  show_exceptions true
61
61
 
62
- get '/error', 'ErrorHandler'
62
+ get '/error', 'ErrorHandler'
63
63
 
64
64
  end
65
65
 
@@ -73,7 +73,7 @@ class ShowHandler
73
73
  end
74
74
 
75
75
  def run!
76
- @message
76
+ body @message
77
77
  end
78
78
 
79
79
  end
@@ -88,7 +88,7 @@ class ShowMobileHandler
88
88
  end
89
89
 
90
90
  def run!
91
- @message
91
+ body @message
92
92
  end
93
93
 
94
94
  end
@@ -111,7 +111,7 @@ class ShowLatinJsonHandler
111
111
  include Deas::ViewHandler
112
112
 
113
113
  def run!
114
- content_type :json, :charset => 'latin1'
114
+ content_type '.json', :charset => 'latin1'
115
115
  end
116
116
 
117
117
  end
@@ -177,7 +177,7 @@ class UseSessionHandler
177
177
  include Deas::ViewHandler
178
178
 
179
179
  def run!
180
- session[:secret]
180
+ body session[:secret]
181
181
  end
182
182
 
183
183
  end
@@ -189,7 +189,6 @@ class HandlerTestsHandler
189
189
  @data = {}
190
190
  set_data('logger_class_name'){ logger.class.name }
191
191
  set_data('request_method'){ request.request_method.to_s }
192
- set_data('response_firstheaderval'){ response.headers.sort.first.to_s }
193
192
  set_data('params_a_param'){ params['a-param'] }
194
193
  set_data('session_inspect'){ session.inspect }
195
194
  end
@@ -202,7 +201,8 @@ class HandlerTestsHandler
202
201
  end
203
202
 
204
203
  def run!
205
- [200, {}, @data.inspect]
204
+ status 200
205
+ body @data.inspect
206
206
  end
207
207
 
208
208
  end