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 ``` 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 . ## 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 ## About thoughtbot ![thoughtbot](https://thoughtbot.com/thoughtbot-logo-for-readmes.svg) This repo is maintained and funded by thoughtbot, inc. The names and logos for thoughtbot are trademarks of thoughtbot, inc. We love open source software! See [our other projects][community]. We are [available for hire][hire]. [community]: https://thoughtbot.com/community?utm_source=github [hire]: https://thoughtbot.com/hire-us?utm_source=github ================================================ 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 ================================================ # 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 . If you have any suggestions to improve this policy, visit . ================================================ 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: # * "test: User should return its full name. " # # Note: The part before should in the test name is gleamed from the name of the Test::Unit class. # # Should statements can also take a Proc as a :before 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 "test: A User instance should return its full name. ". # # 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 # * "test: A User instance should return its full name. " # * "test: A User instance with a profile should return true when sent :has_profile?. " # # Just like should statements, a context block can exist next to normal def test_the_old_way; end # tests. 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: 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 = <`. 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