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

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
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
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.