test/unit/view_handler_tests.rb in deas-0.38.0 vs test/unit/view_handler_tests.rb in deas-0.39.0

- old
+ new

@@ -1,298 +1,441 @@ require 'assert' require 'deas/view_handler' -require 'deas/test_helpers' +require 'much-plugin' +require 'rack/request' +require 'rack/response' require 'deas/template_source' -require 'test/support/view_handlers' +require 'test/support/empty_view_handler' module Deas::ViewHandler class UnitTests < Assert::Context - include Deas::TestHelpers + include Deas::ViewHandler::TestHelpers desc "Deas::ViewHandler" setup do - @handler_class = TestViewHandler + @handler_class = Class.new{ include Deas::ViewHandler } end subject{ @handler_class } should have_imeths :layout, :layouts - should have_imeths :before, :prepend_before, :before_callbacks - should have_imeths :after, :prepend_after, :after_callbacks - should have_imeths :before_init, :prepend_before_init, :before_init_callbacks - should have_imeths :after_init, :prepend_after_init, :after_init_callbacks - should have_imeths :before_run, :prepend_before_run, :before_run_callbacks - should have_imeths :after_run, :prepend_after_run, :after_run_callbacks + should have_imeths :before_callbacks, :after_callbacks + should have_imeths :before_init_callbacks, :after_init_callbacks + should have_imeths :before_run_callbacks, :after_run_callbacks + should have_imeths :before, :after + should have_imeths :before_init, :after_init + should have_imeths :before_run, :after_run + should have_imeths :prepend_before, :prepend_after + should have_imeths :prepend_before_init, :prepend_after_init + should have_imeths :prepend_before_run, :prepend_after_run + should "use much-plugin" do + assert_includes MuchPlugin, Deas::ViewHandler + end + should "specify layouts" do subject.layout 'layouts/app' assert_equal ['layouts/app'], subject.layouts.map(&:call) subject.layout { 'layouts/web' } assert_equal ['layouts/app', 'layouts/web'], subject.layouts.map(&:call) end + should "return an empty array by default using `before_callbacks`" do + assert_equal [], subject.before_callbacks + end + + should "return an empty array by default using `after_callbacks`" do + assert_equal [], subject.after_callbacks + end + + should "return an empty array by default using `before_init_callbacks`" do + assert_equal [], subject.before_init_callbacks + end + + should "return an empty array by default using `after_init_callbacks`" do + assert_equal [], subject.after_init_callbacks + end + + should "return an empty array by default using `before_run_callbacks`" do + assert_equal [], subject.before_run_callbacks + end + + should "return an empty array by default using `after_run_callbacks`" do + assert_equal [], subject.after_run_callbacks + end + + should "append a block to the before callbacks using `before`" do + subject.before_callbacks << proc{ Factory.string } + block = Proc.new{ Factory.string } + subject.before(&block) + assert_equal block, subject.before_callbacks.last end + should "append a block to the after callbacks using `after`" do + subject.after_callbacks << proc{ Factory.string } + block = Proc.new{ Factory.string } + subject.after(&block) + assert_equal block, subject.after_callbacks.last + end + + should "append a block to the before init callbacks using `before_init`" do + subject.before_init_callbacks << proc{ Factory.string } + block = Proc.new{ Factory.string } + subject.before_init(&block) + assert_equal block, subject.before_init_callbacks.last + end + + should "append a block to the after init callbacks using `after_init`" do + subject.after_init_callbacks << proc{ Factory.string } + block = Proc.new{ Factory.string } + subject.after_init(&block) + assert_equal block, subject.after_init_callbacks.last + end + + should "append a block to the before run callbacks using `before_run`" do + subject.before_run_callbacks << proc{ Factory.string } + block = Proc.new{ Factory.string } + subject.before_run(&block) + assert_equal block, subject.before_run_callbacks.last + end + + should "append a block to the after run callbacks using `after_run`" do + subject.after_run_callbacks << proc{ Factory.string } + block = Proc.new{ Factory.string } + subject.after_run(&block) + assert_equal block, subject.after_run_callbacks.last + end + + should "prepend a block to the before callbacks using `prepend_before`" do + subject.before_callbacks << proc{ Factory.string } + block = Proc.new{ Factory.string } + subject.prepend_before(&block) + assert_equal block, subject.before_callbacks.first + end + + should "prepend a block to the after callbacks using `prepend_after`" do + subject.after_callbacks << proc{ Factory.string } + block = Proc.new{ Factory.string } + subject.prepend_after(&block) + assert_equal block, subject.after_callbacks.first + end + + should "prepend a block to the before init callbacks using `prepend_before_init`" do + subject.before_init_callbacks << proc{ Factory.string } + block = Proc.new{ Factory.string } + subject.prepend_before_init(&block) + assert_equal block, subject.before_init_callbacks.first + end + + should "prepend a block to the after init callbacks using `prepend_after_init`" do + subject.after_init_callbacks << proc{ Factory.string } + block = Proc.new{ Factory.string } + subject.prepend_after_init(&block) + assert_equal block, subject.after_init_callbacks.first + end + + should "prepend a block to the before run callbacks using `prepend_before_run`" do + subject.before_run_callbacks << proc{ Factory.string } + block = Proc.new{ Factory.string } + subject.prepend_before_run(&block) + assert_equal block, subject.before_run_callbacks.first + end + + should "prepend a block to the after run callbacks using `prepend_after_run`" do + subject.after_run_callbacks << proc{ Factory.string } + block = Proc.new{ Factory.string } + subject.prepend_after_run(&block) + assert_equal block, subject.after_run_callbacks.first + end + + end + class InitTests < UnitTests desc "when init" setup do - @runner = test_runner(@handler_class) + @runner = test_runner(TestViewHandler) @handler = @runner.handler end subject{ @handler } - should have_imeths :init, :init!, :run, :run! - should have_imeths :layouts + should have_imeths :deas_init, :init!, :deas_run, :run! + should have_imeths :layouts, :deas_run_callback - should "have called `init!` and it's callbacks" do - assert_equal true, subject.before_init_called - assert_equal true, subject.second_before_init_called - assert_equal true, subject.init_bang_called - assert_equal true, subject.after_init_called + should "have called `init!` and its before/after init callbacks" do + assert_equal 1, subject.first_before_init_call_order + assert_equal 2, subject.second_before_init_call_order + assert_equal 3, subject.init_call_order + assert_equal 4, subject.first_after_init_call_order + assert_equal 5, subject.second_after_init_call_order end - should "not have called `run!` or it's callbacks when initialized" do - assert_nil subject.before_run_called - assert_nil subject.run_bang_called - assert_nil subject.after_run_called + should "not have called `run!` and its before/after run callbacks" do + assert_nil subject.first_before_run_call_order + assert_nil subject.second_before_run_call_order + assert_nil subject.run_call_order + assert_nil subject.first_after_run_call_order + assert_nil subject.second_after_run_call_order end - end - - class LayoutsTests < InitTests - desc "with layouts" - setup do - @params = { 'n' => Factory.integer } - @runner = test_runner(LayoutsViewHandler, :params => @params) - @handler = @runner.handler + should "run its callbacks with `deas_run_callback`" do + subject.deas_run_callback 'before_run' + assert_equal 6, subject.first_before_run_call_order + assert_equal 7, subject.second_before_run_call_order end - should "build its layouts by instance eval'ing its class layout procs" do - exp = subject.class.layouts.map{ |proc| @handler.instance_eval(&proc) } - assert_equal exp, subject.layouts + should "know if it is equal to another view handler" do + handler = test_handler(TestViewHandler) + assert_equal handler, subject + + handler = test_handler(Class.new{ include Deas::ViewHandler }) + assert_not_equal handler, subject end end class RunTests < InitTests desc "and run" + setup do + @handler.deas_run + end should "call `run!` and it's callbacks" do - subject.run - assert_equal true, subject.before_run_called - assert_equal true, subject.run_bang_called - assert_equal true, subject.after_run_called + assert_equal 6, subject.first_before_run_call_order + assert_equal 7, subject.second_before_run_call_order + assert_equal 8, subject.run_call_order + assert_equal 9, subject.first_after_run_call_order + assert_equal 10, subject.second_after_run_call_order end - should "complain if run! is not overwritten" do - assert_raises(NotImplementedError){ test_runner(EmptyViewHandler).run } - end - - should "send files" do - send_file_args = test_runner(SendFileViewHandler).run - assert_equal "my_file.txt", send_file_args.file_path - assert_equal({:some => :option}, send_file_args.options) - end - end - class RenderTests < RunTests + class PrivateHelpersTests < InitTests setup do - @template_name = Factory.path - @locals = { Factory.string => Factory.string } - @source = Deas::TemplateSource.new(Factory.path) + @something = Factory.string + @args = (Factory.integer(3)+1).times.map{ Factory.string } + @block = proc{} + end - @render_args = nil - Assert.stub(@runner.template_source, :render){ |*args| @render_args = args } - @source_render_args = nil - Assert.stub(@source, :render){ |*args| @source_render_args = args } - @partial_args = nil - Assert.stub(@runner.template_source, :partial){ |*args| @partial_args = args } - @source_partial_args = nil - Assert.stub(@source, :partial){ |*args| @source_partial_args = args } + should "call to the runner for its logger" do + stub_runner_with_something_for(:logger) + assert_equal @runner.logger, subject.instance_eval{ logger } end - should "render templates" do - subject.send(:render, @template_name, @locals) - exp = [@template_name, subject, @locals] - assert_equal exp, @render_args + should "call to the runner for its router" do + stub_runner_with_something_for(:router) + assert_equal @runner.router, subject.instance_eval{ router } + end - subject.send(:source_render, @source, @template_name, @locals) - exp = [@template_name, subject, @locals] - assert_equal exp, @source_render_args + should "call to the runner for its request" do + stub_runner_with_something_for(:request) + assert_equal @runner.request, subject.instance_eval{ request } + end - subject.send(:partial, @template_name, @locals) - exp = [@template_name, @locals] - assert_equal exp, @partial_args + should "call to the runner for its session" do + stub_runner_with_something_for(:session) + assert_equal @runner.session, subject.instance_eval{ session } + end - subject.send(:source_partial, @source, @template_name, @locals) - exp = [@template_name, @locals] - assert_equal exp, @source_partial_args + should "call to the runner for its params" do + stub_runner_with_something_for(:params) + assert_equal @runner.params, subject.instance_eval{ params } end - end + should "call to the runner for its status helper" do + capture_runner_meth_args_for(:status) + exp_args = @args + subject.instance_eval{ status(*exp_args) } - class CallbackTests < UnitTests - setup do - @proc1 = proc{ '1' } - @proc2 = proc{ '2' } - @handler = Class.new{ include Deas::ViewHandler } + assert_equal exp_args, @meth_args + assert_nil @meth_block end - should "append procs in #before_callbacks with #before" do - @handler.before(&@proc1); @handler.before(&@proc2) - assert_equal @proc1, @handler.before_callbacks.first - assert_equal @proc2, @handler.before_callbacks.last - end + should "call to the runner for its headers helper" do + capture_runner_meth_args_for(:headers) + exp_args = @args + subject.instance_eval{ headers(*exp_args) } - should "prepend procs in #before_callbacks with #before" do - @handler.prepend_before(&@proc1); @handler.prepend_before(&@proc2) - assert_equal @proc2, @handler.before_callbacks.first - assert_equal @proc1, @handler.before_callbacks.last + assert_equal exp_args, @meth_args + assert_nil @meth_block end - should "append procs in #after_callbacks with #after" do - @handler.after(&@proc1); @handler.after(&@proc2) - assert_equal @proc1, @handler.after_callbacks.first - assert_equal @proc2, @handler.after_callbacks.last - end + should "call to the runner for its body helper" do + capture_runner_meth_args_for(:body) + exp_args = @args + subject.instance_eval{ body(*exp_args) } - should "prepend procs in #after_callbacks with #before" do - @handler.prepend_after(&@proc1); @handler.prepend_after(&@proc2) - assert_equal @proc2, @handler.after_callbacks.first - assert_equal @proc1, @handler.after_callbacks.last + assert_equal exp_args, @meth_args + assert_nil @meth_block end - should "append procs in #before_init_callbacks with #before_init" do - @handler.before_init(&@proc1); @handler.before_init(&@proc2) - assert_equal @proc1, @handler.before_init_callbacks.first - assert_equal @proc2, @handler.before_init_callbacks.last - end + should "call to the runner for its content type helper" do + capture_runner_meth_args_for(:content_type) + exp_args = @args + subject.instance_eval{ content_type(*exp_args) } - should "prepend procs in #before_init_callbacks with #before" do - @handler.prepend_before_init(&@proc1); @handler.prepend_before_init(&@proc2) - assert_equal @proc2, @handler.before_init_callbacks.first - assert_equal @proc1, @handler.before_init_callbacks.last + assert_equal exp_args, @meth_args + assert_nil @meth_block end - should "append procs in #after_init_callbacks with #after_init" do - @handler.after_init(&@proc1); @handler.after_init(&@proc2) - assert_equal @proc1, @handler.after_init_callbacks.first - assert_equal @proc2, @handler.after_init_callbacks.last - end + should "call to the runner for its halt helper" do + capture_runner_meth_args_for(:halt) + exp_args = @args + subject.instance_eval{ halt(*exp_args) } - should "prepend procs in #after_init_callbacks with #before" do - @handler.prepend_after_init(&@proc1); @handler.prepend_after_init(&@proc2) - assert_equal @proc2, @handler.after_init_callbacks.first - assert_equal @proc1, @handler.after_init_callbacks.last + assert_equal exp_args, @meth_args + assert_nil @meth_block end - should "append procs in #before_run_callbacks with #before_run" do - @handler.before_run(&@proc1); @handler.before_run(&@proc2) - assert_equal @proc1, @handler.before_run_callbacks.first - assert_equal @proc2, @handler.before_run_callbacks.last - end + should "call to the runner for its redirect helper" do + capture_runner_meth_args_for(:redirect) + exp_args = @args + subject.instance_eval{ redirect(*exp_args) } - should "prepend procs in #before_run_callbacks with #before" do - @handler.prepend_before_run(&@proc1); @handler.prepend_before_run(&@proc2) - assert_equal @proc2, @handler.before_run_callbacks.first - assert_equal @proc1, @handler.before_run_callbacks.last + assert_equal exp_args, @meth_args + assert_nil @meth_block end - should "append procs in #after_run_callbacks with #after_run" do - @handler.after_run(&@proc1); @handler.after_run(&@proc2) - assert_equal @proc1, @handler.after_run_callbacks.first - assert_equal @proc2, @handler.after_run_callbacks.last + should "call to the runner for its send file helper" do + capture_runner_meth_args_for(:send_file) + exp_args = @args + subject.instance_eval{ send_file(*exp_args) } + + assert_equal exp_args, @meth_args + assert_nil @meth_block end - should "prepend procs in #after_run_callbacks with #before" do - @handler.prepend_after_run(&@proc1); @handler.prepend_after_run(&@proc2) - assert_equal @proc2, @handler.after_run_callbacks.first - assert_equal @proc1, @handler.after_run_callbacks.last + should "call to the runner for its render helper" do + capture_runner_meth_args_for(:render) + exp_args, exp_block = @args, @block + subject.instance_eval{ render(*exp_args, &exp_block) } + + assert_equal exp_args, @meth_args + assert_equal exp_block, @meth_block end - end + should "call to the runner for its source render helper" do + capture_runner_meth_args_for(:source_render) + exp_args, exp_block = @args, @block + subject.instance_eval{ source_render(*exp_args, &exp_block) } - class HaltTests < UnitTests - desc "halt" + assert_equal exp_args, @meth_args + assert_equal exp_block, @meth_block + end - should "return a response with the status code and the passed data" do - runner = test_runner(HaltViewHandler, :params => { - 'code' => 200, - 'headers' => { 'Content-Type' => 'text/plain' }, - 'body' => 'test halting' - }) - runner.run + should "call to the runner for its partial helper" do + capture_runner_meth_args_for(:partial) + exp_args, exp_block = @args, @block + subject.instance_eval{ partial(*exp_args, &exp_block) } - assert_equal 200, runner.response_value.status - assert_equal({ 'Content-Type' => 'text/plain' }, runner.response_value.headers) - assert_equal 'test halting', runner.response_value.body + assert_equal exp_args, @meth_args + assert_equal exp_block, @meth_block end - end + should "call to the runner for its source partial helper" do + capture_runner_meth_args_for(:source_partial) + exp_args, exp_block = @args, @block + subject.instance_eval{ source_partial(*exp_args, &exp_block) } - class ContentTypeTests < UnitTests - desc "content_type" + assert_equal exp_args, @meth_args + assert_equal exp_block, @meth_block + end - should "should set the response content_type/charset" do - runner = test_runner(ContentTypeViewHandler) - content_type_args = runner.run + private - assert_equal 'text/plain', content_type_args.value - assert_equal({:charset => 'latin1'}, content_type_args.opts) + def stub_runner_with_something_for(meth) + Assert.stub(@runner, meth){ @something } end + def capture_runner_meth_args_for(meth) + Assert.stub(@runner, meth) do |*args, &block| + @meth_args = args + @meth_block = block + end + end + end - class StatusTests < UnitTests - desc "status" + class InitLayoutsTests < UnitTests + desc "when init with layouts" + setup do + @params = { 'n' => Factory.integer } + @runner = test_runner(LayoutsViewHandler, :params => @params) + @handler = @runner.handler + end + subject{ @handler } - should "should set the response status" do - runner = test_runner(StatusViewHandler) - status_args = runner.run - - assert_equal 422, status_args.value + should "build its layouts by instance eval'ing its class layout procs" do + exp = subject.class.layouts.map{ |proc| subject.instance_eval(&proc) } + assert_equal exp, subject.layouts end end - class HeadersTests < UnitTests - desc "headers" + class TestHelpersTests < UnitTests + desc "TestHelpers" + setup do + context_class = Class.new{ include Deas::ViewHandler::TestHelpers } + @context = context_class.new + end + subject{ @context } - should "should set the response status" do - runner = test_runner(HeadersViewHandler) - headers_args = runner.run - exp_headers = { - 'a-header' => 'some value', - 'other' => 'other' - } + should have_imeths :test_runner, :test_handler - assert_equal exp_headers, headers_args.value + should "build a test runner for a given handler class" do + runner = subject.test_runner(@handler_class) + + assert_kind_of ::Deas::TestRunner, runner + assert_kind_of Rack::Request, runner.request + assert_equal runner.request.session, runner.session end + should "return an initialized handler instance" do + handler = subject.test_handler(@handler_class) + assert_kind_of @handler_class, handler + + exp = subject.test_runner(@handler_class).handler + assert_equal exp, handler + end + end class TestViewHandler include Deas::ViewHandler - attr_reader :before_called, :after_called - attr_reader :before_init_called, :second_before_init_called - attr_reader :init_bang_called, :after_init_called - attr_reader :before_run_called, :run_bang_called, :after_run_called + attr_reader :first_before_init_call_order, :second_before_init_call_order + attr_reader :first_after_init_call_order, :second_after_init_call_order + attr_reader :first_before_run_call_order, :second_before_run_call_order + attr_reader :first_after_run_call_order, :second_after_run_call_order + attr_reader :init_call_order, :run_call_order - before{ @before_called = true } - after{ @after_called = true } + before_init{ @first_before_init_call_order = next_call_order } + before_init{ @second_before_init_call_order = next_call_order } - before_init{ @before_init_called = true } - before_init{ @second_before_init_called = true } - after_init{ @after_init_called = true } - before_run{ @before_run_called = true } - after_run{ @after_run_called = true } + after_init{ @first_after_init_call_order = next_call_order } + after_init{ @second_after_init_call_order = next_call_order } - def init!; @init_bang_called = true; end - def run!; @run_bang_called = true; end + before_run{ @first_before_run_call_order = next_call_order } + before_run{ @second_before_run_call_order = next_call_order } + + after_run{ @first_after_run_call_order = next_call_order } + after_run{ @second_after_run_call_order = next_call_order } + + def init! + @init_call_order = next_call_order + end + + def run! + @run_call_order = next_call_order + end + + private + + def next_call_order + @order ||= 0 + @order += 1 + end end class LayoutsViewHandler include Deas::ViewHandler