require 'rack/multipart' require 'deas/router' require 'deas/runner' require 'deas/view_handler' module Deas InvalidViewHandlerError = Class.new(StandardError) class TestRunner < Runner attr_reader :content_type_args def initialize(handler_class, args = nil) if !handler_class.include?(Deas::ViewHandler) raise InvalidViewHandlerError, "#{handler_class.inspect} is not a " \ "Deas::ViewHandler" end @run_return_value = nil @content_type_args = nil @halted = false a = (args || {}).dup super(handler_class, { :logger => a.delete(:logger), :router => a.delete(:router), :template_source => a.delete(:template_source), :request => a.delete(:request), :route_path => a.delete(:route_path), :params => NormalizedParams.new(a.delete(:params) || {}).value }) @splat = a.delete(:splat) a.each{|key, value| self.handler.send("#{key}=", value) } catch(:halt){ self.handler.deas_init } end def splat; @splat; end def halted?; @halted; end def run catch(:halt){ self.handler.deas_run } if !self.halted? @run_return_value end # helpers def content_type(extname, params = nil) @content_type_args = ContentTypeArgs.new(extname, params) super end def halt(*args) @halted = true @run_return_value ||= HaltArgs.new(args) super end def redirect(location, *halt_args) @run_return_value ||= RedirectArgs.new(location, HaltArgs.new(halt_args)) super end def send_file(file_path, opts = nil) @run_return_value ||= SendFileArgs.new(file_path, opts) super end def source_render(source, template_name, locals = nil) @run_return_value ||= RenderArgs.new(source, template_name, locals) super end def source_partial(source, template_name, locals = nil) # partials don't interact with the response body so they shouldn't affect # the run return value (like renders do). Render the markup and discard # it to test the template. Return the render args so you can test the # expected partials were rendered. super RenderArgs.new(source, template_name, locals) end ContentTypeArgs = Struct.new(:extname, :params) class HaltArgs < Struct.new(:status, :headers, :body) def initialize(args) a = args.dup super(*[ a.first.instance_of?(::Fixnum) ? a.shift : nil, a.first.kind_of?(::Hash) ? a.shift : nil, a.shift ]) end end class RedirectArgs < Struct.new(:location, :halt_args) def redirect?; true; end end SendFileArgs = Struct.new(:file_path, :opts) RenderArgs = Struct.new(:source, :template_name, :locals) class NormalizedParams < Deas::Runner::NormalizedParams def file_type?(value) value.kind_of?(::Tempfile) || value.kind_of?(::File) || value.kind_of?(::Rack::Multipart::UploadedFile) || (defined?(::Rack::Test::UploadedFile) && value.kind_of?(::Rack::Test::UploadedFile)) end end end end