mirror of
				https://github.com/thoughtbot/shoulda-matchers.git
				synced 2022-11-09 12:01:38 -05:00 
			
		
		
		
	fix(rubocop): Fix Layout/LineLength
- bump rubocop to v1.0 - Fix Layout/MultilineAssignmentLayout and other remaining offences - Exculde appraisal generated gemfiles in rubocop - Replace NON_NUMERIC_VALUE constant with instance method against failing test case in rails <= 5.1 and postgres adapter. This is a defect in rails where a frozen string is modified in https://github.com/rails/rails/blob/v5.1.7/activerecord/lib/active_record/connection_adapters/postgresql/oid/money.rb#L25
This commit is contained in:
		
							parent
							
								
									3e88500318
								
							
						
					
					
						commit
						b7e02184d9
					
				
					 101 changed files with 866 additions and 605 deletions
				
			
		
							
								
								
									
										25
									
								
								.rubocop.yml
									
										
									
									
									
								
							
							
						
						
									
										25
									
								
								.rubocop.yml
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -4,6 +4,11 @@ require:
 | 
			
		|||
AllCops:
 | 
			
		||||
  NewCops: disable
 | 
			
		||||
  TargetRubyVersion: 2.4
 | 
			
		||||
  Exclude:
 | 
			
		||||
    - 'gemfiles/*'
 | 
			
		||||
Bundler/OrderedGems:
 | 
			
		||||
  Include:
 | 
			
		||||
    - '**/Gemfile'
 | 
			
		||||
Layout/ArgumentAlignment:
 | 
			
		||||
  EnforcedStyle: with_fixed_indentation
 | 
			
		||||
Layout/CommentIndentation:
 | 
			
		||||
