Full Code of thoughtbot/shoulda-context for AI

main ddbc2dba82cb cached
58 files
106.2 KB
30.3k tokens
197 symbols
1 requests
Download .txt
Repository: thoughtbot/shoulda-context
Branch: main
Commit: ddbc2dba82cb
Files: 58
Total size: 106.2 KB

Directory structure:
gitextract_exvje7qk/

├── .github/
│   └── workflows/
│       ├── ci.yml
│       ├── dynamic-readme.yml
│       ├── dynamic-security.yml
│       └── rubocop.yml
├── .gitignore
├── .rubocop.yml
├── .rubocop_todo.yml
├── .ruby-version
├── Appraisals
├── CHANGELOG.md
├── Gemfile
├── LICENSE
├── MAINTAINING.md
├── README.md
├── Rakefile
├── SECURITY.md
├── bin/
│   ├── install_gems_in_all_appraisals
│   ├── run_all_tests
│   ├── setup
│   ├── supported_ruby_versions
│   ├── update_gem_in_all_appraisals
│   └── update_gems_in_all_appraisals
├── exe/
│   └── convert_to_should_syntax
├── gemfiles/
│   ├── rails_6_0.gemfile
│   └── rails_6_1.gemfile
├── lib/
│   ├── shoulda/
│   │   ├── context/
│   │   │   ├── assertions.rb
│   │   │   ├── autoload_macros.rb
│   │   │   ├── configuration.rb
│   │   │   ├── context.rb
│   │   │   ├── dsl.rb
│   │   │   ├── proc_extensions.rb
│   │   │   ├── railtie.rb
│   │   │   ├── tasks/
│   │   │   │   ├── list_tests.rake
│   │   │   │   └── yaml_to_shoulda.rake
│   │   │   ├── tasks.rb
│   │   │   ├── test_framework_detection.rb
│   │   │   ├── version.rb
│   │   │   └── world.rb
│   │   └── context.rb
│   └── shoulda-context.rb
├── shoulda-context.gemspec
├── tasks/
│   └── shoulda.rake
└── test/
    ├── fake_rails_root/
    │   ├── test/
    │   │   └── shoulda_macros/
    │   │       └── custom_macro.rb
    │   └── vendor/
    │       ├── gems/
    │       │   └── gem_with_macro-0.0.1/
    │       │       └── shoulda_macros/
    │       │           └── gem_macro.rb
    │       └── plugins/
    │           ├── .keep
    │           └── plugin_with_macro/
    │               └── shoulda_macros/
    │                   └── plugin_macro.rb
    ├── shoulda/
    │   ├── autoload_macro_test.rb
    │   ├── context_test.rb
    │   ├── convert_to_should_syntax_test.rb
    │   ├── helpers_test.rb
    │   ├── railtie_test.rb
    │   ├── rerun_snippet_test.rb
    │   ├── should_test.rb
    │   └── test_framework_detection_test.rb
    ├── support/
    │   ├── current_bundle.rb
    │   ├── rails_application_with_shoulda_context.rb
    │   └── snowglobe.rb
    └── test_helper.rb

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/workflows/ci.yml
================================================
name: Test

on:
  push:
    branches:
      - main
    paths-ignore:
      - '**.md'
  pull_request:
    types:
      - opened
      - synchronize
    paths-ignore:
      - '**.md'

jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        ruby:
          - 2.7.7
        appraisal:
          - rails_6_1
          - rails_6_0
        test_framework:
          - minitest
          - test_unit
    env:
      BUNDLE_GEMFILE: gemfiles/${{ matrix.appraisal }}.gemfile
      TEST_FRAMEWORK: ${{ matrix.test_framework }}
    steps:
      - uses: actions/checkout@v3
      - name: Set up Ruby
        id: set-up-ruby
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: ${{ matrix.ruby }}
      - uses: actions/cache@v3
        with:
          path: vendor/bundle
          key: v1-rubygems-local-${{ runner.os }}-${{ matrix.ruby }}-${{ hashFiles(format('gemfiles/{0}.gemfile.lock', matrix.appraisal)) }}
      - name: Install dependencies
        run: bundle install --jobs=3 --retry=3
      - name: Run Tests
        run: bundle exec rake


================================================
FILE: .github/workflows/dynamic-readme.yml
================================================
name: update-templates

on: 
  push:
    branches:
      - main
  workflow_dispatch:

jobs:
  update-templates:
    permissions:
      contents: write
      pull-requests: write
      pages: write
    uses: thoughtbot/templates/.github/workflows/dynamic-readme.yaml@main
    secrets:
      token: ${{ secrets.GITHUB_TOKEN }}


================================================
FILE: .github/workflows/dynamic-security.yml
================================================
name: update-security

on:
  push:
    paths:
      - SECURITY.md
    branches:
      - main
  workflow_dispatch:

jobs:
  update-security:
    permissions:
      contents: write
      pull-requests: write
      pages: write
    uses: thoughtbot/templates/.github/workflows/dynamic-security.yaml@main
    secrets:
      token: ${{ secrets.GITHUB_TOKEN }}


================================================
FILE: .github/workflows/rubocop.yml
================================================
name: RuboCop

on: [push, pull_request]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    - name: Checkout Repository
      uses: actions/checkout@v3

    - name: Setup Ruby
      uses: ruby/setup-ruby@v1

    - name: Cache gems
      uses: actions/cache@v3
      with:
        path: ../vendor/bundle
        key: ${{ runner.os }}-rubocop-${{ hashFiles('**/Gemfile.lock') }}
        restore-keys: |
          ${{ runner.os }}-rubocop-

    - name: Install gems
      run: |
        bundle config path ../vendor/bundle
        bundle install --jobs 4 --retry 3

    - name: Run RuboCop
      run: bundle exec rubocop --parallel


================================================
FILE: .gitignore
================================================
.bundle
vendor/ruby
vendor/cache
doc
coverage
pkg
*.swp
*.swo
tags
tmp


================================================
FILE: .rubocop.yml
================================================
inherit_from: .rubocop_todo.yml

AllCops:
  TargetRubyVersion: 2.7
  Exclude:
    - '*.gemspec'
Layout/AlignParameters:
  EnforcedStyle: with_fixed_indentation
Layout/ConditionPosition:
  Enabled: false
Layout/DotPosition:
  EnforcedStyle: trailing
Layout/MultilineMethodCallIndentation:
  EnforcedStyle: indented
Lint/AmbiguousOperator:
  Enabled: false
Lint/AmbiguousRegexpLiteral:
  Enabled: false
Lint/AssignmentInCondition:
  Enabled: false
Lint/DeprecatedClassMethods:
  Enabled: false
Lint/ElseLayout:
  Enabled: false
Lint/HandleExceptions:
  Enabled: false
Lint/IndentHeredoc:
  Enabled: false
Lint/LiteralInInterpolation:
  Enabled: false
Lint/Loop:
  Enabled: false
Lint/ParenthesesAsGroupedExpression:
  Enabled: false
Lint/RequireParentheses:
  Enabled: false
Lint/UnderscorePrefixedVariableName:
  Enabled: false
Lint/Void:
  Enabled: false
Metrics/BlockLength:
  Enabled: false
Metrics/ClassLength:
  Enabled: false
Metrics/LineLength:
  IgnoredPatterns:
    - "^[ ]*describe.+$"
    - "^[ ]*context.+$"
    - "^[ ]*shared_context.+$"
    - "^[ ]*shared_examples_for.+$"
    - "^[ ]*it.+$"
    - "^[ ]*'.+?' => '.+?',?$"
    - "^[ ]*\".+?\" => \".+?\",?$"
    - "^[ ]*.+?: .+?$"
Metrics/MethodLength:
  Max: 30
Naming/AccessorMethodName:
  Enabled: false
Naming/AsciiIdentifiers:
  Enabled: false
Naming/BinaryOperatorParameterName:
  Enabled: false
Naming/MemoizedInstanceVariableName:
  EnforcedStyleForLeadingUnderscores: required
Style/ClassVars:
  Enabled: false
Style/ColonMethodCall:
  Enabled: false
Naming/FileName:
  Enabled: false
Rails:
  Enabled: true
Rails/Delegate:
  Enabled: false
Rails/HttpPositionalArguments:
  Enabled: false
Style/Alias:
  Enabled: false
Style/ArrayJoin:
  Enabled: false
Style/AsciiComments:
  Enabled: false
Style/Attr:
  Enabled: false
Style/CaseEquality:
  Enabled: false
Style/CharacterLiteral:
  Enabled: false
Style/ClassAndModuleChildren:
  Enabled: false
Style/CollectionMethods:
  PreferredMethods:
    find: detect
    reduce: inject
    collect: map
    find_all: select
Style/CommentAnnotation:
  Enabled: false
Style/Documentation:
  Enabled: false
Style/DoubleNegation:
  Enabled: false
Style/EachWithObject:
  Enabled: false
Style/EmptyLiteral:
  Enabled: false
Style/Encoding:
  Enabled: false
Style/EvenOdd:
  Enabled: false
Style/ExpandPathArguments:
  Enabled: false
Style/FlipFlop:
  Enabled: false
Style/FormatString:
  Enabled: false
Style/FrozenStringLiteralComment:
  Enabled: false
Style/GlobalVars:
  Enabled: false
Style/GuardClause:
  Enabled: false
Style/IfUnlessModifier:
  Enabled: false
Style/IfWithSemicolon:
  Enabled: false
Style/InlineComment:
  Enabled: false
Style/Lambda:
  Enabled: false
Style/LambdaCall:
  Enabled: false
Style/LineEndConcatenation:
  Enabled: false
Style/MethodCalledOnDoEndBlock:
  Enabled: false
Style/ModuleFunction:
  Enabled: false
Style/NegatedIf:
  Enabled: false
Style/NegatedWhile:
  Enabled: false
Style/Next:
  Enabled: false
Style/NilComparison:
  Enabled: false
Style/Not:
  Enabled: false
Style/NumericLiterals:
  Enabled: false
Style/NumericPredicate:
  Enabled: false
Style/OneLineConditional:
  Enabled: false
Style/PercentLiteralDelimiters:
  Enabled: false
Style/PerlBackrefs:
  Enabled: false
Style/PreferredHashMethods:
  Enabled: false
Style/Proc:
  Enabled: false
Style/RaiseArgs:
  Enabled: false
Style/RegexpLiteral:
  Enabled: false
Style/RescueStandardError:
  Enabled: false
Style/SelfAssignment:
  Enabled: false
Style/SignalException:
  Enabled: false
Style/SingleLineBlockParams:
  Enabled: false
Style/SingleLineMethods:
  Enabled: false
Style/SpecialGlobalVars:
  Enabled: false
Style/StringLiterals:
  EnforcedStyle: double_quotes
Style/SymbolArray:
  Enabled: false
Style/TrivialAccessors:
  Enabled: false
Style/WhenThen:
  Enabled: false
Style/WhileUntilModifier:
  Enabled: false
Style/WordArray:
  Enabled: false
Style/VariableInterpolation:
  Enabled: false


================================================
FILE: .rubocop_todo.yml
================================================
# This configuration was generated by
# `rubocop --auto-gen-config`
# on 2023-02-26 11:25:39 -0300 using RuboCop version 0.71.0.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
# versions of RuboCop, may require this file to be generated again.

# Offense count: 39
# Cop supports --auto-correct.
# Configuration parameters: TreatCommentsAsGroupSeparators, Include.
# Include: **/*.gemfile, **/Gemfile, **/gems.rb
Bundler/OrderedGems:
  Exclude:
    - 'gemfiles/rails_4_2.gemfile'
    - 'gemfiles/rails_5_0.gemfile'
    - 'gemfiles/rails_5_1.gemfile'
    - 'gemfiles/rails_5_2.gemfile'
    - 'gemfiles/rails_6_0.gemfile'

# Offense count: 1
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, IndentationWidth.
# SupportedStyles: with_first_argument, with_fixed_indentation
Layout/AlignArguments:
  Exclude:
    - 'test/shoulda/test_framework_detection_test.rb'

# Offense count: 1
# Cop supports --auto-correct.
Layout/EmptyLineAfterGuardClause:
  Exclude:
    - 'lib/shoulda/context/context.rb'

# Offense count: 5
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: empty_lines, no_empty_lines
Layout/EmptyLinesAroundBlockBody:
  Exclude:
    - 'test/shoulda/context_test.rb'

# Offense count: 1
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: empty_lines, empty_lines_except_namespace, empty_lines_special, no_empty_lines, beginning_only, ending_only
Layout/EmptyLinesAroundClassBody:
  Exclude:
    - 'test/shoulda/context_test.rb'

# Offense count: 1
# Cop supports --auto-correct.
# Configuration parameters: AllowForAlignment, AllowBeforeTrailingComments, ForceEqualSignAlignment.
Layout/ExtraSpacing:
  Exclude:
    - 'Appraisals'

# Offense count: 4
# Cop supports --auto-correct.
Layout/SpaceAfterComma:
  Exclude:
    - 'lib/shoulda/context/assertions.rb'
    - 'lib/shoulda/context/context.rb'
    - 'lib/shoulda/context/tasks/yaml_to_shoulda.rake'

# Offense count: 1
# Cop supports --auto-correct.
Layout/SpaceAfterNot:
  Exclude:
    - 'test/shoulda/should_test.rb'

# Offense count: 2
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces.
# SupportedStyles: space, no_space
# SupportedStylesForEmptyBraces: space, no_space
Layout/SpaceBeforeBlockBraces:
  Exclude:
    - 'lib/shoulda/context/autoload_macros.rb'

# Offense count: 16
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces, SpaceBeforeBlockParameters.
# SupportedStyles: space, no_space
# SupportedStylesForEmptyBraces: space, no_space
Layout/SpaceInsideBlockBraces:
  Exclude:
    - 'exe/convert_to_should_syntax'
    - 'lib/shoulda/context/assertions.rb'
    - 'lib/shoulda/context/autoload_macros.rb'
    - 'lib/shoulda/context/tasks/list_tests.rake'
    - 'test/shoulda/convert_to_should_syntax_test.rb'
    - 'test/shoulda/helpers_test.rb'
    - 'test/shoulda/should_test.rb'

# Offense count: 8
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: space, no_space
Layout/SpaceInsideParens:
  Exclude:
    - 'lib/shoulda/context/tasks/yaml_to_shoulda.rake'

# Offense count: 3
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: final_newline, final_blank_line
Layout/TrailingBlankLines:
  Exclude:
    - 'lib/shoulda/context/context.rb'
    - 'test/fake_rails_root/test/shoulda_macros/custom_macro.rb'
    - 'test/shoulda/autoload_macro_test.rb'

# Offense count: 4
# Cop supports --auto-correct.
# Configuration parameters: IgnoreEmptyBlocks, AllowUnusedKeywordArguments.
Lint/UnusedBlockArgument:
  Exclude:
    - 'exe/convert_to_should_syntax'
    - 'test/shoulda/context_test.rb'

# Offense count: 1
# Cop supports --auto-correct.
# Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods.
Lint/UnusedMethodArgument:
  Exclude:
    - 'lib/shoulda/context/dsl.rb'

# Offense count: 2
Lint/UselessAssignment:
  Exclude:
    - 'lib/shoulda/context/context.rb'

# Offense count: 4
Metrics/AbcSize:
  Max: 22

# Offense count: 1
# Configuration parameters: EnforcedStyle.
# SupportedStyles: lowercase, uppercase
Naming/HeredocDelimiterCase:
  Exclude:
    - 'lib/shoulda/context/context.rb'

# Offense count: 2
# Configuration parameters: Blacklist.
# Blacklist: (?-mix:(^|\s)(EO[A-Z]{1}|END)(\s|$))
Naming/HeredocDelimiterNaming:
  Exclude:
    - 'test/shoulda/convert_to_should_syntax_test.rb'

# Offense count: 5
# Configuration parameters: EnforcedStyleForLeadingUnderscores.
# SupportedStylesForLeadingUnderscores: disallowed, required, optional
Naming/MemoizedInstanceVariableName:
  Exclude:
    - 'lib/shoulda/context/context.rb'
    - 'lib/shoulda/context/dsl.rb'
    - 'lib/shoulda/context/world.rb'

# Offense count: 3
# Cop supports --auto-correct.
# Configuration parameters: PreferredName.
Naming/RescuedExceptionsVariableName:
  Exclude:
    - 'test/shoulda/helpers_test.rb'

# Offense count: 4
# Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames.
# AllowedNames: io, id, to, by, on, in, at, ip, db
Naming/UncommunicativeMethodParamName:
  Exclude:
    - 'lib/shoulda/context/assertions.rb'

# Offense count: 3
# Cop supports --auto-correct.
# Configuration parameters: Include.
# Include: **/test/**/*
Rails/AssertNot:
  Exclude:
    - 'test/shoulda/context_test.rb'
    - 'test/shoulda/should_test.rb'

# Offense count: 1
# Configuration parameters: Include.
# Include: app/**/*.rb, config/**/*.rb, db/**/*.rb, lib/**/*.rb
Rails/Output:
  Exclude:
    - 'lib/shoulda/context/context.rb'

# Offense count: 2
# Cop supports --auto-correct.
# Configuration parameters: Include.
# Include: **/test/**/*
Rails/RefuteMethods:
  Exclude:
    - 'test/shoulda/helpers_test.rb'

# Offense count: 1
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: strict, flexible
Rails/TimeZone:
  Exclude:
    - 'lib/shoulda/context/proc_extensions.rb'

# Offense count: 2
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: always, conditionals
Style/AndOr:
  Exclude:
    - 'lib/shoulda/context/tasks/yaml_to_shoulda.rake'

# Offense count: 20
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, ProceduralMethods, FunctionalMethods, IgnoredMethods, AllowBracesOnProceduralOneLiners.
# SupportedStyles: line_count_based, semantic, braces_for_chaining, always_braces
# ProceduralMethods: benchmark, bm, bmbm, create, each_with_object, measure, new, realtime, tap, with_object
# FunctionalMethods: let, let!, subject, watch
# IgnoredMethods: lambda, proc, it
Style/BlockDelimiters:
  Exclude:
    - 'lib/shoulda/context/context.rb'
    - 'test/shoulda/should_test.rb'

# Offense count: 3
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: compact, expanded
Style/EmptyMethod:
  Exclude:
    - 'test/fake_rails_root/test/shoulda_macros/custom_macro.rb'
    - 'test/fake_rails_root/vendor/gems/gem_with_macro-0.0.1/shoulda_macros/gem_macro.rb'
    - 'test/fake_rails_root/vendor/plugins/plugin_with_macro/shoulda_macros/plugin_macro.rb'

# Offense count: 20
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, UseHashRocketsWithSymbolValues, PreferHashRocketsForNonAlnumEndingSymbols.
# SupportedStyles: ruby19, hash_rockets, no_mixed_keys, ruby19_no_mixed_keys
Style/HashSyntax:
  Exclude:
    - 'lib/shoulda/context/context.rb'
    - 'lib/shoulda/context/dsl.rb'
    - 'test/shoulda/helpers_test.rb'
    - 'test/shoulda/should_test.rb'

# Offense count: 1
Style/MethodMissingSuper:
  Exclude:
    - 'lib/shoulda/context/context.rb'

# Offense count: 1
Style/MissingRespondToMissing:
  Exclude:
    - 'lib/shoulda/context/context.rb'

# Offense count: 3
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: literals, strict
Style/MutableConstant:
  Exclude:
    - 'test/shoulda/convert_to_should_syntax_test.rb'

# Offense count: 2
# Cop supports --auto-correct.
Style/ParallelAssignment:
  Exclude:
    - 'lib/shoulda/context/proc_extensions.rb'
    - 'test/shoulda/should_test.rb'

# Offense count: 1
# Cop supports --auto-correct.
# Configuration parameters: AllowMultipleReturnValues.
Style/RedundantReturn:
  Exclude:
    - 'lib/shoulda/context/context.rb'

# Offense count: 18
# Cop supports --auto-correct.
Style/RedundantSelf:
  Exclude:
    - 'lib/shoulda/context/context.rb'
    - 'lib/shoulda/context/dsl.rb'
    - 'lib/shoulda/context/world.rb'
    - 'test/shoulda/should_test.rb'

# Offense count: 1
# Cop supports --auto-correct.
# Configuration parameters: ConvertCodeThatCanStartToReturnNil, Whitelist.
# Whitelist: present?, blank?, presence, try, try!
Style/SafeNavigation:
  Exclude:
    - 'lib/shoulda/context/dsl.rb'

# Offense count: 2
# Cop supports --auto-correct.
# Configuration parameters: AllowAsExpressionSeparator.
Style/Semicolon:
  Exclude:
    - 'lib/shoulda/context/assertions.rb'

# Offense count: 70
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, ConsistentQuotesInMultiline.
# SupportedStyles: single_quotes, double_quotes
Style/StringLiterals:
  Exclude:
    - 'Appraisals'
    - 'bin/supported_ruby_versions'
    - 'exe/convert_to_should_syntax'
    - 'lib/shoulda/context/autoload_macros.rb'
    - 'lib/shoulda/context/context.rb'
    - 'lib/shoulda/context/dsl.rb'
    - 'lib/shoulda/context/tasks.rb'
    - 'lib/shoulda/context/tasks/list_tests.rake'
    - 'lib/shoulda/context/tasks/yaml_to_shoulda.rake'
    - 'test/shoulda/autoload_macro_test.rb'
    - 'test/shoulda/context_test.rb'
    - 'test/shoulda/convert_to_should_syntax_test.rb'
    - 'test/shoulda/helpers_test.rb'
    - 'test/shoulda/should_test.rb'

# Offense count: 1
# Cop supports --auto-correct.
# Configuration parameters: IgnoredMethods.
# IgnoredMethods: respond_to, define_method
Style/SymbolProc:
  Exclude:
    - 'lib/shoulda/context/context.rb'

# Offense count: 55
# Cop supports --auto-correct.
# Configuration parameters: AutoCorrect, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
# URISchemes: http, https
Metrics/LineLength:
  Max: 155


================================================
FILE: .ruby-version
================================================
2.7.7


================================================
FILE: Appraisals
================================================
# Note: All of the dependencies here were obtained by running `rails new` with
# various versions of Rails and copying lines from the generated Gemfile. It's
# best to keep the gems here in the same order as they're listed there so you
# can compare them more easily.

shared_rails_dependencies = proc do
  gem "sqlite3", "~> 1.3.6"
end

shared_spring_dependencies = proc do
  gem "spring"
  gem "spring-commands-rspec"
end

shared_test_dependencies = proc do
  gem "minitest-reporters"
end

shared_dependencies = proc do
  instance_eval(&shared_rails_dependencies)
  instance_eval(&shared_spring_dependencies)
  instance_eval(&shared_test_dependencies)
end

appraise "rails_6_0" do
  instance_eval(&shared_dependencies)

  gem "rails", "~> 6.0.2"
  gem "puma", "~> 4.1"
  gem "sass-rails", ">= 6"
  gem "webpacker", "~> 4.0"
  gem "turbolinks", "~> 5"
  gem "jbuilder", "~> 2.7"
  gem "bcrypt", "~> 3.1.7"
  gem "bootsnap", ">= 1.4.2", require: false
  gem "listen", ">= 3.0.5", "< 3.2"
  gem "spring-watcher-listen", "~> 2.0.0"
  gem "capybara", ">= 2.15"
  gem "selenium-webdriver"
  gem "sqlite3", "~> 1.4.0"
  gem "webdrivers"

  # Other dependencies
  gem "rails-controller-testing", ">= 1.0.4"
  gem "pg", "~> 1.1", platform: :ruby
end

appraise "rails_6_1" do
  instance_eval(&shared_dependencies)

  gem "rails", "~> 6.1.3.2"
  gem "puma", "~> 5.0"
  gem "sass-rails", ">= 6"
  gem "turbolinks", "~> 5"
  gem "jbuilder", "~> 2.7"
  gem "bcrypt", "~> 3.1.7"
  gem "bootsnap", ">= 1.4.2", require: false
  gem "listen", ">= 3.0.5", "< 3.2"
  gem "spring-watcher-listen", "~> 2.0.0"
  gem "capybara", ">= 2.15"
  gem "selenium-webdriver"
  gem "sqlite3", "~> 1.4.0"
  gem "webdrivers"

  # Other dependencies
  gem "rails-controller-testing", ">= 1.0.4"
  gem 'pg', '>= 0.18', '< 2.0'
end


================================================
FILE: CHANGELOG.md
================================================
# Changelog

## 3.0.0.rc1 - 2024-04-21

### Backward-incompatible changes

* Drop support for Ruby 2.5 and 2.6 by @vsppedro. Ruby 2.7.x is the only version supported now. ([#76], [#77], [#78])
* Drop support for Rails 4.2, 5.0, 5.1 and 5.2 by @vsppedro. Rails 6.0.x and Rails 6.1.x are the only versions supported now. ([#79], [#80], [#81], [#82])

[#74]: https://github.com/thoughtbot/shoulda-context/pull/74
[#76]: https://github.com/thoughtbot/shoulda-context/pull/76
[#77]: https://github.com/thoughtbot/shoulda-context/pull/77
[#78]: https://github.com/thoughtbot/shoulda-context/pull/78
[#79]: https://github.com/thoughtbot/shoulda-context/pull/79
[#80]: https://github.com/thoughtbot/shoulda-context/pull/80
[#81]: https://github.com/thoughtbot/shoulda-context/pull/81
[#82]: https://github.com/thoughtbot/shoulda-context/pull/82

### Bug fixes

* Fix broken thoughtbot logo on README.md by @sarahraqueld. ([#0551d18c92eebd94db70917d668202508b7d2268])
* Use proper source location for should calls without a block by @segiddins. ([#92])
* Fix the link to the gem on Rubygems in the README by @mcmire and @0xRichardH. ([#1098f5beb9b49a9d88434f6b3b6ccb58b2dfe93f])
* Fix a method redefinition warning by @Earlopain. ([#94])

[#0551d18c92eebd94db70917d668202508b7d2268]: https://github.com/thoughtbot/shoulda-context/commit/0551d18c92eebd94db70917d668202508b7d2268
[#92]: https://github.com/thoughtbot/shoulda-context/pull/92
[#94]: https://github.com/thoughtbot/shoulda-context/pull/94

### Features

* Add support for Rails 6.1 by @vsppedro. ([#84])

[#84]: https://github.com/thoughtbot/shoulda-context/pull/84

### Improvements

* Update README for consistency across all shoulda-* gems by @mcmire. ([#5da1895f6c9917bc2aa0a248c209edb453a1340e])
* Bump warnings_logger to 0.1.1 by @mcmire. ([#970d3d57a584ecb2652f0bc7188761024de16c52])
* Add 'Getting started' section to the README by @mcmire. ([#52915f3a3cb36ae0494cfbacccc162b95932ca24])
* Switch to Github Actions by @vsppedro. ([#74], [#83])
* Do fewer intermediary allocations when calculating test methods by @segiddins. ([#89])
* Call dynamic-readme reusable workflow by @stefannibrasil. ([#95])

[#5da1895f6c9917bc2aa0a248c209edb453a1340e]: https://github.com/thoughtbot/shoulda-context/commit/5da1895f6c9917bc2aa0a248c209edb453a1340e
[#970d3d57a584ecb2652f0bc7188761024de16c52]: https://github.com/thoughtbot/shoulda-context/commit/970d3d57a584ecb2652f0bc7188761024de16c52
[#52915f3a3cb36ae0494cfbacccc162b95932ca24]: https://github.com/thoughtbot/shoulda-context/commit/52915f3a3cb36ae0494cfbacccc162b95932ca24
[#1098f5beb9b49a9d88434f6b3b6ccb58b2dfe93f]: https://github.com/thoughtbot/shoulda-context/commit/1098f5beb9b49a9d88434f6b3b6ccb58b2dfe93f
[#83]: https://github.com/thoughtbot/shoulda-context/pull/83
[#89]: https://github.com/thoughtbot/shoulda-context/pull/89
[#95]: https://github.com/thoughtbot/shoulda-context/pull/95

## 2.0.0 (2020-06-13)

### Backward-incompatible changes

* Drop support for RSpec 2 matchers. Matchers passed to `should` must conform
  to RSpec 3's API (`failure_message` and `failure_message_when_negated`).
* Drop support for older versions of Rails. Rails 4.x-6.x are the
  only versions supported now.
* Drop support for older versions of Ruby. Ruby 2.4.x-2.7.x are the only
  versions supported now.

### Bug fixes

* Fix how test names are generated so that when including the name of the
  outermost test class, "Test" is not removed from the class name if it does not
  fall at the end.
* Remove warning from Ruby about `context` not being used when using the gem
  with warnings enabled.
* Fix macro autoloading code. Files intended to hold custom macros which are
  located in either `test/shoulda_macros`, `vendor/gems/*/shoulda_macros`, or
  `vendor/plugins/*/shoulda_macros` are now loaded and mixed into your test
  framework's automatically.
* Restore compatibility with Shoulda Matchers, starting from 3.0.
* Fix some compatibility issues with Minitest 5.
* Fix running tests within a Rails < 5.2 environment so that when tests fail, an
  error is not produced claiming that Minitest::Result cannot find a test
  method.


================================================
FILE: Gemfile
================================================
source "https://rubygems.org"

gemspec

gem "appraisal"
gem "bundler", "~> 1.0"
gem "byebug"
gem "m"
gem "minitest"
gem "mocha"
gem "pry", "~> 0.12.0"
gem "pry-byebug", "~> 3.6.0"
gem "rake"
gem "rubocop", "0.71.0"
gem "snowglobe", ">= 0.3.0"
gem "test-unit"
gem "warnings_logger"


================================================
FILE: LICENSE
================================================
Copyright (c) Tammer Saleh and thoughtbot, inc.

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.


================================================
FILE: MAINTAINING.md
================================================
# Maintaining Shoulda Context

Although Shoulda Context doesn't receive feature updates these days, you may
need to update the gem for new versions of Ruby or Rails. Here's what you need
to know in order to do that.

## Getting started

First, run the setup script:

    bin/setup

Then run all the tests to make sure everything is green:

    bundle exec rake

## Running tests

This project uses Minitest for tests and Appraisal to create environments
attuned for different versions of Rails. To run a single test in a single test
file, you will need to use a combination of Appraisal and the [`m`][m] gem. For
instance:

[m]: https://github.com/qrush/m

    bundle exec appraisal rails_6_0 m test/shoulda/context_test.rb:39

## Updating the changelog

After every user-facing change makes it into master, we make a note of it in the
changelog, kept in `CHANGELOG.md`. The changelog is sorted in reverse order by
release version, with the topmost version as the next release (tagged as
"(Unreleased)").

Within each version, there are five available categories you can divide changes
into. They are all optional but they should appear in this order:

1. Backward-compatible changes
1. Deprecations
1. Bug fixes
1. Features
1. Improvements

Within each category section, the changes relevant to that category are listed
in chronological order.

For each change, provide a human-readable description of the change as well as a
linked reference to the PR where that change emerged (or the commit ID if no
such PR is available). This helps users cross-reference changes if they need to.

## Versioning

### Naming a new version

As designated in the README, we follow [SemVer 2.0][semver]. This offers a
meaningful baseline for deciding how to name versions. Generally speaking:

[semver]: https://semver.org/spec/v2.0.0.html

* We bump the "major" part of the version if we're introducing
  backward-incompatible changes (e.g. changing the API or core behavior,
  removing parts of the API, or dropping support for a version of Ruby).
* We bump the "minor" part if we're adding a new feature (e.g. adding a new
  matcher or adding a new qualifier to a matcher).
* We bump the "patch" part if we're merely including bugfixes.

In addition to major, minor, and patch levels, you can also append a
suffix to the version for pre-release versions. We usually use this to issue
release candidates prior to an actual release. A version number in this case
might look like `4.0.0.rc1`.

### Preparing and releasing a new version

In order to release any versions at all, you will need to have been added as
an owner of the Ruby gem. If you want to give someone else these permissions,
then run:

```bash
gem owner shoulda-context -a <email address>
```

Assuming you have permission to publish a new version to RubyGems, then this is
how you release a version:

1. First, you'll want to [make sure that the changelog is up to
   date](#updating-the-changelog).

2. Next, you'll want to update the `VERSION` constant in
   `lib/shoulda/context/version.rb`. This constant is referenced in the
   gemspec and is used in the Rake tasks to publish the gem on RubyGems.

3. Assuming that everything looks good, place your changes to the changelog,
   `version.rb`, and README in their own commit titled "Bump version to
   *X.Y.Z*". Push this to GitHub (you can use `[ci skip]`) in the body of the
   commit message to skip CI for this commit if you so choose). **There is no
   going back after this point!**

6. Once GitHub has the version-change commit, you will run:

   ```bash
   rake release
   ```

   This will push the gem to RubyGems and make it available for download.


================================================
FILE: README.md
================================================
# Shoulda Context [![Gem Version][version-badge]][rubygems] [![Build Status][travis-badge]][travis] ![Downloads][downloads-badge] [![Hound][hound-badge]][hound]

[version-badge]: https://img.shields.io/gem/v/shoulda-context.svg
[rubygems]: https://rubygems.org/gems/shoulda-context
[travis-badge]: https://img.shields.io/travis/thoughtbot/shoulda-context/master.svg
[travis]: https://travis-ci.org/thoughtbot/shoulda-context
[downloads-badge]: https://img.shields.io/gem/dtv/shoulda-context.svg
[hound-badge]: https://img.shields.io/badge/Reviewed_by-Hound-8E64B0.svg
[hound]: https://houndci.com

Shoulda Context makes it easy to write understandable and maintainable tests
under Minitest and Test::Unit within Rails projects or plain Ruby projects. It's
fully compatible with your existing tests and requires no retooling to use.

## Quick links

📖 **[Read the documentation for the latest version.][rubydocs]**
📢 **[See what's changed in recent versions.][changelog]**

[rubydocs]: http://rubydoc.info/github/thoughtbot/shoulda-context/master/frames
[changelog]: CHANGELOG.md

[shoulda-context]: https://github.com/thoughtbot/shoulda-context

## Getting started

If you're working on a Rails app, then make sure to add this gem to the `test`
group in your Gemfile:

``` ruby
group :test do
  gem 'shoulda-context', '~> 3.0.0.rc1'
end
```

If you're not working on a Rails app, then you can simply add:

``` ruby
gem 'shoulda-context', '~> 3.0.0.rc1'
```

Then run `bundle install`.

## Overview

Instead of writing Ruby methods with `lots_of_underscores`, Shoulda Context lets
you name your tests and group them together using English.

At a minimum, the gem provides some convenience layers around core Minitest /
Test::Unit functionality. For instance, this test case:

```ruby
class CalculatorTest < Minitest::Test
  context "a calculator" do
    setup do
      @calculator = Calculator.new
    end

    should "add two numbers for the sum" do
      assert_equal 4, @calculator.sum(2, 2)
    end

    should "multiply two numbers for the product" do
      assert_equal 10, @calculator.product(2, 5)
    end
  end
end
```

turns into:

```ruby
class CalculatorTest < Minitest::Test
  def setup
    @calculator = Calculator.new
  end

  define_method "test_: a calculator should add two numbers for the sum" do
    assert_equal 4, @calculator.sum(2, 2)
  end

  define_method "test_: a calculator should multiply two numbers for the product" do
    assert_equal 10, @calculator.product(2, 5)
  end
end
```

However, Shoulda Context also provides functionality apart from Minitest /
Test::Unit that allows you to shorten tests drastically by making use of
RSpec-compatible matchers. For instance, with [Shoulda
Matchers][shoulda-matchers] you can write such tests as:

```ruby
class User < ActiveSupport::TestCase
  context "validations" do
    subject { FactoryBot.build(:user) }

    should validate_presence_of(:first_name)
    should validate_presence_of(:last_name)
    should validate_uniqueness_of(:email)
    should_not allow_value('weird').for(:email)
  end
end
```

[shoulda-matchers]: https://github.com/thoughtbot/shoulda-matchers

## API

### DSL

The primary method in Shoulda Context's API is `context`, which declares a group
of a tests.

These methods are available inside of a `context`:

* `setup` — a DSL-y alternative to defining a `setup` method
* `teardown` — a DSL-y alternative to defining a `teardown` method
* `should` — There are two forms:
  1. when passed a name + block, creates a test equivalent to defining a
  `test_` method
  2. when passed a matcher, creates a test that will run the matcher, asserting
  that it passes
* `should_not` — like the matcher version of `should`, but creates a test that
  asserts that the matcher fails
* `should_eventually` — allows you to temporarily skip tests
* `context` — creates a subcontext

These methods are available within a test case class, but outside of a
`context`:

* `should` — same as above
* `should_not` — same as above
* `should_eventually` — same as above
* `described_type` — returns the class being tested, as determined by the class
  name of the outermost class
* `subject` — lets you define an object that is the primary focus of the tests
  within a context; this is most useful when using a matcher as the matcher will
  make use of this as _its_ subject

And these methods are available inside of a test (whether defined via a method
or via `should`):

* `subject` — an instance of the class under test, which is derived
  automatically from the name of the test case class but is overridable via the
  class method version of `subject` above

### Assertions

In addition to the main API, the gem also provides some extra assertions that
may be of use:

* `assert_same_elements` — compares two arrays for equality, but ignoring
  ordering
* `assert_contains` — asserts that an array has an item
* `assert_does_not_contain` — the opposite of `assert_contains`
* `assert_accepts` — what `should` uses internally; asserts that a matcher
  object matches against a value
* `assert_reject` — what `should_not` uses internally; asserts that a matcher
  object does not match against a value

## Compatibility

Shoulda Context is [tested][travis] and supported against Ruby 2.7+, Rails 6.0+,
Minitest 4.x, and Test::Unit 3.x.

## Versioning

Shoulda Context follows Semantic Versioning 2.0 as defined at
<http://semver.org>.

## Team

Shoulda Context is currently maintained by [Pedro Paiva][VSPPedro]. Previous
maintainers include [Elliot Winkler][mcmire], [Travis Jeffery][travisjeffery],
[Gabe Berke-Williams][gabebw], [Ryan McGeary][rmm5t], [Joe Ferris][jferris], [Dan
Croaky][croaky], and [Tammer Saleh][tammersaleh].

[VSPPedro]: https://github.com/VSPPedro
[mcmire]: https://github.com/mcmire
[travisjeffery]: https://github.com/travisjeffery
[gabebw]: https://github.com/gabebw
[rmm5t]: https://github.com/rmm5t
[jferris]: https://github.com/jferris
[croaky]: https://github.com/croaky
[tammersaleh]: https://github.com/tammersaleh

## Copyright/License

Shoulda Context is copyright © Tammer Saleh and [thoughtbot,
inc][thoughtbot-website]. It is free and opensource software and may be
redistributed under the terms specified in the [LICENSE](LICENSE) file.

[thoughtbot-website]: https://thoughtbot.com?utm_source=github

<!-- START /templates/footer.md -->
## About thoughtbot

![thoughtbot](https://thoughtbot.com/thoughtbot-logo-for-readmes.svg)

This repo is maintained and funded by thoughtbot, inc.
The names and logos for thoughtbot are trademarks of thoughtbot, inc.

We love open source software!
See [our other projects][community].
We are [available for hire][hire].

[community]: https://thoughtbot.com/community?utm_source=github
[hire]: https://thoughtbot.com/hire-us?utm_source=github


<!-- END /templates/footer.md -->


================================================
FILE: Rakefile
================================================
require "bundler/setup"
require "bundler/gem_tasks"
require "rake/testtask"
require "pry-byebug"

require_relative "test/support/current_bundle"

load "tasks/shoulda.rake"

Rake::TestTask.new do |t|
  t.libs << "test"
  t.ruby_opts += ["-w"]
  t.pattern = "test/**/*_test.rb"
  t.verbose = true
end

task :default do
  if Tests::CurrentBundle.instance.appraisal_in_use?
    Rake::Task["test"].invoke
  elsif ENV["CI"]
    exec "appraisal install && appraisal rake --trace"
  else
    appraisal = Tests::CurrentBundle.instance.latest_appraisal
    exec "appraisal install && appraisal #{appraisal} rake --trace"
  end
end


================================================
FILE: SECURITY.md
================================================
<!-- START /templates/security.md -->
# Security Policy

## Supported Versions

Only the the latest version of this project is supported at a given time. If
you find a security issue with an older version, please try updating to the
latest version first.

If for some reason you can't update to the latest version, please let us know
your reasons so that we can have a better understanding of your situation.

## Reporting a Vulnerability

For security inquiries or vulnerability reports, visit
<https://thoughtbot.com/security>.

If you have any suggestions to improve this policy, visit <https://thoughtbot.com/security>.

<!-- END /templates/security.md -->


================================================
FILE: bin/install_gems_in_all_appraisals
================================================
#!/bin/bash

set -euo pipefail

SUPPORTED_VERSIONS=$(bin/supported_ruby_versions)

install-gems-for-version() {
  local version="$1"
  (export RBENV_VERSION=$version; bundle && bundle exec appraisal install)
}

for version in $SUPPORTED_VERSIONS; do
  echo
  echo "*** Installing gems for $version ***"
  install-gems-for-version $version
done


================================================
FILE: bin/run_all_tests
================================================
#!/bin/bash

set -euo pipefail

SUPPORTED_VERSIONS=$(bin/supported_ruby_versions)

run-tests-for-version() {
  local version="$1"
  (export RBENV_VERSION=$version; bundle exec rake)
}

for version in $SUPPORTED_VERSIONS; do
  echo
  echo "*** Running tests for $version ***"
  run-tests-for-version $version
done


================================================
FILE: bin/setup
================================================
#!/usr/bin/env bash

set -euo pipefail

RUBY_VERSION=$(bin/supported_ruby_versions | xargs -n 1 echo | sort -V | tail -n 1)

cd "$(dirname "$(dirname "$0")")"

uname=$(uname)

if [[ $uname == 'Darwin' ]]; then
  platform='mac'
else
  platform='linux'
fi

banner() {
  echo -e "\033[34m== $@ ==\033[0m"
}

success() {
  echo -e "\033[32m$@\033[0m"
}

warning() {
  echo -e "\033[33m$@\033[0m"
}

error() {
  echo -e "\033[31m$@\033[0m"
}

has-executable() {
  type "$1" &>/dev/null
}

is-running() {
  pgrep "$1" >/dev/null
}

install() {
  local apt_package=""
  local rpm_package=""
  local brew_package=""
  local default_package=""
  local package=""

  for arg in "$@"; do
    case $arg in
      apt=*)
        apt_package="$arg"
        ;;
      rpm=*)
        rpm_package="$arg"
        ;;
      brew=*)
        brew_package="$arg"
        ;;
      *)
        default_package="$arg"
        ;;
    esac
  done

  if has-executable brew; then
    package="${brew_package:-$default_package}"

    if [[ -n $package ]]; then
      brew install "$package"
    fi
  elif has-executable apt-get; then
    package="${apt_package:-$default_package}"

    if [[ -n $package ]]; then
      sudo apt-get install -y "$package"
    fi
  elif has-executable yum; then
    package="${yum_package:-$default_package}"

    if [[ -n $package ]]; then
      sudo yum install -y "$package"
    fi
  else
    error "Sorry, I'm not sure how to install $default_package."
    exit 1
  fi
}

check-for-build-tools() {
  if [[ $platform == "linux" ]]; then
    if ! has-executable apt-get; then
      error "You don't seem to have a package manager installed."
      echo "The setup script assumes you're using Debian or a Debian-derived flavor of Linux"
      echo "(i.e. something with Apt). If this is not the case, then we would gladly take a"
      echo "PR fixing this!"
      exit 1
    fi

    # TODO: Check if build-essential is installed on Debian?
  else
    if ! has-executable brew; then
      error "You don't seem to have Homebrew installed."
      echo
      echo "Follow the instructions here to do this:"
      echo
      echo "http://brew.sh"
      exit 1
    fi

    # TODO: Check that OS X Command Line Tools are installed?
  fi
}

install-development-libraries() {
  install apt=ruby-dev rpm=ruby-devel
  install rpm=zlib-devel
}

install-dependencies() {
  if ! has-executable sqlite3; then
    banner 'Installing SQLite 3'
    install sqlite3
    install apt=libsqlite3-dev rpm=sqlite-devel
  fi

  if ! has-executable psql; then
    banner 'Installing PostgreSQL'
    install postgresql
    install apt=libpq-dev rpm=postgresql-devel
  fi

  if ! is-running postgres; then
    banner 'Starting PostgreSQL'
    start postgresql
  fi

  if ! has-executable heroku; then
    banner 'Installing Heroku'
    install heroku/brew/heroku heroku
  fi

  if has-executable rbenv; then
    if ! (rbenv versions | grep $RUBY_VERSION'\>' &>/dev/null); then
      banner "Installing Ruby $RUBY_VERSION with rbenv"
      rbenv install --skip-existing "$RUBY_VERSION"
    fi
  elif has-executable rvm; then
    if ! (rvm ls | grep $RUBY_VERSION'\>' &>/dev/null); then
      banner "Installing Ruby $RUBY_VERSION with rvm"
      error "You don't seem to have Ruby $RUBY_VERSION installed."
      echo
      echo "Use RVM to do so, and then re-run this command."
      echo
    fi
  else
    error "You don't seem to have a Ruby manager installed."
    echo
    echo 'We recommend using rbenv. You can find installation instructions here:'
    echo
    echo 'http://github.com/rbenv/rbenv'
    echo
    echo "When you're done, simply re-run this script!"
    exit 1
  fi

  banner 'Installing Ruby dependencies'
  gem install bundler -v '~> 1.0' --conservative
  bundle check || bundle install
  bundle exec appraisal install

  if ! has-executable node; then
    banner 'Installing Node'

    if [[ $platform == 'linux' ]]; then
      curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -

      install nodejs

      if ! has-executable npm; then
        install npm
      fi
    else
      install nodejs
    fi
  fi
}

check-for-build-tools
install-development-libraries
install-dependencies


================================================
FILE: bin/supported_ruby_versions
================================================
#!/usr/bin/env ruby

require 'yaml'

ci_config_path = File.expand_path('../../.github//workflows/ci.yml', __FILE__)
ci_config = YAML.load_file(ci_config_path)
puts ci_config.dig('jobs', 'build', 'strategy', 'matrix', 'ruby').join(' ')


================================================
FILE: bin/update_gem_in_all_appraisals
================================================
#!/bin/bash

set -euo pipefail

SUPPORTED_VERSIONS=$(bin/supported_ruby_versions)
gem="$1"

update-gem-for-version() {
  local version="$1"
  (export RBENV_VERSION=$version; bundle update "$gem"; bundle exec appraisal update "$gem")
}

for version in $SUPPORTED_VERSIONS; do
  echo
  echo "*** Updating $gem for $version ***"
  update-gem-for-version $version
done


================================================
FILE: bin/update_gems_in_all_appraisals
================================================
#!/bin/bash

set -euo pipefail

SUPPORTED_VERSIONS=$(bin/supported_ruby_versions)

update-gems-for-version() {
  local version="$1"
  (export RBENV_VERSION=$version; bundle update "${@:2}"; bundle exec appraisal update "${@:2}")
}

for version in $SUPPORTED_VERSIONS; do
  echo
  echo "*** Updating gems for $version ***"
  update-gems-for-version "$version" "$@"
done


================================================
FILE: exe/convert_to_should_syntax
================================================
#!/usr/bin/env ruby
require 'fileutils'
require 'tmpdir'

TMP = Dir::tmpdir

def usage(msg = nil)
  puts "Error: #{msg}" if msg
  puts if msg
  puts "Usage: #{File.basename(__FILE__)} normal_test_file.rb"
  puts
  puts "Will convert an existing test file with names like "
  puts
  puts "  def test_should_do_stuff"
  puts "    ..."
  puts "  end"
  puts
  puts "to one using the new syntax: "
  puts
  puts "  should \"be super cool\" do"
  puts "    ..."
  puts "  end"
  puts
  puts "A copy of the old file will be left under #{TMP} in case\nthis script just seriously screws up"
  puts
  exit (msg ? 2 : 0)
end

usage("Wrong number of arguments.") unless ARGV.size == 1
usage("Temp directory '#{TMP}' is not valid. Set TMPDIR environment variable to a writeable directory.") unless File.directory?(TMP) && File.writable?(TMP)

file = ARGV.shift
tmpfile = File.join(TMP, File.basename(file))
usage("File '#{file}' doesn't exist") unless File.exist?(file)

FileUtils.cp(file, tmpfile)
contents = File.read(tmpfile)
contents.gsub!(/def test_should_(\S+)/) {|line| "should \"#{$1.tr('_', ' ')}\" do"}
contents.gsub!(/def test_(\S+)/) {|line| "should \"RENAME ME: test #{$1.tr('_', ' ')}\" do"}
File.open(file, 'w') { |f| f.write(contents) }

puts "File '#{file}' has been converted to 'should' syntax.  Old version has been stored in '#{tmpfile}'"


================================================
FILE: gemfiles/rails_6_0.gemfile
================================================
# This file was generated by Appraisal

source "https://rubygems.org"

gem "appraisal"
gem "bundler", "~> 1.0"
gem "byebug"
gem "m"
gem "minitest"
gem "mocha"
gem "pry", "~> 0.12.0"
gem "pry-byebug", "~> 3.6.0"
gem "rake"
gem "rubocop", "0.71.0"
gem "snowglobe", ">= 0.3.0"
gem "test-unit"
gem "warnings_logger"
gem "sqlite3", "~> 1.4.0"
gem "spring"
gem "spring-commands-rspec"
gem "minitest-reporters"
gem "rails", "~> 6.0.2"
gem "puma", "~> 4.1"
gem "sass-rails", ">= 6"
gem "webpacker", "~> 4.0"
gem "turbolinks", "~> 5"
gem "jbuilder", "~> 2.7"
gem "bcrypt", "~> 3.1.7"
gem "bootsnap", ">= 1.4.2", require: false
gem "listen", ">= 3.0.5", "< 3.2"
gem "spring-watcher-listen", "~> 2.0.0"
gem "capybara", ">= 2.15"
gem "selenium-webdriver"
gem "webdrivers"
gem "rails-controller-testing", ">= 1.0.4"
gem "pg", "~> 1.1", platform: :ruby

gemspec path: "../"


================================================
FILE: gemfiles/rails_6_1.gemfile
================================================
# This file was generated by Appraisal

source "https://rubygems.org"

gem "appraisal"
gem "bcrypt", "~> 3.1.7"
gem "bootsnap", ">= 1.4.2", require: false
gem "bundler", "~> 1.0"
gem "byebug"
gem "capybara", ">= 2.15"
gem "jbuilder", "~> 2.7"
gem "listen", ">= 3.0.5", "< 3.2"
gem "m"
gem "minitest"
gem "minitest-reporters"
gem "mocha"
gem "pg", ">= 0.18", "< 2.0"
gem "pry", "~> 0.12.0"
gem "pry-byebug", "~> 3.6.0"
gem "puma", "~> 5.0"
gem "rails", "~> 6.1.3.2"
gem "rails-controller-testing", ">= 1.0.4"
gem "rake"
gem "rubocop", "0.71.0"
gem "sass-rails", ">= 6"
gem "selenium-webdriver"
gem "snowglobe", ">= 0.3.0"
gem "spring"
gem "spring-commands-rspec"
gem "spring-watcher-listen", "~> 2.0.0"
gem "sqlite3", "~> 1.4.0"
gem "test-unit"
gem "turbolinks", "~> 5"
gem "warnings_logger"
gem "webdrivers"

gemspec path: "../"


================================================
FILE: lib/shoulda/context/assertions.rb
================================================
module Shoulda # :nodoc:
  module Context
    module Assertions
      # Asserts that two arrays contain the same elements, the same number of times.  Essentially ==, but unordered.
      #
      #   assert_same_elements([:a, :b, :c], [:c, :a, :b]) => passes)
      def assert_same_elements(a1, a2, msg = nil)
        [:select, :inject, :size].each do |m|
          [a1, a2].each {|a| assert_respond_to(a, m, "Are you sure that #{a.inspect} is an array?  It doesn't respond to #{m}.") }
        end

        assert a1h = a1.inject({}) { |h,e| h[e] ||= a1.select { |i| i == e }.size; h }
        assert a2h = a2.inject({}) { |h,e| h[e] ||= a2.select { |i| i == e }.size; h }

        assert_equal(a1h, a2h, msg)
      end

      # Asserts that the given collection contains item x.  If x is a regular expression, ensure that
      # at least one element from the collection matches x.  +extra_msg+ is appended to the error message if the assertion fails.
      #
      #   assert_contains(['a', '1'], /\d/) => passes
      #   assert_contains(['a', '1'], 'a') => passes
      #   assert_contains(['a', '1'], /not there/) => fails
      def assert_contains(collection, x, extra_msg = "")
        collection = Array(collection)
        msg = "#{x.inspect} not found in #{collection.to_a.inspect} #{extra_msg}"
        case x
        when Regexp
          assert(collection.detect { |e| e =~ x }, msg)
        else
          assert(collection.include?(x), msg)
        end
      end

      # Asserts that the given collection does not contain item x.  If x is a regular expression, ensure that
      # none of the elements from the collection match x.
      def assert_does_not_contain(collection, x, extra_msg = "")
        collection = Array(collection)
        msg = "#{x.inspect} found in #{collection.to_a.inspect} " + extra_msg
        case x
        when Regexp
          assert(!collection.detect { |e| e =~ x }, msg)
        else
          assert(!collection.include?(x), msg)
        end
      end

      # Asserts that the given matcher returns true when +target+ is passed to
      # #matches?
      def assert_accepts(matcher, target, options = {})
        if matcher.respond_to?(:in_context)
          matcher.in_context(self)
        end

        if matcher.matches?(target)
          safe_assert_block { true }
          if options[:message]
            assert_match options[:message], matcher.failure_message_when_negated
          end
        else
          safe_assert_block(matcher.failure_message) { false }
        end
      end

      # Asserts that the given matcher returns true when +target+ is passed to
      # #does_not_match? or false when +target+ is passed to #matches? if
      # #does_not_match? is not implemented
      def assert_rejects(matcher, target, options = {})
        if matcher.respond_to?(:in_context)
          matcher.in_context(self)
        end

        not_match =
          if matcher.respond_to?(:does_not_match?)
            matcher.does_not_match?(target)
          else
            !matcher.matches?(target)
          end

        if not_match
          safe_assert_block { true }
          if options[:message]
            assert_match options[:message], matcher.failure_message
          end
        else
          safe_assert_block(matcher.failure_message_when_negated) { false }
        end
      end

      def safe_assert_block(message = "assert_block failed.", &block)
        if respond_to?(:assert_block)
          assert_block message, &block
        else
          assert yield, message
        end
      end
    end
  end
end


================================================
FILE: lib/shoulda/context/autoload_macros.rb
================================================
module Shoulda # :nodoc:
  # Call autoload_macros when you want to load test macros automatically in a non-Rails
  # project (it's done automatically for Rails projects).
  # You don't need to specify ROOT/test/shoulda_macros explicitly. Your custom macros
  # are loaded automatically when you call autoload_macros.
  #
  # The first argument is the path to you application's root directory.
  # All following arguments are directories relative to your root, which contain
  # shoulda_macros subdirectories. These directories support the same kinds of globs as the
  # Dir class.
  #
  # Basic usage (from a test_helper):
  # Shoulda.autoload_macros(File.dirname(__FILE__) + '/..')
  # will load everything in
  # - your_app/test/shoulda_macros
  #
  # To load vendored macros as well:
  # Shoulda.autoload_macros(APP_ROOT, 'vendor/*')
  # will load everything in
  # - APP_ROOT/vendor/*/shoulda_macros
  # - APP_ROOT/test/shoulda_macros
  #
  # To load macros in an app with a vendor directory laid out like Rails':
  # Shoulda.autoload_macros(APP_ROOT, 'vendor/{plugins,gems}/*')
  # or
  # Shoulda.autoload_macros(APP_ROOT, 'vendor/plugins/*', 'vendor/gems/*')
  # will load everything in
  # - APP_ROOT/vendor/plugins/*/shoulda_macros
  # - APP_ROOT/vendor/gems/*/shoulda_macros
  # - APP_ROOT/test/shoulda_macros
  #
  # If you prefer to stick testing dependencies away from your production dependencies:
  # Shoulda.autoload_macros(APP_ROOT, 'vendor/*', 'test/vendor/*')
  # will load everything in
  # - APP_ROOT/vendor/*/shoulda_macros
  # - APP_ROOT/test/vendor/*/shoulda_macros
  # - APP_ROOT/test/shoulda_macros
  def self.autoload_macros(root, *dirs)
    dirs << File.join('test')
    complete_dirs = dirs.map{|d| File.join(root, d, 'shoulda_macros')}
    all_files     = complete_dirs.inject([]){ |files, dir| files + Dir[File.join(dir, '*.rb')] }
    all_files.each do |file|
      require file
    end
  end
end


================================================
FILE: lib/shoulda/context/configuration.rb
================================================
module Shoulda
  module Context
    def self.configure
      yield self
    end

    def self.include(mod)
      test_framework_test_cases.each do |test_case|
        test_case.class_eval { include mod }
      end
    end

    def self.extend(mod)
      test_framework_test_cases.each do |test_case|
        test_case.extend(mod)
      end
    end
  end
end


================================================
FILE: lib/shoulda/context/context.rb
================================================
module Shoulda
  module Context
    class Context # :nodoc:
      attr_accessor :name               # my name
      attr_accessor :parent             # may be another context, or the original test::unit class.
      attr_accessor :subcontexts        # array of contexts nested under myself
      attr_accessor :setup_blocks       # blocks given via setup methods
      attr_accessor :teardown_blocks    # blocks given via teardown methods
      attr_accessor :shoulds            # array of hashes representing the should statements
      attr_accessor :should_eventuallys # array of hashes representing the should eventually statements

      # accessor with cache
      def subject_block
        return @subject_block if @subject_block
        parent.subject_block
      end
      attr_writer :subject_block

      def initialize(name, parent, &blk)
        Shoulda::Context.add_context(self)
        self.name               = name
        self.parent             = parent
        self.setup_blocks       = []
        self.teardown_blocks    = []
        self.shoulds            = []
        self.should_eventuallys = []
        self.subcontexts        = []
        self.subject_block      = nil

        if block_given?
          merge_block(&blk)
        else
          merge_block { warn "  * WARNING: Block missing for context '#{full_name}'" }
        end
        Shoulda::Context.remove_context
      end

      def merge_block(&blk)
        if self.respond_to?(:instance_exec)
          self.instance_exec(&blk)
        else
          # deprecated in Rails 4.x
          blk.bind(self).call
        end
      end

      def context(name, &blk)
        self.subcontexts << Context.new(name, self, &blk)
      end

      def setup(&blk)
        self.setup_blocks << blk
      end

      def teardown(&blk)
        self.teardown_blocks << blk
      end

      class LambdaWithLocation < Proc
        attr_reader :source_location

        def initialize(source_location, &blk)
          @source_location = source_location
          super(&blk)
        end
      end

      def should(name_or_matcher, options = {}, source_location = (loc = caller_locations(1, 1)[0]
                                                                   [loc.path, loc.lineno]), &blk)
        if name_or_matcher.respond_to?(:description) && name_or_matcher.respond_to?(:matches?)
          name = name_or_matcher.description
          blk = LambdaWithLocation.new(source_location, &lambda { assert_accepts name_or_matcher, subject })
        else
          name = name_or_matcher
        end

        if blk
          self.shoulds << { :name => name, :before => options[:before], :block => blk }
        else
          self.should_eventuallys << { :name => name }
        end
      end

      def should_not(matcher, source_location = (loc = caller_locations(1, 1)[0]
                                                 [loc.path, loc.lineno]))
        name = matcher.description
        blk = LambdaWithLocation.new(source_location, &lambda { assert_rejects matcher, subject })
        self.shoulds << { :name => "not #{name}", :block => blk }
      end

      def should_eventually(name, &blk)
        self.should_eventuallys << { :name => name, :block => blk }
      end

      def subject(&block)
        self.subject_block = block
      end

      def full_name
        parent_name = parent.full_name if am_subcontext?
        return [parent_name, name].join(" ").strip
      end

      def am_subcontext?
        parent.is_a?(self.class) # my parent is the same class as myself.
      end

      def test_unit_class
        am_subcontext? ? parent.test_unit_class : parent
      end

      def test_methods
        @test_methods ||= Hash.new { |h,k|
          h[k] = k.instance_methods.each_with_object({}) { |n, a| a[n] = true }
        }
      end

      def create_test_from_should_hash(should)
        test_name = build_test_name_from(should)

        if test_methods[test_unit_class][test_name.to_s]
          raise Shoulda::Context::DuplicateTestError.new(
            "'#{test_name}' is defined more than once."
          )
        end

        test_methods[test_unit_class][test_name.to_s] = true
        file, line_no = should[:block].source_location

        # Ruby doesn't know that we are referring to this variable inside of the
        # eval, so it will emit a warning that it's "assigned but unused".
        # However, making a double assignment places `context` on the right hand
        # side of the assignment, thereby putting it into use.
        context = context = self

        test_unit_class.class_eval <<-end_eval, file, line_no
          define_method test_name do
            @shoulda_context = context
            begin
              context.run_parent_setup_blocks(self)
              if should[:before]
                instance_exec(&should[:before])
              end
              context.run_current_setup_blocks(self)
              instance_exec(&should[:block])
            ensure
              context.run_all_teardown_blocks(self)
            end
          end
        end_eval
      end

      def build_test_name_from(should)
        [
          test_name_prefix,
          full_name,
          "should",
          "#{should[:name]}. "
        ].flatten.join(' ').to_sym
      end

      def run_all_setup_blocks(binding)
        run_parent_setup_blocks(binding)
        run_current_setup_blocks(binding)
      end

      def run_parent_setup_blocks(binding)
        self.parent.run_all_setup_blocks(binding) if am_subcontext?
      end

      def run_current_setup_blocks(binding)
        setup_blocks.each do |setup_block|
          if binding.respond_to?(:instance_exec)
            binding.instance_exec(&setup_block)
          else
            # deprecated in Rails 4.x
            setup_block.bind(binding).call
          end
        end
      end

      def run_all_teardown_blocks(binding)
        teardown_blocks.reverse.each do |teardown_block|
          if binding.respond_to?(:instance_exec)
            binding.instance_exec(&teardown_block)
          else
            # deprecated in Rails 4.x
            teardown_block.bind(binding).call
          end
        end
        self.parent.run_all_teardown_blocks(binding) if am_subcontext?
      end

      def print_should_eventuallys
        should_eventuallys.each do |should|
          test_name = [full_name, "should", "#{should[:name]}. "].flatten.join(' ')
          puts "  * DEFERRED: " + test_name
        end
      end

      def build
        shoulds.each do |should|
          create_test_from_should_hash(should)
        end

        subcontexts.each { |context| context.build }

        print_should_eventuallys
      end

      def test_name_prefix
        if defined?(Minitest)
          'test_:'
        else
          'test:'
        end
      end

      def method_missing(method, *args, &blk)
        test_unit_class.send(method, *args, &blk)
      end
    end

    class DuplicateTestError < RuntimeError; end
  end
end


================================================
FILE: lib/shoulda/context/dsl.rb
================================================
require "shoulda/context/assertions"

module Shoulda
  module Context
    module DSL
      def self.included(base)
        base.class_eval do
          include Assertions
          include InstanceMethods
        end
        base.extend(ClassMethods)
      end

      module ClassMethods
        # == Should statements
        #
        # Should statements are just syntactic sugar over normal Test::Unit test
        # methods.  A should block contains all the normal code and assertions
        # you're used to seeing, with the added benefit that they can be wrapped
        # inside context blocks (see below).
        #
        # === Example:
        #
        #  class UserTest < Test::Unit::TestCase
        #
        #    def setup
        #      @user = User.new("John", "Doe")
        #    end
        #
        #    should "return its full name"
        #      assert_equal 'John Doe', @user.full_name
        #    end
        #
        #  end
        #
        # ...will produce the following test:
        # * <tt>"test: User should return its full name. "</tt>
        #
        # Note: The part before <tt>should</tt> in the test name is gleamed from the name of the Test::Unit class.
        #
        # Should statements can also take a Proc as a <tt>:before </tt>option.  This proc runs after any
        # parent context's setups but before the current context's setup.
        #
        # === Example:
        #
        #  context "Some context" do
        #    setup { puts("I run after the :before proc") }
        #
        #    should "run a :before proc", :before => lambda { puts("I run before the setup") }  do
        #      assert true
        #    end
        #  end
        #
        # Should statements can also wrap matchers, making virtually any matcher
        # usable in a macro style. The matcher's description is used to generate a
        # test name and failure message, and the test will pass if the matcher
        # matches the subject.
        #
        # === Example:
        #
        #   should validate_presence_of(:first_name).with_message(/gotta be there/)
        #

        def should(name_or_matcher, options = {}, source_location = (loc = caller_locations(1, 1)[0]
                                                                     [loc.path, loc.lineno]), &blk)
          if Shoulda::Context.current_context
            Shoulda::Context.current_context.should(name_or_matcher, options, source_location, &blk)
          else
            context_name = self.name.gsub(/Test$/, "") if name
            context = Shoulda::Context::Context.new(context_name, self) do
              should(name_or_matcher, options, source_location, &blk)
            end
            context.build
          end
        end

        # Allows negative tests using matchers. The matcher's description is used
        # to generate a test name and negative failure message, and the test will
        # pass unless the matcher matches the subject.
        #
        # === Example:
        #
        #   should_not set_the_flash
        def should_not(matcher, source_location = (loc = caller_locations(1, 1)[0]
                                                   [loc.path, loc.lineno]))
          if Shoulda::Context.current_context
            Shoulda::Context.current_context.should_not(matcher, source_location)
          else
            context_name = self.name.gsub(/Test$/, "") if name
            context = Shoulda::Context::Context.new(context_name, self) do
              should_not(matcher, source_location)
            end
            context.build
          end
        end

        # == Before statements
        #
        # Before statements are should statements that run before the current
        # context's setup. These are especially useful when setting expectations.
        #
        # === Example:
        #
        #  class UserControllerTest < Test::Unit::TestCase
        #    context "the index action" do
        #      setup do
        #        @users = [Factory(:user)]
        #        User.stubs(:find).returns(@users)
        #      end
        #
        #      context "on GET" do
        #        setup { get :index }
        #
        #        should respond_with(:success)
        #
        #        # runs before "get :index"
        #        before_should "find all users" do
        #          User.expects(:find).with(:all).returns(@users)
        #        end
        #      end
        #    end
        #  end
        def before_should(name, &blk)
          should(name, :before => blk) { assert true }
        end

        # Just like should, but never runs, and instead prints an 'X' in the Test::Unit output.
        def should_eventually(name, options = {}, &blk)
          context_name = self.name.gsub(/Test$/, "")
          context = Shoulda::Context::Context.new(context_name, self) do
            should_eventually(name, &blk)
          end
          context.build
        end

        # == Contexts
        #
        # A context block groups should statements under a common set of setup/teardown methods.
        # Context blocks can be arbitrarily nested, and can do wonders for improving the maintainability
        # and readability of your test code.
        #
        # A context block can contain setup, should, should_eventually, and teardown blocks.
        #
        #  class UserTest < Test::Unit::TestCase
        #    context "A User instance" do
        #      setup do
        #        @user = User.find(:first)
        #      end
        #
        #      should "return its full name"
        #        assert_equal 'John Doe', @user.full_name
        #      end
        #    end
        #  end
        #
        # This code will produce the method <tt>"test: A User instance should return its full name. "</tt>.
        #
        # Contexts may be nested.  Nested contexts run their setup blocks from out to in before each
        # should statement.  They then run their teardown blocks from in to out after each should statement.
        #
        #  class UserTest < Test::Unit::TestCase
        #    context "A User instance" do
        #      setup do
        #        @user = User.find(:first)
        #      end
        #
        #      should "return its full name"
        #        assert_equal 'John Doe', @user.full_name
        #      end
        #
        #      context "with a profile" do
        #        setup do
        #          @user.profile = Profile.find(:first)
        #        end
        #
        #        should "return true when sent :has_profile?"
        #          assert @user.has_profile?
        #        end
        #      end
        #    end
        #  end
        #
        # This code will produce the following methods
        # * <tt>"test: A User instance should return its full name. "</tt>
        # * <tt>"test: A User instance with a profile should return true when sent :has_profile?. "</tt>
        #
        # <b>Just like should statements, a context block can exist next to normal <tt>def test_the_old_way; end</tt>
        # tests</b>.  This means you do not have to fully commit to the context/should syntax in a test file.

        def context(name, &blk)
          if Shoulda::Context.current_context
            Shoulda::Context.current_context.context(name, &blk)
          else
            context = Shoulda::Context::Context.new(name, self, &blk)
            context.build
          end
        end

        # Returns the class being tested, as determined by the test class name.
        #
        #   class UserTest; described_type; end
        #   # => User
        def described_type
          @described_type ||= self.name.
            gsub(/Test$/, '').
            split('::').
            inject(Object) do |parent, local_name|
              parent.const_get(local_name, false)
            end
        end

        # Sets the return value of the subject instance method:
        #
        #   class UserTest < Test::Unit::TestCase
        #     subject { User.first }
        #
        #     # uses the existing user
        #     should validate_uniqueness_of(:email)
        #   end
        def subject(&block)
          @subject_block = block
        end

        def subject_block # :nodoc:
          @subject_block ||= nil
        end
      end

      module InstanceMethods
        # Returns an instance of the class under test.
        #
        #   class UserTest
        #     should "be a user" do
        #       assert_kind_of User, subject # passes
        #     end
        #   end
        #
        # The subject can be explicitly set using the subject class method:
        #
        #   class UserTest
        #     subject { User.first }
        #     should "be an existing user" do
        #       assert !subject.new_record? # uses the first user
        #     end
        #   end
        #
        # The subject is used by all macros that require an instance of the class
        # being tested.
        def subject
          @shoulda_subject ||= construct_subject
        end

        def subject_block # :nodoc:
          (@shoulda_context && @shoulda_context.subject_block) || self.class.subject_block
        end

        def get_instance_of(object_or_klass) # :nodoc:
          if object_or_klass.is_a?(Class)
            object_or_klass.new
          else
            object_or_klass
          end
        end

        def instance_variable_name_for(klass) # :nodoc:
          klass.to_s.split('::').last.underscore
        end

        private

        def construct_subject
          if subject_block
            instance_eval(&subject_block)
          else
            get_instance_of(self.class.described_type)
          end
        end
      end
    end
  end
end


================================================
FILE: lib/shoulda/context/proc_extensions.rb
================================================
# Stolen straight from ActiveSupport

class Proc #:nodoc:
  def bind(object)
    block, time = self, Time.now
    (class << object; self end).class_eval do
      method_name = "__bind_#{time.to_i}_#{time.usec}"
      define_method(method_name, &block)
      method = instance_method(method_name)
      remove_method(method_name)
      method
    end.bind(object)
  end
end


================================================
FILE: lib/shoulda/context/railtie.rb
================================================
module Shoulda
  module Context
    class Railtie < Rails::Railtie
      initializer "shoulda_context.autoload_macros" do
        if Rails.env.test?
          Shoulda.autoload_macros(
            Rails.root,
            File.join("vendor", "{plugins,gems}", "*")
          )
        end
      end
    end
  end
end


================================================
FILE: lib/shoulda/context/tasks/list_tests.rake
================================================
namespace :shoulda do
  desc "List the names of the test methods in a specification like format"
  task :list do
    $LOAD_PATH.unshift("test")

    require 'test/unit'
    require 'rubygems'
    require 'active_support'

    # bug in test unit.  Set to true to stop from running.
    Test::Unit.run = true

    test_files = Dir.glob(File.join('test', '**', '*_test.rb'))
    test_files.each do |file|
      load file
      klass = File.basename(file, '.rb').classify
      unless Object.const_defined?(klass.to_s)
        puts "Skipping #{klass} because it doesn't map to a Class"
        next
      end
      klass = klass.constantize

      puts klass.name.gsub('Test', '')

      test_methods = klass.instance_methods.grep(/^test/).map {|s| s.gsub(/^test: /, '')}.sort
      test_methods.each {|m| puts "  " + m }
    end
  end
end


================================================
FILE: lib/shoulda/context/tasks/yaml_to_shoulda.rake
================================================
namespace :shoulda do
  # From http://blog.internautdesign.com/2007/11/2/a-yaml_to_shoulda-rake-task
  # David.Lowenfels@gmail.com
  desc "Converts a YAML file (FILE=./path/to/yaml) into a Shoulda skeleton"
  task :from_yaml do
    require 'yaml'

    def yaml_to_context(hash, indent = 0)
      indent1 = '  ' * indent
      indent2 = '  ' * (indent + 1)
      hash.each_pair do |context, shoulds|
        puts indent1 + "context \"#{context}\" do"
        puts
        shoulds.each do |should|
          yaml_to_context( should, indent + 1 ) and next if should.is_a?( Hash )
          puts indent2 + "should_eventually \"" + should.gsub(/^should +/,'') + "\" do"
          puts indent2 + "end"
          puts
        end
        puts indent1 + "end"
      end
    end

    puts("Please pass in a FILE argument.") and exit unless ENV['FILE']

    yaml_to_context( YAML.load_file( ENV['FILE'] ) )
  end
end


================================================
FILE: lib/shoulda/context/tasks.rb
================================================
Dir[File.join(File.dirname(__FILE__), 'tasks', '*.rake')].each do |f|
  load f
end


================================================
FILE: lib/shoulda/context/test_framework_detection.rb
================================================
module Shoulda
  module Context
    module TestFrameworkDetection
      def self.possible_test_frameworks
        [
          -> { ActiveSupport::TestCase },
          -> { Minitest::Test },
          -> { Test::Unit::TestCase }
        ]
      end

      def self.resolve_framework(future_framework)
        future_framework.call
      rescue NameError
        nil
      end

      def self.detected_test_framework_test_cases
        possible_test_frameworks.
          map { |future_framework| resolve_framework(future_framework) }.
          compact
      end

      def self.test_framework_test_cases
        @_test_framework_test_cases ||= detected_test_framework_test_cases
      end
    end

    def self.test_framework_test_cases
      TestFrameworkDetection.test_framework_test_cases
    end
  end
end


================================================
FILE: lib/shoulda/context/version.rb
================================================
module Shoulda
  module Context
    VERSION = "3.0.0.rc1".freeze
  end
end


================================================
FILE: lib/shoulda/context/world.rb
================================================
module Shoulda
  module Context
    class << self
      def contexts # :nodoc:
        @contexts ||= []
      end
      attr_writer :contexts

      def current_context # :nodoc:
        self.contexts.last
      end

      def add_context(context) # :nodoc:
        self.contexts.push(context)
      end

      def remove_context # :nodoc:
        self.contexts.pop
      end
    end
  end
end


================================================
FILE: lib/shoulda/context.rb
================================================
require "shoulda/context/autoload_macros"
require "shoulda/context/configuration"
require "shoulda/context/context"
require "shoulda/context/dsl"
require "shoulda/context/proc_extensions"
require "shoulda/context/test_framework_detection"
require "shoulda/context/version"
require "shoulda/context/world"

if defined?(Rails)
  require "shoulda/context/railtie"
end

Shoulda::Context.configure do |config|
  config.include(Shoulda::Context::DSL)
end


================================================
FILE: lib/shoulda-context.rb
================================================
require "shoulda/context"


================================================
FILE: shoulda-context.gemspec
================================================
# -*- encoding: utf-8 -*-

$LOAD_PATH << File.join(File.dirname(__FILE__), "lib")
require "shoulda/context/version"

Gem::Specification.new do |s|
  s.name        = "shoulda-context"
  s.version     = Shoulda::Context::VERSION.dup
  s.platform    = Gem::Platform::RUBY
  s.authors     = ["thoughtbot, inc.", "Tammer Saleh", "Joe Ferris",
                   "Ryan McGeary", "Dan Croak", "Matt Jankowski"]
  s.email       = "support@thoughtbot.com"
  s.homepage    = "http://thoughtbot.com/community/"
  s.summary     = "Context framework extracted from Shoulda"
  s.description = "Context framework extracted from Shoulda"
  s.license     = "MIT"

  s.files            = `git ls-files`.split("\n")
  s.test_files       = `git ls-files -- {test,spec,features}/*`.split("\n")
  s.executables      = `git ls-files -- exe/*`.split("\n").map { |f| File.basename(f) }
  s.bindir           = "exe"
  s.require_paths    = ["lib"]
end


================================================
FILE: tasks/shoulda.rake
================================================
load File.join(File.dirname(__FILE__), "..", "lib", "shoulda", "context", "tasks.rb")


================================================
FILE: test/fake_rails_root/test/shoulda_macros/custom_macro.rb
================================================
module CustomMacro
  def custom_macro
  end
end
PARENT_TEST_CASE.extend(CustomMacro)



================================================
FILE: test/fake_rails_root/vendor/gems/gem_with_macro-0.0.1/shoulda_macros/gem_macro.rb
================================================
module GemMacro
  def gem_macro
  end
end
PARENT_TEST_CASE.extend(GemMacro)


================================================
FILE: test/fake_rails_root/vendor/plugins/.keep
================================================


================================================
FILE: test/fake_rails_root/vendor/plugins/plugin_with_macro/shoulda_macros/plugin_macro.rb
================================================
module PluginMacro
  def plugin_macro
  end
end
PARENT_TEST_CASE.extend(PluginMacro)


================================================
FILE: test/shoulda/autoload_macro_test.rb
================================================
require 'test_helper'

class AutoloadMacroTest < PARENT_TEST_CASE
  context "The macro auto-loader" do
    should "load macros from the plugins" do
      assert self.class.respond_to?('plugin_macro')
    end

    should "load macros from the gems" do
      assert self.class.respond_to?('gem_macro')
    end

    should "load custom macros from ROOT/test/shoulda_macros" do
      assert self.class.respond_to?('custom_macro')
    end
  end
end



================================================
FILE: test/shoulda/context_test.rb
================================================
require 'test_helper'

class ContextTest < PARENT_TEST_CASE
  def self.context_macro(&blk)
    context "with a subcontext made by a macro" do
      setup { @context_macro = :foo }

      merge_block(&blk)
    end
  end

  context "context with setup block" do
    setup do
      @blah = "blah"
    end

    should "run the setup block" do
      assert_equal "blah", @blah
    end

    should "have name set right" do
      assert_match(/^test: context with setup block/, normalized_name)
    end

    context "and a subcontext" do
      setup do
        @blah = "#{@blah} twice"
      end

      should "be named correctly" do
        assert_match(/^test: context with setup block and a subcontext should be named correctly/, normalized_name)
      end

      should "run the setup blocks in order" do
        assert_equal @blah, "blah twice"
      end
    end

    context_macro do
      should "have name set right" do
        assert_match(/^test: context with setup block with a subcontext made by a macro should have name set right/, normalized_name)
      end

      should "run the setup block of that context macro" do
        assert_equal :foo, @context_macro
      end

      should "run the setup block of the main context" do
        assert_equal "blah", @blah
      end
    end

  end

  context "another context with setup block" do
    setup do
      @blah = "foo"
    end

    should "have @blah == 'foo'" do
      assert_equal "foo", @blah
    end

    should "have name set right" do
      assert_match(/^test: another context with setup block/, normalized_name)
    end
  end

  context "context with method definition" do
    setup do
      def hello; "hi"; end
    end

    should "be able to read that method" do
      assert_equal "hi", hello
    end

    should "have name set right" do
      assert_match(/^test: context with method definition/, normalized_name)
    end
  end

  context "another context" do
    should "not define @blah" do
      assert !instance_variable_defined?(:@blah)
    end
  end

  context "context with multiple setups and/or teardowns" do

    cleanup_count = 0

    2.times do |i|
      setup { cleanup_count += 1 }
      teardown { cleanup_count -= 1 }
    end

    2.times do |i|
      should "call all setups and all teardowns (check ##{i + 1})" do
        assert_equal 2, cleanup_count
      end
    end

    context "subcontexts" do

      2.times do |i|
        setup { cleanup_count += 1 }
        teardown { cleanup_count -= 1 }
      end

      2.times do |i|
        should "also call all setups and all teardowns in parent and subcontext (check ##{i + 1})" do
          assert_equal 4, cleanup_count
        end
      end

    end

  end

  should_eventually "pass, since it's unimplemented" do
    flunk "what?"
  end

  should_eventually "not require a block when using should_eventually"
  should "pass without a block, as that causes it to piggyback to should_eventually"

  context "context for testing should piggybacking" do
    should "call should_eventually as we are not passing a block"
  end

  context "context" do
    context "with nested subcontexts" do
      should_eventually "only print this statement once for a should_eventually"
    end
  end

  class ::SomeModel; end

  context "given a test named after a class" do
    setup do
      self.class.stubs(:name).returns("SomeModelTest")
    end

    should "determine the described type" do
      assert_equal SomeModel, self.class.described_type
    end

    should "return a new instance of the described type as the subject if none exists" do
      assert_kind_of SomeModel, subject
    end

    context "with an explicit subject block" do
      setup { @expected = SomeModel.new }
      subject { @expected }
      should "return the result of the block as the subject" do
        assert_equal @expected, subject
      end

      context "nested context block without a subject block" do
        should "return the result of the parent context's subject block" do
          assert_equal @expected, subject
        end
      end
    end
  end

  def normalized_name
    name.sub("test_:", "test:")
  end
end

class ::Some
  class NestedModel; end
end

class Some::NestedModelTest < PARENT_TEST_CASE
  should "determine the described type for a nested model" do
    assert_equal Some::NestedModel, self.class.described_type
  end
end

class Some::SomeTest < PARENT_TEST_CASE
  should "not fallback to higher-level constants with same name" do
    assert_raises(NameError) do
      assert_equal nil, self.class.described_type
    end
  end
end

class ShouldMatcherTest < PARENT_TEST_CASE
  class FakeMatcher
    attr_reader :subject
    attr_accessor :fail

    def description
      "be a fake matcher"
    end

    def matches?(subject)
      @subject = subject
      !@fail
    end

    def failure_message
      "positive failure message"
    end

    def failure_message_when_negated
      "negative failure message"
    end
  end

  def setup
    @matcher = FakeMatcher.new
  end

  def assert_failed_with(message, test_suite)
    assert_equal [message], test_suite.failure_messages
  end

  def assert_passed(test_suite)
    assert_equal [], test_suite.failure_messages
  end

  def assert_test_named(expected_name, test_suite)
    name = test_suite.test_names.first
    assert(
      name.include?(expected_name),
      "Expected #{name} to include #{expected_name}"
    )
  end

  def self.should_use_positive_matcher
    should "generate a test using the matcher's description" do
      assert_test_named "should #{@matcher.description}", @test_suite
    end

    should "pass with a passing matcher" do
      @matcher.fail = false
      @test_suite.run
      assert_passed @test_suite
    end

    should "fail with a failing matcher" do
      @matcher.fail = true
      @test_suite.run
      assert_failed_with "positive failure message", @test_suite
    end

    should "provide the subject" do
      @matcher.fail = false
      @test_suite.run
      assert_equal 'a subject', @matcher.subject
    end
  end

  def self.should_use_negative_matcher
    should "generate a test using the matcher's description" do
      assert_test_named "should not #{@matcher.description}", @test_suite
    end

    should "pass with a failing matcher" do
      @matcher.fail = true
      @test_suite.run
      assert_passed @test_suite
    end

    should "fail with a passing matcher" do
      @matcher.fail = false
      @test_suite.run
      assert_failed_with "negative failure message", @test_suite
    end

    should "provide the subject" do
      @matcher.fail = false
      @test_suite.run
      assert_equal 'a subject', @matcher.subject
    end
  end

  context "a should block with a matcher" do
    setup do
      matcher = @matcher
      @test_suite = TestSuite.create do
        subject { 'a subject' }
        should matcher
      end
    end

    should_use_positive_matcher
  end

  context "a should block with a matcher within a context" do
    setup do
      matcher = @matcher
      @test_suite = TestSuite.create do
        context "in context" do
          subject { 'a subject' }
          should matcher
        end
      end
    end

    should_use_positive_matcher
  end

  context "a should_not block with a matcher" do
    setup do
      matcher = @matcher
      @test_suite = TestSuite.create do
        subject { 'a subject' }
        should_not matcher
      end
    end

    should_use_negative_matcher
  end

  context "a should_not block with a matcher within a context" do
    setup do
      matcher = @matcher
      @test_suite = TestSuite.create do
        context "in context" do
          subject { 'a subject' }
          should_not matcher
        end
      end
    end

    should_use_negative_matcher
  end

  class TestSuite
    def self.create(&definition)
      if defined?(Test::Unit)
        TestUnitSuite.new(&definition)
      else
        MinitestSuite.new(&definition)
      end
    end
  end

  class TestUnitSuite
    def initialize(&definition)
      @suite = Class.new(Test::Unit::TestCase, &definition).suite
      @result = Test::Unit::TestResult.new
    end

    def run
      @suite.run(@result) do |event, name|
        # do nothing
      end
    end

    def failure_messages
      @result.failures.map(&:message)
    end

    def test_names
      @suite.tests.map(&:method_name)
    end
  end

  class MinitestSuite
    def initialize(&definition)
      @test_case_class = Class.new(Minitest::Test, &definition)
      @reporter = Minitest::StatisticsReporter.new(StringIO.new)
    end

    def run
      @test_case_class.run(@reporter)
    end

    def failure_messages
      @reporter.results.flat_map(&:failures).map(&:message)
    end

    def test_names
      @test_case_class.runnable_methods
    end
  end
end

class Subject; end

class SubjectTest < PARENT_TEST_CASE

  def setup
    @expected = Subject.new
  end

  subject { @expected }

  should "return a specified subject" do
    assert_equal @expected, subject
  end
end

class SubjectLazinessTest < PARENT_TEST_CASE
  subject { Subject.new }

  should "only build the subject once" do
    assert_equal subject, subject
  end
end


================================================
FILE: test/shoulda/convert_to_should_syntax_test.rb
================================================
require 'test_helper'

class ConvertToShouldSyntaxTest < PARENT_TEST_CASE
  BEFORE_FIXTURE = <<-EOS
    class DummyTest < #{PARENT_TEST_CASE}

      should "Not change this_word_with_underscores" do
      end

      def test_should_be_working
        assert true
      end

      def test_some_cool_stuff
        assert true
      end

      def non_test_method
      end

    end
  EOS

  AFTER_FIXTURE = <<-EOS
    class DummyTest < #{PARENT_TEST_CASE}

      should "Not change this_word_with_underscores" do
      end

      should "be working" do
        assert true
      end

      should "RENAME ME: test some cool stuff" do
        assert true
      end

      def non_test_method
      end

    end
  EOS

  FIXTURE_PATH = "./convert_to_should_syntax_fixture.dat"

  RUBY = ENV['RUBY'] || 'ruby'

  def test_convert_to_should_syntax
    File.open(FIXTURE_PATH, "w") {|f| f.write(BEFORE_FIXTURE)}
    cmd = "#{RUBY} #{File.join(File.dirname(__FILE__), '../../exe/convert_to_should_syntax')} #{FIXTURE_PATH}"
    output = `#{cmd}`
    File.unlink($1) if output.match(/has been stored in '([^']+)/)
    assert_match(/has been converted/, output)
    result = IO.read(FIXTURE_PATH)
    assert_equal result, AFTER_FIXTURE
  end

  def teardown
    File.unlink(FIXTURE_PATH)
  end
end


================================================
FILE: test/shoulda/helpers_test.rb
================================================
require 'test_helper'

class HelpersTest < PARENT_TEST_CASE
  context "an array of values" do
    setup do
      @a = ['abc', 'def', 3]
    end

    [/b/, 'abc', 3].each do |x|
      should "contain #{x.inspect}" do
        assert_raises(ASSERTION_CLASS) do
          assert_does_not_contain @a, x
        end
        assert_contains @a, x
      end
    end

    should "not contain 'wtf'" do
      assert_raises(ASSERTION_CLASS) {assert_contains @a, 'wtf'}
      assert_does_not_contain @a, 'wtf'
    end

    should "be the same as another array, ordered differently" do
      assert_same_elements(@a, [3, "def", "abc"])
      assert_raises(ASSERTION_CLASS) do
        assert_same_elements(@a, [3, 3, "def", "abc"])
      end
      assert_same_elements([@a, "abc"].flatten, ["abc", 3, "def", "abc"])
      assert_raises(ASSERTION_CLASS) do
        assert_same_elements([@a, "abc"].flatten, [3, 3, "def", "abc"])
      end
    end

    should "only count the number of occurrences once for each unique value" do
      a1 = [@a, "abc"].flatten
      a1.expects(:select).times(3).returns(["abc", "abc"], ["def"], [3])
      assert_same_elements(a1, ["abc", 3, "def", "abc"])
    end
  end

  context "a matching matcher" do
    setup do
      @matcher = stub(
        "matcher",
        matches?: true,
        failure_message: "bad failure message",
        failure_message_when_negated: "big time failure"
      )
    end

    should "pass when given to assert_accepts with no message expectation" do
      assert_accepts @matcher, 'target'
    end

    should "pass when given to assert_accepts with a matching message" do
      assert_accepts @matcher, 'target', :message => /big time/
    end

    should "fail when given to assert_accepts with non-matching message" do
      assert_raises ASSERTION_CLASS do
        assert_accepts @matcher, 'target', :message => /small time/
      end
    end

    context "when given to assert_rejects" do
      context "and matcher has :does_not_match?" do
        setup do
          @error = nil
          begin
            @matcher.stubs(:matches?).returns(false)
            @matcher.stubs(:does_not_match?).returns(true)
            assert_rejects @matcher, 'target'
          rescue ASSERTION_CLASS => @error
          end
        end

        should "pass" do
          assert_nil @error
        end
      end

      context "and matcher does not have :does_not_match?" do
        setup do
          @error = nil
          begin
            assert_rejects @matcher, 'target'
          rescue ASSERTION_CLASS => @error
          end
        end

        should "fail" do
          refute_nil @error
        end

        should "use the error message from the matcher" do
          assert_equal 'big time failure', @error.message
        end
      end
    end
  end

  context "a non-matching matcher" do
    setup do
      @matcher = stub(
        "matcher",
        matches?: false,
        failure_message: "big time failure",
        failure_message_when_negated: "bad failure message"
      )
    end

    should "pass when given to assert_rejects with no message expectation" do
      assert_rejects @matcher, 'target'
    end

    should "pass when given to assert_rejects with a matching message" do
      assert_rejects @matcher, 'target', :message => /big time/
    end

    should "fail when given to assert_rejects with a non-matching message" do
      assert_raises ASSERTION_CLASS do
        assert_rejects @matcher, 'target', :message => /small time/
      end
    end

    context "when given to assert_accepts" do
      setup do
        assert_accepts @matcher, 'target'
      rescue ASSERTION_CLASS => @error
      end

      should "fail" do
        refute_nil @error
      end

      should "use the error message from the matcher" do
        assert_equal 'big time failure', @error.message
      end
    end
  end

  should "assign context to a support matching on assert_accepts" do
    matcher = stub('matcher', :matches? => true)
    matcher.expects(:in_context).with(self)
    assert_accepts matcher, nil
  end

  should "assign context to a support matching on assert_rejects" do
    matcher = stub('matcher', :matches? => false)
    matcher.expects(:in_context).with(self)
    assert_rejects matcher, nil
  end
end


================================================
FILE: test/shoulda/railtie_test.rb
================================================
require "test_helper"

class RailtieTest < PARENT_TEST_CASE
  context "A Rails application with shoulda-context added to it" do
    setup do
      app.create
    end

    should "load files in vendor/gems and vendor/plugins when booted" do
      app.create_gem_with_macro(
        module_name: "MacrosFromVendor",
        location: "vendor/gems/vendored_gem_with_macro",
        macro_name: "macro_from_vendored_gem"
      )
      app.create_gem_with_macro(
        module_name: "MacrosFromPlugin",
        location: "vendor/plugins/plugin_gem_with_macro",
        macro_name: "macro_from_plugin_gem"
      )
      app.create_gem_with_macro(
        module_name: "MacrosFromTest",
        location: "test",
        macro_name: "macro_from_test"
      )
      app.write_file("test/macros_test.rb", <<~RUBY)
        ENV["RAILS_ENV"] = "test"
        require_relative "../config/environment"

        class MacrosTest < #{PARENT_TEST_CASE}
          macro_from_vendored_gem
          macro_from_plugin_gem
          macro_from_test
        end
      RUBY

      app.run_n_unit_test_suite
    end
  end

  def app
    @_app ||= RailsApplicationWithShouldaContext.new
  end
end


================================================
FILE: test/shoulda/rerun_snippet_test.rb
================================================
require "test_helper"

class RerunSnippetTest < PARENT_TEST_CASE
  context "A Rails application with shoulda-context added to it" do
    should "display the correct rerun snippet when a test fails" do
      if app.rails_version >= 5 && TEST_FRAMEWORK == "minitest"
        app.create

        app.write_file("test/models/failing_test.rb", <<~RUBY)
          ENV["RAILS_ENV"] = "test"
          require_relative "../../config/environment"

          class FailingTest < #{PARENT_TEST_CASE}
            class FakeMatcher
              attr_reader :subject
              attr_accessor :fail

              def description
                "be a fake matcher"
              end

              def matches?(subject)
                @subject = subject
                !@fail
              end

              def failure_message
                "positive failure message"
              end

              def failure_message_when_negated
                "negative failure message"
              end
            end

            should "fail" do
              assert false
            end

            should_not FakeMatcher.new.tap { |m| m.fail = false }
            should FakeMatcher.new.tap { |m| m.fail = true }
          end
        RUBY

        command_runner = app.run_n_unit_test_suite

        expected_executable = rails_version >= 6 ? "rails test" : "bin/rails test"

        assert_includes(command_runner.output, "#{expected_executable} test/models/failing_test.rb:27")
        assert_includes(command_runner.output, "#{expected_executable} test/models/failing_test.rb:31")
        assert_includes(command_runner.output, "#{expected_executable} test/models/failing_test.rb:32")
      end
    end
  end

  def app
    @_app ||= RailsApplicationWithShouldaContext.new
  end

  def rails_version
    # TODO: Update snowglobe so that we don't have to do this
    app.send(:bundle).version_of("rails")
  end
end


================================================
FILE: test/shoulda/should_test.rb
================================================
require 'test_helper'

class ShouldTest < PARENT_TEST_CASE
  should "be able to define a should statement outside of a context" do
    assert true
  end

  should "see the name of my class as ShouldTest" do
    assert_equal "ShouldTest", self.class.name
  end

  def self.should_see_class_methods
    should "be able to see class methods" do
      assert true
    end
  end

  def self.should_be_able_to_setup_a_should_eventually_in_a_class_method
    should "be able to setup a should eventually in a class method"
  end

  def self.should_see_a_context_block_like_a_test_case_class
    should "see a context block as a Test::Unit class" do
      assert_equal "ShouldTest", self.class.name
    end
  end

  def self.should_see_blah
    should "see @blah through a macro" do
      assert @blah
    end
  end

  def self.should_not_see_blah
    should "not see @blah through a macro" do
      assert !instance_variable_defined?(:@blah)
    end
  end

  def self.should_be_able_to_make_context_macros(prefix = nil)
    context "a macro" do
      should "have the tests named correctly" do
        assert_match(
          Regexp.new(
            "^" +
            build_expected_test_name(
              "#{prefix}a macro should have the tests named correctly"
            )
          ),
          test_name
        )
      end
    end
  end

  context "Context" do
    should_see_class_methods
    should_see_a_context_block_like_a_test_case_class
    should_be_able_to_make_context_macros("Context ")
    should_be_able_to_setup_a_should_eventually_in_a_class_method

    should "not define @blah" do
      assert ! self.instance_variables.include?("@blah")
    end

    should_not_see_blah

    should "be able to define a should statement" do
      assert true
    end

    should "see the name of my class as ShouldTest" do
      assert_equal "ShouldTest", self.class.name
    end

    context "with a subcontext" do
      should_be_able_to_make_context_macros("Context with a subcontext ")
    end
  end

  context "Context with setup block" do
    setup do
      @blah = "blah"
    end

    should "have @blah == 'blah'" do
      assert_equal "blah", @blah
    end
    should_see_blah

    should "have name set right" do
      assert_match(
        Regexp.new(
          "^" +
          build_expected_test_name("Context with setup block")
        ),
        test_name
      )
    end

    context "and a subcontext" do
      setup do
        @blah = "#{@blah} twice"
      end

      should "be named correctly" do
        assert_match(
          Regexp.new(
            "^" +
            build_expected_test_name(
              "Context with setup block and a subcontext should be named correctly"
            )
          ),
          test_name
        )
      end

      should "run the setup methods in order" do
        assert_equal @blah, "blah twice"
      end
      should_see_blah
    end
  end

  context "Another context with setup block" do
    setup do
      @blah = "foo"
    end

    should "have @blah == 'foo'" do
      assert_equal "foo", @blah
    end

    should "have name set right" do
      assert_match(
        Regexp.new(
          "^" +
          build_expected_test_name("Another context with setup block")
        ),
        test_name
      )
    end
    should_see_blah
  end

  should_eventually "pass, since it's a should_eventually" do
    flunk "what?"
  end

  # Context creation and naming

  def test_should_create_a_new_context
    assert_nothing_raised do
      Shoulda::Context::Context.new("context name", self.class) do; end
    end
  end

  def test_should_create_a_new_context_even_if_block_is_omitted
    old_verbose, $VERBOSE = $VERBOSE, nil
    assert_nothing_raised do
      Shoulda::Context::Context.new("context without a block", self.class)
    end
  ensure
    $VERBOSE = old_verbose
  end

  def test_should_create_a_nested_context
    assert_nothing_raised do
      parent = Shoulda::Context::Context.new("Parent", self.class) do; end
      child  = Shoulda::Context::Context.new("Child", parent) do; end
      raise unless child.instance_of? Shoulda::Context::Context
    end
  end

  def test_should_name_a_contexts_correctly
    parent     = Shoulda::Context::Context.new("Parent", self.class) do; end
    child      = Shoulda::Context::Context.new("Child", parent) do; end
    grandchild = Shoulda::Context::Context.new("GrandChild", child) do; end

    assert_equal "Parent", parent.full_name
    assert_equal "Parent Child", child.full_name
    assert_equal "Parent Child GrandChild", grandchild.full_name
  end

  def test_should_raise_on_duplicate_naming
    context = Shoulda::Context::Context.new("DupContext", self.class) do
      should "dup" do; end
      should "dup" do; end
    end
    assert_raises Shoulda::Context::DuplicateTestError do
      context.build
    end
  end

  # Should statements

  def test_should_have_should_hashes_when_given_should_statements
    context = Shoulda::Context::Context.new("name", self.class) do
      should "be good" do; end
      should "another" do; end
    end

    names = context.shoulds.map {|s| s[:name]}
    assert_equal ["another", "be good"], names.sort
  end

  # setup and teardown

  def test_should_capture_setup_and_teardown_blocks
    context = Shoulda::Context::Context.new("name", self.class) do
      setup    do; "setup";    end
      teardown do; "teardown"; end
    end

    assert_equal "setup",    context.setup_blocks.first.call
    assert_equal "teardown", context.teardown_blocks.first.call
  end

  # building

  def test_should_create_shoulda_test_for_each_should_on_build
    context = Shoulda::Context::Context.new("name", self.class) do
      should "one" do; end
      should "two" do; end
    end
    context.expects(:create_test_from_should_hash).with(has_entry(:name => "one"))
    context.expects(:create_test_from_should_hash).with(has_entry(:name => "two"))
    context.build
  end

  def test_should_create_test_methods_on_build
    tu_class = self.class
    context = Shoulda::Context::Context.new("A Context", tu_class) do
      should "define the test" do; end
    end

    tu_class.
      expects(:define_method).
      with(
        build_expected_test_name("A Context should define the test. ").to_sym
      )
    context.build
  end

  def test_should_create_test_methods_on_build_when_subcontext
    tu_class = self.class
    context = Shoulda::Context::Context.new("A Context", tu_class) do
      context "with a child" do
        should "define the test" do; end
      end
    end

    tu_class.
      expects(:define_method).
      with(
        build_expected_test_name(
          "A Context with a child should define the test. "
        ).to_sym
      )
    context.build
  end

  # Test::Unit integration

  def test_should_create_a_new_context_and_build_it_on_test_case_context
    c = mock("context")
    c.expects(:build)
    Shoulda::Context::Context.expects(:new).with("foo", kind_of(Class)).returns(c)
    self.class.context "foo" do; end
  end

  def test_should_create_a_one_off_context_and_build_it_on_test_case_should
    s = mock("test")
    Shoulda::Context::Context.any_instance.expects(:should).with("rock", {}, [__FILE__, __LINE__ + 2]).returns(s)
    Shoulda::Context::Context.any_instance.expects(:build)
    self.class.should "rock" do; end
  end

  def test_should_create_a_one_off_context_and_build_it_on_test_case_should_eventually
    s = mock("test")
    Shoulda::Context::Context.any_instance.expects(:should_eventually).with("rock").returns(s)
    Shoulda::Context::Context.any_instance.expects(:build)
    self.class.should_eventually "rock" do; end
  end

  should "run a :before proc", :before => lambda { @value = "before" } do
    assert_equal "before", @value
  end

  context "A :before proc" do
    setup do
      assert_equal "before", @value
      @value = "setup"
    end

    should "run before the current setup", :before => lambda { @value = "before" } do
      assert_equal "setup", @value
    end
  end

  context "a before statement" do
    setup do
      assert_equal "before", @value
      @value = "setup"
    end

    before_should "run before the current setup" do
      @value = "before"
    end
  end

  context "A context" do
    setup do
      @value = "outer"
    end

    context "with a subcontext and a :before proc" do
      before = lambda do
        assert "outer", @value
        @value = "before"
      end
      should "run after the parent setup", :before => before do
        assert_equal "before", @value
      end
    end
  end

  def test_name
    name
  end

  def build_expected_test_name(value)
    if TEST_FRAMEWORK == "minitest"
      if value.is_a?(Regexp)
        Regexp.new("^test_: #{value.source}")
      else
        "test_: #{value}"
      end
    elsif value.is_a?(Regexp)
      Regexp.new("^test: #{value.source}")
    else
      "test: #{value}"
    end
  end

  # Minitest removed assert_nothing_raised a while back;
  # see here: <http://www.zenspider.com/ruby/2012/01/assert_nothing_tested.html>
  def assert_nothing_raised
    yield
  end
end

class RedTestarossaDriver; end

class RedTestarossaDriverTest < PARENT_TEST_CASE
  class DummyMatcher
    def description
      "fail to construct the proper test name with a 'should_not'"
    end

    def matches?(*)
      false
    end

    def failure_message_when_negated
      "dummy failure message"
    end
  end

  should "call Shoulda::Context::Context.new using the correct context name" do
    assert_equal "RedTestarossaDriver", @shoulda_context.name
  end

  should "see the name of the test case class as RedTestarossaDriverTest" do
    assert_equal "RedTestarossaDriverTest", self.class.name
  end

  should "include the correct context name in the full name of the test" do
    assert_match(
      build_expected_test_name(/RedTestarossaDriver/),
      test_name
    )
  end

  def test_should_property_construct_test_name_for_should_eventually
    context = Shoulda::Context::Context.new("whatever", self.class) do
      "this is just a placeholder"
    end

    Shoulda::Context::Context.
      expects(:new).
      with("RedTestarossaDriver", RedTestarossaDriverTest).
      returns(context)

    self.class.should_eventually("do something") {}
  end

  def test_should_property_construct_test_name_for_should_not
    context = Shoulda::Context::Context.new("whatever", self.class) do
      "this is just a placeholder"
    end

    Shoulda::Context::Context.
      expects(:new).
      with("RedTestarossaDriver", RedTestarossaDriverTest).
      returns(context)

    self.class.should_not(DummyMatcher.new)
  end

  private

  def test_name
    name
  end

  def build_expected_test_name(value)
    if TEST_FRAMEWORK == "minitest"
      if value.is_a?(Regexp)
        Regexp.new("^test_: #{value.source}")
      else
        "test_: #{value}"
      end
    elsif value.is_a?(Regexp)
      Regexp.new("^test: #{value.source}")
    else
      "test: #{value}"
    end
  end
end


================================================
FILE: test/shoulda/test_framework_detection_test.rb
================================================
require "test_helper"
require "tempfile"

class TestFrameworkDetectionTest < PARENT_TEST_CASE
  if TEST_FRAMEWORK == "minitest"
    should "detect Minitest 5.x when it is loaded standalone" do
      assert_integration_with "Minitest::Test", setup: <<-RUBY
        require "minitest/autorun"
      RUBY
    end
  end

  if TEST_FRAMEWORK == "test_unit"
    should "detect the test-unit gem when it is loaded standalone" do
      assert_integration_with "Test::Unit::TestCase",
        setup: <<-RUBY
          require "test/unit"
        RUBY
    end
  end

  def assert_integration_with_rails_and(*test_cases)
    test_cases = ["ActiveSupport::TestCase"] | test_cases
    options = test_cases.last.is_a?(Hash) ? test_cases.pop : {}
    options[:setup] = <<-RUBY
      require "rails/all"
      require "rails/test_help"
      ActiveRecord::Base.establish_connection(
        adapter: "sqlite3",
        database: ":memory:"
      )
    RUBY
    args = test_cases + [options]

    assert_integration_with(*args)
  end

  def assert_integration_with(*test_cases)
    assert_test_cases_are_detected(*test_cases)
    assert_our_api_is_available_in_test_cases(*test_cases)
  end

  def assert_test_cases_are_detected(*expected_test_cases)
    options = expected_test_cases.last.is_a?(Hash) ? expected_test_cases.pop : {}
    setup = options[:setup] || ""
    output = execute(file_that_detects_test_framework_test_cases([setup]))
    actual_test_cases = output.split("\n").first.split(", ")
    assert_equal expected_test_cases, actual_test_cases
  end

  def file_that_detects_test_framework_test_cases(mixins)
    <<-RUBY
      #{require_gems(mixins)}
      require "yaml"
      test_cases =
      Shoulda::Context.test_framework_test_cases.map do |test_case|
        test_case.to_s
      end
      puts test_cases.join(', ')
    RUBY
  end

  def require_gems(mixins)
    <<-RUBY
      ENV["BUNDLE_GEMFILE"] =
        "#{PROJECT_DIR}/gemfiles/" +
        "#{Tests::CurrentBundle.instance.current_appraisal}.gemfile"
      require "bundler"
      Bundler.setup
      #{mixins.join("\n")}
      require "shoulda-context"
    RUBY
  end

  def assert_our_api_is_available_in_test_cases(*test_cases)
    options = test_cases.last.is_a?(Hash) ? test_cases.pop : {}
    setup = options[:setup] || ""

    test_cases.each do |test_case|
      output = execute(
        file_that_runs_a_test_within_test_case(test_case, [setup])
      )
      assert_match(/1 (tests|runs)/, output)
      assert_match(/1 assertions/, output)
      assert_match(/0 failures/, output)
      assert_match(/0 errors/, output)
    end
  end

  def file_that_runs_a_test_within_test_case(test_case, mixins)
    <<-RUBY
      #{require_gems(mixins)}

      class FrameworkIntegrationTest < #{test_case}
        context "a context" do
          should "have a test" do
            assert_equal true, true
          end
        end
      end
    RUBY
  end

  def execute(code)
    tempfile = Tempfile.new("shoulda-context-test")
    tempfile.write(code)
    tempfile.close

    if ENV["DEBUG"]
      puts "Code:"
      puts code
    end

    output = `RUBYOPT="" ruby #{tempfile.path} 2>/dev/null`

    if ENV["DEBUG"]
      puts "Output:"
      puts output
    end

    output
  end
end


================================================
FILE: test/support/current_bundle.rb
================================================
require "bundler"
require "appraisal"

module Tests
  class CurrentBundle
    AppraisalNotSpecified = Class.new(ArgumentError)

    include Singleton

    def assert_appraisal!
      unless appraisal_in_use?
        message = <<MSG


Please run tests starting with `appraisal <appraisal_name>`.
Possible appraisals are: #{available_appraisals}

MSG
        raise AppraisalNotSpecified, message
      end
    end

    def appraisal_in_use?
      path.dirname == root.join("gemfiles")
    end

    def current_or_latest_appraisal
      current_appraisal || latest_appraisal
    end

    def latest_appraisal
      available_appraisals.max
    end

    def current_appraisal
      if appraisal_in_use?
        File.basename(path, ".gemfile")
      end
    end

    private

    def available_appraisals
      appraisals = []

      Appraisal::AppraisalFile.each do |appraisal|
        appraisals << appraisal.name
      end

      appraisals
    end

    def path
      Bundler.default_gemfile
    end

    def root
      Pathname.new("../../..").expand_path(__FILE__)
    end
  end
end


================================================
FILE: test/support/rails_application_with_shoulda_context.rb
================================================
require_relative "snowglobe"

class RailsApplicationWithShouldaContext < Snowglobe::RailsApplication
  ROOT_DIRECTORY = Pathname.new("../../..").expand_path(__FILE__)

  def create
    super

    bundle.updating do
      bundle.add_gem(test_framework_gem_name, group: :test)
      bundle.add_gem("shoulda-context", path: ROOT_DIRECTORY, group: :test)
    end
  end

  def test_framework_require_path
    if TEST_FRAMEWORK == "test_unit"
      "test-unit"
    else
      "minitest/autorun"
    end
  end

  def create_gem_with_macro(module_name:, location:, macro_name:)
    fs.write_file("#{location}/shoulda_macros/macros.rb", <<~FILE)
      module #{module_name}
        def #{macro_name}
          puts "#{macro_name} is available"
        end
      end

      Shoulda::Context.configure do |config|
        config.extend(#{module_name})
      end
    FILE
  end

  private

  def test_framework_gem_name
    if TEST_FRAMEWORK == "test_unit"
      "test-unit"
    else
      "minitest"
    end
  end
end


================================================
FILE: test/support/snowglobe.rb
================================================
require "snowglobe"

Snowglobe.configure do |config|
  config.project_name = "shoulda-context"
end


================================================
FILE: test/test_helper.rb
================================================
require_relative "support/current_bundle"

Tests::CurrentBundle.instance.assert_appraisal!

#---

require "pry-byebug"
require "warnings_logger"

TEST_FRAMEWORK = ENV.fetch("TEST_FRAMEWORK", "minitest")

if TEST_FRAMEWORK == "test_unit"
  require "test-unit"
  require "mocha/test_unit"
else
  require "minitest/autorun"
  require "mocha/minitest"
end

PROJECT_DIR = File.expand_path("../..", __FILE__)
PARENT_TEST_CASE =
  if TEST_FRAMEWORK == "test_unit"
    Test::Unit::TestCase
  else
    Minitest::Test
  end
ASSERTION_CLASS =
  if TEST_FRAMEWORK == "test_unit"
    Test::Unit::AssertionFailedError
  else
    Minitest::Assertion
  end

WarningsLogger::Spy.call(
  project_name: "shoulda-context",
  project_directory: Pathname.new("../..").expand_path(__FILE__)
)

require_relative "support/rails_application_with_shoulda_context"

require_relative "../lib/shoulda/context"

Shoulda.autoload_macros(
  File.join(File.dirname(__FILE__), "fake_rails_root"),
  File.join("vendor", "{plugins,gems}", "*")
)

$VERBOSE = true
Download .txt
gitextract_exvje7qk/

├── .github/
│   └── workflows/
│       ├── ci.yml
│       ├── dynamic-readme.yml
│       ├── dynamic-security.yml
│       └── rubocop.yml
├── .gitignore
├── .rubocop.yml
├── .rubocop_todo.yml
├── .ruby-version
├── Appraisals
├── CHANGELOG.md
├── Gemfile
├── LICENSE
├── MAINTAINING.md
├── README.md
├── Rakefile
├── SECURITY.md
├── bin/
│   ├── install_gems_in_all_appraisals
│   ├── run_all_tests
│   ├── setup
│   ├── supported_ruby_versions
│   ├── update_gem_in_all_appraisals
│   └── update_gems_in_all_appraisals
├── exe/
│   └── convert_to_should_syntax
├── gemfiles/
│   ├── rails_6_0.gemfile
│   └── rails_6_1.gemfile
├── lib/
│   ├── shoulda/
│   │   ├── context/
│   │   │   ├── assertions.rb
│   │   │   ├── autoload_macros.rb
│   │   │   ├── configuration.rb
│   │   │   ├── context.rb
│   │   │   ├── dsl.rb
│   │   │   ├── proc_extensions.rb
│   │   │   ├── railtie.rb
│   │   │   ├── tasks/
│   │   │   │   ├── list_tests.rake
│   │   │   │   └── yaml_to_shoulda.rake
│   │   │   ├── tasks.rb
│   │   │   ├── test_framework_detection.rb
│   │   │   ├── version.rb
│   │   │   └── world.rb
│   │   └── context.rb
│   └── shoulda-context.rb
├── shoulda-context.gemspec
├── tasks/
│   └── shoulda.rake
└── test/
    ├── fake_rails_root/
    │   ├── test/
    │   │   └── shoulda_macros/
    │   │       └── custom_macro.rb
    │   └── vendor/
    │       ├── gems/
    │       │   └── gem_with_macro-0.0.1/
    │       │       └── shoulda_macros/
    │       │           └── gem_macro.rb
    │       └── plugins/
    │           ├── .keep
    │           └── plugin_with_macro/
    │               └── shoulda_macros/
    │                   └── plugin_macro.rb
    ├── shoulda/
    │   ├── autoload_macro_test.rb
    │   ├── context_test.rb
    │   ├── convert_to_should_syntax_test.rb
    │   ├── helpers_test.rb
    │   ├── railtie_test.rb
    │   ├── rerun_snippet_test.rb
    │   ├── should_test.rb
    │   └── test_framework_detection_test.rb
    ├── support/
    │   ├── current_bundle.rb
    │   ├── rails_application_with_shoulda_context.rb
    │   └── snowglobe.rb
    └── test_helper.rb
Download .txt
SYMBOL INDEX (197 symbols across 24 files)

FILE: lib/shoulda/context/assertions.rb
  type Shoulda (line 1) | module Shoulda # :nodoc:
    type Context (line 2) | module Context
      type Assertions (line 3) | module Assertions
        function assert_same_elements (line 7) | def assert_same_elements(a1, a2, msg = nil)
        function assert_contains (line 24) | def assert_contains(collection, x, extra_msg = "")
        function assert_does_not_contain (line 37) | def assert_does_not_contain(collection, x, extra_msg = "")
        function assert_accepts (line 50) | def assert_accepts(matcher, target, options = {})
        function assert_rejects (line 68) | def assert_rejects(matcher, target, options = {})
        function safe_assert_block (line 90) | def safe_assert_block(message = "assert_block failed.", &block)

FILE: lib/shoulda/context/autoload_macros.rb
  type Shoulda (line 1) | module Shoulda # :nodoc:
    function autoload_macros (line 38) | def self.autoload_macros(root, *dirs)

FILE: lib/shoulda/context/configuration.rb
  type Shoulda (line 1) | module Shoulda
    type Context (line 2) | module Context
      function configure (line 3) | def self.configure
      function include (line 7) | def self.include(mod)
      function extend (line 13) | def self.extend(mod)

FILE: lib/shoulda/context/context.rb
  type Shoulda (line 1) | module Shoulda
    type Context (line 2) | module Context
      class Context (line 3) | class Context # :nodoc:
        method subject_block (line 13) | def subject_block
        method initialize (line 19) | def initialize(name, parent, &blk)
        method merge_block (line 38) | def merge_block(&blk)
        method context (line 47) | def context(name, &blk)
        method setup (line 51) | def setup(&blk)
        method teardown (line 55) | def teardown(&blk)
        class LambdaWithLocation (line 59) | class LambdaWithLocation < Proc
          method initialize (line 62) | def initialize(source_location, &blk)
        method should (line 68) | def should(name_or_matcher, options = {}, source_location = (loc =...
        method should_not (line 84) | def should_not(matcher, source_location = (loc = caller_locations(...
        method should_eventually (line 91) | def should_eventually(name, &blk)
        method subject (line 95) | def subject(&block)
        method full_name (line 99) | def full_name
        method am_subcontext? (line 104) | def am_subcontext?
        method test_unit_class (line 108) | def test_unit_class
        method test_methods (line 112) | def test_methods
        method create_test_from_should_hash (line 118) | def create_test_from_should_hash(should)
        method build_test_name_from (line 153) | def build_test_name_from(should)
        method run_all_setup_blocks (line 162) | def run_all_setup_blocks(binding)
        method run_parent_setup_blocks (line 167) | def run_parent_setup_blocks(binding)
        method run_current_setup_blocks (line 171) | def run_current_setup_blocks(binding)
        method run_all_teardown_blocks (line 182) | def run_all_teardown_blocks(binding)
        method print_should_eventuallys (line 194) | def print_should_eventuallys
        method build (line 201) | def build
        method test_name_prefix (line 211) | def test_name_prefix
        method method_missing (line 219) | def method_missing(method, *args, &blk)
      class DuplicateTestError (line 224) | class DuplicateTestError < RuntimeError; end

FILE: lib/shoulda/context/dsl.rb
  type Shoulda (line 3) | module Shoulda
    type Context (line 4) | module Context
      type DSL (line 5) | module DSL
        function included (line 6) | def self.included(base)
        type ClassMethods (line 14) | module ClassMethods
          function should (line 64) | def should(name_or_matcher, options = {}, source_location = (loc...
          function should_not (line 84) | def should_not(matcher, source_location = (loc = caller_location...
          function before_should (line 123) | def before_should(name, &blk)
          function should_eventually (line 128) | def should_eventually(name, options = {}, &blk)
          function context (line 190) | def context(name, &blk)
          function described_type (line 203) | def described_type
          function subject (line 220) | def subject(&block)
          function subject_block (line 224) | def subject_block # :nodoc:
        type InstanceMethods (line 229) | module InstanceMethods
          function subject (line 249) | def subject
          function subject_block (line 253) | def subject_block # :nodoc:
          function get_instance_of (line 257) | def get_instance_of(object_or_klass) # :nodoc:
          function instance_variable_name_for (line 265) | def instance_variable_name_for(klass) # :nodoc:
          function construct_subject (line 271) | def construct_subject

FILE: lib/shoulda/context/proc_extensions.rb
  class Proc (line 3) | class Proc #:nodoc:
    method bind (line 4) | def bind(object)

FILE: lib/shoulda/context/railtie.rb
  type Shoulda (line 1) | module Shoulda
    type Context (line 2) | module Context
      class Railtie (line 3) | class Railtie < Rails::Railtie

FILE: lib/shoulda/context/tasks/yaml_to_shoulda.rake
  function yaml_to_context (line 8) | def yaml_to_context(hash, indent = 0)

FILE: lib/shoulda/context/test_framework_detection.rb
  type Shoulda (line 1) | module Shoulda
    type Context (line 2) | module Context
      type TestFrameworkDetection (line 3) | module TestFrameworkDetection
        function possible_test_frameworks (line 4) | def self.possible_test_frameworks
        function resolve_framework (line 12) | def self.resolve_framework(future_framework)
        function detected_test_framework_test_cases (line 18) | def self.detected_test_framework_test_cases
        function test_framework_test_cases (line 24) | def self.test_framework_test_cases
      function test_framework_test_cases (line 29) | def self.test_framework_test_cases

FILE: lib/shoulda/context/version.rb
  type Shoulda (line 1) | module Shoulda
    type Context (line 2) | module Context

FILE: lib/shoulda/context/world.rb
  type Shoulda (line 1) | module Shoulda
    type Context (line 2) | module Context
      function contexts (line 4) | def contexts # :nodoc:
      function current_context (line 9) | def current_context # :nodoc:
      function add_context (line 13) | def add_context(context) # :nodoc:
      function remove_context (line 17) | def remove_context # :nodoc:

FILE: test/fake_rails_root/test/shoulda_macros/custom_macro.rb
  type CustomMacro (line 1) | module CustomMacro
    function custom_macro (line 2) | def custom_macro

FILE: test/fake_rails_root/vendor/gems/gem_with_macro-0.0.1/shoulda_macros/gem_macro.rb
  type GemMacro (line 1) | module GemMacro
    function gem_macro (line 2) | def gem_macro

FILE: test/fake_rails_root/vendor/plugins/plugin_with_macro/shoulda_macros/plugin_macro.rb
  type PluginMacro (line 1) | module PluginMacro
    function plugin_macro (line 2) | def plugin_macro

FILE: test/shoulda/autoload_macro_test.rb
  class AutoloadMacroTest (line 3) | class AutoloadMacroTest < PARENT_TEST_CASE

FILE: test/shoulda/context_test.rb
  class ContextTest (line 3) | class ContextTest < PARENT_TEST_CASE
    method context_macro (line 4) | def self.context_macro(&blk)
    method hello (line 71) | def hello; "hi"; end
    class ::SomeModel (line 138) | class ::SomeModel; end
    method normalized_name (line 168) | def normalized_name
  class ::Some (line 173) | class ::Some
    class NestedModel (line 174) | class NestedModel; end
  class Some::NestedModelTest (line 177) | class Some::NestedModelTest < PARENT_TEST_CASE
  class Some::SomeTest (line 183) | class Some::SomeTest < PARENT_TEST_CASE
  class ShouldMatcherTest (line 191) | class ShouldMatcherTest < PARENT_TEST_CASE
    class FakeMatcher (line 192) | class FakeMatcher
      method description (line 196) | def description
      method matches? (line 200) | def matches?(subject)
      method failure_message (line 205) | def failure_message
      method failure_message_when_negated (line 209) | def failure_message_when_negated
    method setup (line 214) | def setup
    method assert_failed_with (line 218) | def assert_failed_with(message, test_suite)
    method assert_passed (line 222) | def assert_passed(test_suite)
    method assert_test_named (line 226) | def assert_test_named(expected_name, test_suite)
    method should_use_positive_matcher (line 234) | def self.should_use_positive_matcher
    method should_use_negative_matcher (line 258) | def self.should_use_negative_matcher
    class TestSuite (line 334) | class TestSuite
      method create (line 335) | def self.create(&definition)
    class TestUnitSuite (line 344) | class TestUnitSuite
      method initialize (line 345) | def initialize(&definition)
      method run (line 350) | def run
      method failure_messages (line 356) | def failure_messages
      method test_names (line 360) | def test_names
    class MinitestSuite (line 365) | class MinitestSuite
      method initialize (line 366) | def initialize(&definition)
      method run (line 371) | def run
      method failure_messages (line 375) | def failure_messages
      method test_names (line 379) | def test_names
  class Subject (line 385) | class Subject; end
  class SubjectTest (line 387) | class SubjectTest < PARENT_TEST_CASE
    method setup (line 389) | def setup
  class SubjectLazinessTest (line 400) | class SubjectLazinessTest < PARENT_TEST_CASE

FILE: test/shoulda/convert_to_should_syntax_test.rb
  class ConvertToShouldSyntaxTest (line 3) | class ConvertToShouldSyntaxTest < PARENT_TEST_CASE
    method test_convert_to_should_syntax (line 48) | def test_convert_to_should_syntax
    method teardown (line 58) | def teardown

FILE: test/shoulda/helpers_test.rb
  class HelpersTest (line 3) | class HelpersTest < PARENT_TEST_CASE

FILE: test/shoulda/railtie_test.rb
  class RailtieTest (line 3) | class RailtieTest < PARENT_TEST_CASE
    method app (line 40) | def app

FILE: test/shoulda/rerun_snippet_test.rb
  class RerunSnippetTest (line 3) | class RerunSnippetTest < PARENT_TEST_CASE
    method app (line 56) | def app
    method rails_version (line 60) | def rails_version

FILE: test/shoulda/should_test.rb
  class ShouldTest (line 3) | class ShouldTest < PARENT_TEST_CASE
    method should_see_class_methods (line 12) | def self.should_see_class_methods
    method should_be_able_to_setup_a_should_eventually_in_a_class_method (line 18) | def self.should_be_able_to_setup_a_should_eventually_in_a_class_method
    method should_see_a_context_block_like_a_test_case_class (line 22) | def self.should_see_a_context_block_like_a_test_case_class
    method should_see_blah (line 28) | def self.should_see_blah
    method should_not_see_blah (line 34) | def self.should_not_see_blah
    method should_be_able_to_make_context_macros (line 40) | def self.should_be_able_to_make_context_macros(prefix = nil)
    method test_should_create_a_new_context (line 152) | def test_should_create_a_new_context
    method test_should_create_a_new_context_even_if_block_is_omitted (line 158) | def test_should_create_a_new_context_even_if_block_is_omitted
    method test_should_create_a_nested_context (line 167) | def test_should_create_a_nested_context
    method test_should_name_a_contexts_correctly (line 175) | def test_should_name_a_contexts_correctly
    method test_should_raise_on_duplicate_naming (line 185) | def test_should_raise_on_duplicate_naming
    method test_should_have_should_hashes_when_given_should_statements (line 197) | def test_should_have_should_hashes_when_given_should_statements
    method test_should_capture_setup_and_teardown_blocks (line 209) | def test_should_capture_setup_and_teardown_blocks
    method test_should_create_shoulda_test_for_each_should_on_build (line 221) | def test_should_create_shoulda_test_for_each_should_on_build
    method test_should_create_test_methods_on_build (line 231) | def test_should_create_test_methods_on_build
    method test_should_create_test_methods_on_build_when_subcontext (line 245) | def test_should_create_test_methods_on_build_when_subcontext
    method test_should_create_a_new_context_and_build_it_on_test_case_context (line 265) | def test_should_create_a_new_context_and_build_it_on_test_case_context
    method test_should_create_a_one_off_context_and_build_it_on_test_case_should (line 272) | def test_should_create_a_one_off_context_and_build_it_on_test_case_should
    method test_should_create_a_one_off_context_and_build_it_on_test_case_should_eventually (line 279) | def test_should_create_a_one_off_context_and_build_it_on_test_case_sho...
    method test_name (line 328) | def test_name
    method build_expected_test_name (line 332) | def build_expected_test_name(value)
    method assert_nothing_raised (line 348) | def assert_nothing_raised
  class RedTestarossaDriver (line 353) | class RedTestarossaDriver; end
  class RedTestarossaDriverTest (line 355) | class RedTestarossaDriverTest < PARENT_TEST_CASE
    class DummyMatcher (line 356) | class DummyMatcher
      method description (line 357) | def description
      method matches? (line 361) | def matches?(*)
      method failure_message_when_negated (line 365) | def failure_message_when_negated
    method test_should_property_construct_test_name_for_should_eventually (line 385) | def test_should_property_construct_test_name_for_should_eventually
    method test_should_property_construct_test_name_for_should_not (line 398) | def test_should_property_construct_test_name_for_should_not
    method test_name (line 413) | def test_name
    method build_expected_test_name (line 417) | def build_expected_test_name(value)

FILE: test/shoulda/test_framework_detection_test.rb
  class TestFrameworkDetectionTest (line 4) | class TestFrameworkDetectionTest < PARENT_TEST_CASE
    method assert_integration_with_rails_and (line 22) | def assert_integration_with_rails_and(*test_cases)
    method assert_integration_with (line 38) | def assert_integration_with(*test_cases)
    method assert_test_cases_are_detected (line 43) | def assert_test_cases_are_detected(*expected_test_cases)
    method file_that_detects_test_framework_test_cases (line 51) | def file_that_detects_test_framework_test_cases(mixins)
    method require_gems (line 63) | def require_gems(mixins)
    method assert_our_api_is_available_in_test_cases (line 75) | def assert_our_api_is_available_in_test_cases(*test_cases)
    method file_that_runs_a_test_within_test_case (line 90) | def file_that_runs_a_test_within_test_case(test_case, mixins)
    method execute (line 104) | def execute(code)

FILE: test/support/current_bundle.rb
  type Tests (line 4) | module Tests
    class CurrentBundle (line 5) | class CurrentBundle
      method assert_appraisal! (line 10) | def assert_appraisal!
      method appraisal_in_use? (line 23) | def appraisal_in_use?
      method current_or_latest_appraisal (line 27) | def current_or_latest_appraisal
      method latest_appraisal (line 31) | def latest_appraisal
      method current_appraisal (line 35) | def current_appraisal
      method available_appraisals (line 43) | def available_appraisals
      method path (line 53) | def path
      method root (line 57) | def root

FILE: test/support/rails_application_with_shoulda_context.rb
  class RailsApplicationWithShouldaContext (line 3) | class RailsApplicationWithShouldaContext < Snowglobe::RailsApplication
    method create (line 6) | def create
    method test_framework_require_path (line 15) | def test_framework_require_path
    method create_gem_with_macro (line 23) | def create_gem_with_macro(module_name:, location:, macro_name:)
    method test_framework_gem_name (line 39) | def test_framework_gem_name
Condensed preview — 58 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (118K chars).
[
  {
    "path": ".github/workflows/ci.yml",
    "chars": 1097,
    "preview": "name: Test\n\non:\n  push:\n    branches:\n      - main\n    paths-ignore:\n      - '**.md'\n  pull_request:\n    types:\n      - "
  },
  {
    "path": ".github/workflows/dynamic-readme.yml",
    "chars": 325,
    "preview": "name: update-templates\n\non: \n  push:\n    branches:\n      - main\n  workflow_dispatch:\n\njobs:\n  update-templates:\n    perm"
  },
  {
    "path": ".github/workflows/dynamic-security.yml",
    "chars": 355,
    "preview": "name: update-security\n\non:\n  push:\n    paths:\n      - SECURITY.md\n    branches:\n      - main\n  workflow_dispatch:\n\njobs:"
  },
  {
    "path": ".github/workflows/rubocop.yml",
    "chars": 636,
    "preview": "name: RuboCop\n\non: [push, pull_request]\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n\n    steps:\n    - name: Checkout Repo"
  },
  {
    "path": ".gitignore",
    "chars": 71,
    "preview": ".bundle\nvendor/ruby\nvendor/cache\ndoc\ncoverage\npkg\n*.swp\n*.swo\ntags\ntmp\n"
  },
  {
    "path": ".rubocop.yml",
    "chars": 3911,
    "preview": "inherit_from: .rubocop_todo.yml\n\nAllCops:\n  TargetRubyVersion: 2.7\n  Exclude:\n    - '*.gemspec'\nLayout/AlignParameters:\n"
  },
  {
    "path": ".rubocop_todo.yml",
    "chars": 10398,
    "preview": "# This configuration was generated by\n# `rubocop --auto-gen-config`\n# on 2023-02-26 11:25:39 -0300 using RuboCop version"
  },
  {
    "path": ".ruby-version",
    "chars": 6,
    "preview": "2.7.7\n"
  },
  {
    "path": "Appraisals",
    "chars": 1795,
    "preview": "# Note: All of the dependencies here were obtained by running `rails new` with\n# various versions of Rails and copying l"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 4140,
    "preview": "# Changelog\n\n## 3.0.0.rc1 - 2024-04-21\n\n### Backward-incompatible changes\n\n* Drop support for Ruby 2.5 and 2.6 by @vsppe"
  },
  {
    "path": "Gemfile",
    "chars": 281,
    "preview": "source \"https://rubygems.org\"\n\ngemspec\n\ngem \"appraisal\"\ngem \"bundler\", \"~> 1.0\"\ngem \"byebug\"\ngem \"m\"\ngem \"minitest\"\ngem "
  },
  {
    "path": "LICENSE",
    "chars": 1094,
    "preview": "Copyright (c) Tammer Saleh and thoughtbot, inc.\r\n\r\nPermission is hereby granted, free of charge, to any person\r\nobtainin"
  },
  {
    "path": "MAINTAINING.md",
    "chars": 3666,
    "preview": "# Maintaining Shoulda Context\n\nAlthough Shoulda Context doesn't receive feature updates these days, you may\nneed to upda"
  },
  {
    "path": "README.md",
    "chars": 6839,
    "preview": "# Shoulda Context [![Gem Version][version-badge]][rubygems] [![Build Status][travis-badge]][travis] ![Downloads][downloa"
  },
  {
    "path": "Rakefile",
    "chars": 621,
    "preview": "require \"bundler/setup\"\nrequire \"bundler/gem_tasks\"\nrequire \"rake/testtask\"\nrequire \"pry-byebug\"\n\nrequire_relative \"test"
  },
  {
    "path": "SECURITY.md",
    "chars": 661,
    "preview": "<!-- START /templates/security.md -->\n# Security Policy\n\n## Supported Versions\n\nOnly the the latest version of this proj"
  },
  {
    "path": "bin/install_gems_in_all_appraisals",
    "chars": 344,
    "preview": "#!/bin/bash\n\nset -euo pipefail\n\nSUPPORTED_VERSIONS=$(bin/supported_ruby_versions)\n\ninstall-gems-for-version() {\n  local "
  },
  {
    "path": "bin/run_all_tests",
    "chars": 313,
    "preview": "#!/bin/bash\n\nset -euo pipefail\n\nSUPPORTED_VERSIONS=$(bin/supported_ruby_versions)\n\nrun-tests-for-version() {\n  local ver"
  },
  {
    "path": "bin/setup",
    "chars": 4194,
    "preview": "#!/usr/bin/env bash\n\nset -euo pipefail\n\nRUBY_VERSION=$(bin/supported_ruby_versions | xargs -n 1 echo | sort -V | tail -n"
  },
  {
    "path": "bin/supported_ruby_versions",
    "chars": 235,
    "preview": "#!/usr/bin/env ruby\n\nrequire 'yaml'\n\nci_config_path = File.expand_path('../../.github//workflows/ci.yml', __FILE__)\nci_c"
  },
  {
    "path": "bin/update_gem_in_all_appraisals",
    "chars": 365,
    "preview": "#!/bin/bash\n\nset -euo pipefail\n\nSUPPORTED_VERSIONS=$(bin/supported_ruby_versions)\ngem=\"$1\"\n\nupdate-gem-for-version() {\n "
  },
  {
    "path": "bin/update_gems_in_all_appraisals",
    "chars": 369,
    "preview": "#!/bin/bash\n\nset -euo pipefail\n\nSUPPORTED_VERSIONS=$(bin/supported_ruby_versions)\n\nupdate-gems-for-version() {\n  local v"
  },
  {
    "path": "exe/convert_to_should_syntax",
    "chars": 1348,
    "preview": "#!/usr/bin/env ruby\nrequire 'fileutils'\nrequire 'tmpdir'\n\nTMP = Dir::tmpdir\n\ndef usage(msg = nil)\n  puts \"Error: #{msg}\""
  },
  {
    "path": "gemfiles/rails_6_0.gemfile",
    "chars": 860,
    "preview": "# This file was generated by Appraisal\n\nsource \"https://rubygems.org\"\n\ngem \"appraisal\"\ngem \"bundler\", \"~> 1.0\"\ngem \"byeb"
  },
  {
    "path": "gemfiles/rails_6_1.gemfile",
    "chars": 829,
    "preview": "# This file was generated by Appraisal\n\nsource \"https://rubygems.org\"\n\ngem \"appraisal\"\ngem \"bcrypt\", \"~> 3.1.7\"\ngem \"boo"
  },
  {
    "path": "lib/shoulda/context/assertions.rb",
    "chars": 3590,
    "preview": "module Shoulda # :nodoc:\n  module Context\n    module Assertions\n      # Asserts that two arrays contain the same element"
  },
  {
    "path": "lib/shoulda/context/autoload_macros.rb",
    "chars": 1928,
    "preview": "module Shoulda # :nodoc:\n  # Call autoload_macros when you want to load test macros automatically in a non-Rails\n  # pro"
  },
  {
    "path": "lib/shoulda/context/configuration.rb",
    "chars": 358,
    "preview": "module Shoulda\n  module Context\n    def self.configure\n      yield self\n    end\n\n    def self.include(mod)\n      test_fr"
  },
  {
    "path": "lib/shoulda/context/context.rb",
    "chars": 7031,
    "preview": "module Shoulda\n  module Context\n    class Context # :nodoc:\n      attr_accessor :name               # my name\n      attr"
  },
  {
    "path": "lib/shoulda/context/dsl.rb",
    "chars": 9765,
    "preview": "require \"shoulda/context/assertions\"\n\nmodule Shoulda\n  module Context\n    module DSL\n      def self.included(base)\n     "
  },
  {
    "path": "lib/shoulda/context/proc_extensions.rb",
    "chars": 373,
    "preview": "# Stolen straight from ActiveSupport\n\nclass Proc #:nodoc:\n  def bind(object)\n    block, time = self, Time.now\n    (class"
  },
  {
    "path": "lib/shoulda/context/railtie.rb",
    "chars": 315,
    "preview": "module Shoulda\n  module Context\n    class Railtie < Rails::Railtie\n      initializer \"shoulda_context.autoload_macros\" d"
  },
  {
    "path": "lib/shoulda/context/tasks/list_tests.rake",
    "chars": 836,
    "preview": "namespace :shoulda do\n  desc \"List the names of the test methods in a specification like format\"\n  task :list do\n    $LO"
  },
  {
    "path": "lib/shoulda/context/tasks/yaml_to_shoulda.rake",
    "chars": 907,
    "preview": "namespace :shoulda do\n  # From http://blog.internautdesign.com/2007/11/2/a-yaml_to_shoulda-rake-task\n  # David.Lowenfels"
  },
  {
    "path": "lib/shoulda/context/tasks.rb",
    "chars": 83,
    "preview": "Dir[File.join(File.dirname(__FILE__), 'tasks', '*.rake')].each do |f|\n  load f\nend\n"
  },
  {
    "path": "lib/shoulda/context/test_framework_detection.rb",
    "chars": 811,
    "preview": "module Shoulda\n  module Context\n    module TestFrameworkDetection\n      def self.possible_test_frameworks\n        [\n    "
  },
  {
    "path": "lib/shoulda/context/version.rb",
    "chars": 75,
    "preview": "module Shoulda\n  module Context\n    VERSION = \"3.0.0.rc1\".freeze\n  end\nend\n"
  },
  {
    "path": "lib/shoulda/context/world.rb",
    "chars": 394,
    "preview": "module Shoulda\n  module Context\n    class << self\n      def contexts # :nodoc:\n        @contexts ||= []\n      end\n      "
  },
  {
    "path": "lib/shoulda/context.rb",
    "chars": 449,
    "preview": "require \"shoulda/context/autoload_macros\"\nrequire \"shoulda/context/configuration\"\nrequire \"shoulda/context/context\"\nrequ"
  },
  {
    "path": "lib/shoulda-context.rb",
    "chars": 26,
    "preview": "require \"shoulda/context\"\n"
  },
  {
    "path": "shoulda-context.gemspec",
    "chars": 925,
    "preview": "# -*- encoding: utf-8 -*-\n\n$LOAD_PATH << File.join(File.dirname(__FILE__), \"lib\")\nrequire \"shoulda/context/version\"\n\nGem"
  },
  {
    "path": "tasks/shoulda.rake",
    "chars": 86,
    "preview": "load File.join(File.dirname(__FILE__), \"..\", \"lib\", \"shoulda\", \"context\", \"tasks.rb\")\n"
  },
  {
    "path": "test/fake_rails_root/test/shoulda_macros/custom_macro.rb",
    "chars": 86,
    "preview": "module CustomMacro\n  def custom_macro\n  end\nend\nPARENT_TEST_CASE.extend(CustomMacro)\n\n"
  },
  {
    "path": "test/fake_rails_root/vendor/gems/gem_with_macro-0.0.1/shoulda_macros/gem_macro.rb",
    "chars": 76,
    "preview": "module GemMacro\n  def gem_macro\n  end\nend\nPARENT_TEST_CASE.extend(GemMacro)\n"
  },
  {
    "path": "test/fake_rails_root/vendor/plugins/.keep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "test/fake_rails_root/vendor/plugins/plugin_with_macro/shoulda_macros/plugin_macro.rb",
    "chars": 85,
    "preview": "module PluginMacro\n  def plugin_macro\n  end\nend\nPARENT_TEST_CASE.extend(PluginMacro)\n"
  },
  {
    "path": "test/shoulda/autoload_macro_test.rb",
    "chars": 445,
    "preview": "require 'test_helper'\n\nclass AutoloadMacroTest < PARENT_TEST_CASE\n  context \"The macro auto-loader\" do\n    should \"load "
  },
  {
    "path": "test/shoulda/context_test.rb",
    "chars": 9190,
    "preview": "require 'test_helper'\n\nclass ContextTest < PARENT_TEST_CASE\n  def self.context_macro(&blk)\n    context \"with a subcontex"
  },
  {
    "path": "test/shoulda/convert_to_should_syntax_test.rb",
    "chars": 1289,
    "preview": "require 'test_helper'\n\nclass ConvertToShouldSyntaxTest < PARENT_TEST_CASE\n  BEFORE_FIXTURE = <<-EOS\n    class DummyTest "
  },
  {
    "path": "test/shoulda/helpers_test.rb",
    "chars": 4287,
    "preview": "require 'test_helper'\n\nclass HelpersTest < PARENT_TEST_CASE\n  context \"an array of values\" do\n    setup do\n      @a = ['"
  },
  {
    "path": "test/shoulda/railtie_test.rb",
    "chars": 1173,
    "preview": "require \"test_helper\"\n\nclass RailtieTest < PARENT_TEST_CASE\n  context \"A Rails application with shoulda-context added to"
  },
  {
    "path": "test/shoulda/rerun_snippet_test.rb",
    "chars": 1913,
    "preview": "require \"test_helper\"\n\nclass RerunSnippetTest < PARENT_TEST_CASE\n  context \"A Rails application with shoulda-context add"
  },
  {
    "path": "test/shoulda/should_test.rb",
    "chars": 10993,
    "preview": "require 'test_helper'\n\nclass ShouldTest < PARENT_TEST_CASE\n  should \"be able to define a should statement outside of a c"
  },
  {
    "path": "test/shoulda/test_framework_detection_test.rb",
    "chars": 3253,
    "preview": "require \"test_helper\"\nrequire \"tempfile\"\n\nclass TestFrameworkDetectionTest < PARENT_TEST_CASE\n  if TEST_FRAMEWORK == \"mi"
  },
  {
    "path": "test/support/current_bundle.rb",
    "chars": 1084,
    "preview": "require \"bundler\"\nrequire \"appraisal\"\n\nmodule Tests\n  class CurrentBundle\n    AppraisalNotSpecified = Class.new(Argument"
  },
  {
    "path": "test/support/rails_application_with_shoulda_context.rb",
    "chars": 1007,
    "preview": "require_relative \"snowglobe\"\n\nclass RailsApplicationWithShouldaContext < Snowglobe::RailsApplication\n  ROOT_DIRECTORY = "
  },
  {
    "path": "test/support/snowglobe.rb",
    "chars": 99,
    "preview": "require \"snowglobe\"\n\nSnowglobe.configure do |config|\n  config.project_name = \"shoulda-context\"\nend\n"
  },
  {
    "path": "test/test_helper.rb",
    "chars": 1026,
    "preview": "require_relative \"support/current_bundle\"\n\nTests::CurrentBundle.instance.assert_appraisal!\n\n#---\n\nrequire \"pry-byebug\"\nr"
  }
]

About this extraction

This page contains the full source code of the thoughtbot/shoulda-context GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 58 files (106.2 KB), approximately 30.3k tokens, and a symbol index with 197 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!