abstract_unit.rb 11.1 KB
Newer Older
1
require File.expand_path('../../../load_paths', __FILE__)
2

3
$:.unshift(File.dirname(__FILE__) + '/lib')
4
$:.unshift(File.dirname(__FILE__) + '/fixtures/helpers')
5
$:.unshift(File.dirname(__FILE__) + '/fixtures/alternate_helpers')
D
Initial  
David Heinemeier Hansson 已提交
6

J
Joshua Peek 已提交
7 8
ENV['TMPDIR'] = File.join(File.dirname(__FILE__), 'tmp')

9 10
require 'active_support/core_ext/kernel/reporting'

11 12 13 14 15
# These are the normal settings that will be set up by Railties
# TODO: Have these tests support other combinations of these values
silence_warnings do
  Encoding.default_internal = "UTF-8"
  Encoding.default_external = "UTF-8"
16 17
end

18
require 'active_support/testing/autorun'
J
Joshua Peek 已提交
19
require 'abstract_controller'
20
require 'action_controller'
J
Joshua Peek 已提交
21
require 'action_view'
22
require 'action_view/testing/resolvers'
J
Joshua Peek 已提交
23
require 'action_dispatch'
24
require 'active_support/dependencies'
25
require 'active_model'
N
Neeraj Singh 已提交
26 27
require 'active_record'
require 'action_controller/caching'
28

J
Joshua Peek 已提交
29 30
require 'pp' # require 'pp' early to prevent hidden_methods from not picking up the pretty-print methods until too late

31
module Rails
32 33 34 35 36
  class << self
    def env
      @_env ||= ActiveSupport::StringInquirer.new(ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "test")
    end
  end
37 38
end

39
ActiveSupport::Dependencies.hook!
40

41 42
Thread.abort_on_exception = true

43 44 45
# Show backtraces for deprecated behavior for quicker cleanup.
ActiveSupport::Deprecation.debug = true

46 47 48
# Disable available locale checks to avoid warnings running the test suite.
I18n.enforce_available_locales = false

J
Joshua Peek 已提交
49 50
# Register danish language for testing
I18n.backend.store_translations 'da', {}
51
I18n.backend.store_translations 'pt-BR', {}
52
ORIGINAL_LOCALES = I18n.available_locales.map {|locale| locale.to_s }.sort
J
Joshua Peek 已提交
53

Y
Yehuda Katz + Carl Lerche 已提交
54
FIXTURE_LOAD_PATH = File.join(File.dirname(__FILE__), 'fixtures')
55
FIXTURES = Pathname.new(FIXTURE_LOAD_PATH)
56

57 58 59 60 61 62 63 64 65 66 67 68 69
module RackTestUtils
  def body_to_string(body)
    if body.respond_to?(:each)
      str = ""
      body.each {|s| str << s }
      str
    else
      body
    end
  end
  extend self
end

C
Carlhuda 已提交
70 71
SharedTestRoutes = ActionDispatch::Routing::RouteSet.new

72 73 74 75 76 77 78 79
module ActionDispatch
  module SharedRoutes
    def before_setup
      @routes = SharedTestRoutes
      super
    end
  end

80 81 82 83 84 85 86 87 88 89 90 91
  # Hold off drawing routes until all the possible controller classes
  # have been loaded.
  module DrawOnce
    class << self
      attr_accessor :drew
    end
    self.drew = false

    def before_setup
      super
      return if DrawOnce.drew

92
      SharedTestRoutes.draw do
93
        get ':controller(/:action)'
C
Carlhuda 已提交
94 95
      end

96
      ActionDispatch::IntegrationTest.app.routes.draw do
97
        get ':controller(/:action)'
C
Carlhuda 已提交
98
      end
99 100

      DrawOnce.drew = true
J
Joshua Peek 已提交
101 102 103 104
    end
  end
end

105 106 107 108 109 110
module ActiveSupport
  class TestCase
    include ActionDispatch::DrawOnce
  end
end

C
Carlhuda 已提交
111
class RoutedRackApp
J
Joshua Peek 已提交
112
  attr_reader :routes
C
Carlhuda 已提交
113

J
Joshua Peek 已提交
114 115 116
  def initialize(routes, &blk)
    @routes = routes
    @stack = ActionDispatch::MiddlewareStack.new(&blk).build(@routes)
C
Carlhuda 已提交
117 118 119 120 121 122 123
  end

  def call(env)
    @stack.call(env)
  end
end

124
class BasicController
125
  attr_accessor :request
126 127

  def config
128
    @config ||= ActiveSupport::InheritableOptions.new(ActionController::Base.config).tap do |config|
129 130 131 132 133
      # VIEW TODO: View tests should not require a controller
      public_dir = File.expand_path("../fixtures/public", __FILE__)
      config.assets_dir = public_dir
      config.javascripts_dir = "#{public_dir}/javascripts"
      config.stylesheets_dir = "#{public_dir}/stylesheets"