| 
						 | 
				
			
			@ -20,10 +25,12 @@ Layout/LineLength:
 | 
			
		|||
  Exclude:
 | 
			
		||||
    - spec/**/*
 | 
			
		||||
  IgnoredPatterns:
 | 
			
		||||
    - !ruby/regexp /\A +(it|describe|context|shared_examples|include_examples|it_behaves_like) ["']/
 | 
			
		||||
    - !ruby/regexp /\A(require|require_relative) ["']/
 | 
			
		||||
    - '^[ ]*#.+$'
 | 
			
		||||
    - '^[ ]*''.+?'' => ''.+?'',?$'
 | 
			
		||||
    - '^[ ]*".+?" => ".+?",?$'
 | 
			
		||||
  Max: 120
 | 
			
		||||
  Max: 80
 | 
			
		||||
Layout/MultilineMethodCallIndentation:
 | 
			
		||||
  EnforcedStyle: indented
 | 
			
		||||
Layout/ParameterAlignment:
 | 
			
		||||
| 
						 | 
				
			
			@ -51,6 +58,8 @@ Lint/LiteralInInterpolation:
 | 
			
		|||
  Enabled: false
 | 
			
		||||
Lint/Loop:
 | 
			
		||||
  Enabled: false
 | 
			
		||||
Lint/MissingSuper:
 | 
			
		||||
  Enabled: false
 | 
			
		||||
Lint/ParenthesesAsGroupedExpression:
 | 
			
		||||
  Enabled: false
 | 
			
		||||
Lint/RequireParentheses:
 | 
			
		||||
| 
						 | 
				
			
			@ -64,11 +73,13 @@ Lint/UnderscorePrefixedVariableName:
 | 
			
		|||
Lint/Void:
 | 
			
		||||
  Enabled: false
 | 
			
		||||
Metrics/AbcSize:
 | 
			
		||||
  Max: 25
 | 
			
		||||
  Enabled: false
 | 
			
		||||
Metrics/BlockLength:
 | 
			
		||||
  Enabled: false
 | 
			
		||||
Metrics/ClassLength:
 | 
			
		||||
  Enabled: false
 | 
			
		||||
Metrics/CyclomaticComplexity:
 | 
			
		||||
  Enabled: false
 | 
			
		||||
Metrics/MethodLength:
 | 
			
		||||
  Max: 30
 | 
			
		||||
Metrics/ModuleLength:
 | 
			
		||||
| 
						 | 
				
			
			@ -78,7 +89,7 @@ Metrics/ModuleLength:
 | 
			
		|||
Metrics/ParameterLists:
 | 
			
		||||
  CountKeywordArgs: false
 | 
			
		||||
Metrics/PerceivedComplexity:
 | 
			
		||||
  Max: 10
 | 
			
		||||
  Enabled: false
 | 
			
		||||
Naming/AccessorMethodName:
 | 
			
		||||
  Enabled: false
 | 
			
		||||
Naming/AsciiIdentifiers:
 | 
			
		||||
| 
						 | 
				
			
			@ -93,6 +104,8 @@ Naming/MemoizedInstanceVariableName:
 | 
			
		|||
  EnforcedStyleForLeadingUnderscores: required
 | 
			
		||||
Naming/PredicateName:
 | 
			
		||||
  Enabled: false
 | 
			
		||||
Naming/RescuedExceptionsVariableName:
 | 
			
		||||
  Enabled: false
 | 
			
		||||
Rails/Date:
 | 
			
		||||
  Enabled: false
 | 
			
		||||
Rails/Delegate:
 | 
			
		||||
| 
						 | 
				
			
			@ -143,6 +156,8 @@ Style/EmptyElse:
 | 
			
		|||
  Enabled: false
 | 
			
		||||
Style/EmptyLiteral:
 | 
			
		||||
  Enabled: false
 | 
			
		||||
Style/EmptyMethod:
 | 
			
		||||
  EnforcedStyle: expanded
 | 
			
		||||
Style/Encoding:
 | 
			
		||||
  Enabled: false
 | 
			
		||||
Style/EvenOdd:
 | 
			
		||||
| 
						 | 
				
			
			@ -163,6 +178,8 @@ Style/IfWithSemicolon:
 | 
			
		|||
  Enabled: false
 | 
			
		||||
Style/InlineComment:
 | 
			
		||||
  Enabled: false
 | 
			
		||||
Style/InverseMethods:
 | 
			
		||||
  Enabled: false
 | 
			
		||||
Style/Lambda:
 | 
			
		||||
  Enabled: false
 | 
			
		||||
Style/LambdaCall:
 | 
			
		||||
| 
						 | 
				
			
			@ -189,6 +206,8 @@ Style/NumericPredicate:
 | 
			
		|||
  Enabled: false
 | 
			
		||||
Style/OneLineConditional:
 | 
			
		||||
  Enabled: false
 | 
			
		||||
Style/OptionalBooleanParameter:
 | 
			
		||||
  Enabled: false
 | 
			
		||||
Style/ParenthesesAroundCondition:
 | 
			
		||||
  Enabled: false
 | 
			
		||||
Style/PercentLiteralDelimiters:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -107,7 +107,8 @@ appraise 'rails_5_2' do
 | 
			
		|||
  gem 'sqlite3', '~> 1.3.6'
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
if Gem::Requirement.new('>= 2.5.0').satisfied_by?(Gem::Version.new(RUBY_VERSION))
 | 
			
		||||
if Gem::Requirement.new('>= 2.5.0').
 | 
			
		||||
    satisfied_by?(Gem::Version.new(RUBY_VERSION))
 | 
			
		||||
  appraise 'rails_6_0' do
 | 
			
		||||
    instance_eval(&shared_dependencies)
 | 
			
		||||
    instance_eval(&controller_test_dependency)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										41
									
								
								Gemfile.lock
									
										
									
									
									
								
							
							
						
						
									
										41
									
								
								Gemfile.lock
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,6 +1,12 @@
 | 
			
		|||
GEM
 | 
			
		||||
  remote: https://rubygems.org/
 | 
			
		||||
  specs:
 | 
			
		||||
    activesupport (6.0.3.4)
 | 
			
		||||
      concurrent-ruby (~> 1.0, >= 1.0.2)
 | 
			
		||||
      i18n (>= 0.7, < 2)
 | 
			
		||||
      minitest (~> 5.1)
 | 
			
		||||
      tzinfo (~> 1.1)
 | 
			
		||||
      zeitwerk (~> 2.2, >= 2.2.2)
 | 
			
		||||
    appraisal (2.2.0)
 | 
			
		||||
      bundler
 | 
			
		||||
      rake
 | 
			
		||||
| 
						 | 
				
			
			@ -8,11 +14,15 @@ GEM
 | 
			
		|||
    ast (2.4.1)
 | 
			
		||||
    byebug (11.1.3)
 | 
			
		||||
    coderay (1.1.3)
 | 
			
		||||
    concurrent-ruby (1.1.7)
 | 
			
		||||
    diff-lcs (1.3)
 | 
			
		||||
    fssm (0.2.10)
 | 
			
		||||
    i18n (1.8.5)
 | 
			
		||||
      concurrent-ruby (~> 1.0)
 | 
			
		||||
    method_source (1.0.0)
 | 
			
		||||
    minitest (5.14.2)
 | 
			
		||||
    parallel (1.19.2)
 | 
			
		||||
    parser (2.7.1.4)
 | 
			
		||||
    parser (2.7.2.0)
 | 
			
		||||
      ast (~> 2.4.1)
 | 
			
		||||
    pry (0.13.1)
 | 
			
		||||
      coderay (~> 1.1)
 | 
			
		||||
| 
						 | 
				
			
			@ -20,11 +30,11 @@ GEM
 | 
			
		|||
    pry-byebug (3.9.0)
 | 
			
		||||
      byebug (~> 11.0)
 | 
			
		||||
      pry (~> 0.13.0)
 | 
			
		||||
    rack (2.2.2)
 | 
			
		||||
    rack (2.2.3)
 | 
			
		||||
    rainbow (3.0.0)
 | 
			
		||||
    rake (13.0.1)
 | 
			
		||||
    redcarpet (3.5.0)
 | 
			
		||||
    regexp_parser (1.7.1)
 | 
			
		||||
    regexp_parser (1.8.2)
 | 
			
		||||
    rexml (3.2.4)
 | 
			
		||||
    rouge (3.22.0)
 | 
			
		||||
    rspec (3.9.0)
 | 
			
		||||
| 
						 | 
				
			
			@ -40,27 +50,32 @@ GEM
 | 
			
		|||
      diff-lcs (>= 1.2.0, < 2.0)
 | 
			
		||||
      rspec-support (~> 3.9.0)
 | 
			
		||||
    rspec-support (3.9.0)
 | 
			
		||||
    rubocop (0.90.0)
 | 
			
		||||
    rubocop (1.0.0)
 | 
			
		||||
      parallel (~> 1.10)
 | 
			
		||||
      parser (>= 2.7.1.1)
 | 
			
		||||
      parser (>= 2.7.1.5)
 | 
			
		||||
      rainbow (>= 2.2.2, < 4.0)
 | 
			
		||||
      regexp_parser (>= 1.7)
 | 
			
		||||
      regexp_parser (>= 1.8)
 | 
			
		||||
      rexml
 | 
			
		||||
      rubocop-ast (>= 0.3.0, < 1.0)
 | 
			
		||||
      rubocop-ast (>= 0.6.0)
 | 
			
		||||
      ruby-progressbar (~> 1.7)
 | 
			
		||||
      unicode-display_width (>= 1.4.0, < 2.0)
 | 
			
		||||
    rubocop-ast (0.3.0)
 | 
			
		||||
      parser (>= 2.7.1.4)
 | 
			
		||||
    rubocop-packaging (0.4.0)
 | 
			
		||||
      rubocop (~> 0.89)
 | 
			
		||||
    rubocop-rails (2.0.1)
 | 
			
		||||
    rubocop-ast (1.1.0)
 | 
			
		||||
      parser (>= 2.7.1.5)
 | 
			
		||||
    rubocop-packaging (0.5.1)
 | 
			
		||||
      rubocop (>= 0.89, < 2.0)
 | 
			
		||||
    rubocop-rails (2.8.1)
 | 
			
		||||
      activesupport (>= 4.2.0)
 | 
			
		||||
      rack (>= 1.1)
 | 
			
		||||
      rubocop (>= 0.70.0)
 | 
			
		||||
      rubocop (>= 0.87.0)
 | 
			
		||||
    ruby-progressbar (1.10.1)
 | 
			
		||||
    thor (0.20.0)
 | 
			
		||||
    thread_safe (0.3.6)
 | 
			
		||||
    tzinfo (1.2.7)
 | 
			
		||||
      thread_safe (~> 0.1)
 | 
			
		||||
    unicode-display_width (1.7.0)
 | 
			
		||||
    warnings_logger (0.1.1)
 | 
			
		||||
    yard (0.9.25)
 | 
			
		||||
    zeitwerk (2.4.0)
 | 
			
		||||
    zeus (0.15.14)
 | 
			
		||||
      method_source (>= 0.6.7)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								Rakefile
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								Rakefile
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -33,7 +33,7 @@ task :default do
 | 
			
		|||
end
 | 
			
		||||
 | 
			
		||||
namespace :appraisal do
 | 
			
		||||
  task :list do
 | 
			
		||||
  task list: :environment do
 | 
			
		||||
    appraisals = Tests::CurrentBundle.instance.available_appraisals
 | 
			
		||||
    puts "Valid appraisals: #{appraisals.join(', ')}"
 | 
			
		||||
  end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -45,7 +45,8 @@ class CustomPlan < Zeus::Plan
 | 
			
		|||
    raise CouldNotBootZeusError.create(underlying_error: e)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def after_fork; end
 | 
			
		||||
  def after_fork
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def test_environment
 | 
			
		||||
    require_relative 'spec/unit_spec_helper'
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,6 @@
 | 
			
		|||
YARD::Templates::Engine.register_template_path(File.dirname(__FILE__) + '/templates')
 | 
			
		||||
YARD::Templates::Engine.register_template_path(
 | 
			
		||||
  "#{File.dirname(__FILE__)}/templates",
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
require 'rouge'
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,12 +17,15 @@ def class_list(root = Registry.root, tree = TreeContext.new)
 | 
			
		|||
    next unless child.is_a?(CodeObjects::NamespaceObject)
 | 
			
		||||
 | 
			
		||||
    name = child.namespace.is_a?(CodeObjects::Proxy) ? child.path : child.name
 | 
			
		||||
    has_children = run_verifier(child.children).any? {|o| o.is_a?(CodeObjects::NamespaceObject) }
 | 
			
		||||
    has_children = run_verifier(child.children).
 | 
			
		||||
      any? {|o| o.is_a?(CodeObjects::NamespaceObject) }
 | 
			
		||||
    out << "<li id='object_#{child.path}' class='#{tree.classes.join(' ')}'>"
 | 
			
		||||
    out << "<div class='item'>"
 | 
			
		||||
    out << "<a class='toggle'></a> " if has_children
 | 
			
		||||
    out << linkify(child, name)
 | 
			
		||||
    out << " < #{child.superclass.name}" if child.is_a?(CodeObjects::ClassObject) && child.superclass
 | 
			
		||||
    if child.is_a?(CodeObjects::ClassObject) && child.superclass
 | 
			
		||||
      out << " < #{child.superclass.name}"
 | 
			
		||||
    end
 | 
			
		||||
    out << "<small class='search_info'>"
 | 
			
		||||
    out << child.namespace.title
 | 
			
		||||
    out << '</small>'
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,14 +10,15 @@ end
 | 
			
		|||
def diskfile
 | 
			
		||||
  @file.attributes[:markup] ||= markup_for_file('', @file.filename)
 | 
			
		||||
 | 
			
		||||
  contents = if @file.filename == 'README.md'
 | 
			
		||||
               preprocess_index(@file.contents)
 | 
			
		||||
             else
 | 
			
		||||
               @file.contents
 | 
			
		||||
             end
 | 
			
		||||
  contents =
 | 
			
		||||
    if @file.filename == 'README.md'
 | 
			
		||||
      preprocess_index(@file.contents)
 | 
			
		||||
    else
 | 
			
		||||
      @file.contents
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
  data = htmlify(contents, @file.attributes[:markup])
 | 
			
		||||
  "<div id='filecontents'>" + data + '</div>'
 | 
			
		||||
  "<div id='filecontents'>#{data}</div>"
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
def preprocess_index(contents)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,36 +1,37 @@
 | 
			
		|||
# This file was generated by Appraisal
 | 
			
		||||
 | 
			
		||||
source 'https://rubygems.org'
 | 
			
		||||
source "https://rubygems.org"
 | 
			
		||||
 | 
			
		||||
gem 'activeresource', '4.0.0'
 | 
			
		||||
gem 'appraisal', '2.2.0'
 | 
			
		||||
gem 'bcrypt', '~> 3.1.7'
 | 
			
		||||
gem 'bundler', '~> 1.1'
 | 
			
		||||
gem 'coffee-rails', '~> 4.1.0'
 | 
			
		||||
gem 'fssm'
 | 
			
		||||
gem 'jbuilder', '~> 2.0'
 | 
			
		||||
gem 'jquery-rails'
 | 
			
		||||
gem 'json', '~> 1.4'
 | 
			
		||||
gem 'pg', '~> 0.18'
 | 
			
		||||
gem 'protected_attributes', '~> 1.0.6'
 | 
			
		||||
gem 'pry'
 | 
			
		||||
gem 'pry-byebug'
 | 
			
		||||
gem 'rails', '4.2.11.1'
 | 
			
		||||
gem 'rake', '13.0.1'
 | 
			
		||||
gem 'redcarpet'
 | 
			
		||||
gem 'rouge'
 | 
			
		||||
gem 'rspec', '~> 3.9'
 | 
			
		||||
gem 'rspec-rails', '~> 3.9'
 | 
			
		||||
gem 'rubocop', require: false
 | 
			
		||||
gem 'rubocop-rails', require: false
 | 
			
		||||
gem 'sass-rails', '~> 5.0'
 | 
			
		||||
gem 'sdoc', '~> 0.4.0', group: :doc
 | 
			
		||||
gem 'shoulda-context', '~> 1.2.0'
 | 
			
		||||
gem 'spring'
 | 
			
		||||
gem 'spring-commands-rspec'
 | 
			
		||||
gem 'sqlite3', '~> 1.3.6'
 | 
			
		||||
gem 'turbolinks'
 | 
			
		||||
gem 'uglifier', '>= 1.3.0'
 | 
			
		||||
gem 'warnings_logger'
 | 
			
		||||
gem 'yard'
 | 
			
		||||
gem 'zeus', require: false
 | 
			
		||||
gem "appraisal", "2.2.0"
 | 
			
		||||
gem "bundler", "~> 1.1"
 | 
			
		||||
gem "pry"
 | 
			
		||||
gem "pry-byebug"
 | 
			
		||||
gem "rake", "13.0.1"
 | 
			
		||||
gem "rspec", "~> 3.9"
 | 
			
		||||
gem "rubocop", require: false
 | 
			
		||||
gem "rubocop-packaging", require: false
 | 
			
		||||
gem "rubocop-rails", require: false
 | 
			
		||||
gem "warnings_logger"
 | 
			
		||||
gem "zeus", require: false
 | 
			
		||||
gem "fssm"
 | 
			
		||||
gem "redcarpet"
 | 
			
		||||
gem "rouge"
 | 
			
		||||
gem "yard"
 | 
			
		||||
gem "spring"
 | 
			
		||||
gem "spring-commands-rspec"
 | 
			
		||||
gem "rspec-rails", "~> 3.9"
 | 
			
		||||
gem "shoulda-context", "~> 1.2.0"
 | 
			
		||||
gem "rails", "4.2.11.1"
 | 
			
		||||
gem "sass-rails", "~> 5.0"
 | 
			
		||||
gem "uglifier", ">= 1.3.0"
 | 
			
		||||
gem "coffee-rails", "~> 4.1.0"
 | 
			
		||||
gem "jquery-rails"
 | 
			
		||||
gem "turbolinks"
 | 
			
		||||
gem "jbuilder", "~> 2.0"
 | 
			
		||||
gem "sdoc", "~> 0.4.0", group: :doc
 | 
			
		||||
gem "bcrypt", "~> 3.1.7"
 | 
			
		||||
gem "activeresource", "4.0.0"
 | 
			
		||||
gem "json", "~> 1.4"
 | 
			
		||||
gem "protected_attributes", "~> 1.0.6"
 | 
			
		||||
gem "pg", "~> 0.18"
 | 
			
		||||
gem "sqlite3", "~> 1.3.6"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -168,6 +168,8 @@ GEM
 | 
			
		|||
      unicode-display_width (>= 1.4.0, < 2.0)
 | 
			
		||||
    rubocop-ast (0.3.0)
 | 
			
		||||
      parser (>= 2.7.1.4)
 | 
			
		||||
    rubocop-packaging (0.4.0)
 | 
			
		||||
      rubocop (~> 0.89)
 | 
			
		||||
    rubocop-rails (2.4.1)
 | 
			
		||||
      rack (>= 1.1)
 | 
			
		||||
      rubocop (>= 0.72.0)
 | 
			
		||||
| 
						 | 
				
			
			@ -238,6 +240,7 @@ DEPENDENCIES
 | 
			
		|||
  rspec (~> 3.9)
 | 
			
		||||
  rspec-rails (~> 3.9)
 | 
			
		||||
  rubocop
 | 
			
		||||
  rubocop-packaging
 | 
			
		||||
  rubocop-rails
 | 
			
		||||
  sass-rails (~> 5.0)
 | 
			
		||||
  sdoc (~> 0.4.0)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,34 +1,35 @@
 | 
			
		|||
# This file was generated by Appraisal
 | 
			
		||||
 | 
			
		||||
source 'https://rubygems.org'
 | 
			
		||||
source "https://rubygems.org"
 | 
			
		||||
 | 
			
		||||
gem 'appraisal', '2.2.0'
 | 
			
		||||
gem 'bcrypt', '~> 3.1.7'
 | 
			
		||||
gem 'bundler', '~> 1.1'
 | 
			
		||||
gem 'fssm'
 | 
			
		||||
gem 'jbuilder', '~> 2.5'
 | 
			
		||||
gem 'jquery-rails'
 | 
			
		||||
gem 'listen', '~> 3.0.5'
 | 
			
		||||
gem 'pg', '~> 0.18'
 | 
			
		||||
gem 'pry'
 | 
			
		||||
gem 'pry-byebug'
 | 
			
		||||
gem 'puma', '~> 3.0'
 | 
			
		||||
gem 'rails', '5.0.7.2'
 | 
			
		||||
gem 'rails-controller-testing', '>= 1.0.1'
 | 
			
		||||
gem 'rake', '13.0.1'
 | 
			
		||||
gem 'redcarpet'
 | 
			
		||||
gem 'rouge'
 | 
			
		||||
gem 'rspec', '~> 3.9'
 | 
			
		||||
gem 'rspec-rails', '~> 3.9'
 | 
			
		||||
gem 'rubocop', require: false
 | 
			
		||||
gem 'rubocop-rails', require: false
 | 
			
		||||
gem 'sass-rails', '~> 5.0'
 | 
			
		||||
gem 'shoulda-context', '~> 1.2.0'
 | 
			
		||||
gem 'spring'
 | 
			
		||||
gem 'spring-commands-rspec'
 | 
			
		||||
gem 'spring-watcher-listen', '~> 2.0.0'
 | 
			
		||||
gem 'sqlite3', '~> 1.3.6'
 | 
			
		||||
gem 'turbolinks', '~> 5'
 | 
			
		||||
gem 'warnings_logger'
 | 
			
		||||
gem 'yard'
 | 
			
		||||
gem 'zeus', require: false
 | 
			
		||||
gem "appraisal", "2.2.0"
 | 
			
		||||
gem "bundler", "~> 1.1"
 | 
			
		||||
gem "pry"
 | 
			
		||||
gem "pry-byebug"
 | 
			
		||||
gem "rake", "13.0.1"
 | 
			
		||||
gem "rspec", "~> 3.9"
 | 
			
		||||
gem "rubocop", require: false
 | 
			
		||||
gem "rubocop-packaging", require: false
 | 
			
		||||
gem "rubocop-rails", require: false
 | 
			
		||||
gem "warnings_logger"
 | 
			
		||||
gem "zeus", require: false
 | 
			
		||||
gem "fssm"
 | 
			
		||||
gem "redcarpet"
 | 
			
		||||
gem "rouge"
 | 
			
		||||
gem "yard"
 | 
			
		||||
gem "spring"
 | 
			
		||||
gem "spring-commands-rspec"
 | 
			
		||||
gem "rspec-rails", "~> 3.9"
 | 
			
		||||
gem "shoulda-context", "~> 1.2.0"
 | 
			
		||||
gem "rails-controller-testing", ">= 1.0.1"
 | 
			
		||||
gem "rails", "5.0.7.2"
 | 
			
		||||
gem "puma", "~> 3.0"
 | 
			
		||||
gem "sass-rails", "~> 5.0"
 | 
			
		||||
gem "jquery-rails"
 | 
			
		||||
gem "turbolinks", "~> 5"
 | 
			
		||||
gem "jbuilder", "~> 2.5"
 | 
			
		||||
gem "bcrypt", "~> 3.1.7"
 | 
			
		||||
gem "listen", "~> 3.0.5"
 | 
			
		||||
gem "spring-watcher-listen", "~> 2.0.0"
 | 
			
		||||
gem "pg", "~> 0.18"
 | 
			
		||||
gem "sqlite3", "~> 1.3.6"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -161,6 +161,8 @@ GEM
 | 
			
		|||
      unicode-display_width (>= 1.4.0, < 2.0)
 | 
			
		||||
    rubocop-ast (0.3.0)
 | 
			
		||||
      parser (>= 2.7.1.4)
 | 
			
		||||
    rubocop-packaging (0.4.0)
 | 
			
		||||
      rubocop (~> 0.89)
 | 
			
		||||
    rubocop-rails (2.4.1)
 | 
			
		||||
      rack (>= 1.1)
 | 
			
		||||
      rubocop (>= 0.72.0)
 | 
			
		||||
| 
						 | 
				
			
			@ -231,6 +233,7 @@ DEPENDENCIES
 | 
			
		|||
  rspec (~> 3.9)
 | 
			
		||||
  rspec-rails (~> 3.9)
 | 
			
		||||
  rubocop
 | 
			
		||||
  rubocop-packaging
 | 
			
		||||
  rubocop-rails
 | 
			
		||||
  sass-rails (~> 5.0)
 | 
			
		||||
  shoulda-context (~> 1.2.0)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,35 +1,36 @@
 | 
			
		|||
# This file was generated by Appraisal
 | 
			
		||||
 | 
			
		||||
source 'https://rubygems.org'
 | 
			
		||||
source "https://rubygems.org"
 | 
			
		||||
 | 
			
		||||
gem 'appraisal', '2.2.0'
 | 
			
		||||
gem 'bcrypt', '~> 3.1.7'
 | 
			
		||||
gem 'bundler', '~> 1.1'
 | 
			
		||||
gem 'capybara', '~> 2.13'
 | 
			
		||||
gem 'fssm'
 | 
			
		||||
gem 'jbuilder', '~> 2.5'
 | 
			
		||||
gem 'listen', '>= 3.0.5', '< 3.2'
 | 
			
		||||
gem 'pg', '~> 0.18'
 | 
			
		||||
gem 'pry'
 | 
			
		||||
gem 'pry-byebug'
 | 
			
		||||
gem 'puma', '~> 3.7'
 | 
			
		||||
gem 'rails', '5.1.7'
 | 
			
		||||
gem 'rails-controller-testing', '>= 1.0.1'
 | 
			
		||||
gem 'rake', '13.0.1'
 | 
			
		||||
gem 'redcarpet'
 | 
			
		||||
gem 'rouge'
 | 
			
		||||
gem 'rspec', '~> 3.9'
 | 
			
		||||
gem 'rspec-rails', '~> 3.9'
 | 
			
		||||
gem 'rubocop', require: false
 | 
			
		||||
gem 'rubocop-rails', require: false
 | 
			
		||||
gem 'sass-rails', '~> 5.0'
 | 
			
		||||
gem 'selenium-webdriver'
 | 
			
		||||
gem 'shoulda-context', '~> 1.2.0'
 | 
			
		||||
gem 'spring'
 | 
			
		||||
gem 'spring-commands-rspec'
 | 
			
		||||
gem 'spring-watcher-listen', '~> 2.0.0'
 | 
			
		||||
gem 'sqlite3', '~> 1.3.6'
 | 
			
		||||
gem 'turbolinks', '~> 5'
 | 
			
		||||
gem 'warnings_logger'
 | 
			
		||||
gem 'yard'
 | 
			
		||||
gem 'zeus', require: false
 | 
			
		||||
gem "appraisal", "2.2.0"
 | 
			
		||||
gem "bundler", "~> 1.1"
 | 
			
		||||
gem "pry"
 | 
			
		||||
gem "pry-byebug"
 | 
			
		||||
gem "rake", "13.0.1"
 | 
			
		||||
gem "rspec", "~> 3.9"
 | 
			
		||||
gem "rubocop", require: false
 | 
			
		||||
gem "rubocop-packaging", require: false
 | 
			
		||||
gem "rubocop-rails", require: false
 | 
			
		||||
gem "warnings_logger"
 | 
			
		||||
gem "zeus", require: false
 | 
			
		||||
gem "fssm"
 | 
			
		||||
gem "redcarpet"
 | 
			
		||||
gem "rouge"
 | 
			
		||||
gem "yard"
 | 
			
		||||
gem "spring"
 | 
			
		||||
gem "spring-commands-rspec"
 | 
			
		||||
gem "rspec-rails", "~> 3.9"
 | 
			
		||||
gem "shoulda-context", "~> 1.2.0"
 | 
			
		||||
gem "rails-controller-testing", ">= 1.0.1"
 | 
			
		||||
gem "rails", "5.1.7"
 | 
			
		||||
gem "puma", "~> 3.7"
 | 
			
		||||
gem "sass-rails", "~> 5.0"
 | 
			
		||||
gem "turbolinks", "~> 5"
 | 
			
		||||
gem "jbuilder", "~> 2.5"
 | 
			
		||||
gem "bcrypt", "~> 3.1.7"
 | 
			
		||||
gem "capybara", "~> 2.13"
 | 
			
		||||
gem "selenium-webdriver"
 | 
			
		||||
gem "listen", ">= 3.0.5", "< 3.2"
 | 
			
		||||
gem "spring-watcher-listen", "~> 2.0.0"
 | 
			
		||||
gem "pg", "~> 0.18"
 | 
			
		||||
gem "sqlite3", "~> 1.3.6"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -169,6 +169,8 @@ GEM
 | 
			
		|||
      unicode-display_width (>= 1.4.0, < 2.0)
 | 
			
		||||
    rubocop-ast (0.3.0)
 | 
			
		||||
      parser (>= 2.7.1.4)
 | 
			
		||||
    rubocop-packaging (0.4.0)
 | 
			
		||||
      rubocop (~> 0.89)
 | 
			
		||||
    rubocop-rails (2.4.1)
 | 
			
		||||
      rack (>= 1.1)
 | 
			
		||||
      rubocop (>= 0.72.0)
 | 
			
		||||
| 
						 | 
				
			
			@ -246,6 +248,7 @@ DEPENDENCIES
 | 
			
		|||
  rspec (~> 3.9)
 | 
			
		||||
  rspec-rails (~> 3.9)
 | 
			
		||||
  rubocop
 | 
			
		||||
  rubocop-packaging
 | 
			
		||||
  rubocop-rails
 | 
			
		||||
  sass-rails (~> 5.0)
 | 
			
		||||
  selenium-webdriver
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,37 +1,38 @@
 | 
			
		|||
# This file was generated by Appraisal
 | 
			
		||||
 | 
			
		||||
source 'https://rubygems.org'
 | 
			
		||||
source "https://rubygems.org"
 | 
			
		||||
 | 
			
		||||
gem 'appraisal', '2.2.0'
 | 
			
		||||
gem 'bcrypt', '~> 3.1.7'
 | 
			
		||||
gem 'bootsnap', '>= 1.1.0', require: false
 | 
			
		||||
gem 'bundler', '~> 1.1'
 | 
			
		||||
gem 'capybara', '~> 3.1.1'
 | 
			
		||||
gem 'chromedriver-helper'
 | 
			
		||||
gem 'fssm'
 | 
			
		||||
gem 'jbuilder', '~> 2.5'
 | 
			
		||||
gem 'listen', '>= 3.0.5', '< 3.2'
 | 
			
		||||
gem 'pg', '~> 0.18'
 | 
			
		||||
gem 'pry'
 | 
			
		||||
gem 'pry-byebug'
 | 
			
		||||
gem 'puma', '~> 3.11'
 | 
			
		||||
gem 'rails', '5.2.4.1'
 | 
			
		||||
gem 'rails-controller-testing', '>= 1.0.1'
 | 
			
		||||
gem 'rake', '13.0.1'
 | 
			
		||||
gem 'redcarpet'
 | 
			
		||||
gem 'rouge'
 | 
			
		||||
gem 'rspec', '~> 3.9'
 | 
			
		||||
gem 'rspec-rails', '~> 3.9'
 | 
			
		||||
gem 'rubocop', require: false
 | 
			
		||||
gem 'rubocop-rails', require: false
 | 
			
		||||
gem 'sass-rails', '~> 5.0'
 | 
			
		||||
gem 'selenium-webdriver'
 | 
			
		||||
gem 'shoulda-context', '~> 1.2.0'
 | 
			
		||||
gem 'spring'
 | 
			
		||||
gem 'spring-commands-rspec'
 | 
			
		||||
gem 'spring-watcher-listen', '~> 2.0.0'
 | 
			
		||||
gem 'sqlite3', '~> 1.3.6'
 | 
			
		||||
gem 'turbolinks', '~> 5'
 | 
			
		||||
gem 'warnings_logger'
 | 
			
		||||
gem 'yard'
 | 
			
		||||
gem 'zeus', require: false
 | 
			
		||||
gem "appraisal", "2.2.0"
 | 
			
		||||
gem "bundler", "~> 1.1"
 | 
			
		||||
gem "pry"
 | 
			
		||||
gem "pry-byebug"
 | 
			
		||||
gem "rake", "13.0.1"
 | 
			
		||||
gem "rspec", "~> 3.9"
 | 
			
		||||
gem "rubocop", require: false
 | 
			
		||||
gem "rubocop-packaging", require: false
 | 
			
		||||
gem "rubocop-rails", require: false
 | 
			
		||||
gem "warnings_logger"
 | 
			
		||||
gem "zeus", require: false
 | 
			
		||||
gem "fssm"
 | 
			
		||||
gem "redcarpet"
 | 
			
		||||
gem "rouge"
 | 
			
		||||
gem "yard"
 | 
			
		||||
gem "spring"
 | 
			
		||||
gem "spring-commands-rspec"
 | 
			
		||||
gem "rspec-rails", "~> 3.9"
 | 
			
		||||
gem "shoulda-context", "~> 1.2.0"
 | 
			
		||||
gem "rails-controller-testing", ">= 1.0.1"
 | 
			
		||||
gem "rails", "5.2.4.1"
 | 
			
		||||
gem "puma", "~> 3.11"
 | 
			
		||||
gem "bootsnap", ">= 1.1.0", require: false
 | 
			
		||||
gem "sass-rails", "~> 5.0"
 | 
			
		||||
gem "turbolinks", "~> 5"
 | 
			
		||||
gem "jbuilder", "~> 2.5"
 | 
			
		||||
gem "bcrypt", "~> 3.1.7"
 | 
			
		||||
gem "capybara", "~> 3.1.1"
 | 
			
		||||
gem "selenium-webdriver"
 | 
			
		||||
gem "chromedriver-helper"
 | 
			
		||||
gem "listen", ">= 3.0.5", "< 3.2"
 | 
			
		||||
gem "spring-watcher-listen", "~> 2.0.0"
 | 
			
		||||
gem "pg", "~> 0.18"
 | 
			
		||||
gem "sqlite3", "~> 1.3.6"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -186,6 +186,8 @@ GEM
 | 
			
		|||
      unicode-display_width (>= 1.4.0, < 2.0)
 | 
			
		||||
    rubocop-ast (0.3.0)
 | 
			
		||||
      parser (>= 2.7.1.4)
 | 
			
		||||
    rubocop-packaging (0.4.0)
 | 
			
		||||
      rubocop (~> 0.89)
 | 
			
		||||
    rubocop-rails (2.4.1)
 | 
			
		||||
      rack (>= 1.1)
 | 
			
		||||
      rubocop (>= 0.72.0)
 | 
			
		||||
| 
						 | 
				
			
			@ -265,6 +267,7 @@ DEPENDENCIES
 | 
			
		|||
  rspec (~> 3.9)
 | 
			
		||||
  rspec-rails (~> 3.9)
 | 
			
		||||
  rubocop
 | 
			
		||||
  rubocop-packaging
 | 
			
		||||
  rubocop-rails
 | 
			
		||||
  sass-rails (~> 5.0)
 | 
			
		||||
  selenium-webdriver
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,38 +1,39 @@
 | 
			
		|||
# This file was generated by Appraisal
 | 
			
		||||
 | 
			
		||||
source 'https://rubygems.org'
 | 
			
		||||
source "https://rubygems.org"
 | 
			
		||||
 | 
			
		||||
gem 'actiontext', '~> 6.0.2.1'
 | 
			
		||||
gem 'appraisal', '2.2.0'
 | 
			
		||||
gem 'bcrypt', '~> 3.1.7'
 | 
			
		||||
gem 'bootsnap', '>= 1.4.2', require: false
 | 
			
		||||
gem 'bundler', '~> 1.1'
 | 
			
		||||
gem 'capybara', '>= 2.15'
 | 
			
		||||
gem 'fssm'
 | 
			
		||||
gem 'jbuilder', '~> 2.7'
 | 
			
		||||
gem 'listen', '>= 3.0.5', '< 3.2'
 | 
			
		||||
gem 'pg', '>= 0.18', '< 2.0'
 | 
			
		||||
gem 'pry'
 | 
			
		||||
gem 'pry-byebug'
 | 
			
		||||
gem 'puma', '~> 4.1'
 | 
			
		||||
gem 'rails', '6.0.2.1'
 | 
			
		||||
gem 'rails-controller-testing', '>= 1.0.1'
 | 
			
		||||
gem 'rake', '13.0.1'
 | 
			
		||||
gem 'redcarpet'
 | 
			
		||||
gem 'rouge'
 | 
			
		||||
gem 'rspec', '~> 3.9'
 | 
			
		||||
gem 'rspec-rails', '~> 3.9'
 | 
			
		||||
gem 'rubocop', require: false
 | 
			
		||||
gem 'rubocop-rails', require: false
 | 
			
		||||
gem 'sass-rails', '>= 6'
 | 
			
		||||
gem 'selenium-webdriver'
 | 
			
		||||
gem 'shoulda-context', '~> 1.2.0'
 | 
			
		||||
gem 'spring'
 | 
			
		||||
gem 'spring-commands-rspec'
 | 
			
		||||
gem 'spring-watcher-listen', '~> 2.0.0'
 | 
			
		||||
gem 'sqlite3', '~> 1.4'
 | 
			
		||||
gem 'turbolinks', '~> 5'
 | 
			
		||||
gem 'warnings_logger'
 | 
			
		||||
gem 'webdrivers'
 | 
			
		||||
gem 'yard'
 | 
			
		||||
gem 'zeus', require: false
 | 
			
		||||
gem "appraisal", "2.2.0"
 | 
			
		||||
gem "bundler", "~> 1.1"
 | 
			
		||||
gem "pry"
 | 
			
		||||
gem "pry-byebug"
 | 
			
		||||
gem "rake", "13.0.1"
 | 
			
		||||
gem "rspec", "~> 3.9"
 | 
			
		||||
gem "rubocop", require: false
 | 
			
		||||
gem "rubocop-packaging", require: false
 | 
			
		||||
gem "rubocop-rails", require: false
 | 
			
		||||
gem "warnings_logger"
 | 
			
		||||
gem "zeus", require: false
 | 
			
		||||
gem "fssm"
 | 
			
		||||
gem "redcarpet"
 | 
			
		||||
gem "rouge"
 | 
			
		||||
gem "yard"
 | 
			
		||||
gem "spring"
 | 
			
		||||
gem "spring-commands-rspec"
 | 
			
		||||
gem "rspec-rails", "~> 3.9"
 | 
			
		||||
gem "shoulda-context", "~> 1.2.0"
 | 
			
		||||
gem "rails-controller-testing", ">= 1.0.1"
 | 
			
		||||
gem "rails", "6.0.2.1"
 | 
			
		||||
gem "puma", "~> 4.1"
 | 
			
		||||
gem "bootsnap", ">= 1.4.2", require: false
 | 
			
		||||
gem "sass-rails", ">= 6"
 | 
			
		||||
gem "turbolinks", "~> 5"
 | 
			
		||||
gem "jbuilder", "~> 2.7"
 | 
			
		||||
gem "bcrypt", "~> 3.1.7"
 | 
			
		||||
gem "capybara", ">= 2.15"
 | 
			
		||||
gem "listen", ">= 3.0.5", "< 3.2"
 | 
			
		||||
gem "spring-watcher-listen", "~> 2.0.0"
 | 
			
		||||
gem "selenium-webdriver"
 | 
			
		||||
gem "webdrivers"
 | 
			
		||||
gem "actiontext", "~> 6.0.2.1"
 | 
			
		||||
gem "pg", ">= 0.18", "< 2.0"
 | 
			
		||||
gem "sqlite3", "~> 1.4"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -196,6 +196,8 @@ GEM
 | 
			
		|||
      unicode-display_width (>= 1.4.0, < 2.0)
 | 
			
		||||
    rubocop-ast (0.3.0)
 | 
			
		||||
      parser (>= 2.7.1.4)
 | 
			
		||||
    rubocop-packaging (0.1.1)
 | 
			
		||||
      rubocop (>= 0.75.0)
 | 
			
		||||
    rubocop-rails (2.4.1)
 | 
			
		||||
      rack (>= 1.1)
 | 
			
		||||
      rubocop (>= 0.72.0)
 | 
			
		||||
| 
						 | 
				
			
			@ -279,6 +281,7 @@ DEPENDENCIES
 | 
			
		|||
  rspec (~> 3.9)
 | 
			
		||||
  rspec-rails (~> 3.9)
 | 
			
		||||
  rubocop
 | 
			
		||||
  rubocop-packaging
 | 
			
		||||
  rubocop-rails
 | 
			
		||||
  sass-rails (>= 6)
 | 
			
		||||
  selenium-webdriver
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -179,11 +179,13 @@ module Shoulda
 | 
			
		|||
        end
 | 
			
		||||
 | 
			
		||||
        def failure_message
 | 
			
		||||
          "Expected that #{controller_class.name} would have :#{method_name} as a #{kind}_#{callback_type}"
 | 
			
		||||
          "Expected that #{controller_class.name} would have :#{method_name}"\
 | 
			
		||||
            " as a #{kind}_#{callback_type}"
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def failure_message_when_negated
 | 
			
		||||
          "Expected that #{controller_class.name} would not have :#{method_name} as a #{kind}_#{callback_type}"
 | 
			
		||||
          "Expected that #{controller_class.name} would not have"\
 | 
			
		||||
            " :#{method_name} as a #{kind}_#{callback_type}"
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def description
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,7 +36,8 @@ module Shoulda
 | 
			
		|||
        end
 | 
			
		||||
 | 
			
		||||
        def failure_message
 | 
			
		||||
          "Expected #{@key} to be filtered; filtered keys: #{filtered_keys.join(', ')}"
 | 
			
		||||
          "Expected #{@key} to be filtered; filtered keys:"\
 | 
			
		||||
            " #{filtered_keys.join(', ')}"
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def failure_message_when_negated
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -209,7 +209,8 @@ module Shoulda
 | 
			
		|||
        attr_writer :stubbed_params
 | 
			
		||||
 | 
			
		||||
        def initialize(expected_permitted_parameter_names)
 | 
			
		||||
          @expected_permitted_parameter_names = expected_permitted_parameter_names
 | 
			
		||||
          @expected_permitted_parameter_names =
 | 
			
		||||
            expected_permitted_parameter_names
 | 
			
		||||
          @action = nil
 | 
			
		||||
          @verb = nil
 | 
			
		||||
          @request_params = {}
 | 
			
		||||
| 
						 | 
				
			
			@ -262,18 +263,20 @@ module Shoulda
 | 
			
		|||
        end
 | 
			
		||||
 | 
			
		||||
        def failure_message
 | 
			
		||||
          "Expected #{verb.upcase} ##{action} to #{expectation},\nbut #{reality}."
 | 
			
		||||
          "Expected #{verb.upcase} ##{action} to #{expectation},"\
 | 
			
		||||
          "\nbut #{reality}."
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def failure_message_when_negated
 | 
			
		||||
          "Expected #{verb.upcase} ##{action} not to #{expectation},\nbut it did."
 | 
			
		||||
          "Expected #{verb.upcase} ##{action} not to #{expectation},"\
 | 
			
		||||
          "\nbut it did."
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        protected
 | 
			
		||||
 | 
			
		||||
        attr_reader :controller, :double_collections_by_parameter_name, :action, :verb,
 | 
			
		||||
          :request_params, :expected_permitted_parameter_names, :context, :subparameter_name,
 | 
			
		||||
          :parameters_double_registry
 | 
			
		||||
        attr_reader :controller, :double_collections_by_parameter_name, :action,
 | 
			
		||||
          :verb, :request_params, :expected_permitted_parameter_names,
 | 
			
		||||
          :context, :subparameter_name, :parameters_double_registry
 | 
			
		||||
 | 
			
		||||
        def expectation
 | 
			
		||||
          message = 'restrict parameters '
 | 
			
		||||
| 
						 | 
				
			
			@ -282,7 +285,8 @@ module Shoulda
 | 
			
		|||
            message << "on #{subparameter_name.inspect} "
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          message << 'to ' + format_parameter_names(expected_permitted_parameter_names)
 | 
			
		||||
          message << 'to '\
 | 
			
		||||
            "#{format_parameter_names(expected_permitted_parameter_names)}"
 | 
			
		||||
 | 
			
		||||
          message
 | 
			
		||||
        end
 | 
			
		||||
| 
						 | 
				
			
			@ -291,9 +295,9 @@ module Shoulda
 | 
			
		|||
          if actual_permitted_parameter_names.empty?
 | 
			
		||||
            'it did not restrict any parameters'
 | 
			
		||||
          else
 | 
			
		||||
            'the restricted parameters were ' +
 | 
			
		||||
              format_parameter_names(actual_permitted_parameter_names) +
 | 
			
		||||
              ' instead'
 | 
			
		||||
            'the restricted parameters were '\
 | 
			
		||||
            "#{format_parameter_names(actual_permitted_parameter_names)}"\
 | 
			
		||||
            ' instead'
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -303,12 +307,12 @@ module Shoulda
 | 
			
		|||
 | 
			
		||||
        def actual_permitted_parameter_names
 | 
			
		||||
          @_actual_permitted_parameter_names ||= begin
 | 
			
		||||
            options = if subparameter_name
 | 
			
		||||
                        { for: subparameter_name }
 | 
			
		||||
                      else
 | 
			
		||||
                        {}
 | 
			
		||||
                      end
 | 
			
		||||
 | 
			
		||||
            options =
 | 
			
		||||
              if subparameter_name
 | 
			
		||||
                { for: subparameter_name }
 | 
			
		||||
              else
 | 
			
		||||
                {}
 | 
			
		||||
              end
 | 
			
		||||
            parameters_double_registry.permitted_parameter_names(options)
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
| 
						 | 
				
			
			@ -436,7 +440,8 @@ module Shoulda
 | 
			
		|||
        # @private
 | 
			
		||||
        class VerbNotDefinedError < StandardError
 | 
			
		||||
          def message
 | 
			
		||||
            'You must specify an HTTP verb when using a non-RESTful action. For example: for(:authorize, verb: :post)'
 | 
			
		||||
            'You must specify an HTTP verb when using a non-RESTful action.'\
 | 
			
		||||
            ' For example: for(:authorize, verb: :post)'
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -64,12 +64,12 @@ module Shoulda
 | 
			
		|||
      # @private
 | 
			
		||||
      class RenderWithLayoutMatcher
 | 
			
		||||
        def initialize(expected_layout)
 | 
			
		||||
          @expected_layout = if expected_layout
 | 
			
		||||
                               expected_layout.to_s
 | 
			
		||||
                             else
 | 
			
		||||
                               nil
 | 
			
		||||
                             end
 | 
			
		||||
 | 
			
		||||
          @expected_layout =
 | 
			
		||||
            if expected_layout
 | 
			
		||||
              expected_layout.to_s
 | 
			
		||||
            else
 | 
			
		||||
              nil
 | 
			
		||||
            end
 | 
			
		||||
          @controller = nil
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -95,11 +95,12 @@ module Shoulda
 | 
			
		|||
 | 
			
		||||
        def description
 | 
			
		||||
          description = 'render with '
 | 
			
		||||
          description << if @expected_layout.nil?
 | 
			
		||||
                           'a layout'
 | 
			
		||||
                         else
 | 
			
		||||
                           "the #{@expected_layout.inspect} layout"
 | 
			
		||||
                         end
 | 
			
		||||
          description <<
 | 
			
		||||
            if @expected_layout.nil?
 | 
			
		||||
              'a layout'
 | 
			
		||||
            else
 | 
			
		||||
              "the #{@expected_layout.inspect} layout"
 | 
			
		||||
            end
 | 
			
		||||
          description
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -118,7 +119,9 @@ module Shoulda
 | 
			
		|||
        end
 | 
			
		||||
 | 
			
		||||
        def rendered_layouts
 | 
			
		||||
          recorded_layouts.keys.compact.map { |layout| layout.sub(%r{^layouts/}, '') }
 | 
			
		||||
          recorded_layouts.keys.compact.map { |layout|
 | 
			
		||||
            layout.sub(%r{^layouts/}, '')
 | 
			
		||||
          }
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def recorded_layouts
 | 
			
		||||
| 
						 | 
				
			
			@ -135,7 +138,7 @@ module Shoulda
 | 
			
		|||
 | 
			
		||||
        def result
 | 
			
		||||
          if rendered_with_layout?
 | 
			
		||||
            'rendered with ' + rendered_layouts.map(&:inspect).join(', ')
 | 
			
		||||
            "rendered with #{rendered_layouts.map(&:inspect).join(', ')}"
 | 
			
		||||
          else
 | 
			
		||||
            'rendered without a layout'
 | 
			
		||||
          end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -79,7 +79,8 @@ module Shoulda
 | 
			
		|||
          end
 | 
			
		||||
 | 
			
		||||
          unless handler_exists?
 | 
			
		||||
            expectation << " but #{controller} does not respond to #{expected_method}"
 | 
			
		||||
            expectation << " but #{controller} does not respond to"\
 | 
			
		||||
              " #{expected_method}"
 | 
			
		||||
          end
 | 
			
		||||
          expectation
 | 
			
		||||
        end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,8 +20,9 @@ module Shoulda
 | 
			
		|||
        def to(expected_value = nil, &block)
 | 
			
		||||
          if block
 | 
			
		||||
            unless context_set?
 | 
			
		||||
              message = "When specifying a value as a block, a context must be specified beforehand,
 | 
			
		||||
                         e.g., #{store.name}.in_context(context).to { ... }"
 | 
			
		||||
              message = 'When specifying a value as a block, a context must be'\
 | 
			
		||||
                ' specified beforehand,'\
 | 
			
		||||
                " e.g., #{store.name}.in_context(context).to { ... }"
 | 
			
		||||
              raise ArgumentError, message
 | 
			
		||||
            end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -43,12 +44,14 @@ module Shoulda
 | 
			
		|||
        end
 | 
			
		||||
 | 
			
		||||
        def failure_message
 | 
			
		||||
          "Expected #{controller.class} to #{expectation_description}, but it did not"
 | 
			
		||||
          "Expected #{controller.class} to #{expectation_description},"\
 | 
			
		||||
          ' but it did not'
 | 
			
		||||
        end
 | 
			
		||||
        alias_method :failure_message_for_should, :failure_message
 | 
			
		||||
 | 
			
		||||
        def failure_message_when_negated
 | 
			
		||||
          "Expected #{controller.class} not to #{expectation_description}, but it did"
 | 
			
		||||
          "Expected #{controller.class} not to #{expectation_description},"\
 | 
			
		||||
          ' but it did'
 | 
			
		||||
        end
 | 
			
		||||
        alias_method :failure_message_for_should_not,
 | 
			
		||||
          :failure_message_when_negated
 | 
			
		||||
| 
						 | 
				
			
			@ -82,18 +85,20 @@ module Shoulda
 | 
			
		|||
        def expectation_description
 | 
			
		||||
          string = 'set'
 | 
			
		||||
 | 
			
		||||
          string << if key_set?
 | 
			
		||||
                      " #{store.name}[#{key.inspect}]"
 | 
			
		||||
                    else
 | 
			
		||||
                      " any key in #{store.name}"
 | 
			
		||||
                    end
 | 
			
		||||
          string <<
 | 
			
		||||
            if key_set?
 | 
			
		||||
              " #{store.name}[#{key.inspect}]"
 | 
			
		||||
            else
 | 
			
		||||
              " any key in #{store.name}"
 | 
			
		||||
            end
 | 
			
		||||
 | 
			
		||||
          if expected_value_set?
 | 
			
		||||
            string << if expected_value.is_a?(Regexp)
 | 
			
		||||
                        " to a value matching #{expected_value.inspect}"
 | 
			
		||||
                      else
 | 
			
		||||
                        " to #{expected_value.inspect}"
 | 
			
		||||
                      end
 | 
			
		||||
            string <<
 | 
			
		||||
              if expected_value.is_a?(Regexp)
 | 
			
		||||
                " to a value matching #{expected_value.inspect}"
 | 
			
		||||
              else
 | 
			
		||||
                " to #{expected_value.inspect}"
 | 
			
		||||
              end
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          string
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -89,21 +89,24 @@ module Shoulda
 | 
			
		|||
          @subject = subject
 | 
			
		||||
          if attr_mass_assignable?
 | 
			
		||||
            if whitelisting?
 | 
			
		||||
              @failure_message_when_negated = "#{@attribute} was made accessible"
 | 
			
		||||
              @failure_message_when_negated = "#{@attribute} was made "\
 | 
			
		||||
                'accessible'
 | 
			
		||||
            elsif protected_attributes.empty?
 | 
			
		||||
              @failure_message_when_negated = 'no attributes were protected'
 | 
			
		||||
            else
 | 
			
		||||
              @failure_message_when_negated = "#{class_name} is protecting " <<
 | 
			
		||||
                                              "#{protected_attributes.to_a.to_sentence}, " <<
 | 
			
		||||
                                              "but not #{@attribute}."
 | 
			
		||||
              @failure_message_when_negated =
 | 
			
		||||
                "#{class_name} is protecting " <<
 | 
			
		||||
                "#{protected_attributes.to_a.to_sentence}, " <<
 | 
			
		||||
                "but not #{@attribute}."
 | 
			
		||||
            end
 | 
			
		||||
            true
 | 
			
		||||
          else
 | 
			
		||||
            @failure_message = if whitelisting?
 | 
			
		||||
                                 "Expected #{@attribute} to be accessible"
 | 
			
		||||
                               else
 | 
			
		||||
                                 "Did not expect #{@attribute} to be protected"
 | 
			
		||||
                               end
 | 
			
		||||
            @failure_message =
 | 
			
		||||
              if whitelisting?
 | 
			
		||||
                "Expected #{@attribute} to be accessible"
 | 
			
		||||
              else
 | 
			
		||||
                "Did not expect #{@attribute} to be protected"
 | 
			
		||||
              end
 | 
			
		||||
            false
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
| 
						 | 
				
			
			@ -133,7 +136,8 @@ module Shoulda
 | 
			
		|||
        end
 | 
			
		||||
 | 
			
		||||
        def accessible_attributes
 | 
			
		||||
          @_accessible_attributes ||= (@subject.class.accessible_attributes || [])
 | 
			
		||||
          @_accessible_attributes ||=
 | 
			
		||||
            (@subject.class.accessible_attributes || [])
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def whitelisting?
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -423,40 +423,41 @@ module Shoulda
 | 
			
		|||
          end
 | 
			
		||||
 | 
			
		||||
          if include_attribute_changed_value_message?
 | 
			
		||||
            message << "\n\n" + attribute_changed_value_message.call
 | 
			
		||||
            message << "\n\n#{attribute_changed_value_message.call}"
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          Shoulda::Matchers.word_wrap(message)
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def failure_message_when_negated
 | 
			
		||||
        def failure_message_when_negated # rubocop:disable Metrics/MethodLength
 | 
			
		||||
          attribute_setter = result.attribute_setter
 | 
			
		||||
 | 
			
		||||
          if attribute_setter.unsuccessfully_checked?
 | 
			
		||||
            message = attribute_setter.failure_message
 | 
			
		||||
          else
 | 
			
		||||
            validator = result.validator
 | 
			
		||||
            message = failure_message_preface.call + ' invalid'
 | 
			
		||||
            message = "#{failure_message_preface.call} invalid"
 | 
			
		||||
 | 
			
		||||
            if validator.type_of_message_matched?
 | 
			
		||||
              if validator.has_messages?
 | 
			
		||||
                message << ' and to'
 | 
			
		||||
 | 
			
		||||
                if validator.captured_validation_exception?
 | 
			
		||||
                if validator.captured_validation_exception? # rubocop:disable Metrics/BlockNesting
 | 
			
		||||
                  message << ' raise a validation exception with message'
 | 
			
		||||
                else
 | 
			
		||||
                  message << ' produce'
 | 
			
		||||
 | 
			
		||||
                  message << if expected_message.is_a?(Regexp)
 | 
			
		||||
                               ' a'
 | 
			
		||||
                             else
 | 
			
		||||
                               ' the'
 | 
			
		||||
                             end
 | 
			
		||||
                  message <<
 | 
			
		||||
                    if expected_message.is_a?(Regexp) # rubocop:disable Metrics/BlockNesting
 | 
			
		||||
                      ' a'
 | 
			
		||||
                    else
 | 
			
		||||
                      ' the'
 | 
			
		||||
                    end
 | 
			
		||||
 | 
			
		||||
                  message << ' validation error'
 | 
			
		||||
                end
 | 
			
		||||
 | 
			
		||||
                if expected_message.is_a?(Regexp)
 | 
			
		||||
                if expected_message.is_a?(Regexp) # rubocop:disable Metrics/BlockNesting
 | 
			
		||||
                  message << ' matching '
 | 
			
		||||
                  message << Shoulda::Matchers::Util.inspect_value(
 | 
			
		||||
                    expected_message,
 | 
			
		||||
| 
						 | 
				
			
			@ -465,13 +466,13 @@ module Shoulda
 | 
			
		|||
                  message << " #{expected_message.inspect}"
 | 
			
		||||
                end
 | 
			
		||||
 | 
			
		||||
                unless validator.captured_validation_exception?
 | 
			
		||||
                unless validator.captured_validation_exception? # rubocop:disable Metrics/BlockNesting
 | 
			
		||||
                  message << " on :#{attribute_to_check_message_against}"
 | 
			
		||||
                end
 | 
			
		||||
 | 
			
		||||
                message << '. The record was indeed invalid, but'
 | 
			
		||||
 | 
			
		||||
                if validator.captured_validation_exception?
 | 
			
		||||
                if validator.captured_validation_exception? # rubocop:disable Metrics/BlockNesting
 | 
			
		||||
                  message << ' the exception message was '
 | 
			
		||||
                  message << validator.validation_exception_message.inspect
 | 
			
		||||
                  message << ' instead.'
 | 
			
		||||
| 
						 | 
				
			
			@ -492,7 +493,7 @@ module Shoulda
 | 
			
		|||
          end
 | 
			
		||||
 | 
			
		||||
          if include_attribute_changed_value_message?
 | 
			
		||||
            message << "\n\n" + attribute_changed_value_message.call
 | 
			
		||||
            message << "\n\n#{attribute_changed_value_message.call}"
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          Shoulda::Matchers.word_wrap(message)
 | 
			
		||||
| 
						 | 
				
			
			@ -531,7 +532,8 @@ module Shoulda
 | 
			
		|||
 | 
			
		||||
        def run(strategy)
 | 
			
		||||
          attribute_setters_for_values_to_preset.first_failing ||
 | 
			
		||||
            attribute_setters_and_validators_for_values_to_set.public_send(strategy)
 | 
			
		||||
            attribute_setters_and_validators_for_values_to_set.
 | 
			
		||||
              public_send(strategy)
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def failure_message_preface
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -38,13 +38,15 @@ module Shoulda
 | 
			
		|||
      class HaveSecurePasswordMatcher
 | 
			
		||||
        attr_reader :failure_message
 | 
			
		||||
 | 
			
		||||
        CORRECT_PASSWORD = "aBcDe12345".freeze
 | 
			
		||||
        INCORRECT_PASSWORD = "password".freeze
 | 
			
		||||
        CORRECT_PASSWORD = 'aBcDe12345'.freeze
 | 
			
		||||
        INCORRECT_PASSWORD = 'password'.freeze
 | 
			
		||||
 | 
			
		||||
        MESSAGES = {
 | 
			
		||||
          authenticated_incorrect_password: "expected %{subject} to not authenticate an incorrect %{attribute}",
 | 
			
		||||
          did_not_authenticate_correct_password: "expected %{subject} to authenticate the correct %{attribute}",
 | 
			
		||||
          method_not_found: "expected %{subject} to respond to %{methods}"
 | 
			
		||||
          authenticated_incorrect_password: 'expected %{subject} to not'\
 | 
			
		||||
            ' authenticate an incorrect %{attribute}',
 | 
			
		||||
          did_not_authenticate_correct_password: 'expected %{subject} to'\
 | 
			
		||||
            ' authenticate the correct %{attribute}',
 | 
			
		||||
          method_not_found: 'expected %{subject} to respond to %{methods}',
 | 
			
		||||
        }.freeze
 | 
			
		||||
 | 
			
		||||
        def initialize(attribute)
 | 
			
		||||
| 
						 | 
				
			
			@ -60,7 +62,8 @@ module Shoulda
 | 
			
		|||
 | 
			
		||||
          if failure = validate
 | 
			
		||||
            key, params = failure
 | 
			
		||||
            @failure_message = MESSAGES[key] % { subject: subject.class }.merge(params)
 | 
			
		||||
            @failure_message =
 | 
			
		||||
              MESSAGES[key] % { subject: subject.class }.merge(params)
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          failure.nil?
 | 
			
		||||
| 
						 | 
				
			
			@ -71,7 +74,9 @@ module Shoulda
 | 
			
		|||
        attr_reader :subject
 | 
			
		||||
 | 
			
		||||
        def validate
 | 
			
		||||
          missing_methods = expected_methods.reject {|m| subject.respond_to?(m) }
 | 
			
		||||
          missing_methods = expected_methods.reject do |m|
 | 
			
		||||
            subject.respond_to?(m)
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          if missing_methods.present?
 | 
			
		||||
            [:method_not_found, { methods: missing_methods.to_sentence }]
 | 
			
		||||
| 
						 | 
				
			
			@ -80,7 +85,8 @@ module Shoulda
 | 
			
		|||
            subject.send("#{@attribute}_confirmation=", CORRECT_PASSWORD)
 | 
			
		||||
 | 
			
		||||
            if not subject.send(authenticate_method, CORRECT_PASSWORD)
 | 
			
		||||
              [:did_not_authenticate_correct_password, { attribute: @attribute }]
 | 
			
		||||
              [:did_not_authenticate_correct_password,
 | 
			
		||||
               { attribute: @attribute },]
 | 
			
		||||
            elsif subject.send(authenticate_method, INCORRECT_PASSWORD)
 | 
			
		||||
              [:authenticated_incorrect_password, { attribute: @attribute }]
 | 
			
		||||
            end
 | 
			
		||||
| 
						 | 
				
			
			@ -90,7 +96,7 @@ module Shoulda
 | 
			
		|||
        private
 | 
			
		||||
 | 
			
		||||
        def expected_methods
 | 
			
		||||
          @expected_methods ||= %I[
 | 
			
		||||
          @_expected_methods ||= %I[
 | 
			
		||||
            #{authenticate_method}
 | 
			
		||||
            #{@attribute}=
 | 
			
		||||
            #{@attribute}_confirmation=
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,12 +5,30 @@ module Shoulda
 | 
			
		|||
        # @private
 | 
			
		||||
        class ComparisonMatcher < ValidationMatcher
 | 
			
		||||
          ERROR_MESSAGES = {
 | 
			
		||||
            :> => :greater_than,
 | 
			
		||||
            :>= => :greater_than_or_equal_to,
 | 
			
		||||
            :< => :less_than,
 | 
			
		||||
            :<= => :less_than_or_equal_to,
 | 
			
		||||
            :== => :equal_to,
 | 
			
		||||
            :!= => :other_than,
 | 
			
		||||
            :> => {
 | 
			
		||||
              label: :greater_than,
 | 
			
		||||
              assertions: [false, false, true],
 | 
			
		||||
            },
 | 
			
		||||
            :>= => {
 | 
			
		||||
              label: :greater_than_or_equal_to,
 | 
			
		||||
              assertions: [false, true, true],
 | 
			
		||||
            },
 | 
			
		||||
            :< => {
 | 
			
		||||
              label: :less_than,
 | 
			
		||||
              assertions: [true, false, false],
 | 
			
		||||
            },
 | 
			
		||||
            :<= => {
 | 
			
		||||
              label: :less_than_or_equal_to,
 | 
			
		||||
              assertions: [true, true, false],
 | 
			
		||||
            },
 | 
			
		||||
            :== => {
 | 
			
		||||
              label: :equal_to,
 | 
			
		||||
              assertions: [false, true, false],
 | 
			
		||||
            },
 | 
			
		||||
            :!= => {
 | 
			
		||||
              label: :other_than,
 | 
			
		||||
              assertions: [true, false, true],
 | 
			
		||||
            },
 | 
			
		||||
          }.freeze
 | 
			
		||||
 | 
			
		||||
          def initialize(numericality_matcher, value, operator)
 | 
			
		||||
| 
						 | 
				
			
			@ -22,7 +40,7 @@ module Shoulda
 | 
			
		|||
            @numericality_matcher = numericality_matcher
 | 
			
		||||
            @value = value
 | 
			
		||||
            @operator = operator
 | 
			
		||||
            @message = ERROR_MESSAGES[operator]
 | 
			
		||||
            @message = ERROR_MESSAGES[operator][:label]
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          def simple_description
 | 
			
		||||
| 
						 | 
				
			
			@ -77,7 +95,7 @@ module Shoulda
 | 
			
		|||
 | 
			
		||||
          def failing_submatchers
 | 
			
		||||
            submatchers_and_results.
 | 
			
		||||
              reject { |x| x[:matched] }.
 | 
			
		||||
              select { |x| !x[:matched] }.
 | 
			
		||||
              map { |x| x[:matcher] }
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -95,10 +113,9 @@ module Shoulda
 | 
			
		|||
          end
 | 
			
		||||
 | 
			
		||||
          def submatchers_and_results
 | 
			
		||||
            @_submatchers_and_results ||=
 | 
			
		||||
              submatchers.map do |matcher|
 | 
			
		||||
                { matcher: matcher, matched: matcher.matches?(@subject) }
 | 
			
		||||
              end
 | 
			
		||||
            @_submatchers_and_results ||= submatchers.map do |matcher|
 | 
			
		||||
              { matcher: matcher, matched: matcher.matches?(@subject) }
 | 
			
		||||
            end
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          def comparison_combos
 | 
			
		||||
| 
						 | 
				
			
			@ -116,20 +133,7 @@ module Shoulda
 | 
			
		|||
          end
 | 
			
		||||
 | 
			
		||||
          def assertions
 | 
			
		||||
            case @operator
 | 
			
		||||
            when :>
 | 
			
		||||
              [false, false, true]
 | 
			
		||||
            when :>=
 | 
			
		||||
              [false, true, true]
 | 
			
		||||
            when :==
 | 
			
		||||
              [false, true, false]
 | 
			
		||||
            when :<
 | 
			
		||||
              [true, false, false]
 | 
			
		||||
            when :<=
 | 
			
		||||
              [true, true, false]
 | 
			
		||||
            when :!=
 | 
			
		||||
              [true, false, true]
 | 
			
		||||
            end
 | 
			
		||||
            ERROR_MESSAGES[@operator][:assertions]
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          def diffs_to_compare
 | 
			
		||||
| 
						 | 
				
			
			@ -144,14 +148,7 @@ module Shoulda
 | 
			
		|||
          end
 | 
			
		||||
 | 
			
		||||
          def comparison_expectation
 | 
			
		||||
            case @operator
 | 
			
		||||
            when :> then 'greater than'
 | 
			
		||||
            when :>= then 'greater than or equal to'
 | 
			
		||||
            when :== then 'equal to'
 | 
			
		||||
            when :< then 'less than'
 | 
			
		||||
            when :<= then 'less than or equal to'
 | 
			
		||||
            when :!= then 'other than'
 | 
			
		||||
            end
 | 
			
		||||
            ERROR_MESSAGES[@operator][:label].to_s.tr('_', ' ')
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -44,7 +44,7 @@ module Shoulda
 | 
			
		|||
 | 
			
		||||
          attr_reader :attribute
 | 
			
		||||
 | 
			
		||||
          def wrap_disallow_value_matcher(matcher)
 | 
			
		||||
          def wrap_disallow_value_matcher(_matcher)
 | 
			
		||||
            raise NotImplementedError
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,7 +6,7 @@ module Shoulda
 | 
			
		|||
        module IgnoringInterferenceByWriter
 | 
			
		||||
          attr_reader :ignore_interference_by_writer
 | 
			
		||||
 | 
			
		||||
          def initialize(*_args)
 | 
			
		||||
          def initialize(*)
 | 
			
		||||
            @ignore_interference_by_writer = IgnoreInterferenceByWriter.new
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -146,11 +146,12 @@ module Shoulda
 | 
			
		|||
          else
 | 
			
		||||
            description = "validate that :#{@attribute}"
 | 
			
		||||
 | 
			
		||||
            description << if @array.many?
 | 
			
		||||
                             " is neither #{inspected_array}"
 | 
			
		||||
                           else
 | 
			
		||||
                             " is not #{inspected_array}"
 | 
			
		||||
                           end
 | 
			
		||||
            description <<
 | 
			
		||||
              if @array.many?
 | 
			
		||||
                " is neither #{inspected_array}"
 | 
			
		||||
              else
 | 
			
		||||
                " is not #{inspected_array}"
 | 
			
		||||
              end
 | 
			
		||||
 | 
			
		||||
            description
 | 
			
		||||
          end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -354,11 +354,12 @@ EOT
 | 
			
		|||
          else
 | 
			
		||||
            description = "validate that :#{@attribute}"
 | 
			
		||||
 | 
			
		||||
            description << if @array.many?
 | 
			
		||||
                             " is either #{inspected_array}"
 | 
			
		||||
                           else
 | 
			
		||||
                             " is #{inspected_array}"
 | 
			
		||||
                           end
 | 
			
		||||
            description <<
 | 
			
		||||
              if @array.many?
 | 
			
		||||
                " is either #{inspected_array}"
 | 
			
		||||
              else
 | 
			
		||||
                " is #{inspected_array}"
 | 
			
		||||
              end
 | 
			
		||||
 | 
			
		||||
            description
 | 
			
		||||
          end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -332,7 +332,6 @@ module Shoulda
 | 
			
		|||
      # @private
 | 
			
		||||
      class ValidateNumericalityOfMatcher
 | 
			
		||||
        NUMERIC_NAME = 'number'.freeze
 | 
			
		||||
        NON_NUMERIC_VALUE = 'abcd'.freeze
 | 
			
		||||
        DEFAULT_DIFF_TO_COMPARE = 1
 | 
			
		||||
 | 
			
		||||
        include Qualifiers::IgnoringInterferenceByWriter
 | 
			
		||||
| 
						 | 
				
			
			@ -459,7 +458,7 @@ module Shoulda
 | 
			
		|||
          description << Shoulda::Matchers::Util.a_or_an(full_allowed_type)
 | 
			
		||||
 | 
			
		||||
          if comparison_descriptions.present?
 | 
			
		||||
            description << ' ' + comparison_descriptions
 | 
			
		||||
            description << " #{comparison_descriptions}"
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          description
 | 
			
		||||
| 
						 | 
				
			
			@ -479,7 +478,8 @@ module Shoulda
 | 
			
		|||
        def failure_message_when_negated
 | 
			
		||||
          overall_failure_message_when_negated.dup.tap do |message|
 | 
			
		||||
            message << "\n"
 | 
			
		||||
            message << failure_message_for_first_submatcher_that_fails_to_not_match
 | 
			
		||||
            message <<
 | 
			
		||||
              failure_message_for_first_submatcher_that_fails_to_not_match
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -500,14 +500,14 @@ module Shoulda
 | 
			
		|||
 | 
			
		||||
        def overall_failure_message
 | 
			
		||||
          Shoulda::Matchers.word_wrap(
 | 
			
		||||
            "Expected #{model.name} to #{description}, but this could not " +
 | 
			
		||||
            "Expected #{model.name} to #{description}, but this could not "\
 | 
			
		||||
            'be proved.',
 | 
			
		||||
          )
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def overall_failure_message_when_negated
 | 
			
		||||
          Shoulda::Matchers.word_wrap(
 | 
			
		||||
            "Expected #{model.name} not to #{description}, but this could not " +
 | 
			
		||||
            "Expected #{model.name} not to #{description}, but this could not "\
 | 
			
		||||
            'be proved.',
 | 
			
		||||
          )
 | 
			
		||||
        end
 | 
			
		||||
| 
						 | 
				
			
			@ -530,7 +530,7 @@ module Shoulda
 | 
			
		|||
 | 
			
		||||
        def add_disallow_value_matcher
 | 
			
		||||
          disallow_value_matcher = DisallowValueMatcher.
 | 
			
		||||
            new(NON_NUMERIC_VALUE).
 | 
			
		||||
            new(non_numeric_value).
 | 
			
		||||
            for(@attribute).
 | 
			
		||||
            with_message(:not_a_number)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -558,7 +558,10 @@ module Shoulda
 | 
			
		|||
          end
 | 
			
		||||
 | 
			
		||||
          if submatcher.respond_to?(:diff_to_compare)
 | 
			
		||||
            @diff_to_compare = [@diff_to_compare, submatcher.diff_to_compare].max
 | 
			
		||||
            @diff_to_compare = [
 | 
			
		||||
              @diff_to_compare,
 | 
			
		||||
              submatcher.diff_to_compare,
 | 
			
		||||
            ].max
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          @submatchers << submatcher
 | 
			
		||||
| 
						 | 
				
			
			@ -600,15 +603,17 @@ module Shoulda
 | 
			
		|||
        end
 | 
			
		||||
 | 
			
		||||
        def first_submatcher_that_fails_to_match
 | 
			
		||||
          @_first_submatcher_that_fails_to_match ||= @submatchers.detect do |submatcher|
 | 
			
		||||
            !submatcher.matches?(@subject)
 | 
			
		||||
          end
 | 
			
		||||
          @_first_submatcher_that_fails_to_match ||=
 | 
			
		||||
            @submatchers.detect do |submatcher|
 | 
			
		||||
              !submatcher.matches?(@subject)
 | 
			
		||||
            end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def first_submatcher_that_fails_to_not_match
 | 
			
		||||
          @_first_submatcher_that_fails_to_not_match ||= @submatchers.detect do |submatcher|
 | 
			
		||||
            !submatcher.does_not_match?(@subject)
 | 
			
		||||
          end
 | 
			
		||||
          @_first_submatcher_that_fails_to_not_match ||=
 | 
			
		||||
            @submatchers.detect do |submatcher|
 | 
			
		||||
              !submatcher.does_not_match?(@subject)
 | 
			
		||||
            end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def failure_message_for_first_submatcher_that_fails_to_match
 | 
			
		||||
| 
						 | 
				
			
			@ -652,7 +657,11 @@ module Shoulda
 | 
			
		|||
 | 
			
		||||
        def comparison_descriptions
 | 
			
		||||
          description_array = submatcher_comparison_descriptions
 | 
			
		||||
          description_array.empty? ? '' : submatcher_comparison_descriptions.join(' and ')
 | 
			
		||||
          if description_array.empty?
 | 
			
		||||
            ''
 | 
			
		||||
          else
 | 
			
		||||
            submatcher_comparison_descriptions.join(' and ')
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def submatcher_comparison_descriptions
 | 
			
		||||
| 
						 | 
				
			
			@ -667,6 +676,10 @@ module Shoulda
 | 
			
		|||
        def model
 | 
			
		||||
          @subject.class
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def non_numeric_value
 | 
			
		||||
          'abcd'
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -260,11 +260,11 @@ validation for you? Instead of using `validate_presence_of`, try
 | 
			
		|||
 | 
			
		||||
        def reason_for_existing_presence_validation
 | 
			
		||||
          if belongs_to_association_configured_to_be_required?
 | 
			
		||||
            "you've instructed your `belongs_to` association to add a " +
 | 
			
		||||
            "you've instructed your `belongs_to` association to add a "\
 | 
			
		||||
              'presence validation to the attribute'
 | 
			
		||||
          else
 | 
			
		||||
            # assume ::ActiveRecord::Base.belongs_to_required_by_default == true
 | 
			
		||||
            'ActiveRecord is configured to add a presence validation to all ' +
 | 
			
		||||
            'ActiveRecord is configured to add a presence validation to all '\
 | 
			
		||||
              '`belongs_to` associations, and this includes yours'
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -137,14 +137,14 @@ module Shoulda
 | 
			
		|||
 | 
			
		||||
        def overall_failure_message
 | 
			
		||||
          Shoulda::Matchers.word_wrap(
 | 
			
		||||
            "Expected #{model.name} to #{description}, but this could not be " +
 | 
			
		||||
            "Expected #{model.name} to #{description}, but this could not be "\
 | 
			
		||||
            'proved.',
 | 
			
		||||
          )
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def overall_failure_message_when_negated
 | 
			
		||||
          Shoulda::Matchers.word_wrap(
 | 
			
		||||
            "Expected #{model.name} not to #{description}, but this could " +
 | 
			
		||||
            "Expected #{model.name} not to #{description}, but this could "\
 | 
			
		||||
            'not be proved.',
 | 
			
		||||
          )
 | 
			
		||||
        end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,10 +15,8 @@ module Shoulda
 | 
			
		|||
 | 
			
		||||
          def call
 | 
			
		||||
            if description_clauses_for_qualifiers.any?
 | 
			
		||||
              main_description +
 | 
			
		||||
                clause_for_allow_blank_or_nil +
 | 
			
		||||
                ', ' +
 | 
			
		||||
                description_clauses_for_qualifiers.to_sentence
 | 
			
		||||
              "#{main_description}#{clause_for_allow_blank_or_nil},"\
 | 
			
		||||
              " #{description_clauses_for_qualifiers.to_sentence}"
 | 
			
		||||
            else
 | 
			
		||||
              main_description + clause_for_allow_blank_or_nil
 | 
			
		||||
            end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -158,17 +158,20 @@ module Shoulda
 | 
			
		|||
        end
 | 
			
		||||
 | 
			
		||||
        def allow_destroy_correct?
 | 
			
		||||
          failure_message = "#{should_or_should_not(@options[:allow_destroy])} allow destroy"
 | 
			
		||||
          failure_message = "#{should_or_should_not(@options[:allow_destroy])}"\
 | 
			
		||||
            ' allow destroy'
 | 
			
		||||
          verify_option_is_correct(:allow_destroy, failure_message)
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def limit_correct?
 | 
			
		||||
          failure_message = "limit should be #{@options[:limit]}, got #{config[:limit]}"
 | 
			
		||||
          failure_message = "limit should be #{@options[:limit]},"\
 | 
			
		||||
            " got #{config[:limit]}"
 | 
			
		||||
          verify_option_is_correct(:limit, failure_message)
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def update_only_correct?
 | 
			
		||||
          failure_message = "#{should_or_should_not(@options[:update_only])} be update only"
 | 
			
		||||
          failure_message = "#{should_or_should_not(@options[:update_only])}"\
 | 
			
		||||
            ' be update only'
 | 
			
		||||
          verify_option_is_correct(:update_only, failure_message)
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -985,6 +985,13 @@ module Shoulda
 | 
			
		|||
 | 
			
		||||
      # @private
 | 
			
		||||
      class AssociationMatcher
 | 
			
		||||
        MACROS = {
 | 
			
		||||
          'belongs_to' => 'belong to',
 | 
			
		||||
          'has_many' => 'have many',
 | 
			
		||||
          'has_one' => 'have one',
 | 
			
		||||
          'has_and_belongs_to_many' => 'have and belong to many',
 | 
			
		||||
        }.freeze
 | 
			
		||||
 | 
			
		||||
        delegate :reflection, :model_class, :associated_class, :through?,
 | 
			
		||||
          :polymorphic?, to: :reflector
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1128,7 +1135,9 @@ module Shoulda
 | 
			
		|||
 | 
			
		||||
        def description
 | 
			
		||||
          description = "#{macro_description} #{name}"
 | 
			
		||||
          description += " class_name => #{options[:class_name]}" if options.key?(:class_name)
 | 
			
		||||
          if options.key?(:class_name)
 | 
			
		||||
            description += " class_name => #{options[:class_name]}"
 | 
			
		||||
          end
 | 
			
		||||
          [description, submatchers.map(&:description)].flatten.join(' ')
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1163,7 +1172,8 @@ module Shoulda
 | 
			
		|||
        end
 | 
			
		||||
 | 
			
		||||
        def option_verifier
 | 
			
		||||
          @_option_verifier ||= AssociationMatchers::OptionVerifier.new(reflector)
 | 
			
		||||
          @_option_verifier ||=
 | 
			
		||||
            AssociationMatchers::OptionVerifier.new(reflector)
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        protected
 | 
			
		||||
| 
						 | 
				
			
			@ -1186,16 +1196,7 @@ module Shoulda
 | 
			
		|||
        end
 | 
			
		||||
 | 
			
		||||
        def macro_description
 | 
			
		||||
          case macro.to_s
 | 
			
		||||
          when 'belongs_to'
 | 
			
		||||
            'belong to'
 | 
			
		||||
          when 'has_many'
 | 
			
		||||
            'have many'
 | 
			
		||||
          when 'has_one'
 | 
			
		||||
            'have one'
 | 
			
		||||
          when 'has_and_belongs_to_many'
 | 
			
		||||
            'have and belong to many'
 | 
			
		||||
          end
 | 
			
		||||
          MACROS[macro.to_s]
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def expectation
 | 
			
		||||
| 
						 | 
				
			
			@ -1215,12 +1216,14 @@ module Shoulda
 | 
			
		|||
        end
 | 
			
		||||
 | 
			
		||||
        def failing_submatchers
 | 
			
		||||
          @_failing_submatchers ||= submatchers.reject { |matcher| matcher.matches?(subject) }
 | 
			
		||||
          @_failing_submatchers ||= submatchers.reject do |matcher|
 | 
			
		||||
            matcher.matches?(subject)
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def missing_options_for_failing_submatchers
 | 
			
		||||
          if defined?(@failing_submatchers)
 | 
			
		||||
            @failing_submatchers.map(&:missing_option)
 | 
			
		||||
          if defined?(@_failing_submatchers)
 | 
			
		||||
            @_failing_submatchers.map(&:missing_option)
 | 
			
		||||
          else
 | 
			
		||||
            []
 | 
			
		||||
          end
 | 
			
		||||
| 
						 | 
				
			
			@ -1280,10 +1283,14 @@ module Shoulda
 | 
			
		|||
 | 
			
		||||
        def class_name_correct?
 | 
			
		||||
          if options.key?(:class_name)
 | 
			
		||||
            if option_verifier.correct_for_constant?(:class_name, options[:class_name])
 | 
			
		||||
            if option_verifier.correct_for_constant?(
 | 
			
		||||
              :class_name,
 | 
			
		||||
              options[:class_name],
 | 
			
		||||
            )
 | 
			
		||||
              true
 | 
			
		||||
            else
 | 
			
		||||
              @missing = "#{name} should resolve to #{options[:class_name]} for class_name"
 | 
			
		||||
              @missing = "#{name} should resolve to #{options[:class_name]}"\
 | 
			
		||||
                ' for class_name'
 | 
			
		||||
              false
 | 
			
		||||
            end
 | 
			
		||||
          else
 | 
			
		||||
| 
						 | 
				
			
			@ -1292,7 +1299,10 @@ module Shoulda
 | 
			
		|||
        end
 | 
			
		||||
 | 
			
		||||
        def join_table_correct?
 | 
			
		||||
          if macro != :has_and_belongs_to_many || join_table_matcher.matches?(@subject)
 | 
			
		||||
          if (
 | 
			
		||||
            macro != :has_and_belongs_to_many ||
 | 
			
		||||
            join_table_matcher.matches?(@subject)
 | 
			
		||||
          )
 | 
			
		||||
            true
 | 
			
		||||
          else
 | 
			
		||||
            @missing = join_table_matcher.failure_message
 | 
			
		||||
| 
						 | 
				
			
			@ -1301,7 +1311,10 @@ module Shoulda
 | 
			
		|||
        end
 | 
			
		||||
 | 
			
		||||
        def join_table_matcher
 | 
			
		||||
          @_join_table_matcher ||= AssociationMatchers::JoinTableMatcher.new(self, reflector)
 | 
			
		||||
          @_join_table_matcher ||= AssociationMatchers::JoinTableMatcher.new(
 | 
			
		||||
            self,
 | 
			
		||||
            reflector,
 | 
			
		||||
          )
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def class_exists?
 | 
			
		||||
| 
						 | 
				
			
			@ -1314,10 +1327,14 @@ module Shoulda
 | 
			
		|||
 | 
			
		||||
        def autosave_correct?
 | 
			
		||||
          if options.key?(:autosave)
 | 
			
		||||
            if option_verifier.correct_for_boolean?(:autosave, options[:autosave])
 | 
			
		||||
            if option_verifier.correct_for_boolean?(
 | 
			
		||||
              :autosave,
 | 
			
		||||
              options[:autosave],
 | 
			
		||||
            )
 | 
			
		||||
              true
 | 
			
		||||
            else
 | 
			
		||||
              @missing = "#{name} should have autosave set to #{options[:autosave]}"
 | 
			
		||||
              @missing = "#{name} should have autosave set to"\
 | 
			
		||||
                " #{options[:autosave]}"
 | 
			
		||||
              false
 | 
			
		||||
            end
 | 
			
		||||
          else
 | 
			
		||||
| 
						 | 
				
			
			@ -1343,10 +1360,14 @@ module Shoulda
 | 
			
		|||
 | 
			
		||||
        def conditions_correct?
 | 
			
		||||
          if options.key?(:conditions)
 | 
			
		||||
            if option_verifier.correct_for_relation_clause?(:conditions, options[:conditions])
 | 
			
		||||
            if option_verifier.correct_for_relation_clause?(
 | 
			
		||||
              :conditions,
 | 
			
		||||
              options[:conditions],
 | 
			
		||||
            )
 | 
			
		||||
              true
 | 
			
		||||
            else
 | 
			
		||||
              @missing = "#{name} should have the following conditions: #{options[:conditions]}"
 | 
			
		||||
              @missing = "#{name} should have the following conditions:" +
 | 
			
		||||
                         " #{options[:conditions]}"
 | 
			
		||||
              false
 | 
			
		||||
            end
 | 
			
		||||
          else
 | 
			
		||||
| 
						 | 
				
			
			@ -1374,7 +1395,10 @@ module Shoulda
 | 
			
		|||
 | 
			
		||||
        def class_has_foreign_key?(klass)
 | 
			
		||||
          if options.key?(:foreign_key)
 | 
			
		||||
            option_verifier.correct_for_string?(:foreign_key, options[:foreign_key])
 | 
			
		||||
            option_verifier.correct_for_string?(
 | 
			
		||||
              :foreign_key,
 | 
			
		||||
              options[:foreign_key],
 | 
			
		||||
            )
 | 
			
		||||
          elsif column_names_for(klass).include?(foreign_key)
 | 
			
		||||
            true
 | 
			
		||||
          else
 | 
			
		||||
| 
						 | 
				
			
			@ -1385,10 +1409,14 @@ module Shoulda
 | 
			
		|||
 | 
			
		||||
        def primary_key_correct?(klass)
 | 
			
		||||
          if options.key?(:primary_key)
 | 
			
		||||
            if option_verifier.correct_for_string?(:primary_key, options[:primary_key])
 | 
			
		||||
            if option_verifier.correct_for_string?(
 | 
			
		||||
              :primary_key,
 | 
			
		||||
              options[:primary_key],
 | 
			
		||||
            )
 | 
			
		||||
              true
 | 
			
		||||
            else
 | 
			
		||||
              @missing = "#{klass} does not have a #{options[:primary_key]} primary key"
 | 
			
		||||
              @missing = "#{klass} does not have a #{options[:primary_key]}"\
 | 
			
		||||
                ' primary key'
 | 
			
		||||
              false
 | 
			
		||||
            end
 | 
			
		||||
          else
 | 
			
		||||
| 
						 | 
				
			
			@ -1407,9 +1435,14 @@ module Shoulda
 | 
			
		|||
        end
 | 
			
		||||
 | 
			
		||||
        def foreign_key_reflection
 | 
			
		||||
          if [:has_one, :has_many].include?(macro) && reflection.options.include?(:inverse_of) && \
 | 
			
		||||
             reflection.options[:inverse_of] != false
 | 
			
		||||
            associated_class.reflect_on_association(reflection.options[:inverse_of])
 | 
			
		||||
          if (
 | 
			
		||||
            [:has_one, :has_many].include?(macro) &&
 | 
			
		||||
            reflection.options.include?(:inverse_of) &&
 | 
			
		||||
            reflection.options[:inverse_of] != false
 | 
			
		||||
          )
 | 
			
		||||
            associated_class.reflect_on_association(
 | 
			
		||||
              reflection.options[:inverse_of],
 | 
			
		||||
            )
 | 
			
		||||
          else
 | 
			
		||||
            reflection
 | 
			
		||||
          end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,7 +19,10 @@ module Shoulda
 | 
			
		|||
          def matches?(subject)
 | 
			
		||||
            self.subject = ModelReflector.new(subject, name)
 | 
			
		||||
 | 
			
		||||
            if option_verifier.correct_for_string?(:counter_cache, counter_cache)
 | 
			
		||||
            if option_verifier.correct_for_string?(
 | 
			
		||||
              :counter_cache,
 | 
			
		||||
              counter_cache,
 | 
			
		||||
            )
 | 
			
		||||
              true
 | 
			
		||||
            else
 | 
			
		||||
              self.missing_option = "#{name} should have #{description}"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,10 +26,14 @@ module Shoulda
 | 
			
		|||
 | 
			
		||||
          def join_table_option_correct?
 | 
			
		||||
            if options.key?(:join_table_name)
 | 
			
		||||
              if option_verifier.correct_for_string?(:join_table, options[:join_table_name])
 | 
			
		||||
              if option_verifier.correct_for_string?(
 | 
			
		||||
                :join_table,
 | 
			
		||||
                options[:join_table_name],
 | 
			
		||||
              )
 | 
			
		||||
                true
 | 
			
		||||
              else
 | 
			
		||||
                @failure_message = "#{name} should use #{options[:join_table_name].inspect} for :join_table option"
 | 
			
		||||
                @failure_message = "#{name} should use"\
 | 
			
		||||
                  " #{options[:join_table_name].inspect} for :join_table option"
 | 
			
		||||
                false
 | 
			
		||||
              end
 | 
			
		||||
            else
 | 
			
		||||
| 
						 | 
				
			
			@ -38,7 +42,8 @@ module Shoulda
 | 
			
		|||
          end
 | 
			
		||||
 | 
			
		||||
          def join_table_exists?
 | 
			
		||||
            if RailsShim.tables_and_views(connection).include?(join_table_name.to_s)
 | 
			
		||||
            if RailsShim.tables_and_views(connection).
 | 
			
		||||
                include?(join_table_name.to_s)
 | 
			
		||||
              true
 | 
			
		||||
            else
 | 
			
		||||
              @failure_message = missing_table_message
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,7 +25,8 @@ module Shoulda
 | 
			
		|||
          end
 | 
			
		||||
 | 
			
		||||
          def join_table_name
 | 
			
		||||
            join_table_name = has_and_belongs_to_many_name_table_name || reflection.join_table
 | 
			
		||||
            join_table_name =
 | 
			
		||||
              has_and_belongs_to_many_name_table_name || reflection.join_table
 | 
			
		||||
            join_table_name.to_s
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -48,9 +48,12 @@ module Shoulda
 | 
			
		|||
 | 
			
		||||
          def build_relation_with_clause(name, value)
 | 
			
		||||
            case name
 | 
			
		||||
            when :conditions then associated_class.where(value)
 | 
			
		||||
            when :order      then associated_class.order(value)
 | 
			
		||||
            else                  raise ArgumentError, "Unknown clause '#{name}'"
 | 
			
		||||
            when :conditions
 | 
			
		||||
              associated_class.where(value)
 | 
			
		||||
            when :order
 | 
			
		||||
              associated_class.order(value)
 | 
			
		||||
            else
 | 
			
		||||
              raise ArgumentError, "Unknown clause '#{name}'"
 | 
			
		||||
            end
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -59,7 +62,9 @@ module Shoulda
 | 
			
		|||
            when :conditions
 | 
			
		||||
              relation.where_values_hash
 | 
			
		||||
            when :order
 | 
			
		||||
              relation.order_values.map { |value| value_as_sql(value) }.join(', ')
 | 
			
		||||
              relation.order_values.map do |value|
 | 
			
		||||
                value_as_sql(value)
 | 
			
		||||
              end.join(', ')
 | 
			
		||||
            else
 | 
			
		||||
              raise ArgumentError, "Unknown clause '#{name}'"
 | 
			
		||||
            end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -107,7 +107,10 @@ module Shoulda
 | 
			
		|||
          end
 | 
			
		||||
 | 
			
		||||
          def actual_value_for_relation_clause(name)
 | 
			
		||||
            reflector.extract_relation_clause_from(reflector.association_relation, name)
 | 
			
		||||
            reflector.extract_relation_clause_from(
 | 
			
		||||
              reflector.association_relation,
 | 
			
		||||
              name,
 | 
			
		||||
            )
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          def actual_value_for_class_name
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,9 +32,9 @@ module Shoulda
 | 
			
		|||
                end
 | 
			
		||||
 | 
			
		||||
              missing_option << (
 | 
			
		||||
                'fail validation if ' +
 | 
			
		||||
                ":#{attribute_name} is unset; i.e., either the association " +
 | 
			
		||||
                'should have been defined with `optional: ' +
 | 
			
		||||
                'fail validation if '\
 | 
			
		||||
                ":#{attribute_name} is unset; i.e., either the association "\
 | 
			
		||||
                'should have been defined with `optional: '\
 | 
			
		||||
                "#{optional.inspect}`, or there "
 | 
			
		||||
              )
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -33,9 +33,9 @@ module Shoulda
 | 
			
		|||
                end
 | 
			
		||||
 | 
			
		||||
              missing_option << (
 | 
			
		||||
                'fail validation if ' +
 | 
			
		||||
                ":#{attribute_name} is unset; i.e., either the association " +
 | 
			
		||||
                'should have been defined with `required: ' +
 | 
			
		||||
                'fail validation if '\
 | 
			
		||||
                ":#{attribute_name} is unset; i.e., either the association "\
 | 
			
		||||
                'should have been defined with `required: '\
 | 
			
		||||
                "#{required.inspect}`, or there "
 | 
			
		||||
              )
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,7 +22,8 @@ module Shoulda
 | 
			
		|||
            if option_verifier.correct_for_string?(:source, source)
 | 
			
		||||
              true
 | 
			
		||||
            else
 | 
			
		||||
              self.missing_option = "#{name} should have #{source} as source option"
 | 
			
		||||
              self.missing_option =
 | 
			
		||||
                "#{name} should have #{source} as source option"
 | 
			
		||||
              false
 | 
			
		||||
            end
 | 
			
		||||
          end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,7 +29,8 @@ module Shoulda
 | 
			
		|||
            if through_reflection.present?
 | 
			
		||||
              true
 | 
			
		||||
            else
 | 
			
		||||
              self.missing_option = "#{name} does not have any relationship to #{through}"
 | 
			
		||||
              self.missing_option =
 | 
			
		||||
                "#{name} does not have any relationship to #{through}"
 | 
			
		||||
              false
 | 
			
		||||
            end
 | 
			
		||||
          end
 | 
			
		||||
| 
						 | 
				
			
			@ -43,8 +44,9 @@ module Shoulda
 | 
			
		|||
              true
 | 
			
		||||
            else
 | 
			
		||||
              self.missing_option =
 | 
			
		||||
                "Expected #{name} to have #{name} through #{through}, " +
 | 
			
		||||
                "but got it through #{option_verifier.actual_value_for(:through)}"
 | 
			
		||||
                "Expected #{name} to have #{name} through #{through}, "\
 | 
			
		||||
                'but got it through ' +
 | 
			
		||||
                option_verifier.actual_value_for(:through).to_s
 | 
			
		||||
              false
 | 
			
		||||
            end
 | 
			
		||||
          end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -237,7 +237,7 @@ module Shoulda
 | 
			
		|||
              "Expected #{model} to #{expectation}, but "
 | 
			
		||||
            end
 | 
			
		||||
 | 
			
		||||
          message << failure_message_continuation + '.'
 | 
			
		||||
          message << "#{failure_message_continuation}."
 | 
			
		||||
 | 
			
		||||
          Shoulda::Matchers.word_wrap(message)
 | 
			
		||||
        end
 | 
			
		||||
| 
						 | 
				
			
			@ -252,7 +252,7 @@ module Shoulda
 | 
			
		|||
        attr_reader :attribute_name, :options, :record,
 | 
			
		||||
          :failure_message_continuation
 | 
			
		||||
 | 
			
		||||
        def expectation
 | 
			
		||||
        def expectation # rubocop:disable Metrics/MethodLength
 | 
			
		||||
          if enum_defined?
 | 
			
		||||
            expectation = "#{simple_description} backed by "
 | 
			
		||||
            expectation << Shoulda::Matchers::Util.a_or_an(expected_column_type)
 | 
			
		||||
| 
						 | 
				
			
			@ -358,8 +358,8 @@ module Shoulda
 | 
			
		|||
            true
 | 
			
		||||
          else
 | 
			
		||||
            @failure_message_continuation =
 | 
			
		||||
              "However, #{attribute_name.inspect} is " +
 | 
			
		||||
              Shoulda::Matchers::Util.a_or_an(column.type) +
 | 
			
		||||
              "However, #{attribute_name.inspect} is "\
 | 
			
		||||
              "#{Shoulda::Matchers::Util.a_or_an(column.type)}"\
 | 
			
		||||
              ' column'
 | 
			
		||||
            false
 | 
			
		||||
          end
 | 
			
		||||
| 
						 | 
				
			
			@ -421,9 +421,9 @@ module Shoulda
 | 
			
		|||
        def expected_prefix
 | 
			
		||||
          if options.include?(:prefix)
 | 
			
		||||
            if options[:prefix] == true
 | 
			
		||||
              attribute_name # .to_sym
 | 
			
		||||
              attribute_name
 | 
			
		||||
            else
 | 
			
		||||
              options[:prefix] # .to_sym
 | 
			
		||||
              options[:prefix]
 | 
			
		||||
            end
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
| 
						 | 
				
			
			@ -431,9 +431,9 @@ module Shoulda
 | 
			
		|||
        def expected_suffix
 | 
			
		||||
          if options.include?(:suffix)
 | 
			
		||||
            if options[:suffix] == true
 | 
			
		||||
              attribute_name # .to_sym
 | 
			
		||||
              attribute_name
 | 
			
		||||
            else
 | 
			
		||||
              options[:suffix] # .to_sym
 | 
			
		||||
              options[:suffix]
 | 
			
		||||
            end
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -125,13 +125,17 @@ module Shoulda
 | 
			
		|||
 | 
			
		||||
        def description
 | 
			
		||||
          desc = "have db column named #{@column}"
 | 
			
		||||
          desc << " of type #{@options[:column_type]}"    if @options.key?(:column_type)
 | 
			
		||||
          desc << " of precision #{@options[:precision]}" if @options.key?(:precision)
 | 
			
		||||
          desc << " of limit #{@options[:limit]}"         if @options.key?(:limit)
 | 
			
		||||
          desc << " of default #{@options[:default]}"     if @options.key?(:default)
 | 
			
		||||
          desc << " of null #{@options[:null]}"           if @options.key?(:null)
 | 
			
		||||
          desc << " of primary #{@options[:primary]}"     if @options.key?(:primary)
 | 
			
		||||
          desc << " of scale #{@options[:scale]}"         if @options.key?(:scale)
 | 
			
		||||
          if @options.key?(:column_type)
 | 
			
		||||
            desc << " of type #{@options[:column_type]}"
 | 
			
		||||
          end
 | 
			
		||||
          if @options.key?(:precision)
 | 
			
		||||
            desc << " of precision #{@options[:precision]}"
 | 
			
		||||
          end
 | 
			
		||||
          desc << " of limit #{@options[:limit]}" if @options.key?(:limit)
 | 
			
		||||
          desc << " of default #{@options[:default]}" if @options.key?(:default)
 | 
			
		||||
          desc << " of null #{@options[:null]}" if @options.key?(:null)
 | 
			
		||||
          desc << " of primary #{@options[:primary]}" if @options.key?(:primary)
 | 
			
		||||
          desc << " of scale #{@options[:scale]}" if @options.key?(:scale)
 | 
			
		||||
          desc
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -141,7 +145,8 @@ module Shoulda
 | 
			
		|||
          if model_class.column_names.include?(@column.to_s)
 | 
			
		||||
            true
 | 
			
		||||
          else
 | 
			
		||||
            @missing = "#{model_class} does not have a db column named #{@column}."
 | 
			
		||||
            @missing =
 | 
			
		||||
              "#{model_class} does not have a db column named #{@column}."
 | 
			
		||||
            false
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
| 
						 | 
				
			
			@ -152,8 +157,9 @@ module Shoulda
 | 
			
		|||
          if matched_column.type.to_s == @options[:column_type].to_s
 | 
			
		||||
            true
 | 
			
		||||
          else
 | 
			
		||||
            @missing = "#{model_class} has a db column named #{@column} " <<
 | 
			
		||||
                       "of type #{matched_column.type}, not #{@options[:column_type]}."
 | 
			
		||||
            @missing =
 | 
			
		||||
              "#{model_class} has a db column named #{@column} " <<
 | 
			
		||||
              "of type #{matched_column.type}, not #{@options[:column_type]}."
 | 
			
		||||
            false
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
| 
						 | 
				
			
			@ -229,18 +235,21 @@ module Shoulda
 | 
			
		|||
            true
 | 
			
		||||
          else
 | 
			
		||||
            @missing = "#{model_class} has a db column named #{@column} "
 | 
			
		||||
            @missing << if @options[:primary]
 | 
			
		||||
                          'that is not primary, but should be'
 | 
			
		||||
                        else
 | 
			
		||||
                          'that is primary, but should not be'
 | 
			
		||||
                        end
 | 
			
		||||
            @missing <<
 | 
			
		||||
              if @options[:primary]
 | 
			
		||||
                'that is not primary, but should be'
 | 
			
		||||
              else
 | 
			
		||||
                'that is primary, but should not be'
 | 
			
		||||
              end
 | 
			
		||||
            false
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def matched_column
 | 
			
		||||
          @_matched_column ||= begin
 | 
			
		||||
            column = model_class.columns.detect { |each| each.name == @column.to_s }
 | 
			
		||||
            column = model_class.columns.detect do |each|
 | 
			
		||||
              each.name == @column.to_s
 | 
			
		||||
            end
 | 
			
		||||
            DecoratedColumn.new(model_class, column)
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -156,7 +156,7 @@ module Shoulda
 | 
			
		|||
 | 
			
		||||
          description <<
 | 
			
		||||
            if qualifiers.include?(:unique)
 | 
			
		||||
              Shoulda::Matchers::Util.a_or_an(index_type) + ' '
 | 
			
		||||
              "#{Shoulda::Matchers::Util.a_or_an(index_type)} "
 | 
			
		||||
            else
 | 
			
		||||
              'an '
 | 
			
		||||
            end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,17 +35,19 @@ module Shoulda
 | 
			
		|||
        def matches?(subject)
 | 
			
		||||
          @subject = subject
 | 
			
		||||
          if readonly_attributes.include?(@attribute)
 | 
			
		||||
            @failure_message_when_negated = "Did not expect #{@attribute} to be read-only"
 | 
			
		||||
            @failure_message_when_negated = "Did not expect #{@attribute}"\
 | 
			
		||||
            ' to be read-only'
 | 
			
		||||
            true
 | 
			
		||||
          else
 | 
			
		||||
            @failure_message = if readonly_attributes.empty?
 | 
			
		||||
                                 "#{class_name} attribute #{@attribute} " <<
 | 
			
		||||
                                   'is not read-only'
 | 
			
		||||
                               else
 | 
			
		||||
                                 "#{class_name} is making " <<
 | 
			
		||||
                                   "#{readonly_attributes.to_a.to_sentence} " <<
 | 
			
		||||
                                   "read-only, but not #{@attribute}."
 | 
			
		||||
                               end
 | 
			
		||||
            @failure_message =
 | 
			
		||||
              if readonly_attributes.empty?
 | 
			
		||||
                "#{class_name} attribute #{@attribute} " <<
 | 
			
		||||
                  'is not read-only'
 | 
			
		||||
              else
 | 
			
		||||
                "#{class_name} is making " <<
 | 
			
		||||
                  "#{readonly_attributes.to_a.to_sentence} " <<
 | 
			
		||||
                  "read-only, but not #{@attribute}."
 | 
			
		||||
              end
 | 
			
		||||
            false
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -33,7 +33,8 @@ module Shoulda
 | 
			
		|||
        end
 | 
			
		||||
 | 
			
		||||
        def description
 | 
			
		||||
          "have configured :#{rich_text_attribute} as a ActionText::RichText association"
 | 
			
		||||
          "have configured :#{rich_text_attribute} as a "\
 | 
			
		||||
          'ActionText::RichText association'
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def failure_message
 | 
			
		||||
| 
						 | 
				
			
			@ -41,7 +42,8 @@ module Shoulda
 | 
			
		|||
        end
 | 
			
		||||
 | 
			
		||||
        def failure_message_when_negated
 | 
			
		||||
          "Did not expect #{subject.class} to have ActionText::RichText :#{rich_text_attribute}"
 | 
			
		||||
          "Did not expect #{subject.class} to have ActionText::RichText"\
 | 
			
		||||
          " :#{rich_text_attribute}"
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def matches?(subject)
 | 
			
		||||
| 
						 | 
				
			
			@ -67,7 +69,9 @@ module Shoulda
 | 
			
		|||
        end
 | 
			
		||||
 | 
			
		||||
        def has_expected_action_text?
 | 
			
		||||
          @subject.send(rich_text_attribute).class.name == 'ActionText::RichText'
 | 
			
		||||
          defined?(ActionText::RichText) &&
 | 
			
		||||
            @subject.send(rich_text_attribute).
 | 
			
		||||
              instance_of?(ActionText::RichText)
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def error_description
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -121,7 +121,9 @@ module Shoulda
 | 
			
		|||
 | 
			
		||||
        def description
 | 
			
		||||
          description = "serialize :#{@name}"
 | 
			
		||||
          description += " class_name => #{@options[:type]}" if @options.key?(:type)
 | 
			
		||||
          if @options.key?(:type)
 | 
			
		||||
            description += " class_name => #{@options[:type]}"
 | 
			
		||||
          end
 | 
			
		||||
          description
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -141,7 +143,8 @@ module Shoulda
 | 
			
		|||
            klass = serialization_coder
 | 
			
		||||
            if klass == @options[:type]
 | 
			
		||||
              true
 | 
			
		||||
            elsif klass.respond_to?(:object_class) && klass.object_class == @options[:type]
 | 
			
		||||
            elsif klass.respond_to?(:object_class) &&
 | 
			
		||||
                  klass.object_class == @options[:type]
 | 
			
		||||
              true
 | 
			
		||||
            else
 | 
			
		||||
              @missing = ":#{@name} should be a type of #{@options[:type]}"
 | 
			
		||||
| 
						 | 
				
			
			@ -174,9 +177,12 @@ module Shoulda
 | 
			
		|||
        end
 | 
			
		||||
 | 
			
		||||
        def expectation
 | 
			
		||||
          expectation = "#{model_class.name} to serialize the attribute called :#{@name}"
 | 
			
		||||
          expectation = "#{model_class.name} to serialize the attribute called"\
 | 
			
		||||
            " :#{@name}"
 | 
			
		||||
          expectation += " with a type of #{@options[:type]}" if @options[:type]
 | 
			
		||||
          expectation += " with an instance of #{@options[:instance_type]}" if @options[:instance_type]
 | 
			
		||||
          if @options[:instance_type]
 | 
			
		||||
            expectation += " with an instance of #{@options[:instance_type]}"
 | 
			
		||||
          end
 | 
			
		||||
          expectation
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -413,11 +413,12 @@ module Shoulda
 | 
			
		|||
          else
 | 
			
		||||
            @failure_reason = 'Expected the validation '
 | 
			
		||||
 | 
			
		||||
            @failure_reason << if expected_scopes.empty?
 | 
			
		||||
                                 'not to be scoped to anything, '
 | 
			
		||||
                               else
 | 
			
		||||
                                 "to be scoped to #{inspected_expected_scopes}, "
 | 
			
		||||
                               end
 | 
			
		||||
            @failure_reason <<
 | 
			
		||||
              if expected_scopes.empty?
 | 
			
		||||
                'not to be scoped to anything, '
 | 
			
		||||
              else
 | 
			
		||||
                "to be scoped to #{inspected_expected_scopes}, "
 | 
			
		||||
              end
 | 
			
		||||
 | 
			
		||||
            if actual_sets_of_scopes.any?
 | 
			
		||||
              @failure_reason << 'but it was scoped to '
 | 
			
		||||
| 
						 | 
				
			
			@ -497,7 +498,9 @@ module Shoulda
 | 
			
		|||
        def does_not_match_allow_nil?
 | 
			
		||||
          expects_to_allow_nil? && (
 | 
			
		||||
            update_existing_record!(nil) &&
 | 
			
		||||
            (@failure_reason = nil || disallows_value_of(nil, @expected_message))
 | 
			
		||||
            (@failure_reason = nil ||
 | 
			
		||||
              disallows_value_of(nil, @expected_message)
 | 
			
		||||
            )
 | 
			
		||||
          )
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -533,8 +536,7 @@ module Shoulda
 | 
			
		|||
        end
 | 
			
		||||
 | 
			
		||||
        def find_existing_record
 | 
			
		||||
          record = model.first
 | 
			
		||||
          record.presence
 | 
			
		||||
          model.first.presence
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def create_existing_record
 | 
			
		||||
| 
						 | 
				
			
			@ -620,11 +622,12 @@ module Shoulda
 | 
			
		|||
 | 
			
		||||
            reason << inspected_scopes.to_sentence
 | 
			
		||||
 | 
			
		||||
            reason << if inspected_scopes.many?
 | 
			
		||||
                        ' do not seem to be attributes'
 | 
			
		||||
                      else
 | 
			
		||||
                        ' does not seem to be an attribute'
 | 
			
		||||
                      end
 | 
			
		||||
            reason <<
 | 
			
		||||
              if inspected_scopes.many?
 | 
			
		||||
                ' do not seem to be attributes'
 | 
			
		||||
              else
 | 
			
		||||
                ' does not seem to be an attribute'
 | 
			
		||||
              end
 | 
			
		||||
 | 
			
		||||
            reason << " on #{model.name}."
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -644,11 +647,12 @@ module Shoulda
 | 
			
		|||
 | 
			
		||||
            reason << inspected_scopes.to_sentence
 | 
			
		||||
 | 
			
		||||
            reason << if inspected_scopes.many?
 | 
			
		||||
                        ' seem to be attributes'
 | 
			
		||||
                      else
 | 
			
		||||
                        ' seems to be an attribute'
 | 
			
		||||
                      end
 | 
			
		||||
            reason <<
 | 
			
		||||
              if inspected_scopes.many?
 | 
			
		||||
                ' seem to be attributes'
 | 
			
		||||
              else
 | 
			
		||||
                ' seems to be an attribute'
 | 
			
		||||
              end
 | 
			
		||||
 | 
			
		||||
            reason << " on #{model.name}."
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -897,13 +901,14 @@ module Shoulda
 | 
			
		|||
        end
 | 
			
		||||
 | 
			
		||||
        def build_attribute_setter(record, attribute_name, value)
 | 
			
		||||
          Shoulda::Matchers::ActiveModel::AllowValueMatcher::AttributeSetter.new(
 | 
			
		||||
            matcher_name: :validate_uniqueness_of,
 | 
			
		||||
            object: record,
 | 
			
		||||
            attribute_name: attribute_name,
 | 
			
		||||
            value: value,
 | 
			
		||||
            ignore_interference_by_writer: ignore_interference_by_writer,
 | 
			
		||||
          )
 | 
			
		||||
          Shoulda::Matchers::ActiveModel::AllowValueMatcher::AttributeSetter.
 | 
			
		||||
            new(
 | 
			
		||||
              matcher_name: :validate_uniqueness_of,
 | 
			
		||||
              object: record,
 | 
			
		||||
              attribute_name: attribute_name,
 | 
			
		||||
              value: value,
 | 
			
		||||
              ignore_interference_by_writer: ignore_interference_by_writer,
 | 
			
		||||
            )
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def existing_value_read
 | 
			
		||||
| 
						 | 
				
			
			@ -930,7 +935,7 @@ module Shoulda
 | 
			
		|||
          @given_record.class
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def failure_message_preface
 | 
			
		||||
        def failure_message_preface # rubocop:disable Metrics/MethodLength
 | 
			
		||||
          prefix = ''
 | 
			
		||||
 | 
			
		||||
          if @existing_record_created
 | 
			
		||||
| 
						 | 
				
			
			@ -987,7 +992,10 @@ different altogether.
 | 
			
		|||
          MESSAGE
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def description_for_attribute_setter(attribute_setter, same_as_existing: nil)
 | 
			
		||||
        def description_for_attribute_setter(
 | 
			
		||||
          attribute_setter,
 | 
			
		||||
          same_as_existing: nil
 | 
			
		||||
        )
 | 
			
		||||
          description = "its :#{attribute_setter.attribute_name} to "
 | 
			
		||||
 | 
			
		||||
          if same_as_existing == false
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,7 +21,7 @@ module Shoulda
 | 
			
		|||
 | 
			
		||||
        def debug(&block)
 | 
			
		||||
          if debugging_enabled?
 | 
			
		||||
            Logger.new(STDOUT).debug block.call
 | 
			
		||||
            puts block.call # rubocop:disable Rails/Output
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,25 +4,26 @@ module Shoulda
 | 
			
		|||
      # @private
 | 
			
		||||
      module DoubleImplementationRegistry
 | 
			
		||||
        class << self
 | 
			
		||||
          # rubocop:disable Style/MutableConstant
 | 
			
		||||
          REGISTRY = {}
 | 
			
		||||
          # rubocop:enable Style/MutableConstant
 | 
			
		||||
 | 
			
		||||
          def find(type)
 | 
			
		||||
            find_class!(type).create
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          def register(klass, type)
 | 
			
		||||
            REGISTRY[type] = klass
 | 
			
		||||
            registry[type] = klass
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          private
 | 
			
		||||
 | 
			
		||||
          def find_class!(type)
 | 
			
		||||
            REGISTRY.fetch(type) do
 | 
			
		||||
              raise ArgumentError, "No double implementation class found for '#{type}'"
 | 
			
		||||
            registry.fetch(type) do
 | 
			
		||||
              raise ArgumentError, 'No double implementation class found for'\
 | 
			
		||||
                " '#{type}'"
 | 
			
		||||
            end
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          def registry
 | 
			
		||||
            @_registry ||= {}
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -399,7 +399,8 @@ module Shoulda
 | 
			
		|||
              rescue Module::DelegationError
 | 
			
		||||
                false
 | 
			
		||||
              rescue NoMethodError => e
 | 
			
		||||
                if e.message =~ /undefined method `#{delegate_method}' for nil:NilClass/
 | 
			
		||||
                if e.message =~
 | 
			
		||||
                   /undefined method `#{delegate_method}' for nil:NilClass/
 | 
			
		||||
                  false
 | 
			
		||||
                else
 | 
			
		||||
                  raise e
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,8 +13,9 @@ module Shoulda
 | 
			
		|||
            test_framework.include(matchers_module, type: :controller)
 | 
			
		||||
 | 
			
		||||
            include_into(::ActionController::TestCase, matchers_module) do
 | 
			
		||||
              subject = -> { @controller }
 | 
			
		||||
              subject.call
 | 
			
		||||
              def subject # rubocop:disable Lint/NestedMethodDefinition
 | 
			
		||||
                @controller
 | 
			
		||||
              end
 | 
			
		||||
            end
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,7 +6,8 @@ module Shoulda
 | 
			
		|||
        class MissingLibrary
 | 
			
		||||
          Integrations.register_library(self, :missing_library)
 | 
			
		||||
 | 
			
		||||
          def integrate_with(test_framework); end
 | 
			
		||||
          def integrate_with(test_framework)
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          def rails?
 | 
			
		||||
            false
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,7 +6,8 @@ module Shoulda
 | 
			
		|||
        class ActiveSupportTestCase
 | 
			
		||||
          Integrations.register_test_framework(self, :active_support_test_case)
 | 
			
		||||
 | 
			
		||||
          def validate!; end
 | 
			
		||||
          def validate!
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          def include(*modules, **_options)
 | 
			
		||||
            test_case_class.include(*modules)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,7 +6,8 @@ module Shoulda
 | 
			
		|||
        class Minitest4
 | 
			
		||||
          Integrations.register_test_framework(self, :minitest_4)
 | 
			
		||||
 | 
			
		||||
          def validate!; end
 | 
			
		||||
          def validate!
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          def include(*modules, **_options)
 | 
			
		||||
            test_case_class.class_eval do
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,7 +7,8 @@ module Shoulda
 | 
			
		|||
          Integrations.register_test_framework(self, :minitest_5)
 | 
			
		||||
          Integrations.register_test_framework(self, :minitest)
 | 
			
		||||
 | 
			
		||||
          def validate!; end
 | 
			
		||||
          def validate!
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          def include(*modules, **_options)
 | 
			
		||||
            test_case_class.class_eval do
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,7 +23,8 @@ end
 | 
			
		|||
            EOT
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          def include(*modules, **options); end
 | 
			
		||||
          def include(*modules, **options)
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          def n_unit?
 | 
			
		||||
            false
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,7 +6,8 @@ module Shoulda
 | 
			
		|||
        class Rspec
 | 
			
		||||
          Integrations.register_test_framework(self, :rspec)
 | 
			
		||||
 | 
			
		||||
          def validate!; end
 | 
			
		||||
          def validate!
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          def include(*modules, **options)
 | 
			
		||||
            ::RSpec.configure do |config|
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,7 +6,8 @@ module Shoulda
 | 
			
		|||
        class TestUnit
 | 
			
		||||
          Integrations.register_test_framework(self, :test_unit)
 | 
			
		||||
 | 
			
		||||
          def validate!; end
 | 
			
		||||
          def validate!
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          def include(*modules, **_options)
 | 
			
		||||
            test_case_class.class_eval do
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -180,10 +180,12 @@ module Shoulda
 | 
			
		|||
          options
 | 
			
		||||
        )
 | 
			
		||||
          default_translation_keys = [
 | 
			
		||||
            :"activemodel.errors.models.#{model_name}.attributes.#{attribute}.#{type}",
 | 
			
		||||
            :"activemodel.errors.models.#{model_name}.attributes.#{attribute}
 | 
			
		||||
              .#{type}",
 | 
			
		||||
            :"activemodel.errors.models.#{model_name}.#{type}",
 | 
			
		||||
            :"activemodel.errors.messages.#{type}",
 | 
			
		||||
            :"activerecord.errors.models.#{model_name}.attributes.#{attribute}.#{type}",
 | 
			
		||||
            :"activerecord.errors.models.#{model_name}.attributes.#{attribute}
 | 
			
		||||
              .#{type}",
 | 
			
		||||
            :"activerecord.errors.models.#{model_name}.#{type}",
 | 
			
		||||
            :"activerecord.errors.messages.#{type}",
 | 
			
		||||
            :"errors.attributes.#{attribute}.#{type}",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,8 +7,10 @@ module Shoulda
 | 
			
		|||
      MAXIMUM_LENGTH_OF_VALUE_TO_DISPLAY = 500
 | 
			
		||||
 | 
			
		||||
      def self.deconstantize(path)
 | 
			
		||||
        if defined?(ActiveSupport::Inflector) &&
 | 
			
		||||
           ActiveSupport::Inflector.respond_to?(:deconstantize)
 | 
			
		||||
        if (
 | 
			
		||||
          defined?(ActiveSupport::Inflector) &&
 | 
			
		||||
          ActiveSupport::Inflector.respond_to?(:deconstantize)
 | 
			
		||||
        )
 | 
			
		||||
          ActiveSupport::Inflector.deconstantize(path)
 | 
			
		||||
        else
 | 
			
		||||
          path.to_s[0...(path.to_s.rindex('::') || 0)]
 | 
			
		||||
| 
						 | 
				
			
			@ -16,8 +18,10 @@ module Shoulda
 | 
			
		|||
      end
 | 
			
		||||
 | 
			
		||||
      def self.safe_constantize(camel_cased_word)
 | 
			
		||||
        if defined?(ActiveSupport::Inflector) &&
 | 
			
		||||
           ActiveSupport::Inflector.respond_to?(:safe_constantize)
 | 
			
		||||
        if (
 | 
			
		||||
          defined?(ActiveSupport::Inflector) &&
 | 
			
		||||
          ActiveSupport::Inflector.respond_to?(:safe_constantize)
 | 
			
		||||
        )
 | 
			
		||||
          ActiveSupport::Inflector.safe_constantize(camel_cased_word)
 | 
			
		||||
        else
 | 
			
		||||
          begin
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -44,7 +44,7 @@ module Shoulda
 | 
			
		|||
      LIST_ITEM_REGEXP = /\A((?:[a-z0-9]+(?:\)|\.)|\*) )/.freeze
 | 
			
		||||
 | 
			
		||||
      def indented?
 | 
			
		||||
        self =~ /\A[ ]+/
 | 
			
		||||
        self =~ /\A +/
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def list_item?
 | 
			
		||||
| 
						 | 
				
			
			@ -92,7 +92,7 @@ module Shoulda
 | 
			
		|||
          if line.list_item?
 | 
			
		||||
            combined_lines << line
 | 
			
		||||
          else
 | 
			
		||||
            combined_lines.last << (' ' + line).squeeze(' ')
 | 
			
		||||
            combined_lines.last << (" #{line}").squeeze(' ')
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          combined_lines
 | 
			
		||||
| 
						 | 
				
			
			@ -169,7 +169,7 @@ module Shoulda
 | 
			
		|||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def wrap_line(line, _direction: :left)
 | 
			
		||||
      def wrap_line(line)
 | 
			
		||||
        index = nil
 | 
			
		||||
 | 
			
		||||
        if line.length > Shoulda::Matchers::WordWrap::TERMINAL_WIDTH
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,10 +18,13 @@ Gem::Specification.new do |s|
 | 
			
		|||
  s.homepage    = 'https://matchers.shoulda.io/'
 | 
			
		||||
  s.summary     = 'Simple one-liner tests for common Rails functionality'
 | 
			
		||||
  s.license     = 'MIT'
 | 
			
		||||
  s.description = 'Shoulda Matchers provides RSpec- and Minitest-compatible one-liners to test
 | 
			
		||||
                   common Rails functionality that, if written by hand, would be much longer, more complex,
 | 
			
		||||
                   and error-prone.'
 | 
			
		||||
  s.metadata    = {
 | 
			
		||||
  s.description = <<~DESC.tr("\n", ' ').squeeze(' ')
 | 
			
		||||
    Shoulda Matchers provides RSpec- and Minitest-compatible one-liners to test
 | 
			
		||||
    common Rails functionality that, if written by hand, would be much
 | 
			
		||||
    longer, more complex, and error-prone.
 | 
			
		||||
  DESC
 | 
			
		||||
 | 
			
		||||
  s.metadata = {
 | 
			
		||||
    'bug_tracker_uri' => 'https://github.com/thoughtbot/shoulda-matchers/issues',
 | 
			
		||||
    'changelog_uri' => 'https://github.com/thoughtbot/shoulda-matchers/blob/master/CHANGELOG.md',
 | 
			
		||||
    'documentation_uri' => 'https://matchers.shoulda.io/docs',
 | 
			
		||||
| 
						 | 
				
			
			@ -29,7 +32,8 @@ Gem::Specification.new do |s|
 | 
			
		|||
    'source_code_uri' => 'https://github.com/thoughtbot/shoulda-matchers',
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  s.files = Dir['{docs,lib}/**/*', 'README.md', 'LICENSE', 'shoulda-matchers.gemspec']
 | 
			
		||||
  s.files = Dir['{docs,lib}/**/*', 'README.md', 'LICENSE',
 | 
			
		||||
    'shoulda-matchers.gemspec']
 | 
			
		||||
  s.require_paths = ['lib']
 | 
			
		||||
 | 
			
		||||
  s.required_ruby_version = '>= 2.4.0'
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -99,11 +99,12 @@ module AcceptanceTests
 | 
			
		|||
      end
 | 
			
		||||
 | 
			
		||||
      if integrates_with_rspec?(test_framework)
 | 
			
		||||
        files << if bundle.includes?('rspec-rails')
 | 
			
		||||
                   'spec/rails_helper.rb'
 | 
			
		||||
                 else
 | 
			
		||||
                   'spec/spec_helper.rb'
 | 
			
		||||
                 end
 | 
			
		||||
        files <<
 | 
			
		||||
          if bundle.includes?('rspec-rails')
 | 
			
		||||
            'spec/rails_helper.rb'
 | 
			
		||||
          else
 | 
			
		||||
            'spec/spec_helper.rb'
 | 
			
		||||
          end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      files
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,9 +1,10 @@
 | 
			
		|||
module AcceptanceTests
 | 
			
		||||
  module ArrayHelpers
 | 
			
		||||
    def to_sentence(array)
 | 
			
		||||
      if array.size == 1
 | 
			
		||||
      case array.size
 | 
			
		||||
      when 1
 | 
			
		||||
        array[0]
 | 
			
		||||
      elsif array.size == 2
 | 
			
		||||
      when 2
 | 
			
		||||
        array.join(' and ')
 | 
			
		||||
      else
 | 
			
		||||
        to_sentence(array[1..-2].join(', '), [array[-1]])
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
module AcceptanceTests
 | 
			
		||||
  module PluralizationHelpers
 | 
			
		||||
    def pluralize(count, singular_version, plural_version = nil)
 | 
			
		||||
      plural_version ||= singular_version + 's'
 | 
			
		||||
      plural_version ||= "#{singular_version}s"
 | 
			
		||||
 | 
			
		||||
      if count == 1
 | 
			
		||||
        "#{count} #{singular_version}"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -58,11 +58,12 @@ module AcceptanceTests
 | 
			
		|||
 | 
			
		||||
    def create_rails_application
 | 
			
		||||
      fs.clean
 | 
			
		||||
      command = if rails_version =~ '~> 6.0'
 | 
			
		||||
                  "bundle exec rails new #{fs.project_directory} --skip-bundle --skip-javascript --no-rc"
 | 
			
		||||
                else
 | 
			
		||||
                  "bundle exec rails new #{fs.project_directory} --skip-bundle --no-rc"
 | 
			
		||||
                end
 | 
			
		||||
      command =
 | 
			
		||||
        if rails_version =~ '~> 6.0'
 | 
			
		||||
          "bundle exec rails new #{fs.project_directory} --skip-bundle --skip-javascript --no-rc"
 | 
			
		||||
        else
 | 
			
		||||
          "bundle exec rails new #{fs.project_directory} --skip-bundle --no-rc"
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
      run_command!(command) do |runner|
 | 
			
		||||
        runner.directory = nil
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,10 +15,10 @@ module AcceptanceTests
 | 
			
		|||
      end
 | 
			
		||||
 | 
			
		||||
      def failure_message
 | 
			
		||||
        "Expected command to have output, but did not.\n\n" +
 | 
			
		||||
          "Command: #{runner.formatted_command}\n\n" +
 | 
			
		||||
        "Expected command to have output, but did not.\n\n"\
 | 
			
		||||
          "Command: #{runner.formatted_command}\n\n"\
 | 
			
		||||
          "Expected output:\n" +
 | 
			
		||||
          output.inspect + "\n\n" +
 | 
			
		||||
          output.inspect + "\n\n"\
 | 
			
		||||
          "Actual output:\n" +
 | 
			
		||||
          runner.output
 | 
			
		||||
      end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,11 +24,12 @@ module AcceptanceTests
 | 
			
		|||
        message = "Expected output to indicate that #{some_tests_were_run}.\n" +
 | 
			
		||||
                  "Expected output: #{expected_output}\n"
 | 
			
		||||
 | 
			
		||||
        message << if actual_output.empty?
 | 
			
		||||
                     'Actual output: (empty)'
 | 
			
		||||
                   else
 | 
			
		||||
                     "Actual output:\n#{actual_output}"
 | 
			
		||||
                   end
 | 
			
		||||
        message <<
 | 
			
		||||
          if actual_output.empty?
 | 
			
		||||
            'Actual output: (empty)'
 | 
			
		||||
          else
 | 
			
		||||
            "Actual output:\n#{actual_output}"
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
        message
 | 
			
		||||
      end
 | 
			
		||||
| 
						 | 
				
			
			@ -48,7 +49,7 @@ module AcceptanceTests
 | 
			
		|||
      end
 | 
			
		||||
 | 
			
		||||
      def some_tests_were_run
 | 
			
		||||
        pluralize(number, 'test was', 'tests were') + ' run'
 | 
			
		||||
        "#{pluralize(number, 'test was', 'tests were')} run"
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,7 +9,7 @@ module Tests
 | 
			
		|||
      @fs = Filesystem.new
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def updating(&_block)
 | 
			
		||||
    def updating
 | 
			
		||||
      if already_updating?
 | 
			
		||||
        yield self
 | 
			
		||||
        return
 | 
			
		||||
| 
						 | 
				
			
			@ -35,7 +35,7 @@ module Tests
 | 
			
		|||
 | 
			
		||||
    def remove_gem(gem)
 | 
			
		||||
      updating do
 | 
			
		||||
        fs.comment_lines_matching('Gemfile', /^[ ]*gem ("|')#{gem}\1/)
 | 
			
		||||
        fs.comment_lines_matching('Gemfile', /^ *gem ("|')#{gem}\1/)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -177,7 +177,7 @@ Output:
 | 
			
		|||
 | 
			
		||||
      run_with_wrapper
 | 
			
		||||
 | 
			
		||||
      debug { "\n" + divider('START') + output + divider('END') }
 | 
			
		||||
      debug { "\n#{divider('START')}#{output}#{divider('END')}" }
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def possibly_running_quickly(&block)
 | 
			
		||||
| 
						 | 
				
			
			@ -188,7 +188,7 @@ Output:
 | 
			
		|||
          stop
 | 
			
		||||
 | 
			
		||||
          message =
 | 
			
		||||
            "Command timed out after #{timeout} seconds: #{formatted_command}\n" +
 | 
			
		||||
            "Command timed out after #{timeout} seconds: #{formatted_command}\n"\
 | 
			
		||||
            "Output:\n" +
 | 
			
		||||
            output
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,7 +5,8 @@ module Tests
 | 
			
		|||
        :sqlite3
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def initialize(_database); end
 | 
			
		||||
      def initialize(_database)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def adapter
 | 
			
		||||
        self.class.name
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -65,12 +65,12 @@ module Tests
 | 
			
		|||
 | 
			
		||||
    def append_to_file(path, content, _options = {})
 | 
			
		||||
      create_parents_of(path)
 | 
			
		||||
      File.open(path, 'a') { |f| f.puts(content + "\n") }
 | 
			
		||||
      open(path, 'a') { |f| f.puts("#{content}\n") } # rubocop: disable Security/Open
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def remove_from_file(path, pattern)
 | 
			
		||||
      unless pattern.is_a?(Regexp)
 | 
			
		||||
        pattern = Regexp.new('^' + Regexp.escape(pattern) + '$')
 | 
			
		||||
        pattern = Regexp.new("^#{Regexp.escape(pattern)}$")
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      transform(path) do |lines|
 | 
			
		||||
| 
						 | 
				
			
			@ -94,7 +94,7 @@ module Tests
 | 
			
		|||
      content = read(path)
 | 
			
		||||
      lines = content.split(/\n/)
 | 
			
		||||
      transformed_lines = yield lines
 | 
			
		||||
      write(path, transformed_lines.join("\n") + "\n")
 | 
			
		||||
      write(path, "#{transformed_lines.join("\n")}\n")
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
module Tests
 | 
			
		||||
  class Version
 | 
			
		||||
    def initialize(version)
 | 
			
		||||
      @version = Gem::Version.new(version.to_s + '')
 | 
			
		||||
      @version = Gem::Version.new(version.to_s)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def <(other_version)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -102,16 +102,16 @@ module UnitTests
 | 
			
		|||
        if column_options[:array]
 | 
			
		||||
          if !active_record_supports_array_columns?
 | 
			
		||||
            raise ArgumentError.new(
 | 
			
		||||
              'An array column is being added to a table, but this version ' +
 | 
			
		||||
              "of ActiveRecord (#{active_record_version}) " +
 | 
			
		||||
              'An array column is being added to a table, but this version '\
 | 
			
		||||
              "of ActiveRecord (#{active_record_version}) "\
 | 
			
		||||
              'does not support array columns.',
 | 
			
		||||
            )
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          if !database_supports_array_columns?
 | 
			
		||||
            raise ArgumentError.new(
 | 
			
		||||
              'An array column is being added to a table, but this ' +
 | 
			
		||||
              "database adapter (#{database_adapter}) " +
 | 
			
		||||
              'An array column is being added to a table, but this '\
 | 
			
		||||
              "database adapter (#{database_adapter}) "\
 | 
			
		||||
              'does not support array columns.',
 | 
			
		||||
            )
 | 
			
		||||
          end
 | 
			
		||||
| 
						 | 
				
			
			@ -119,8 +119,8 @@ module UnitTests
 | 
			
		|||
 | 
			
		||||
        if column_specification.any?
 | 
			
		||||
          raise ArgumentError.new(
 | 
			
		||||
            "Invalid column specification.\nYou need to put " +
 | 
			
		||||
            "#{column_specification.keys.map(&:inspect).to_sentence} " +
 | 
			
		||||
            "Invalid column specification.\nYou need to put "\
 | 
			
		||||
            "#{column_specification.keys.map(&:inspect).to_sentence} "\
 | 
			
		||||
            'inside an :options key!',
 | 
			
		||||
          )
 | 
			
		||||
        end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -41,6 +41,6 @@ module Kernel
 | 
			
		|||
  end
 | 
			
		||||
 | 
			
		||||
  def silence_stderr
 | 
			
		||||
    silence_stream(STDERR) { yield }
 | 
			
		||||
    silence_stream($stderr) { yield if block_given? }
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -85,7 +85,7 @@ module UnitTests
 | 
			
		|||
    end
 | 
			
		||||
 | 
			
		||||
    def add_character
 | 
			
		||||
      value + 'a'
 | 
			
		||||
      "#{value}a"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    def remove_character
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,8 +9,10 @@ module UnitTests
 | 
			
		|||
 | 
			
		||||
    def builder_for_record_validating_confirmation_with_18n_message(options = {})
 | 
			
		||||
      builder = builder_for_record_validating_confirmation(options)
 | 
			
		||||
      RecordBuilderWithI18nValidationMessage.new(builder,
 | 
			
		||||
        validation_message_key: :confirmation,)
 | 
			
		||||
      RecordBuilderWithI18nValidationMessage.new(
 | 
			
		||||
        builder,
 | 
			
		||||
        validation_message_key: :confirmation,
 | 
			
		||||
      )
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -48,7 +48,7 @@ module UnitTests
 | 
			
		|||
 | 
			
		||||
        if expected_message && should_be_negated?
 | 
			
		||||
          raise ArgumentError.new(
 | 
			
		||||
            'Use `or_fail_with`, not `and_fail_with`, when using ' +
 | 
			
		||||
            'Use `or_fail_with`, not `and_fail_with`, when using '\
 | 
			
		||||
            '`should match_against(...)`!',
 | 
			
		||||
          )
 | 
			
		||||
        end
 | 
			
		||||
| 
						 | 
				
			
			@ -73,7 +73,7 @@ Expected the matcher to match in the positive, but it failed with this message:
 | 
			
		|||
 | 
			
		||||
        if expected_message && !should_be_negated?
 | 
			
		||||
          raise ArgumentError.new(
 | 
			
		||||
            'Use `and_fail_with`, not `or_fail_with`, when using ' +
 | 
			
		||||
            'Use `and_fail_with`, not `or_fail_with`, when using '\
 | 
			
		||||
            '`should_not match_against(...)`!',
 | 
			
		||||
          )
 | 
			
		||||
        end
 | 
			
		||||
| 
						 | 
				
			
			@ -148,7 +148,7 @@ Diff:
 | 
			
		|||
          end
 | 
			
		||||
        else
 | 
			
		||||
          @failure_message =
 | 
			
		||||
            'Expected the negative version of the matcher not to match, ' +
 | 
			
		||||
            'Expected the negative version of the matcher not to match, '\
 | 
			
		||||
            'but it did.'
 | 
			
		||||
          false
 | 
			
		||||
        end
 | 
			
		||||
| 
						 | 
				
			
			@ -198,7 +198,7 @@ Diff:
 | 
			
		|||
          end
 | 
			
		||||
        else
 | 
			
		||||
          @failure_message_when_negated =
 | 
			
		||||
            'Expected the positive version of the matcher not to match, ' +
 | 
			
		||||
            'Expected the positive version of the matcher not to match, '\
 | 
			
		||||
            'but it did.'
 | 
			
		||||
          false
 | 
			
		||||
        end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -107,7 +107,7 @@ module UnitTests
 | 
			
		|||
          middle = '%s:0x%014x%s' % [ # rubocop:disable Style/FormatStringToken
 | 
			
		||||
            self.class,
 | 
			
		||||
            object_id * 2,
 | 
			
		||||
            ' ' + inspected_attributes.join(' '),
 | 
			
		||||
            " #{inspected_attributes.join(' ')}",
 | 
			
		||||
          ]
 | 
			
		||||
 | 
			
		||||
          "#<#{middle.strip}>"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -328,8 +328,8 @@ describe Shoulda::Matchers::ActionController::PermitMatcher, type: :controller d
 | 
			
		|||
        end
 | 
			
		||||
 | 
			
		||||
        message =
 | 
			
		||||
          'Expected POST #create to restrict parameters to ' +
 | 
			
		||||
          ":name, :age, :city, and :country,\n" +
 | 
			
		||||
          'Expected POST #create to restrict parameters to '\
 | 
			
		||||
          ":name, :age, :city, and :country,\n"\
 | 
			
		||||
          'but it did not restrict any parameters.'
 | 
			
		||||
 | 
			
		||||
        expect(&assertion).to fail_with_message(message)
 | 
			
		||||
| 
						 | 
				
			
			@ -349,8 +349,8 @@ describe Shoulda::Matchers::ActionController::PermitMatcher, type: :controller d
 | 
			
		|||
        end
 | 
			
		||||
 | 
			
		||||
        message =
 | 
			
		||||
          'Expected POST #create to restrict parameters to ' +
 | 
			
		||||
          ":name, :age, :city, and :country,\n" +
 | 
			
		||||
          'Expected POST #create to restrict parameters to '\
 | 
			
		||||
          ":name, :age, :city, and :country,\n"\
 | 
			
		||||
          'but the restricted parameters were :name and :age instead.'
 | 
			
		||||
 | 
			
		||||
        expect(&assertion).to fail_with_message(message)
 | 
			
		||||
| 
						 | 
				
			
			@ -372,8 +372,8 @@ describe Shoulda::Matchers::ActionController::PermitMatcher, type: :controller d
 | 
			
		|||
          end
 | 
			
		||||
 | 
			
		||||
          message =
 | 
			
		||||
            'Expected POST #create to restrict parameters on :person to ' +
 | 
			
		||||
            ":name, :age, :city, and :country,\n" +
 | 
			
		||||
            'Expected POST #create to restrict parameters on :person to '\
 | 
			
		||||
            ":name, :age, :city, and :country,\n"\
 | 
			
		||||
            'but it did not restrict any parameters.'
 | 
			
		||||
 | 
			
		||||
          expect(&assertion).to fail_with_message(message)
 | 
			
		||||
| 
						 | 
				
			
			@ -401,8 +401,8 @@ describe Shoulda::Matchers::ActionController::PermitMatcher, type: :controller d
 | 
			
		|||
            end
 | 
			
		||||
 | 
			
		||||
            message =
 | 
			
		||||
              'Expected POST #create to restrict parameters on :person to ' +
 | 
			
		||||
              ":name, :age, :city, and :country,\n" +
 | 
			
		||||
              'Expected POST #create to restrict parameters on :person to '\
 | 
			
		||||
              ":name, :age, :city, and :country,\n"\
 | 
			
		||||
              'but it did not restrict any parameters.'
 | 
			
		||||
 | 
			
		||||
            expect(&assertion).to fail_with_message(message)
 | 
			
		||||
| 
						 | 
				
			
			@ -429,8 +429,8 @@ describe Shoulda::Matchers::ActionController::PermitMatcher, type: :controller d
 | 
			
		|||
            end
 | 
			
		||||
 | 
			
		||||
            message =
 | 
			
		||||
              'Expected POST #create to restrict parameters on :person to ' +
 | 
			
		||||
              ":name, :age, :city, and :country,\n" +
 | 
			
		||||
              'Expected POST #create to restrict parameters on :person to '\
 | 
			
		||||
              ":name, :age, :city, and :country,\n"\
 | 
			
		||||
              'but the restricted parameters were :name and :age instead.'
 | 
			
		||||
 | 
			
		||||
            expect(&assertion).to fail_with_message(message)
 | 
			
		||||
| 
						 | 
				
			
			@ -453,8 +453,8 @@ describe Shoulda::Matchers::ActionController::PermitMatcher, type: :controller d
 | 
			
		|||
      end
 | 
			
		||||
 | 
			
		||||
      message =
 | 
			
		||||
        'Expected POST #create not to restrict parameters to ' +
 | 
			
		||||
        ":name, :age, :city, and :country,\n" +
 | 
			
		||||
        'Expected POST #create not to restrict parameters to '\
 | 
			
		||||
        ":name, :age, :city, and :country,\n"\
 | 
			
		||||
        'but it did.'
 | 
			
		||||
 | 
			
		||||
      expect(&assertion).to fail_with_message(message)
 | 
			
		||||
| 
						 | 
				
			
			@ -480,8 +480,8 @@ describe Shoulda::Matchers::ActionController::PermitMatcher, type: :controller d
 | 
			
		|||
        end
 | 
			
		||||
 | 
			
		||||
        message =
 | 
			
		||||
          'Expected POST #create not to restrict parameters on :person to ' +
 | 
			
		||||
          ":name and :age,\n" +
 | 
			
		||||
          'Expected POST #create not to restrict parameters on :person to '\
 | 
			
		||||
          ":name and :age,\n"\
 | 
			
		||||
          'but it did.'
 | 
			
		||||
 | 
			
		||||
        expect(&assertion).to fail_with_message(message)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,8 +32,11 @@ describe Shoulda::Matchers::ActiveModel::AllowMassAssignmentOfMatcher, type: :mo
 | 
			
		|||
 | 
			
		||||
    context 'an attribute that is not whitelisted for mass-assignment' do
 | 
			
		||||
      it 'rejects being mass-assignable' do
 | 
			
		||||
        model = define_model(:example, not_whitelisted: :string,
 | 
			
		||||
                                       whitelisted: :string,) do
 | 
			
		||||
        model = define_model(
 | 
			
		||||
          :example,
 | 
			
		||||
          not_whitelisted: :string,
 | 
			
		||||
          whitelisted: :string,
 | 
			
		||||
        ) do
 | 
			
		||||
          attr_accessible :whitelisted
 | 
			
		||||
        end.new
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -51,8 +54,11 @@ describe Shoulda::Matchers::ActiveModel::AllowMassAssignmentOfMatcher, type: :mo
 | 
			
		|||
 | 
			
		||||
    context 'an attribute not included in the mass-assignment blacklist' do
 | 
			
		||||
      it 'accepts being mass-assignable' do
 | 
			
		||||
        model = define_model(:example, not_blacklisted: :string,
 | 
			
		||||
                                       blacklisted: :string,) do
 | 
			
		||||
        model = define_model(
 | 
			
		||||
          :example,
 | 
			
		||||
          not_blacklisted: :string,
 | 
			
		||||
          blacklisted: :string,
 | 
			
		||||
        ) do
 | 
			
		||||
          attr_protected :blacklisted
 | 
			
		||||
        end.new
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -463,8 +463,11 @@ indeed invalid, but it produced these validation errors instead:
 | 
			
		|||
      define_model :example, attr: :string do
 | 
			
		||||
        validates_presence_of     :attr
 | 
			
		||||
        validates_length_of       :attr, within: 1..5
 | 
			
		||||
        validates_numericality_of :attr, greater_than_or_equal_to: 1,
 | 
			
		||||
                                         less_than_or_equal_to: 50000
 | 
			
		||||
        validates_numericality_of(
 | 
			
		||||
          :attr,
 | 
			
		||||
          greater_than_or_equal_to: 1,
 | 
			
		||||
          less_than_or_equal_to: 50000,
 | 
			
		||||
        )
 | 
			
		||||
      end.new
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,8 +36,10 @@ describe Shoulda::Matchers::ActiveModel::DisallowValueMatcher, type: :model do
 | 
			
		|||
    end
 | 
			
		||||
 | 
			
		||||
    it "delegates its failure message to its allow matcher's negative failure message" do
 | 
			
		||||
      allow_matcher = double('allow_matcher',
 | 
			
		||||
        failure_message_when_negated: 'allow matcher failure',).as_null_object
 | 
			
		||||
      allow_matcher = double(
 | 
			
		||||
        'allow_matcher',
 | 
			
		||||
        failure_message_when_negated: 'allow matcher failure',
 | 
			
		||||
      ).as_null_object
 | 
			
		||||
      allow(Shoulda::Matchers::ActiveModel::AllowValueMatcher).
 | 
			
		||||
        to receive(:new).
 | 
			
		||||
        and_return(allow_matcher)
 | 
			
		||||
| 
						 | 
				
			
			@ -68,8 +70,12 @@ describe Shoulda::Matchers::ActiveModel::DisallowValueMatcher, type: :model do
 | 
			
		|||
    def record_with_custom_validation
 | 
			
		||||
      define_model :example, attr: :string, attr2: :string do
 | 
			
		||||
        validate :custom_validation
 | 
			
		||||
        custom_validation = -> { errors[:attr2] << 'some message' if self[:attr] != 'good value' }
 | 
			
		||||
        custom_validation.call
 | 
			
		||||
 | 
			
		||||
        def custom_validation # rubocop:disable Lint/NestedMethodDefinition
 | 
			
		||||
          if self[:attr] != 'good value'
 | 
			
		||||
            errors[:attr2] << 'some message'
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
      end.new
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
require 'unit_spec_helper'
 | 
			
		||||
 | 
			
		||||
describe Shoulda::Matchers::ActiveModel::HaveSecurePasswordMatcher, type: :model do
 | 
			
		||||
  context "with no arguments passed to has_secure_password" do
 | 
			
		||||
  context 'with no arguments passed to has_secure_password' do
 | 
			
		||||
    it 'matches when the subject configures has_secure_password with default options' do
 | 
			
		||||
      working_model = define_model(:example, password_digest: :string) { has_secure_password }
 | 
			
		||||
      expect(working_model.new).to have_secure_password
 | 
			
		||||
| 
						 | 
				
			
			@ -19,7 +19,7 @@ describe Shoulda::Matchers::ActiveModel::HaveSecurePasswordMatcher, type: :model
 | 
			
		|||
  end
 | 
			
		||||
 | 
			
		||||
  if active_model_supports_custom_has_secure_password_attribute?
 | 
			
		||||
    context "when custom attribute is given to has_secure_password" do
 | 
			
		||||
    context 'when custom attribute is given to has_secure_password' do
 | 
			
		||||
      it 'matches when the subject configures has_secure_password with correct options' do
 | 
			
		||||
        working_model = define_model(:example, reset_password_digest: :string) { has_secure_password :reset_password }
 | 
			
		||||
        expect(working_model.new).to have_secure_password :reset_password
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -81,8 +81,10 @@ describe Shoulda::Matchers::ActiveModel::Helpers do
 | 
			
		|||
 | 
			
		||||
    context 'if ActiveModel::Errors#generate_message behavior has changed' do
 | 
			
		||||
      it 'provides the right error message for validate_presence_of' do
 | 
			
		||||
        stub_active_model_message_generation(type: :blank,
 | 
			
		||||
                                             message: 'Behavior has diverged.',)
 | 
			
		||||
        stub_active_model_message_generation(
 | 
			
		||||
          type: :blank,
 | 
			
		||||
          message: 'Behavior has diverged.',
 | 
			
		||||
        )
 | 
			
		||||
        assert_presence_validation_has_correct_message
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
| 
						 | 
				
			
			@ -102,7 +104,7 @@ describe Shoulda::Matchers::ActiveModel::Helpers do
 | 
			
		|||
    expect(record).to validate_length_of(:attr).is_equal_to(40)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def store_translations(options = { without: [] })
 | 
			
		||||
  def store_translations(options = { without: [] }) # rubocop:disable Metrics/MethodLength
 | 
			
		||||
    options[:without] = Array.wrap(options[:without] || [])
 | 
			
		||||
 | 
			
		||||
    translations = {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -768,7 +768,7 @@ describe Shoulda::Matchers::ActiveModel::ValidateInclusionOfMatcher, type: :mode
 | 
			
		|||
          valid_values = booleans
 | 
			
		||||
          builder = build_object_allowing(valid_values)
 | 
			
		||||
          message =
 | 
			
		||||
            'You are using `validate_inclusion_of` to assert that a boolean ' +
 | 
			
		||||
            'You are using `validate_inclusion_of` to assert that a boolean '\
 | 
			
		||||
            'column allows boolean values and disallows non-boolean ones'
 | 
			
		||||
 | 
			
		||||
          stderr = capture(:stderr) do
 | 
			
		||||
| 
						 | 
				
			
			@ -829,7 +829,7 @@ describe Shoulda::Matchers::ActiveModel::ValidateInclusionOfMatcher, type: :mode
 | 
			
		|||
            valid_values = [nil]
 | 
			
		||||
            builder = build_object_allowing(valid_values)
 | 
			
		||||
            message =
 | 
			
		||||
              'You are using `validate_inclusion_of` to assert that a ' +
 | 
			
		||||
              'You are using `validate_inclusion_of` to assert that a '\
 | 
			
		||||
              'boolean column allows nil'
 | 
			
		||||
 | 
			
		||||
            stderr = capture(:stderr) do
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,7 +2,7 @@ require 'unit_spec_helper'
 | 
			
		|||
 | 
			
		||||
describe Shoulda::Matchers::ActiveModel::ValidateNumericalityOfMatcher, type: :model do
 | 
			
		||||
  class << self
 | 
			
		||||
    def all_qualifiers
 | 
			
		||||
    def all_qualifiers # rubocop:disable Metrics/MethodLength
 | 
			
		||||
      [
 | 
			
		||||
        {
 | 
			
		||||
          category: :comparison,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -489,6 +489,7 @@ describe Shoulda::Matchers::ActiveRecord::AssociationMatcher, type: :model do
 | 
			
		|||
                  with_belongs_to_as_optional_by_default do
 | 
			
		||||
                    child_model = create_child_model_belonging_to_parent do
 | 
			
		||||
                      attr_accessor :condition
 | 
			
		||||
 | 
			
		||||
                      validates_presence_of :parent, if: :condition
 | 
			
		||||
                    end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -504,6 +505,7 @@ describe Shoulda::Matchers::ActiveRecord::AssociationMatcher, type: :model do
 | 
			
		|||
                  with_belongs_to_as_optional_by_default do
 | 
			
		||||
                    child_model = create_child_model_belonging_to_parent do
 | 
			
		||||
                      attr_accessor :condition
 | 
			
		||||
 | 
			
		||||
                      validates_presence_of :parent, if: :condition
 | 
			
		||||
                    end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -535,6 +537,7 @@ describe Shoulda::Matchers::ActiveRecord::AssociationMatcher, type: :model do
 | 
			
		|||
              it 'passes' do
 | 
			
		||||
                child_model = create_child_model_belonging_to_parent do
 | 
			
		||||
                  attr_accessor :condition
 | 
			
		||||
 | 
			
		||||
                  validates_presence_of :parent, if: :condition
 | 
			
		||||
                end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -548,6 +551,7 @@ describe Shoulda::Matchers::ActiveRecord::AssociationMatcher, type: :model do
 | 
			
		|||
              it 'passes' do
 | 
			
		||||
                child_model = create_child_model_belonging_to_parent do
 | 
			
		||||
                  attr_accessor :condition
 | 
			
		||||
 | 
			
		||||
                  validates_presence_of :parent, if: :condition
 | 
			
		||||
                end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -916,8 +920,11 @@ Expected Parent to have a has_many association called children through conceptio
 | 
			
		|||
    end
 | 
			
		||||
 | 
			
		||||
    it 'rejects an association with a bad :as option' do
 | 
			
		||||
      define_model :child, caretaker_type: :string,
 | 
			
		||||
                           caretaker_id: :integer
 | 
			
		||||
      define_model(
 | 
			
		||||
        :child,
 | 
			
		||||
        caretaker_type: :string,
 | 
			
		||||
        caretaker_id: :integer,
 | 
			
		||||
      )
 | 
			
		||||
      define_model :parent do
 | 
			
		||||
        has_many :children, as: :guardian
 | 
			
		||||
      end
 | 
			
		||||
| 
						 | 
				
			
			@ -1159,7 +1166,7 @@ Expected Parent to have a has_many association called children through conceptio
 | 
			
		|||
          end
 | 
			
		||||
 | 
			
		||||
          message =
 | 
			
		||||
            'Expected Parent to have a has_many association called children ' +
 | 
			
		||||
            'Expected Parent to have a has_many association called children '\
 | 
			
		||||
            '(children should have index_errors set to true)'
 | 
			
		||||
 | 
			
		||||
          expect {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,7 +24,8 @@ describe Shoulda::Matchers::ActiveRecord::DefineEnumForMatcher, type: :model do
 | 
			
		|||
  context 'if a method to hold enum values exists on the model but was not created via the enum macro' do
 | 
			
		||||
    it 'rejects with an appropriate failure message' do
 | 
			
		||||
      model = define_model 'Example' do
 | 
			
		||||
        def self.statuses; end
 | 
			
		||||
        def self.statuses
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      message = format_message(<<-MESSAGE)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -79,8 +79,11 @@ describe Shoulda::Matchers::ActiveRecord::SerializeMatcher, type: :model do
 | 
			
		|||
 | 
			
		||||
  def define_serializer(name)
 | 
			
		||||
    define_class(name) do
 | 
			
		||||
      def load(*); end # rubocop:disable Lint/NestedMethodDefinition
 | 
			
		||||
      def dump(*); end # rubocop:disable Lint/NestedMethodDefinition
 | 
			
		||||
      def load(*) # rubocop:disable Lint/NestedMethodDefinition
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def dump(*) # rubocop:disable Lint/NestedMethodDefinition
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1471,9 +1471,7 @@ this could not be proved.
 | 
			
		|||
      record = build_record_validating_uniqueness(attribute_type: :boolean)
 | 
			
		||||
      running_validation = -> { expect(record).to validate_uniqueness }
 | 
			
		||||
      message =
 | 
			
		||||
        'You attempted to assign a value which is not explicitly `true` or ' +
 | 
			
		||||
        '`false`'
 | 
			
		||||
 | 
			
		||||
        'You attempted to assign a value which is not explicitly `true` or `false`'
 | 
			
		||||
      expect(&running_validation).not_to print_warning_including(message)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
| 
						 | 
				
			
			@ -1590,9 +1588,7 @@ this could not be proved.
 | 
			
		|||
        validation_options.merge(scope: scope_attribute_names)
 | 
			
		||||
 | 
			
		||||
      if m.respond_to?(:attr_accessible)
 | 
			
		||||
        attributes.each do |attr|
 | 
			
		||||
          m.attr_accessible(attr[:name])
 | 
			
		||||
        end
 | 
			
		||||
        attributes.each { |attr| m.attr_accessible(attr[:name]) }
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      block&.call(m)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -264,7 +264,7 @@ describe Shoulda::Matchers::Independent::DelegateMethodMatcher do
 | 
			
		|||
      define_class('Mailman')
 | 
			
		||||
 | 
			
		||||
      define_class('PostOffice') do
 | 
			
		||||
        def deliver_mail(*_args)
 | 
			
		||||
        def deliver_mail(*)
 | 
			
		||||
          mailman.deliver_mail('221B Baker St.', hastily: true)
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -394,7 +394,7 @@ describe Shoulda::Matchers::Independent::DelegateMethodMatcher do
 | 
			
		|||
          end
 | 
			
		||||
 | 
			
		||||
          person = Person.new
 | 
			
		||||
          expect(person).to delegate_method(:hello). to(:country).with_prefix
 | 
			
		||||
          expect(person).to delegate_method(:hello).to(:country).with_prefix
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -535,7 +535,8 @@ describe Shoulda::Matchers::Independent::DelegateMethodMatcher do
 | 
			
		|||
        it 'accepts' do
 | 
			
		||||
          define_class('Person') do
 | 
			
		||||
            delegate :hello, to: :country, allow_nil: true
 | 
			
		||||
            def country; end
 | 
			
		||||
            def country
 | 
			
		||||
            end
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          person = Person.new
 | 
			
		||||
| 
						 | 
				
			
			@ -548,7 +549,8 @@ describe Shoulda::Matchers::Independent::DelegateMethodMatcher do
 | 
			
		|||
        it 'rejects with the correct failure message' do
 | 
			
		||||
          define_class('Person') do
 | 
			
		||||
            delegate :hello, to: :country
 | 
			
		||||
            def country; end
 | 
			
		||||
            def country
 | 
			
		||||
            end
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          person = Person.new
 | 
			
		||||
| 
						 | 
				
			
			@ -578,7 +580,8 @@ to account for when #country *was* nil.
 | 
			
		|||
 | 
			
		||||
            def_delegators :country, :hello
 | 
			
		||||
 | 
			
		||||
            def country; end
 | 
			
		||||
            def country
 | 
			
		||||
            end
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          person = Person.new
 | 
			
		||||
| 
						 | 
				
			
			@ -606,7 +609,8 @@ to account for when #country *was* nil.
 | 
			
		|||
      context 'when the delegating method accounts for the delegate object being nil' do
 | 
			
		||||
        it 'accepts' do
 | 
			
		||||
          define_class('Person') do
 | 
			
		||||
            def country; end
 | 
			
		||||
            def country
 | 
			
		||||
            end
 | 
			
		||||
 | 
			
		||||
            def hello
 | 
			
		||||
              return unless country
 | 
			
		||||
| 
						 | 
				
			
			@ -624,7 +628,8 @@ to account for when #country *was* nil.
 | 
			
		|||
      context 'when the delegating method does not account for the delegate object being nil' do
 | 
			
		||||
        it 'rejects with the correct failure message' do
 | 
			
		||||
          define_class('Person') do
 | 
			
		||||
            def country; end
 | 
			
		||||
            def country
 | 
			
		||||
            end
 | 
			
		||||
 | 
			
		||||
            def hello
 | 
			
		||||
              country.hello
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -66,7 +66,7 @@ posuere diam ex ut velit.
 | 
			
		|||
    wrapped_message = described_class.word_wrap(<<-MESSAGE.rstrip)
 | 
			
		||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean luctus, ipsum sit amet efficitur feugiat, dolor mauris fringilla erat, sed posuere diam ex ut velit.
 | 
			
		||||
 | 
			
		||||
Etiam ultrices cursus ligula eget feugiat. Vestibulum eget tincidunt risus, non faucibus sem. 
 | 
			
		||||
Etiam ultrices cursus ligula eget feugiat. Vestibulum eget tincidunt risus, non faucibus sem.
 | 
			
		||||
    MESSAGE
 | 
			
		||||
 | 
			
		||||
    expect(wrapped_message).to eq(<<-MESSAGE.rstrip)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
Some files were not shown because too many files have changed in this diff Show more
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue