diff --git a/Rakefile b/Rakefile index 4dcac60..dc8ab0f 100644 --- a/Rakefile +++ b/Rakefile @@ -12,6 +12,10 @@ Hoe.spec 'gin' do self.extra_deps << ['rack', '~>1.1'] self.extra_deps << ['rack-protection', '~>1.0'] self.extra_deps << ['tilt', '~>1.4'] + + self.extra_dev_deps << ['nokogiri', '~>1.5.9'] + self.extra_dev_deps << ['plist', '~>3.1.0'] + self.extra_dev_deps << ['bson', '~>1.9.0'] end # vim: syntax=ruby diff --git a/lib/gin/test.rb b/lib/gin/test.rb index fbe8bb1..d85f1a4 100644 --- a/lib/gin/test.rb +++ b/lib/gin/test.rb @@ -175,10 +175,9 @@ def assert_cookie name, value=nil, opts={}, msg=nil # Checks that a rendered view name or path matches the one given. def assert_view view, msg=nil - @templates ||= [] expected = @app.template_files(@controller.template_path(view)).first - assert @templates.include?(expected), - msg || "Expected view `#{name_or_path}' in #{@templates.inspect}" + assert templates.include?(expected), + msg || "Expected view `#{name_or_path}' in #{templates.inspect}" end @@ -186,10 +185,9 @@ def assert_view view, msg=nil # Checks that a specific layout was use to render the response. def assert_layout layout, msg=nil - @templates ||= [] expected = @app.template_files(@controller.template_path(layout, true)).first - assert @templates.include?(expected), - msg || "Expected view `#{name_or_path}' in #{@templates.inspect}" + assert templates.include?(expected), + msg || "Expected view `#{name_or_path}' in #{templates.inspect}" end @@ -297,8 +295,8 @@ def use_lib lib, gemname=nil # :nodoc: rescue LoadError => e raise unless e.message == "cannot load such file -- #{lib}" gemname ||= lib - puts "You need the `#{gemname}' gem to access some of the features you are \ -trying to use. + $stderr.puts "You need the `#{gemname}' gem to access some of the features \ +you are trying to use. Run the following command and try again: gem install #{gemname}" exit 1 end @@ -352,6 +350,14 @@ def response end + ## + # Array of template file paths used to render the response body. + + def templates + @templates ||= [] + end + + ## # Make a GET request. # get FooController, :show, :id => 123 @@ -439,8 +445,8 @@ def make_request verb, *args headers = (Hash === args[-2] && Hash === args[-1]) ? args.pop : {} path, query = path_to(*args).split("?") - env['HTTP_COOKIE'] = - @set_cookies.map{|k,v| "#{k}=#{v}"}.join("; ") if defined?(@set_cookies) + env['HTTP_COOKIE'] = @set_cookies.map{|k,v| "#{k}=#{v}"}.join("; ") if + defined?(@set_cookies) && @set_cookies && !@set_cookies.empty? env['REQUEST_METHOD'] = verb.to_s.upcase env['QUERY_STRING'] = query @@ -556,11 +562,11 @@ def parsed_body @parsed_body = case ct - when /[\/+]json$/i + when /[\/+]json/i use_lib 'json' JSON.parse(body) - when /[\/+]bson$/i + when /[\/+]bson/i use_lib 'bson' BSON.deserialize(body) diff --git a/test/test_test.rb b/test/test_test.rb index 3cd106d..4365a6e 100644 --- a/test/test_test.rb +++ b/test/test_test.rb @@ -1,6 +1,12 @@ require 'test/test_helper' require 'gin/test' +require 'plist' +require 'bson' +require 'nokogiri' +require 'json' + + class TestTest < Test::Unit::TestCase def setup @@ -75,41 +81,122 @@ def test_make_request assert_equal "foo=BAR&bar=BAZ", @tests.req_env['QUERY_STRING'] assert_equal "/bar/123", @tests.req_env['PATH_INFO'] assert_equal "127.0.0.1", @tests.req_env['REMOTE_ADDR'] + assert_equal "127.0.0.1", @tests.request.ip assert_equal "GET", @tests.req_env['REQUEST_METHOD'] + assert_equal Gin::Request, @tests.request.class + assert_equal Gin::Response, @tests.response.class + assert_equal resp, @tests.rack_response assert_equal 200, resp[0] assert_equal "text/html;charset=UTF-8", resp[1]["Content-Type"] assert_equal "9", resp[1]["Content-Length"] assert_equal ["SHOW 123!"], resp[2] + + assert_equal "SHOW 123!", @tests.body + assert_equal ["SHOW 123!"], @tests.stream + assert_equal [], @tests.templates + + assert BarController === @tests.controller end - def test_make_request_w_cookies + def test_make_request_w_views + resp = @tests.make_request :get, :index_foo + + assert_equal "text/html;charset=UTF-8", resp[1]["Content-Type"] + assert /Value is LOCAL/ === @tests.body + + assert_equal 2, @tests.templates.length + assert_equal File.join(MockApp.layouts_dir, "foo.erb"), @tests.templates[0] + assert_equal File.join(MockApp.views_dir, "bar.erb"), @tests.templates[1] end - def test_make_request_w_headers + def test_make_request_w_cookies + resp = @tests.make_request :get, :login_foo + assert_equal "foo_session=12345; expires=Fri, 01 Jan 2100 00:00:00 -0000", + resp[1]["Set-Cookie"] + + time = Time.parse "2100-01-01 00:00:00 UTC" + cookie = {name: "foo_session", value: "12345", expires_at: time} + assert_equal cookie, @tests.cookies["foo_session"] + + @tests.set_cookie "bar", 5678 + resp = @tests.make_request :get, :show_bar, id: 123 + assert_equal "foo_session=12345; bar=5678", @tests.req_env['HTTP_COOKIE'] end def test_make_request_verb_methods + %w{get post put patch delete head options}.each do |verb| + resp = @tests.send verb, :show_bar, id: 123 + assert_equal verb.upcase, @tests.req_env['REQUEST_METHOD'] + if verb == 'get' + assert_equal BarController, + @tests.req_env[Gin::Constants::GIN_CTRL].class + assert_equal 200, resp[0] + else + assert_equal nil, @tests.req_env[Gin::Constants::GIN_CTRL] + assert_equal 404, resp[0] + end + end end - def test_parsed_body + def test_parsed_body_json + @tests.get '/api/json' + assert_equal({'foo' => 1234}, @tests.parsed_body) end - def test_parsed_body_missing_parser + def test_parsed_body_bson + @tests.get '/api/bson' + assert_equal({'foo' => 1234}, @tests.parsed_body) end - def test_cookie_get_and_set + def test_parsed_body_plist + @tests.get '/api/plist' + assert_equal({'foo' => 1234}, @tests.parsed_body) end - class MockTestClass; end + def test_parsed_body_xml + @tests.get '/api/xml' + assert_equal "foo", @tests.parsed_body.children.first.name + assert_equal "1234", @tests.parsed_body.children.first.text + end + + + def test_parsed_body_html + @tests.get '/foo' + assert_equal "html", @tests.parsed_body.children.first.name + end + + + def test_parsed_body_missing_parser + @tests.get '/api/pdf' + assert_raises(RuntimeError) do + @tests.parsed_body + end + end + + + class AssertionError < StandardError; end + + class MockTestClass + def initialize + @assertions = 0 + end + + def assert value, msg=nil + @assertions += 1 + msg ||= "Mock assertion failure message" + raise AssertionError, msg unless value + end + end + module TestAccess def env @@ -135,16 +222,67 @@ def index end + class ApiController < Gin::Controller + controller_name "api" + + def pdf + content_type 'application/pdf' + 'fake pdf' + end + + def json + content_type :json + '{"foo":1234}' + end + + def bson + content_type 'application/bson' + BSON.serialize({'foo' => 1234}).to_s + end + + def xml + content_type :xml + '1234' + end + + def plist + content_type 'application/plist' + <<-STR + +\n +\n\tfoo\n\t1234\n\n + STR + end + end + + class FooController < Gin::Controller + controller_name "foo" + layout "foo" + + def index + view :bar, locals: {test_val: "LOCAL"} + end + + def login + set_cookie "foo_session", "12345", + expires: Time.parse("Fri, 01 Jan 2100 00:00:00 -0000") + "OK" + end end class MockApp < Gin::App logger StringIO.new + root_dir "test/app" mount BarController do get :show, "/:id" get :index, "/" end + + mount FooController + + mount ApiController end end