134
      config.assets          = ActiveSupport::InheritableOptions.new({ :prefix => "assets" })
135 136 137 138 139
      config
    end
  end
end

140
class ActionDispatch::IntegrationTest < ActiveSupport::TestCase
141
  include ActionDispatch::SharedRoutes
142

143
  def self.build_app(routes = nil)
C
Carlhuda 已提交
144
    RoutedRackApp.new(routes || ActionDispatch::Routing::RouteSet.new) do |middleware|
145
      middleware.use "ActionDispatch::ShowExceptions", ActionDispatch::PublicExceptions.new("#{FIXTURE_LOAD_PATH}/public")
146
      middleware.use "ActionDispatch::DebugExceptions"
147 148
      middleware.use "ActionDispatch::Callbacks"
      middleware.use "ActionDispatch::ParamsParser"
J
Joshua Peek 已提交
149
      middleware.use "ActionDispatch::Cookies"
J
Joshua Peek 已提交
150
      middleware.use "ActionDispatch::Flash"
151
      middleware.use "Rack::Head"
152
      yield(middleware) if block_given?
C
Carlhuda 已提交
153
    end
154 155 156 157
  end

  self.app = build_app

158 159 160 161 162 163 164 165 166 167
  # Stub Rails dispatcher so it does not get controller references and
  # simply return the controller#action as Rack::Body.
  class StubDispatcher < ::ActionDispatch::Routing::RouteSet::Dispatcher
    protected
    def controller_reference(controller_param)
      controller_param
    end

    def dispatch(controller, action, env)
      [200, {'Content-Type' => 'text/html'}, ["#{controller}##{action}"]]
168 169 170 171 172 173 174 175 176 177 178 179 180
    end
  end

  def self.stub_controllers
    old_dispatcher = ActionDispatch::Routing::RouteSet::Dispatcher
    ActionDispatch::Routing::RouteSet.module_eval { remove_const :Dispatcher }
    ActionDispatch::Routing::RouteSet.module_eval { const_set :Dispatcher, StubDispatcher }
    yield ActionDispatch::Routing::RouteSet.new
  ensure
    ActionDispatch::Routing::RouteSet.module_eval { remove_const :Dispatcher }
    ActionDispatch::Routing::RouteSet.module_eval { const_set :Dispatcher, old_dispatcher }
  end

181
  def with_routing(&block)
182
    temporary_routes = ActionDispatch::Routing::RouteSet.new
C
Carlhuda 已提交
183 184 185
    old_app, self.class.app = self.class.app, self.class.build_app(temporary_routes)
    old_routes = SharedTestRoutes
    silence_warnings { Object.const_set(:SharedTestRoutes, temporary_routes) }
186 187 188

    yield temporary_routes
  ensure
C
Carlhuda 已提交
189 190
    self.class.app = old_app
    silence_warnings { Object.const_set(:SharedTestRoutes, old_routes) }
191
  end
192 193

  def with_autoload_path(path)
194
    path = File.join(File.dirname(__FILE__), "fixtures", path)
195 196 197 198 199 200 201 202 203 204 205 206
    if ActiveSupport::Dependencies.autoload_paths.include?(path)
      yield
    else
      begin
        ActiveSupport::Dependencies.autoload_paths << path
        yield
      ensure
        ActiveSupport::Dependencies.autoload_paths.reject! {|p| p == path}
        ActiveSupport::Dependencies.clear
      end
    end
  end
207 208
end

J
Joshua Peek 已提交
209
# Temporary base class
210
class Rack::TestCase < ActionDispatch::IntegrationTest
J
Joshua Peek 已提交
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227
  def self.testing(klass = nil)
    if klass
      @testing = "/#{klass.name.underscore}".sub!(/_controller$/, '')
    else
      @testing
    end
  end

  def get(thing, *args)
    if thing.is_a?(Symbol)
      super("#{self.class.testing}/#{thing}", *args)
    else
      super
    end
  end

  def assert_body(body)
228
    assert_equal body, Array(response.body).join
J
Joshua Peek 已提交
229 230 231 232 233 234 235
  end

  def assert_status(code)
    assert_equal code, response.status
  end

  def assert_response(body, status = 200, headers = {})
236
    assert_body body
J
Joshua Peek 已提交
237 238 239 240 241 242 243 244 245 246 247 248 249 250 251
    assert_status status
    headers.each do |header, value|
      assert_header header, value
    end
  end

  def assert_content_type(type)
    assert_equal type, response.headers["Content-Type"]
  end

  def assert_header(name, value)
    assert_equal value, response.headers[name]
  end
end

252 253
module ActionController
  class Base
254 255
    # This stub emulates the Railtie including the URL helpers from a Rails application
    include SharedTestRoutes.url_helpers
256
    include SharedTestRoutes.mounted_helpers
257

258 259 260 261 262 263 264 265
    self.view_paths = FIXTURE_LOAD_PATH

    def self.test_routes(&block)
      routes = ActionDispatch::Routing::RouteSet.new
      routes.draw(&block)
      include routes.url_helpers
    end
  end
266

267
  class TestCase
J
Joshua Peek 已提交
268
    include ActionDispatch::TestProcess
269
    include ActionDispatch::SharedRoutes
270 271
  end
end
C
Carlhuda 已提交
272

273

274 275 276
class ::ApplicationController < ActionController::Base
end

A
Aaron Patterson 已提交
277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293
class Workshop
  extend ActiveModel::Naming
  include ActiveModel::Conversion
  attr_accessor :id

  def initialize(id)
    @id = id
  end

  def persisted?
    id.present?
  end

  def to_s
    id.to_s
  end
end
A
Aaron Patterson 已提交
294 295

module ActionDispatch
296 297 298 299 300 301 302
  class DebugExceptions
    private
    remove_method :stderr_logger
    # Silence logger
    def stderr_logger
      nil
    end
A
Aaron Patterson 已提交
303 304 305
  end
end

306 307
module ActionDispatch
  module RoutingVerbs
308
    def send_request(uri_or_host, method, path)
309 310 311 312
      host = uri_or_host.host unless path
      path ||= uri_or_host.path

      params = {'PATH_INFO'      => path,
313
                'REQUEST_METHOD' => method,
314 315
                'HTTP_HOST'      => host}

316 317 318
      routes.call(params)
    end

319 320
    def request_path_params(path, options = {})
      method = options[:method] || 'GET'
321
      resp = send_request URI('http://localhost' + path), method.to_s.upcase, nil
A
Aaron Patterson 已提交
322
      status = resp.first
323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346
      if status == 404
        raise ActionController::RoutingError, "No route matches #{path.inspect}"
      end
      controller.request.path_parameters
    end

    def get(uri_or_host, path = nil)
      send_request(uri_or_host, 'GET', path)[2].join
    end

    def post(uri_or_host, path = nil)
      send_request(uri_or_host, 'POST', path)[2].join
    end

    def put(uri_or_host, path = nil)
      send_request(uri_or_host, 'PUT', path)[2].join
    end

    def delete(uri_or_host, path = nil)
      send_request(uri_or_host, 'DELETE', path)[2].join
    end

    def patch(uri_or_host, path = nil)
      send_request(uri_or_host, 'PATCH', path)[2].join
347 348 349 350
    end
  end
end

L
lest 已提交
351
module RoutingTestHelpers
A
Aaron Patterson 已提交
352
  def url_for(set, options)
353 354
    route_name = options.delete :use_route
    set.url_for options.merge(:only_path => true), route_name
L
lest 已提交
355
  end
356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397

  def make_set(strict = true)
    tc = self
    TestSet.new ->(c) { tc.controller = c }, strict
  end

  class TestSet < ActionDispatch::Routing::RouteSet
    attr_reader :strict

    def initialize(block, strict = false)
      @block = block
      @strict = strict
      super()
    end

    class Dispatcher < ActionDispatch::Routing::RouteSet::Dispatcher
      def initialize(defaults, set, block)
        super(defaults)
        @block = block
        @set = set
      end

      def controller(params, default_controller=true)
        super(params, @set.strict)
      end

      def controller_reference(controller_param)
        block = @block
        set = @set
        super if @set.strict
        Class.new(ActionController::Base) {
          include set.url_helpers
          define_method(:process) { |name| block.call(self) }
          def to_a; [200, {}, []]; end
        }
      end
    end

    def dispatcher defaults
      TestSet::Dispatcher.new defaults, self, @block
    end
  end
L
lest 已提交
398
end
399 400 401 402 403 404 405 406 407

class ResourcesController < ActionController::Base
  def index() render :nothing => true end
  alias_method :show, :index
end

class ThreadsController  < ResourcesController; end
class MessagesController < ResourcesController; end
class CommentsController < ResourcesController; end
408
class ReviewsController < ResourcesController; end
409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425
class LogosController < ResourcesController; end

class AccountsController <  ResourcesController; end
class AdminController   <  ResourcesController; end
class ProductsController < ResourcesController; end
class ImagesController < ResourcesController; end
class PreferencesController < ResourcesController; end

module Backoffice
  class ProductsController < ResourcesController; end
  class ImagesController < ResourcesController; end

  module Admin
    class ProductsController < ResourcesController; end
    class ImagesController < ResourcesController; end
  end
end
426 427 428 429 430 431 432 433 434

# Skips the current run on Rubinius using Minitest::Assertions#skip
def rubinius_skip(message = '')
  skip message if RUBY_ENGINE == 'rbx'
end
# Skips the current run on JRuby using Minitest::Assertions#skip
def jruby_skip(message = '')
  skip message if defined?(JRUBY_VERSION)
end