Namespace
Methods
A
B
C
D
E
H
I
L
M
O
P
S
T
U
V
W
Included Modules
Constants
FIXTURE_LOAD_PATH = File.expand_path("fixtures", __dir__)
 
CACHE_DIR = "test_cache"
 
FILE_STORE_PATH = File.join(__dir__, "/../temp/", CACHE_DIR)
 

Don't change '/../temp/' cavalierly or you might hose something you don't want hosed

AppRoutes = ActionDispatch::Routing::RouteSet.new
 
PROCESS_COUNT = 0
 
SharedTestRoutes = ActionDispatch::Routing::RouteSet.new
 
Customer = Struct.new(:name, :id) do extend ActiveModel::Naming include ActiveModel::Conversion undef_method :to_json def to_xml(options = {}) if options[:builder] options[:builder].name name else "<name>#{name}</name>" end end def to_js(options = {}) "name: #{name.inspect}" end alias :to_text :to_js def errors [] end def persisted? id.present? end def cache_key "#{name}/#{id}" end end
 
Post = Struct.new(:title, :author_name, :body, :secret, :persisted, :written_on, :cost) do extend ActiveModel::Naming include ActiveModel::Conversion extend ActiveModel::Translation alias_method :secret?, :secret alias_method :persisted?, :persisted def initialize(*args) super @persisted = false end attr_accessor :author def author_attributes=(attributes); end attr_accessor :comments, :comment_ids def comments_attributes=(attributes); end attr_accessor :tags def tags_attributes=(attributes); end end
 
APPLICATION_PACK_PATH = Pathname.new("app/javascript/packs/application.js")
 
JS_PACKAGE_PATH = Pathname.new("#{__dir__}/../../package.json")
 
JS_PACKAGE = JSON.load(JS_PACKAGE_PATH)
 
JS_DEPENDENCIES = JS_PACKAGE["peerDependencies"].dup.merge \ JS_PACKAGE["name"] => "^#{JS_PACKAGE["version"]}"
 
ORIGINAL_LOCALES = I18n.available_locales.map(&:to_s).sort
 
PATH_TO_AR = File.expand_path("../../activerecord/lib", __dir__)
 
Game = Struct.new(:name, :id) do extend ActiveModel::Naming include ActiveModel::Conversion def to_param id.to_s end end
 
Car = Struct.new(:color)
 
Scroll = Struct.new(:id, :to_param, :title, :body, :updated_at, :created_at) do extend ActiveModel::Naming include ActiveModel::Conversion def persisted? false end end
 
Neckbeard = lambda { |template, source| source }
 
Bowtie = lambda { |template, source| source }
 
Category = Struct.new(:id, :name)
 
TIME = (ENV["BENCHMARK_TIME"] || 20).to_i
 
RECORDS = (ENV["BENCHMARK_RECORDS"] || TIME * 1000).to_i
 
QUOTED_TYPE = ActiveRecord::Base.connection.quote_column_name("type")
 

Quote “type” if it's a reserved word for the current connection.

EXPECTED_ZONE = nil
 

This method makes sure that tests don't leak global state related to time zones.

EXPECTED_DEFAULT_TIMEZONE = :utc
 
EXPECTED_TIME_ZONE_AWARE_ATTRIBUTES = false
 
TEST_ROOT = __dir__
 
ASSETS_ROOT = TEST_ROOT + "/assets"
 
FIXTURES_ROOT = TEST_ROOT + "/fixtures"
 
MIGRATIONS_ROOT = TEST_ROOT + "/migrations"
 
SCHEMA_ROOT = TEST_ROOT + "/schema"
 
SERVICE_CONFIGURATIONS = begin erb = ERB.new(Pathname.new(File.expand_path("service/configurations.yml", __dir__)).read) configuration = YAML.load(erb.result) || {} configuration.deep_symbolize_keys rescue Errno::ENOENT puts "Missing service configuration file in test/service/configurations.yml" {} end
 
ORIG_ARGV = ARGV.dup
 
ApplicationController = 10
 
Conflict = 2
 
MultipleConstantFile = 10
 
SiblingConstant = MultipleConstantFile * 2
 
RaisesArbitraryException = 1
 
ShouldNotBeAutoloaded = 0
 
Throws = 1
 
TypO = 1
 
Payment = Struct.new(:price)
 
ExpandedPayment = Struct.new(:dollars, :cents)
 
Somewhere = Struct.new(:street, :city) do attr_accessor :name end
 
Someone = Struct.new(:name, :place) do delegate :street, :city, :to_f, to: :place delegate :name=, to: :place, prefix: true delegate :upcase, to: "place.city" delegate :table_name, to: :class delegate :table_name, to: :class, prefix: true def self.table_name "some_table" end self::FAILED_DELEGATE_LINE = __LINE__ + 1 delegate :foo, to: :place self::FAILED_DELEGATE_LINE_2 = __LINE__ + 1 delegate :bar, to: :place, allow_nil: true private def private_name "Private" end end
 
Invoice = Struct.new(:client) do delegate :street, :city, :name, to: :client, prefix: true delegate :street, :city, :name, to: :client, prefix: :customer end
 
Project = Struct.new(:description, :person) do delegate :name, to: :person, allow_nil: true delegate :to_f, to: :description, allow_nil: true end
 
Developer = Struct.new(:client) do delegate :name, to: :client, prefix: nil end
 
Event = Struct.new(:case) do delegate :foo, to: :case end
 
Tester = Struct.new(:client) do delegate :name, to: :client, prefix: false def foo; 1; end end
 
Product = Struct.new(:name) do delegate :name, to: :manufacturer, prefix: true delegate :name, to: :type, prefix: true def manufacturer @manufacturer ||= begin nil.unknown_method end end def type @type ||= begin nil.type_name end end end
 
DecoratedTester = Struct.new(:client) do include ExtraMissing delegate_missing_to :client end
 
HasBlock = Struct.new(:block) do delegate :hello?, to: :block end
 
ConstFromLib = 1
 
SCENARIOS = { "Empty" => "", "Single Space" => " ", "Two Spaces" => " ", "Mixed Whitspaces" => " \t\r\n", "Very Long String" => " " * 100 }
 

Enumerate some representative scenarios here.

It is very easy to make an optimization that improves performance for a specific scenario you care about but regresses on other common cases. Therefore, you should test your change against a list of representative scenarios. Ideally, they should be based on real-world scenarios extracted from production applications.

APP_PATH = File.expand_path("test/dummy/config/application", ENGINE_ROOT)
 
DEFAULT_APP_FILES = %w( .gitignore .ruby-version README.md Gemfile Rakefile config.ru app/assets/config/manifest.js app/assets/images app/javascript app/javascript/channels app/javascript/channels/consumer.js app/javascript/channels/index.js app/javascript/packs/application.js app/assets/stylesheets app/assets/stylesheets/application.css app/channels/application_cable/channel.rb app/channels/application_cable/connection.rb app/controllers app/controllers/application_controller.rb app/controllers/concerns app/helpers app/helpers/application_helper.rb app/mailers app/mailers/application_mailer.rb app/models app/models/application_record.rb app/models/concerns app/jobs app/jobs/application_job.rb app/views/layouts app/views/layouts/application.html.erb app/views/layouts/mailer.html.erb app/views/layouts/mailer.text.erb bin/rails bin/rake bin/setup bin/yarn config/application.rb config/boot.rb config/cable.yml config/environment.rb config/environments config/environments/development.rb config/environments/production.rb config/environments/test.rb config/initializers config/initializers/application_controller_renderer.rb config/initializers/assets.rb config/initializers/backtrace_silencers.rb config/initializers/cookies_serializer.rb config/initializers/content_security_policy.rb config/initializers/filter_parameter_logging.rb config/initializers/inflections.rb config/initializers/mime_types.rb config/initializers/wrap_parameters.rb config/locales config/locales/en.yml config/puma.rb config/routes.rb config/credentials.yml.enc config/spring.rb config/storage.yml db db/seeds.rb lib lib/tasks lib/assets log package.json public storage test/application_system_test_case.rb test/test_helper.rb test/fixtures test/fixtures/files test/channels/application_cable/connection_test.rb test/controllers test/models test/helpers test/mailers test/integration test/system vendor tmp tmp/cache tmp/cache/assets tmp/storage )
 
ObjectHelper = Class.new
 
AnotherObjectHelperTest = Class.new
 
DEFAULT_PLUGIN_FILES = %w( .gitignore Gemfile Rakefile README.md bukkits.gemspec MIT-LICENSE lib lib/bukkits.rb lib/tasks/bukkits_tasks.rake lib/bukkits/version.rb test/bukkits_test.rb test/test_helper.rb test/dummy )
 
RAILS_FRAMEWORK_ROOT = File.expand_path("../../..", __dir__)
 
RAILS_ISOLATED_ENGINE = true
 
FRAMEWORKS = %w( activesupport activemodel activerecord actionview actionpack activejob actionmailer actioncable activestorage actionmailbox actiontext railties )
 

Order dependent. E.g. Action Mailbox depends on Active Record so it should be after.

FRAMEWORK_NAMES = Hash.new { |h, k| k.split(/(?<=active|action)/).map(&:capitalize).join(" ") }
 
Class Public methods
enqueue(job_class, args = [], opts = {})
Also aliased as: original_enqueue, original_enqueue
  # File activejob/test/support/backburner/inline.rb
7 def self.enqueue(job_class, args = [], opts = {})
8   job_class.perform(*args)
9 end
original_enqueue(job_class, args = [], opts = {})
Alias for: enqueue
Instance Public methods
acts_like?(duck)

A duck-type assistant method. For example, Active Support extends Date to define an acts_like_date? method, and extends Time to define acts_like_time?. As a result, we can do x.acts_like?(:time) and x.acts_like?(:date) to do duck-type-safe comparisons, since classes that we want to act like Time simply need to define an acts_like_time? method.

   # File activesupport/lib/active_support/core_ext/object/acts_like.rb
 9 def acts_like?(duck)
10   case duck
11   when :time
12     respond_to? :acts_like_time?
13   when :date
14     respond_to? :acts_like_date?
15   when :string
16     respond_to? :acts_like_string?
17   else
18     respond_to? :"acts_like_#{duck}?"
19   end
20 end
blank?()

An object is blank if it's false, empty, or a whitespace string. For example, nil, '', ' ', [], {}, and false are all blank.

This simplifies

!address || address.empty?

to

address.blank?

@return [true, false]

   # File activesupport/lib/active_support/core_ext/object/blank.rb
18 def blank?
19   respond_to?(:empty?) ? !!empty? : !self
20 end
current_adapter?(*types)
   # File activerecord/test/cases/helper.rb
31 def current_adapter?(*types)
32   types.any? do |type|
33     ActiveRecord::ConnectionAdapters.const_defined?(type) &&
34       ActiveRecord::Base.connection.is_a?(ActiveRecord::ConnectionAdapters.const_get(type))
35   end
36 end
deep_dup()

Returns a deep copy of object if it's duplicable. If it's not duplicable, returns self.

object = Object.new
dup    = object.deep_dup
dup.instance_variable_set(:@a, 1)

object.instance_variable_defined?(:@a) # => false
dup.instance_variable_defined?(:@a)    # => true
   # File activesupport/lib/active_support/core_ext/object/deep_dup.rb
15 def deep_dup
16   duplicable? ? dup : self
17 end
disable_extension!(extension, connection)
    # File activerecord/test/cases/helper.rb
144 def disable_extension!(extension, connection)
145   return false unless connection.supports_extensions?
146   return true unless connection.extension_enabled?(extension)
147 
148   connection.disable_extension extension
149   connection.reconnect!
150 end
duplicable?()

Can you safely dup this object?

False for method objects; true otherwise.

   # File activesupport/lib/active_support/core_ext/object/duplicable.rb
26 def duplicable?
27   true
28 end
enable_extension!(extension, connection)
    # File activerecord/test/cases/helper.rb
135 def enable_extension!(extension, connection)
136   return false unless connection.supports_extensions?
137   return connection.reconnect! if connection.extension_enabled?(extension)
138 
139   connection.enable_extension extension
140   connection.commit_db_transaction if connection.transaction_open?
141   connection.reconnect!
142 end
html_safe?()
    # File activesupport/lib/active_support/core_ext/string/output_safety.rb
123 def html_safe?
124   false
125 end
in?(another_object)

Returns true if this object is included in the argument. Argument must be any object which responds to #include?. Usage:

characters = ["Konata", "Kagami", "Tsukasa"]
"Konata".in?(characters) # => true

This will throw an ArgumentError if the argument doesn't respond to #include?.

   # File activesupport/lib/active_support/core_ext/object/inclusion.rb
12 def in?(another_object)
13   another_object.include?(self)
14 rescue NoMethodError
15   raise ArgumentError.new("The parameter passed to #in? must respond to #include?")
16 end
in_memory_db?()
   # File activerecord/test/cases/helper.rb
38 def in_memory_db?
39   current_adapter?(:SQLite3Adapter) &&
40   ActiveRecord::Base.connection_pool.spec.config[:database] == ":memory:"
41 end
instance_values()

Returns a hash with string keys that maps instance variable names without “@” to their corresponding values.

class C
  def initialize(x, y)
    @x, @y = x, y
  end
end

C.new(0, 1).instance_values # => {"x" => 0, "y" => 1}
   # File activesupport/lib/active_support/core_ext/object/instance_variables.rb
14 def instance_values
15   Hash[instance_variables.map { |name| [name[1..-1], instance_variable_get(name)] }]
16 end
instance_variable_names()

Returns an array of instance variable names as strings including “@”.

class C
  def initialize(x, y)
    @x, @y = x, y
  end
end

C.new(0, 1).instance_variable_names # => ["@y", "@x"]
   # File activesupport/lib/active_support/core_ext/object/instance_variables.rb
27 def instance_variable_names
28   instance_variables.map(&:to_s)
29 end
load_schema()
    # File activerecord/test/cases/helper.rb
152 def load_schema
153   # silence verbose schema loading
154   original_stdout = $stdout
155   $stdout = StringIO.new
156 
157   adapter_name = ActiveRecord::Base.connection.adapter_name.downcase
158   adapter_specific_schema_file = SCHEMA_ROOT + "/#{adapter_name}_specific_schema.rb"
159 
160   load SCHEMA_ROOT + "/schema.rb"
161 
162   if File.exist?(adapter_specific_schema_file)
163     load adapter_specific_schema_file
164   end
165 
166   ActiveRecord::FixtureSet.reset_cache
167 ensure
168   $stdout = original_stdout
169 end
must_be_like(other)
   # File activerecord/test/cases/arel/helper.rb
10 def must_be_like(other)
11   gsub(/\s+/, " ").strip.must_equal other.gsub(/\s+/, " ").strip
12 end
mysql_enforcing_gtid_consistency?()
   # File activerecord/test/cases/helper.rb
47 def mysql_enforcing_gtid_consistency?
48   current_adapter?(:Mysql2Adapter) && "ON" == ActiveRecord::Base.connection.show_variable("enforce_gtid_consistency")
49 end
presence()

Returns the receiver if it's present otherwise returns nil. object.presence is equivalent to

object.present? ? object : nil

For example, something like

state   = params[:state]   if params[:state].present?
country = params[:country] if params[:country].present?
region  = state || country || 'US'

becomes

region = params[:state].presence || params[:country].presence || 'US'

@return [Object]

   # File activesupport/lib/active_support/core_ext/object/blank.rb
45 def presence
46   self if present?
47 end
presence_in(another_object)

Returns the receiver if it's included in the argument otherwise returns nil. Argument must be any object which responds to #include?. Usage:

params[:bucket_type].presence_in %w( project calendar )

This will throw an ArgumentError if the argument doesn't respond to #include?.

@return [Object]

   # File activesupport/lib/active_support/core_ext/object/inclusion.rb
26 def presence_in(another_object)
27   in?(another_object) ? self : nil
28 end
present?()

An object is present if it's not blank.

@return [true, false]

   # File activesupport/lib/active_support/core_ext/object/blank.rb
25 def present?
26   !blank?
27 end
progress_bar(int)
   # File activerecord/examples/performance.rb
47 def progress_bar(int); print "." if (int % 100).zero? ; end
subsecond_precision_supported?()
   # File activerecord/test/cases/helper.rb
43 def subsecond_precision_supported?
44   ActiveRecord::Base.connection.supports_datetime_with_precision?
45 end
supports_default_expression?()
   # File activerecord/test/cases/helper.rb
51 def supports_default_expression?
52   if current_adapter?(:PostgreSQLAdapter)
53     true
54   elsif current_adapter?(:Mysql2Adapter)
55     conn = ActiveRecord::Base.connection
56     !conn.mariadb? && conn.database_version >= "8.0.13"
57   end
58 end
to_param()

Alias of to_s.

  # File activesupport/lib/active_support/core_ext/object/to_query.rb
7 def to_param
8   to_s
9 end
to_query(key)

Converts an object into a string suitable for use as a URL query string, using the given key as the param name.

   # File activesupport/lib/active_support/core_ext/object/to_query.rb
13 def to_query(key)
14   "#{CGI.escape(key.to_param)}=#{CGI.escape(to_param.to_s)}"
15 end
try(*a, &b)

Invokes the public method whose name goes as first argument just like public_send does, except that if the receiver does not respond to it the call returns nil rather than raising an exception.

This method is defined to be able to write

@person.try(:name)

instead of

@person.name if @person

try calls can be chained:

@person.try(:spouse).try(:name)

instead of

@person.spouse.name if @person && @person.spouse

try will also return nil if the receiver does not respond to the method:

@person.try(:non_existing_method) # => nil

instead of

@person.non_existing_method if @person.respond_to?(:non_existing_method) # => nil

try returns nil when called on nil regardless of whether it responds to the method:

nil.try(:to_i) # => nil, rather than 0

Arguments and blocks are forwarded to the method if invoked:

@posts.try(:each_slice, 2) do |a, b|
  ...
end

The number of arguments in the signature must match. If the object responds to the method the call is attempted and ArgumentError is still raised in case of argument mismatch.

If try is called without arguments it yields the receiver to a given block unless it is nil:

@person.try do |p|
  ...
end

You can also call try with a block without accepting an argument, and the block will be instance_eval'ed instead:

@person.try { upcase.truncate(50) }

Please also note that try is defined on Object. Therefore, it won't work with instances of classes that do not have Object among their ancestors, like direct subclasses of BasicObject.

    # File activesupport/lib/active_support/core_ext/object/try.rb
101   
try!(*a, &b)

Same as try, but raises a NoMethodError exception if the receiver is not nil and does not implement the tried method.

"a".try!(:upcase) # => "A"
nil.try!(:upcase) # => nil
123.try!(:upcase) # => NoMethodError: undefined method `upcase' for 123:Integer
    # File activesupport/lib/active_support/core_ext/object/try.rb
unescape(str, escaped = /%[a-fA-F\d]{2}/)
   # File activesupport/lib/active_support/core_ext/uri.rb
 9 def unescape(str, escaped = /%[a-fA-F\d]{2}/)
10   # TODO: Are we actually sure that ASCII == UTF-8?
11   # YK: My initial experiments say yes, but let's be sure please
12   enc = str.encoding
13   enc = Encoding::UTF_8 if enc == Encoding::US_ASCII
14   str.dup.force_encoding(Encoding::ASCII_8BIT).gsub(escaped) { |match| [match[1, 2].hex].pack("C") }.force_encoding(enc)
15 end
verify_default_timezone_config()
    # File activerecord/test/cases/helper.rb
108 def verify_default_timezone_config
109   if Time.zone != EXPECTED_ZONE
110     $stderr.puts <<-MSG
111 \n#{self}
112     Global state `Time.zone` was leaked.
113       Expected: #{EXPECTED_ZONE}
114       Got: #{Time.zone}
115     MSG
116   end
117   if ActiveRecord::Base.default_timezone != EXPECTED_DEFAULT_TIMEZONE
118     $stderr.puts <<-MSG
119 \n#{self}
120     Global state `ActiveRecord::Base.default_timezone` was leaked.
121       Expected: #{EXPECTED_DEFAULT_TIMEZONE}
122       Got: #{ActiveRecord::Base.default_timezone}
123     MSG
124   end
125   if ActiveRecord::Base.time_zone_aware_attributes != EXPECTED_TIME_ZONE_AWARE_ATTRIBUTES
126     $stderr.puts <<-MSG
127 \n#{self}
128     Global state `ActiveRecord::Base.time_zone_aware_attributes` was leaked.
129       Expected: #{EXPECTED_TIME_ZONE_AWARE_ATTRIBUTES}
130       Got: #{ActiveRecord::Base.time_zone_aware_attributes}
131     MSG
132   end
133 end
with_env_tz(new_tz = "US/Eastern")
   # File activerecord/test/cases/helper.rb
74 def with_env_tz(new_tz = "US/Eastern")
75   old_tz, ENV["TZ"] = ENV["TZ"], new_tz
76   yield
77 ensure
78   old_tz ? ENV["TZ"] = old_tz : ENV.delete("TZ")
79 end
with_options(options, &block)

An elegant way to factor duplication out of options passed to a series of method calls. Each method called in the block, with the block variable as the receiver, will have its options merged with the default options hash provided. Each method called on the block variable must take an options hash as its final argument.

Without with_options, this code contains duplication:

class Account < ActiveRecord::Base
  has_many :customers, dependent: :destroy
  has_many :products,  dependent: :destroy
  has_many :invoices,  dependent: :destroy
  has_many :expenses,  dependent: :destroy
end

Using with_options, we can remove the duplication:

class Account < ActiveRecord::Base
  with_options dependent: :destroy do |assoc|
    assoc.has_many :customers
    assoc.has_many :products
    assoc.has_many :invoices
    assoc.has_many :expenses
  end
end

It can also be used with an explicit receiver:

I18n.with_options locale: user.locale, scope: 'newsletter' do |i18n|
  subject i18n.t :subject
  body    i18n.t :body, user_name: user.name
end

When you don't pass an explicit receiver, it executes the whole block in merging options context:

class Account < ActiveRecord::Base
  with_options dependent: :destroy do
    has_many :customers
    has_many :products
    has_many :invoices
    has_many :expenses
  end
end

with_options can also be nested since the call is forwarded to its receiver.

NOTE: Each nesting level will merge inherited defaults in addition to their own.

class Post < ActiveRecord::Base
  with_options if: :persisted?, length: { minimum: 50 } do
    validates :content, if: -> { content.present? }
  end
end

The code is equivalent to:

validates :content, length: { minimum: 50 }, if: -> { content.present? }

Hence the inherited default for if key is ignored.

NOTE: You cannot call class methods implicitly inside of with_options. You can access these methods using the class name instead:

class Phone < ActiveRecord::Base
  enum phone_number_type: { home: 0, office: 1, mobile: 2 }

  with_options presence: true do
    validates :phone_number_type, inclusion: { in: Phone.phone_number_types.keys }
  end
end
   # File activesupport/lib/active_support/core_ext/object/with_options.rb
78 def with_options(options, &block)
79   option_merger = ActiveSupport::OptionMerger.new(self, options)
80   block.arity.zero? ? option_merger.instance_eval(&block) : block.call(option_merger)
81 end
with_timezone_config(cfg)
    # File activerecord/test/cases/helper.rb
 81 def with_timezone_config(cfg)
 82   verify_default_timezone_config
 83 
 84   old_default_zone = ActiveRecord::Base.default_timezone
 85   old_awareness = ActiveRecord::Base.time_zone_aware_attributes
 86   old_zone = Time.zone
 87 
 88   if cfg.has_key?(:default)
 89     ActiveRecord::Base.default_timezone = cfg[:default]
 90   end
 91   if cfg.has_key?(:aware_attributes)
 92     ActiveRecord::Base.time_zone_aware_attributes = cfg[:aware_attributes]
 93   end
 94   if cfg.has_key?(:zone)
 95     Time.zone = cfg[:zone]
 96   end
 97   yield
 98 ensure
 99   ActiveRecord::Base.default_timezone = old_default_zone
100   ActiveRecord::Base.time_zone_aware_attributes = old_awareness
101   Time.zone = old_zone
102 end