├── .ruby-version ├── .tool-versions ├── .hound.yml ├── lib ├── shoulda │ └── version.rb └── shoulda.rb ├── .gitignore ├── script ├── supported_ruby_versions ├── run_all_tests ├── install_gems_in_all_appraisals ├── update_gem_in_all_appraisals └── update_gems_in_all_appraisals ├── test ├── support │ ├── acceptance │ │ ├── helpers │ │ │ ├── array_helpers.rb │ │ │ └── pluralization_helpers.rb │ │ ├── matchers │ │ │ ├── have_output.rb │ │ │ └── indicate_that_tests_were_run.rb │ │ ├── rails_application_with_shoulda.rb │ │ └── add_shoulda_to_project.rb │ ├── current_bundle.rb │ └── snowglobe.rb ├── test_helper.rb ├── acceptance_test_helper.rb └── acceptance │ └── integrates_with_rails_test.rb ├── .autotest ├── .github └── workflows │ ├── dynamic-readme.yml │ ├── dynamic-security.yml │ ├── rubocop.yml │ └── ci.yml ├── Gemfile ├── CODEOWNERS ├── SECURITY.md ├── Rakefile ├── CHANGELOG.md ├── gemfiles ├── rails_7_0.gemfile ├── rails_6_1.gemfile ├── rails_7_0.gemfile.lock └── rails_6_1.gemfile.lock ├── LICENSE ├── shoulda.gemspec ├── Appraisals ├── MAINTAINING.md ├── README.md └── .rubocop.yml /.ruby-version: -------------------------------------------------------------------------------- 1 | 3.2.1 2 | -------------------------------------------------------------------------------- /.tool-versions: -------------------------------------------------------------------------------- 1 | ruby 3.2.1 2 | -------------------------------------------------------------------------------- /.hound.yml: -------------------------------------------------------------------------------- 1 | ruby: 2 | enabled: true 3 | config_file: .rubocop.yml 4 | -------------------------------------------------------------------------------- /lib/shoulda/version.rb: -------------------------------------------------------------------------------- 1 | module Shoulda 2 | VERSION = '5.0.0.rc1'.freeze 3 | end 4 | -------------------------------------------------------------------------------- /lib/shoulda.rb: -------------------------------------------------------------------------------- 1 | require 'shoulda/version' 2 | require 'shoulda/matchers' 3 | require 'shoulda/context' 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.swo 2 | *.swp 3 | .DS_Store 4 | .byebug_history 5 | .bundle 6 | .svn/ 7 | Gemfile.lock 8 | coverage 9 | doc 10 | pkg 11 | tags 12 | test/*/log/*.log 13 | tmp 14 | -------------------------------------------------------------------------------- /script/supported_ruby_versions: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require 'yaml' 4 | 5 | travis_config_path = File.expand_path('../.travis.yml', __dir__) 6 | travis_config = YAML.load_file(travis_config_path) 7 | puts travis_config.fetch('rvm').join(' ') 8 | -------------------------------------------------------------------------------- /test/support/acceptance/helpers/array_helpers.rb: -------------------------------------------------------------------------------- 1 | module AcceptanceTests 2 | module ArrayHelpers 3 | def to_sentence(array) 4 | if array.size == 1 5 | array[0] 6 | elsif array.size == 2 7 | array.join(' and ') 8 | else 9 | to_sentence(array[1..-2].join(', '), [array[-1]]) 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /.autotest: -------------------------------------------------------------------------------- 1 | Autotest.add_hook :initialize do |at| 2 | at.add_mapping(%r{^lib/\w.*\.rb}) do 3 | at.files_matching(%r{^test/*/\w.*_test\.rb}) 4 | end 5 | 6 | at.add_mapping(%r{^test/rails_root/\w.*}) do 7 | at.files_matching(%r{^test/*/\w.*_test\.rb}) 8 | end 9 | 10 | at.add_exception(%r{.svn}) 11 | at.add_exception(%r{.log$}) 12 | at.add_exception(%r{^.autotest$}) 13 | end 14 | -------------------------------------------------------------------------------- /script/run_all_tests: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euo pipefail 4 | 5 | SUPPORTED_VERSIONS=$(script/supported_ruby_versions) 6 | 7 | run-tests-for-version() { 8 | local version="$1" 9 | (export RBENV_VERSION=$version; bundle exec rake) 10 | } 11 | 12 | for version in $SUPPORTED_VERSIONS; do 13 | echo 14 | echo "*** Running tests for $version ***" 15 | run-tests-for-version $version 16 | done 17 | -------------------------------------------------------------------------------- /test/support/acceptance/helpers/pluralization_helpers.rb: -------------------------------------------------------------------------------- 1 | module AcceptanceTests 2 | module PluralizationHelpers 3 | def pluralize(count, singular_version, plural_version = nil) 4 | plural_version ||= "#{singular_version}s" 5 | 6 | if count == 1 7 | "#{count} #{singular_version}" 8 | else 9 | "#{count} #{plural_version}" 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /.github/workflows/dynamic-readme.yml: -------------------------------------------------------------------------------- 1 | name: update-templates 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | workflow_dispatch: 8 | 9 | jobs: 10 | update-templates: 11 | permissions: 12 | contents: write 13 | pull-requests: write 14 | pages: write 15 | uses: thoughtbot/templates/.github/workflows/dynamic-readme.yaml@main 16 | secrets: 17 | token: ${{ secrets.GITHUB_TOKEN }} 18 | -------------------------------------------------------------------------------- /script/install_gems_in_all_appraisals: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euo pipefail 4 | 5 | SUPPORTED_VERSIONS=$(script/supported_ruby_versions) 6 | 7 | install-gems-for-version() { 8 | local version="$1" 9 | (export RBENV_VERSION=$version; bundle && bundle exec appraisal install) 10 | } 11 | 12 | for version in $SUPPORTED_VERSIONS; do 13 | echo 14 | echo "*** Installing gems for $version ***" 15 | install-gems-for-version $version 16 | done 17 | -------------------------------------------------------------------------------- /.github/workflows/dynamic-security.yml: -------------------------------------------------------------------------------- 1 | name: update-security 2 | 3 | on: 4 | push: 5 | paths: 6 | - SECURITY.md 7 | branches: 8 | - main 9 | workflow_dispatch: 10 | 11 | jobs: 12 | update-security: 13 | permissions: 14 | contents: write 15 | pull-requests: write 16 | pages: write 17 | uses: thoughtbot/templates/.github/workflows/dynamic-security.yaml@main 18 | secrets: 19 | token: ${{ secrets.GITHUB_TOKEN }} 20 | -------------------------------------------------------------------------------- /script/update_gem_in_all_appraisals: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euo pipefail 4 | 5 | SUPPORTED_VERSIONS=$(script/supported_ruby_versions) 6 | gem="$1" 7 | 8 | update-gem-for-version() { 9 | local version="$1" 10 | (export RBENV_VERSION=$version; bundle update "$gem"; bundle exec appraisal update "$gem") 11 | } 12 | 13 | for version in $SUPPORTED_VERSIONS; do 14 | echo 15 | echo "*** Updating $gem for $version ***" 16 | update-gem-for-version $version 17 | done 18 | -------------------------------------------------------------------------------- /script/update_gems_in_all_appraisals: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euo pipefail 4 | 5 | SUPPORTED_VERSIONS=$(script/supported_ruby_versions) 6 | 7 | update-gems-for-version() { 8 | local version="$1" 9 | (export RBENV_VERSION=$version; bundle update "${@:2}"; bundle exec appraisal update "${@:2}") 10 | } 11 | 12 | for version in $SUPPORTED_VERSIONS; do 13 | echo 14 | echo "*** Updating gems for $version ***" 15 | update-gems-for-version "$version" "$@" 16 | done 17 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gemspec 4 | 5 | gem 'appraisal' 6 | gem 'm' 7 | gem 'minitest', '~> 5.0' 8 | gem 'minitest-reporters', '~> 1.0' 9 | gem 'pry' 10 | gem 'pry-byebug' 11 | gem 'rake', '13.0.1' 12 | gem 'rspec', '~> 3.9' 13 | gem 'rubocop', require: false 14 | gem 'rubocop-packaging', require: false 15 | gem 'rubocop-rails', require: false 16 | gem 'snowglobe', github: 'mcmire/snowglobe', ref: '408ee4c08f823a4d9f89902fa0fa29aff7cafe6d' 17 | gem 'warnings_logger' 18 | -------------------------------------------------------------------------------- /test/test_helper.rb: -------------------------------------------------------------------------------- 1 | require 'pry' 2 | require 'pry-byebug' 3 | require 'minitest/autorun' 4 | require 'minitest/reporters' 5 | require 'warnings_logger' 6 | 7 | require 'shoulda' 8 | 9 | Minitest::Reporters.use!(Minitest::Reporters::SpecReporter.new) 10 | 11 | WarningsLogger::Spy.call( 12 | project_name: 'shoulda', 13 | project_directory: Pathname.new('../..').expand_path(__FILE__), 14 | ) 15 | 16 | Shoulda::Matchers.configure do |config| 17 | config.integrate do |with| 18 | with.test_framework :minitest 19 | end 20 | end 21 | 22 | $VERBOSE = true 23 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Lines starting with '#' are comments. 2 | # Each line is a file pattern followed by one or more owners. 3 | 4 | # More details are here: https://help.github.com/articles/about-codeowners/ 5 | 6 | # The '*' pattern is global owners. 7 | 8 | # Order is important. The last matching pattern has the most precedence. 9 | # The folders are ordered as follows: 10 | 11 | # In each subsection folders are ordered first by depth, then alphabetically. 12 | # This should make it easy to add new rules without breaking existing ones. 13 | 14 | # Global rule: 15 | * @matsales28 16 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | # Security Policy 3 | 4 | ## Supported Versions 5 | 6 | Only the the latest version of this project is supported at a given time. If 7 | you find a security issue with an older version, please try updating to the 8 | latest version first. 9 | 10 | If for some reason you can't update to the latest version, please let us know 11 | your reasons so that we can have a better understanding of your situation. 12 | 13 | ## Reporting a Vulnerability 14 | 15 | For security inquiries or vulnerability reports, visit 16 | . 17 | 18 | If you have any suggestions to improve this policy, visit . 19 | 20 | 21 | -------------------------------------------------------------------------------- /.github/workflows/rubocop.yml: -------------------------------------------------------------------------------- 1 | name: RuboCop 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - name: Checkout Repository 11 | uses: actions/checkout@v3 12 | 13 | - name: Setup Ruby 14 | uses: ruby/setup-ruby@v1 15 | 16 | - name: Cache gems 17 | uses: actions/cache@v3 18 | with: 19 | path: ../vendor/bundle 20 | key: ${{ runner.os }}-rubocop-${{ hashFiles('**/Gemfile.lock') }} 21 | restore-keys: | 22 | ${{ runner.os }}-rubocop- 23 | 24 | - name: Install gems 25 | run: | 26 | bundle config path ../vendor/bundle 27 | bundle install --jobs 4 --retry 3 28 | 29 | - name: Run RuboCop 30 | run: bundle exec rubocop --parallel 31 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'bundler/gem_tasks' 3 | require 'rake/testtask' 4 | require 'pry-byebug' 5 | 6 | require_relative 'test/support/current_bundle' 7 | 8 | Rake::TestTask.new do |t| 9 | t.libs << 'test' 10 | t.ruby_opts += ['-w'] 11 | t.pattern = 'test/**/*_test.rb' 12 | t.verbose = false 13 | end 14 | 15 | task :default do 16 | if Tests::CurrentBundle.instance.appraisal_in_use? 17 | Rake::Task['test'].invoke 18 | elsif ENV['CI'] 19 | exec 'appraisal install && appraisal rake --trace' 20 | else 21 | appraisal = Tests::CurrentBundle.instance.latest_appraisal 22 | exec "appraisal install && appraisal #{appraisal} rake --trace" 23 | end 24 | end 25 | 26 | namespace :appraisal do 27 | task :list do 28 | appraisals = Tests::CurrentBundle.instance.available_appraisals 29 | puts "Valid appraisals: #{appraisals.join(', ')}" 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /test/support/acceptance/matchers/have_output.rb: -------------------------------------------------------------------------------- 1 | module AcceptanceTests 2 | module Matchers 3 | def have_output(output) 4 | HaveOutputMatcher.new(output) 5 | end 6 | # rubocop:enable Naming/PredicateName 7 | 8 | class HaveOutputMatcher 9 | def initialize(output) 10 | @output = output 11 | end 12 | 13 | def matches?(runner) 14 | @runner = runner 15 | runner.has_output?(output) 16 | end 17 | 18 | def failure_message 19 | [ 20 | "Expected command to have output, but did not.\n\n", 21 | "Command: #{runner.formatted_command}\n\n", 22 | "Expected output:\n", 23 | output.inspect, 24 | "\n\n", 25 | "Actual output:\n", 26 | runner.output, 27 | ].join 28 | end 29 | 30 | protected 31 | 32 | attr_reader :output, :runner 33 | end 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## 5.0.0.rc1 - 2023-03-23 4 | 5 | * `shoulda` now relies upon `shoulda-matchers` 5.x. You can find changes to 6 | `shoulda-matchers` in its [changelog][shoulda-matchers-5-3-0-changelog]. 7 | * Support for Ruby < 3 and Rails < 6.1 have been dropped due to being EOL. 8 | * Support for Ruby 3.0, 3.1, and 3.2 as well as Rails 6.1 and 7.0 have been 9 | added. 10 | 11 | [shoulda-matchers-5-3-0-changelog]: https://github.com/thoughtbot/shoulda-matchers/blob/v5.3.0/CHANGELOG.md 12 | 13 | ## 4.0.0 - 2020-06-13 14 | 15 | * `shoulda` now brings in `shoulda-context` 2.0.0, which adds compatibility for 16 | Ruby 2.7, Rails 6.0, and shoulda-matchers 4.0! Note that there are some 17 | backward incompatible changes, so please see the [changelog 18 | entry][shoulda-context-2-0-0] for this release to learn more. 19 | 20 | [shoulda-context-2-0-0]: https://github.com/thoughtbot/shoulda-context/blob/master/CHANGELOG.md#200-2020-06-13 21 | -------------------------------------------------------------------------------- /gemfiles/rails_7_0.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "https://rubygems.org" 4 | 5 | gem "appraisal" 6 | gem "m" 7 | gem "minitest", "~> 5.0" 8 | gem "minitest-reporters", "~> 1.0" 9 | gem "pry" 10 | gem "pry-byebug" 11 | gem "rake", "13.0.1" 12 | gem "rspec", "~> 3.9" 13 | gem "rubocop", require: false 14 | gem "rubocop-packaging", require: false 15 | gem "rubocop-rails", require: false 16 | gem "snowglobe", github: "mcmire/snowglobe", ref: "408ee4c08f823a4d9f89902fa0fa29aff7cafe6d" 17 | gem "warnings_logger" 18 | gem "spring" 19 | gem "spring-watcher-listen", "~> 2.0.0" 20 | gem "rails-controller-testing", ">= 1.0.1" 21 | gem "rails", "7.0.4.2" 22 | gem "sprockets-rails" 23 | gem "puma", "~> 5.0" 24 | gem "importmap-rails" 25 | gem "turbo-rails" 26 | gem "stimulus-rails" 27 | gem "jbuilder" 28 | gem "bootsnap", require: false 29 | gem "capybara" 30 | gem "selenium-webdriver" 31 | gem "webdrivers" 32 | gem "rspec-rails", "~> 6.0" 33 | gem "shoulda-context", "~> 2.0.0" 34 | gem "bcrypt", "~> 3.1.7" 35 | gem "sqlite3", "~> 1.4" 36 | gem "pg", "~> 1.1" 37 | 38 | gemspec path: "../" 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2006-2020 Tammer Saleh and thoughtbot, inc. 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /shoulda.gemspec: -------------------------------------------------------------------------------- 1 | $LOAD_PATH << File.join(File.dirname(__FILE__), 'lib') 2 | require 'shoulda/version' 3 | 4 | Gem::Specification.new do |s| 5 | s.name = 'shoulda' 6 | s.version = Shoulda::VERSION.dup 7 | s.authors = [ 8 | 'Tammer Saleh', 9 | 'Joe Ferris', 10 | 'Ryan McGeary', 11 | 'Dan Croak', 12 | 'Matt Jankowski', 13 | ] 14 | s.date = Time.now.strftime('%Y-%m-%d') 15 | s.email = 'support@thoughtbot.com' 16 | s.homepage = 'https://github.com/thoughtbot/shoulda' 17 | s.summary = 'Making tests easy on the fingers and eyes' 18 | s.license = 'MIT' 19 | s.description = 'Making tests easy on the fingers and eyes' 20 | 21 | s.metadata = { 22 | 'bug_tracker_uri' => 'https://github.com/thoughtbot/shoulda/issues', 23 | 'changelog_uri' => 'https://github.com/thoughtbot/shoulda/blob/main/CHANGELOG.md', 24 | 'source_code_uri' => 'https://github.com/thoughtbot/shoulda', 25 | } 26 | 27 | s.files = Dir['lib/**/*', 'README.md', 'LICENSE', 'shoulda.gemspec'] 28 | s.require_paths = ['lib'] 29 | 30 | s.required_ruby_version = '>= 3.0.5' 31 | s.add_dependency('shoulda-context', '~> 2.0') 32 | s.add_dependency('shoulda-matchers', '~> 5.0') 33 | end 34 | -------------------------------------------------------------------------------- /gemfiles/rails_6_1.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "https://rubygems.org" 4 | 5 | gem "appraisal" 6 | gem "m" 7 | gem "minitest", "~> 5.0" 8 | gem "minitest-reporters", "~> 1.0" 9 | gem "pry" 10 | gem "pry-byebug" 11 | gem "rake", "13.0.1" 12 | gem "rspec", "~> 3.9" 13 | gem "rubocop", require: false 14 | gem "rubocop-packaging", require: false 15 | gem "rubocop-rails", require: false 16 | gem "snowglobe", github: "mcmire/snowglobe", ref: "408ee4c08f823a4d9f89902fa0fa29aff7cafe6d" 17 | gem "warnings_logger" 18 | gem "spring" 19 | gem "spring-watcher-listen", "~> 2.0.0" 20 | gem "rails-controller-testing", ">= 1.0.1" 21 | gem "rails", "6.1.7.2" 22 | gem "puma", "~> 5.0" 23 | gem "sass-rails", ">= 6" 24 | gem "turbolinks", "~> 5" 25 | gem "jbuilder", "~> 2.7" 26 | gem "bcrypt", "~> 3.1.7" 27 | gem "bootsnap", ">= 1.4.4", require: false 28 | gem "rack-mini-profiler", "~> 2.0.0" 29 | gem "listen", "~> 3.3" 30 | gem "capybara", ">= 3.26" 31 | gem "selenium-webdriver", ">= 4.0.0.rc1" 32 | gem "webdrivers" 33 | gem "net-smtp", require: false 34 | gem "psych", "~> 3.0" 35 | gem "rspec-rails", "~> 6.0" 36 | gem "shoulda-context", "~> 2.0.0" 37 | gem "pg", ">= 0.18", "< 2.0" 38 | gem "sqlite3", "~> 1.4" 39 | 40 | gemspec path: "../" 41 | -------------------------------------------------------------------------------- /test/acceptance_test_helper.rb: -------------------------------------------------------------------------------- 1 | require_relative 'support/current_bundle' 2 | 3 | Tests::CurrentBundle.instance.assert_appraisal! 4 | 5 | #--- 6 | 7 | require 'test_helper' 8 | 9 | require_relative 'support/acceptance/rails_application_with_shoulda' 10 | require_relative 'support/acceptance/matchers/have_output' 11 | require_relative 'support/acceptance/matchers/indicate_that_tests_were_run' 12 | 13 | class AcceptanceTest < Minitest::Test 14 | include AcceptanceTests::Matchers 15 | 16 | private 17 | 18 | def app 19 | @_app ||= AcceptanceTests::RailsApplicationWithShoulda.new 20 | end 21 | end 22 | 23 | begin 24 | require 'rails/test_unit/reporter' 25 | 26 | # Patch Rails' reporter for Minitest so that it looks for the test 27 | # correctly under Minitest 5.11 28 | # See: 29 | Rails::TestUnitReporter.class_eval do 30 | def format_rerun_snippet(result) 31 | location, line = 32 | if result.respond_to?(:source_location) 33 | result.source_location 34 | else 35 | result.method(result.name).source_location 36 | end 37 | 38 | "#{executable} #{relative_path_for(location)}:#{line}" 39 | end 40 | end 41 | rescue LoadError 42 | # Okay, rails/test_unit/reporter isn't a thing, no big deal 43 | end 44 | -------------------------------------------------------------------------------- /test/support/current_bundle.rb: -------------------------------------------------------------------------------- 1 | require 'bundler' 2 | require 'appraisal' 3 | 4 | module Tests 5 | class CurrentBundle 6 | AppraisalNotSpecified = Class.new(ArgumentError) 7 | 8 | include Singleton 9 | 10 | def assert_appraisal! 11 | unless appraisal_in_use? 12 | message = <`. 16 | Possible appraisals are: #{available_appraisals} 17 | 18 | MSG 19 | raise AppraisalNotSpecified, message 20 | end 21 | end 22 | 23 | def appraisal_in_use? 24 | path.dirname == root.join('gemfiles') 25 | end 26 | 27 | def current_or_latest_appraisal 28 | current_appraisal || latest_appraisal 29 | end 30 | 31 | def latest_appraisal 32 | available_appraisals.max 33 | end 34 | 35 | private 36 | 37 | def available_appraisals 38 | appraisals = [] 39 | 40 | Appraisal::AppraisalFile.each do |appraisal| 41 | appraisals << appraisal.name 42 | end 43 | 44 | appraisals 45 | end 46 | 47 | def current_appraisal 48 | if appraisal_in_use? 49 | File.basename(path, '.gemfile') 50 | end 51 | end 52 | 53 | def path 54 | Bundler.default_gemfile 55 | end 56 | 57 | def root 58 | Pathname.new('../../..').expand_path(__FILE__) 59 | end 60 | end 61 | end 62 | -------------------------------------------------------------------------------- /test/support/snowglobe.rb: -------------------------------------------------------------------------------- 1 | require 'snowglobe' 2 | 3 | Snowglobe.configure do |config| 4 | config.project_name = 'shoulda_test' 5 | config.temporary_directory = Pathname.new('../../tmp').expand_path(__dir__) 6 | end 7 | 8 | Snowglobe::Project.class_eval do 9 | # Snowglobe is missing a delegator for run_n_unit_test_suite, so add it in 10 | def_delegators :command_runner, :run_n_unit_test_suite 11 | end 12 | 13 | Snowglobe::CommandRunner.class_eval do 14 | # Patch a bug in Snowglobe where ProjectCommandRunner tries to access `env` 15 | # from a CommandRunner instance, but it is private 16 | attr_reader :env 17 | end 18 | 19 | Snowglobe::RailsApplication.class_eval do 20 | def run_migrations! 21 | command_runner.run_rake_tasks!([ 22 | 'db:environment:set RAILS_ENV=test', 23 | 'db:drop', 24 | 'db:create', 25 | 'db:migrate', 26 | ]) 27 | end 28 | 29 | private 30 | 31 | # In recent versions of Rails, config/boot.rb uses double quotes instead of 32 | # single quotes, so patch Snowglobe to work either way 33 | def remove_bootsnap 34 | fs.comment_lines_matching_in_file( 35 | 'config/boot.rb', 36 | %r{\Arequire (['"])bootsnap/setup\1}, 37 | ) 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | paths-ignore: 8 | - '**.md' 9 | pull_request: 10 | types: 11 | - opened 12 | - synchronize 13 | paths-ignore: 14 | - '**.md' 15 | 16 | jobs: 17 | build: 18 | runs-on: ubuntu-latest 19 | strategy: 20 | fail-fast: false 21 | matrix: 22 | ruby: 23 | - 3.2.1 24 | - 3.1.3 25 | - 3.0.5 26 | appraisal: 27 | - rails_7_0 28 | - rails_6_1 29 | adapter: 30 | - sqlite3 31 | - postgresql 32 | exclude: 33 | - { ruby: 3.2.1, appraisal: rails_6_1 } 34 | - { ruby: 3.0.5, appraisal: rails_7_0 } 35 | env: 36 | BUNDLE_GEMFILE: gemfiles/${{ matrix.appraisal }}.gemfile 37 | steps: 38 | - uses: actions/checkout@v3 39 | - name: Set up Ruby 40 | id: set-up-ruby 41 | uses: ruby/setup-ruby@v1 42 | with: 43 | ruby-version: ${{ matrix.ruby }} 44 | - uses: actions/cache@v3 45 | with: 46 | path: vendor/bundle 47 | key: v1-rubygems-local-${{ runner.os }}-${{ matrix.ruby }}-${{ hashFiles(format('gemfiles/{0}.gemfile.lock', matrix.appraisal)) }} 48 | - name: Install dependencies 49 | run: bundle install --jobs=3 --retry=3 50 | - name: Run Tests 51 | run: bundle exec rake 52 | -------------------------------------------------------------------------------- /test/support/acceptance/rails_application_with_shoulda.rb: -------------------------------------------------------------------------------- 1 | require_relative 'add_shoulda_to_project' 2 | require_relative '../snowglobe' 3 | 4 | module AcceptanceTests 5 | class RailsApplicationWithShoulda < Snowglobe::RailsApplication 6 | def create 7 | super 8 | 9 | bundle.updating do 10 | bundle.add_gem 'minitest-reporters' 11 | AddShouldaToProject.call( 12 | self, 13 | test_framework: :minitest, 14 | libraries: [:rails], 15 | ) 16 | bundle.add_gem 'rails-controller-testing', group: [:test] 17 | bundle.add_gem 'bcrypt' 18 | end 19 | 20 | fs.append_to_file 'test/test_helper.rb', <<-FILE 21 | require 'minitest/autorun' 22 | require 'minitest/reporters' 23 | 24 | Minitest::Reporters.use!(Minitest::Reporters::SpecReporter.new) 25 | 26 | begin 27 | require "rails/test_unit/reporter" 28 | 29 | # Patch Rails' reporter for Minitest so that it looks for the test 30 | # correctly under Minitest 5.11 31 | # See: 32 | Rails::TestUnitReporter.class_eval do 33 | def format_rerun_snippet(result) 34 | location, line = if result.respond_to?(:source_location) 35 | result.source_location 36 | else 37 | result.method(result.name).source_location 38 | end 39 | 40 | "\#{executable} \#{relative_path_for(location)}:\#{line}" 41 | end 42 | end 43 | rescue LoadError 44 | # Okay, rails/test_unit/reporter isn't a thing, no big deal 45 | end 46 | FILE 47 | end 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /test/support/acceptance/add_shoulda_to_project.rb: -------------------------------------------------------------------------------- 1 | module AcceptanceTests 2 | class AddShouldaToProject 3 | ROOT_DIRECTORY = Pathname.new('../../..').expand_path(__dir__) 4 | 5 | def self.call(app, options) 6 | new(app, options).call 7 | end 8 | 9 | def initialize(app, options) 10 | @app = app 11 | @options = options 12 | end 13 | 14 | def call 15 | app.add_gem 'shoulda', gem_options 16 | 17 | unless options[:with_configuration] === false 18 | add_configuration_block_to_test_helper 19 | end 20 | end 21 | 22 | private 23 | 24 | attr_reader :app, :options 25 | 26 | def test_framework 27 | options[:test_framework] 28 | end 29 | 30 | def libraries 31 | options.fetch(:libraries, []) 32 | end 33 | 34 | def gem_options 35 | gem_options = { path: ROOT_DIRECTORY } 36 | 37 | if options[:manually] 38 | gem_options[:require] = false 39 | end 40 | 41 | gem_options 42 | end 43 | 44 | def add_configuration_block_to_test_helper 45 | content = <<-CONTENT 46 | Shoulda::Matchers.configure do |config| 47 | config.integrate do |with| 48 | #{test_framework_config} 49 | #{library_config} 50 | end 51 | end 52 | CONTENT 53 | 54 | if options[:manually] 55 | content = "require 'shoulda'\n#{content}" 56 | end 57 | 58 | app.append_to_file('test/test_helper.rb', content) 59 | end 60 | 61 | def test_framework_config 62 | if test_framework 63 | "with.test_framework :#{test_framework}\n" 64 | else 65 | '' 66 | end 67 | end 68 | 69 | def library_config 70 | libraries.map { |library| "with.library :#{library}" }.join("\n") 71 | end 72 | end 73 | end 74 | -------------------------------------------------------------------------------- /Appraisals: -------------------------------------------------------------------------------- 1 | # Note: All of the dependencies here were obtained by running `rails new` with 2 | # various versions of Rails and copying lines from the generated Gemfile. It's 3 | # best to keep the gems here in the same order as they're listed there so you 4 | # can compare them more easily. 5 | 6 | # Needed for Rails 5+ controller tests 7 | controller_test_dependency = proc do 8 | gem 'rails-controller-testing', '>= 1.0.1' 9 | end 10 | 11 | shared_spring_dependencies = proc do 12 | gem 'spring' 13 | gem 'spring-watcher-listen', '~> 2.0.0' 14 | end 15 | 16 | appraise 'rails_6_1' do 17 | instance_eval(&shared_spring_dependencies) 18 | instance_eval(&controller_test_dependency) 19 | 20 | gem 'rails', '6.1.7.2' 21 | gem 'puma', '~> 5.0' 22 | gem 'sass-rails', '>= 6' 23 | gem 'turbolinks', '~> 5' 24 | gem 'jbuilder', '~> 2.7' 25 | gem 'bcrypt', '~> 3.1.7' 26 | gem 'bootsnap', '>= 1.4.4', require: false 27 | gem 'rack-mini-profiler', '~> 2.0.0' 28 | gem 'listen', '~> 3.3' 29 | gem 'capybara', '>= 3.26' 30 | gem 'selenium-webdriver', '>= 4.0.0.rc1' 31 | gem 'webdrivers' 32 | gem 'net-smtp', require: false 33 | gem 'psych', '~> 3.0' 34 | 35 | # test dependencies 36 | gem 'rspec-rails', '~> 6.0' 37 | gem 'shoulda-context', '~> 2.0.0' 38 | 39 | # Database adapters 40 | gem 'pg', '>= 0.18', '< 2.0' 41 | gem 'sqlite3', '~> 1.4' 42 | end 43 | 44 | appraise 'rails_7_0' do 45 | instance_eval(&shared_spring_dependencies) 46 | instance_eval(&controller_test_dependency) 47 | 48 | gem 'rails', '7.0.4.2' 49 | gem 'sprockets-rails' 50 | gem 'puma', '~> 5.0' 51 | gem 'importmap-rails' 52 | gem 'turbo-rails' 53 | gem 'stimulus-rails' 54 | gem 'jbuilder' 55 | gem 'bootsnap', require: false 56 | gem 'capybara' 57 | gem 'selenium-webdriver' 58 | gem 'webdrivers' 59 | 60 | # test dependencies 61 | gem 'rspec-rails', '~> 6.0' 62 | gem 'shoulda-context', '~> 2.0.0' 63 | 64 | # other dependencies 65 | gem 'bcrypt', '~> 3.1.7' 66 | 67 | # Database adapters 68 | gem 'sqlite3', '~> 1.4' 69 | gem 'pg', '~> 1.1' 70 | end 71 | -------------------------------------------------------------------------------- /test/support/acceptance/matchers/indicate_that_tests_were_run.rb: -------------------------------------------------------------------------------- 1 | require_relative '../helpers/array_helpers' 2 | require_relative '../helpers/pluralization_helpers' 3 | 4 | module AcceptanceTests 5 | module Matchers 6 | def indicate_that_tests_were_run(series) 7 | IndicateThatTestsWereRunMatcher.new(series) 8 | end 9 | 10 | class IndicateThatTestsWereRunMatcher 11 | include ArrayHelpers 12 | include PluralizationHelpers 13 | 14 | def initialize(expected_numbers) 15 | @expected_numbers = expected_numbers 16 | end 17 | 18 | def matches?(runner) 19 | @runner = runner 20 | Set.new(expected_numbers).subset?(Set.new(actual_numbers)) 21 | end 22 | 23 | def failure_message 24 | [ 25 | "Expected output to indicate that #{some_tests_were_run}.\n", 26 | "#{formatted_expected_numbers}\n", 27 | "#{formatted_actual_numbers}\n\n", 28 | "Output:\n\n", 29 | actual_output, 30 | ].join 31 | end 32 | 33 | protected 34 | 35 | attr_reader :expected_numbers, :runner 36 | 37 | private 38 | 39 | def some_tests_were_run 40 | if some_tests_were_run_clauses.size > 1 41 | "#{to_sentence(some_tests_were_run_clauses)} were run" 42 | else 43 | "#{some_tests_were_run_clauses} was run" 44 | end 45 | end 46 | 47 | def some_tests_were_run_clauses 48 | expected_numbers.map do |type, number| 49 | if number == 1 50 | "#{number} #{type.to_s.chop}" 51 | else 52 | "#{number} #{type}" 53 | end 54 | end 55 | end 56 | 57 | def formatted_expected_numbers 58 | "Expected numbers: #{format_hash(expected_numbers)}" 59 | end 60 | 61 | def formatted_actual_numbers 62 | report_line = find_report_line_in(actual_output) 63 | 64 | if report_line 65 | "Actual numbers: #{report_line.inspect}" 66 | else 67 | 'Actual numbers: (n/a)' 68 | end 69 | end 70 | 71 | def actual_numbers 72 | numbers = parse( 73 | actual_output, 74 | [:tests, :assertions, :failures, :errors, :skips], 75 | ) 76 | numbers || {} 77 | end 78 | 79 | def actual_output 80 | runner.output 81 | end 82 | 83 | def parse(text, pieces) 84 | report_line = find_report_line_in(text) 85 | 86 | if report_line 87 | pieces.inject({}) do |hash, piece| 88 | number = report_line.match(/(\d+) #{piece}/)[1].to_i 89 | hash.merge(piece => number) 90 | end 91 | end 92 | end 93 | 94 | def find_report_line_in(text) 95 | lines = text.split(/\n/) 96 | 97 | index_of_line_with_time = lines.find_index do |line| 98 | line =~ /\AFinished in \d\.\d+s\Z/ 99 | end 100 | 101 | if index_of_line_with_time 102 | lines[index_of_line_with_time + 1] 103 | end 104 | end 105 | 106 | def format_hash(hash) 107 | ['{', hash.map { |k, v| "#{k}: #{v.inspect}" }.join(', '), '}'].join 108 | end 109 | end 110 | end 111 | end 112 | -------------------------------------------------------------------------------- /MAINTAINING.md: -------------------------------------------------------------------------------- 1 | # Maintaining Shoulda 2 | 3 | Although Shoulda doesn't receive feature updates these days, you may need to 4 | update the gem for new versions of Ruby or Rails. Here's what you need to know 5 | in order to do that. 6 | 7 | ## Getting started 8 | 9 | First, run the setup script: 10 | 11 | bin/setup 12 | 13 | Then run all the tests to make sure everything is green: 14 | 15 | bundle exec rake 16 | 17 | ## Running tests 18 | 19 | This project uses Minitest for tests and Appraisal to create environments 20 | attuned for different versions of Rails. To run a single test in a single test 21 | file, you will need to use a combination of Appraisal and the [`m`][m] gem. For 22 | instance: 23 | 24 | [m]: https://github.com/qrush/m 25 | 26 | bundle exec appraisal rails_6_0 m test/acceptance/integrates_with_rails_test.rb:9 27 | 28 | ## Updating the changelog 29 | 30 | After every user-facing change makes it into master, we make a note of it in the 31 | changelog, kept in `CHANGELOG.md`. The changelog is sorted in reverse order by 32 | release version, with the topmost version as the next release (tagged as 33 | "(Unreleased)"). 34 | 35 | Within each version, there are five available categories you can divide changes 36 | into. They are all optional but they should appear in this order: 37 | 38 | 1. Backward-compatible changes 39 | 1. Deprecations 40 | 1. Bug fixes 41 | 1. Features 42 | 1. Improvements 43 | 44 | Within each category section, the changes relevant to that category are listed 45 | in chronological order. 46 | 47 | For each change, provide a human-readable description of the change as well as a 48 | linked reference to the PR where that change emerged (or the commit ID if no 49 | such PR is available). This helps users cross-reference changes if they need to. 50 | 51 | ## Versioning 52 | 53 | ### Naming a new version 54 | 55 | As designated in the README, we follow [SemVer 2.0][semver]. This offers a 56 | meaningful baseline for deciding how to name versions. Generally speaking: 57 | 58 | [semver]: https://semver.org/spec/v2.0.0.html 59 | 60 | * We bump the "major" part of the version if we're introducing 61 | backward-incompatible changes (e.g. changing the API or core behavior, 62 | removing parts of the API, or dropping support for a version of Ruby). 63 | * We bump the "minor" part if we're adding a new feature (e.g. adding a new 64 | matcher or adding a new qualifier to a matcher). 65 | * We bump the "patch" part if we're merely including bugfixes. 66 | 67 | In addition to major, minor, and patch levels, you can also append a 68 | suffix to the version for pre-release versions. We usually use this to issue 69 | release candidates prior to an actual release. A version number in this case 70 | might look like `4.0.0.rc1`. 71 | 72 | ### Preparing and releasing a new version 73 | 74 | In order to release any versions at all, you will need to have been added as 75 | an owner of the Ruby gem. If you want to give someone else these permissions, 76 | then run: 77 | 78 | ```bash 79 | gem owner shoulda -a 80 | ``` 81 | 82 | Assuming you have permission to publish a new version to RubyGems, then this is 83 | how you release a version: 84 | 85 | 1. First, you'll want to [make sure that the changelog is up to 86 | date](#updating-the-changelog). 87 | 88 | 2. Next, you'll want to update the `VERSION` constant in 89 | `lib/shoulda/version.rb`. This constant is referenced in the gemspec and is 90 | used in the Rake tasks to publish the gem on RubyGems. 91 | 92 | 3. Assuming that everything looks good, place your changes to the changelog, 93 | `version.rb`, and README in their own commit titled "Bump version to 94 | *X.Y.Z*". Push this to GitHub (you can use `[ci skip]`) in the body of the 95 | commit message to skip CI for this commit if you so choose). **There is no 96 | going back after this point!** 97 | 98 | 6. Once GitHub has the version-change commit, you will run: 99 | 100 | ```bash 101 | rake release 102 | ``` 103 | 104 | This will push the gem to RubyGems and make it available for download. 105 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Shoulda [![Gem Version][version-badge]][rubygems] [![Build Status][github-actions-badge]][github-actions] [![Total Downloads][downloads-total]][rubygems] [![Downloads][downloads-badge]][rubygems] 2 | 3 | [version-badge]: https://img.shields.io/gem/v/shoulda.svg 4 | [rubygems]: https://rubygems.org/gems/shoulda 5 | [github-actions-badge]: https://img.shields.io/github/actions/workflow/status/thoughtbot/shoulda/ci.yml?branch=main 6 | [github-actions]: https://github.com/thoughtbot/shoulda/actions 7 | [downloads-total]: https://img.shields.io/gem/dt/shoulda.svg 8 | [downloads-badge]: https://img.shields.io/gem/dtv/shoulda.svg 9 | [downloads-badge]: https://img.shields.io/gem/dtv/shoulda.svg 10 | 11 | Shoulda helps you write more understandable, maintainable Rails-specific tests 12 | under Minitest and Test::Unit. 13 | 14 | ## Quick links 15 | 16 | 📢 **[See what's changed in recent versions.][changelog]** 17 | 18 | [changelog]: CHANGELOG.md 19 | 20 | ## Overview 21 | 22 | As an umbrella gem, the `shoulda` gem doesn't contain any code of its own but 23 | rather brings in behavior from two other gems: 24 | 25 | * [Shoulda Context] 26 | * [Shoulda Matchers] 27 | 28 | [Shoulda Context]: https://github.com/thoughtbot/shoulda-context 29 | [Shoulda Matchers]: https://github.com/thoughtbot/shoulda-matchers 30 | 31 | For instance: 32 | 33 | ```ruby 34 | require "test_helper" 35 | 36 | class UserTest < ActiveSupport::TestCase 37 | context "associations" do 38 | should have_many(:posts) 39 | end 40 | 41 | context "validations" do 42 | should validate_presence_of(:email) 43 | should allow_value("user@example.com").for(:email) 44 | should_not allow_value("not-an-email").for(:email) 45 | end 46 | 47 | context "#name" do 48 | should "consist of first and last name" do 49 | user = User.new(first_name: "John", last_name: "Smith") 50 | assert_equal "John Smith", user.name 51 | end 52 | end 53 | end 54 | ``` 55 | 56 | Here, the `context` and `should` methods come from Shoulda Context; matchers 57 | (e.g. `have_many`, `allow_value`) come from Shoulda Matchers. 58 | 59 | See the READMEs for these projects for more information. 60 | 61 | ## Compatibility 62 | 63 | Shoulda is tested and supported against Ruby 3.0+, Rails 6.1+, RSpec 3.x, 64 | Minitest 4.x, and Test::Unit 3.x. 65 | 66 | - For Ruby < 3 and Rails < 6.1 compatibility, please use [v4.0.0][v4.0.0]. 67 | 68 | [v4.0.0]: https://github.com/thoughtbot/shoulda-matchers/tree/v4.0.0 69 | 70 | ## Versioning 71 | 72 | Shoulda follows Semantic Versioning 2.0 as defined at . 73 | 74 | ## Team 75 | 76 | Shoulda is currently maintained by [Pedro Paiva][VSPPedro]. Previous maintainers 77 | include [Elliot Winkler][mcmire], [Jason Draper][drapergeek], [Gabe 78 | Berke-Williams][gabebw], [Ryan McGeary][rmm5t], [Joe Ferris][jferris], [Dan 79 | Croaky][croaky], and [Tammer Saleh][tammersaleh]. 80 | 81 | [VSPPedro]: https://github.com/VSPPedro 82 | [mcmire]: https://github.com/mcmire 83 | [drapergeek]: https://github.com/drapergeek 84 | [gabebw]: https://github.com/gabebw 85 | [rmm5t]: https://github.com/rmm5t 86 | [jferris]: https://github.com/jferris 87 | [croaky]: https://github.com/croaky 88 | [tammersaleh]: https://github.com/tammersaleh 89 | 90 | ## Copyright/License 91 | 92 | Shoulda is copyright © Tammer Saleh and [thoughtbot, 93 | inc][thoughtbot-website]. It is free and opensource software and may be 94 | redistributed under the terms specified in the [LICENSE](LICENSE) file. 95 | 96 | [thoughtbot-website]: https://thoughtbot.com 97 | 98 | 99 | ## About thoughtbot 100 | 101 | ![thoughtbot](https://thoughtbot.com/thoughtbot-logo-for-readmes.svg) 102 | 103 | This repo is maintained and funded by thoughtbot, inc. 104 | The names and logos for thoughtbot are trademarks of thoughtbot, inc. 105 | 106 | We love open source software! 107 | See [our other projects][community]. 108 | We are [available for hire][hire]. 109 | 110 | [community]: https://thoughtbot.com/community?utm_source=github 111 | [hire]: https://thoughtbot.com/hire-us?utm_source=github 112 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | require: 2 | - rubocop-packaging 3 | AllCops: 4 | NewCops: disable 5 | TargetRubyVersion: 3.0 6 | Exclude: 7 | - 'gemfiles/*' 8 | - 'tmp/**/*' 9 | SuggestExtensions: false 10 | Bundler/OrderedGems: 11 | Include: 12 | - '**/Gemfile' 13 | Layout/ArgumentAlignment: 14 | EnforcedStyle: with_fixed_indentation 15 | Layout/CommentIndentation: 16 | Enabled: false 17 | Layout/ConditionPosition: 18 | Enabled: false 19 | Layout/DotPosition: 20 | EnforcedStyle: trailing 21 | Layout/EmptyLineBetweenDefs: 22 | AllowAdjacentOneLineDefs: true 23 | Layout/HeredocIndentation: 24 | Enabled: false 25 | Layout/LineLength: 26 | Exclude: 27 | - spec/**/* 28 | AllowedPatterns: 29 | - !ruby/regexp /\A +(it|describe|context|shared_examples|include_examples|it_behaves_like) ["']/ 30 | - !ruby/regexp /\A(require|require_relative) ["']/ 31 | - '^[ ]*#.+$' 32 | - '^[ ]*''.+?'' => ''.+?'',?$' 33 | - '^[ ]*".+?" => ".+?",?$' 34 | Max: 100 35 | Layout/MultilineMethodCallIndentation: 36 | EnforcedStyle: indented 37 | Layout/ParameterAlignment: 38 | EnforcedStyle: with_fixed_indentation 39 | Layout/SpaceInLambdaLiteral: 40 | EnforcedStyle: require_space 41 | Layout/SpaceInsideBlockBraces: 42 | Enabled: false 43 | Lint/AmbiguousBlockAssociation: 44 | Exclude: 45 | - spec/**/* 46 | Lint/AmbiguousOperator: 47 | Enabled: false 48 | Lint/AmbiguousRegexpLiteral: 49 | Enabled: false 50 | Lint/AssignmentInCondition: 51 | Enabled: false 52 | Lint/DeprecatedClassMethods: 53 | Enabled: false 54 | Lint/ElseLayout: 55 | Enabled: false 56 | Lint/FlipFlop: 57 | Enabled: false 58 | Lint/LiteralInInterpolation: 59 | Enabled: false 60 | Lint/Loop: 61 | Enabled: false 62 | Lint/MissingSuper: 63 | Enabled: false 64 | Lint/ParenthesesAsGroupedExpression: 65 | Enabled: false 66 | Lint/RequireParentheses: 67 | Enabled: false 68 | Lint/SafeNavigationChain: 69 | Enabled: false 70 | Lint/SuppressedException: 71 | Enabled: false 72 | Lint/UnderscorePrefixedVariableName: 73 | Enabled: false 74 | Lint/Void: 75 | Enabled: false 76 | Metrics/AbcSize: 77 | Enabled: false 78 | Metrics/BlockLength: 79 | Enabled: false 80 | Metrics/ClassLength: 81 | Enabled: false 82 | Metrics/CyclomaticComplexity: 83 | Enabled: false 84 | Metrics/MethodLength: 85 | Max: 30 86 | Metrics/ModuleLength: 87 | Enabled: true 88 | Exclude: 89 | - spec/**/* 90 | Metrics/ParameterLists: 91 | CountKeywordArgs: false 92 | Metrics/PerceivedComplexity: 93 | Enabled: false 94 | Naming/AccessorMethodName: 95 | Enabled: false 96 | Naming/AsciiIdentifiers: 97 | Enabled: false 98 | Naming/BinaryOperatorParameterName: 99 | Enabled: false 100 | Naming/FileName: 101 | Enabled: false 102 | Naming/HeredocDelimiterNaming: 103 | Enabled: false 104 | Naming/MemoizedInstanceVariableName: 105 | EnforcedStyleForLeadingUnderscores: required 106 | Naming/PredicateName: 107 | Enabled: false 108 | Naming/VariableNumber: 109 | Enabled: false 110 | Naming/RescuedExceptionsVariableName: 111 | Enabled: false 112 | Style/Alias: 113 | Enabled: false 114 | Style/ArrayJoin: 115 | Enabled: false 116 | Style/AsciiComments: 117 | Enabled: false 118 | Style/Attr: 119 | Enabled: false 120 | Style/BlockDelimiters: 121 | Enabled: false 122 | Style/CaseEquality: 123 | Enabled: false 124 | Style/CharacterLiteral: 125 | Enabled: false 126 | Style/ClassAndModuleChildren: 127 | Enabled: false 128 | Style/ClassVars: 129 | Enabled: false 130 | Style/CollectionMethods: 131 | Enabled: true 132 | PreferredMethods: 133 | collect: map 134 | find: detect 135 | find_all: select 136 | reduce: inject 137 | Style/ColonMethodCall: 138 | Enabled: false 139 | Style/CommentAnnotation: 140 | Enabled: false 141 | Style/Documentation: 142 | Enabled: false 143 | Style/DoubleNegation: 144 | Enabled: false 145 | Style/EachWithObject: 146 | Enabled: false 147 | Style/EmptyElse: 148 | Enabled: false 149 | Style/EmptyLiteral: 150 | Enabled: false 151 | Style/EmptyMethod: 152 | EnforcedStyle: expanded 153 | Style/Encoding: 154 | Enabled: false 155 | Style/EvenOdd: 156 | Enabled: false 157 | Style/FormatString: 158 | Enabled: false 159 | Style/FormatStringToken: 160 | EnforcedStyle: template 161 | Style/FrozenStringLiteralComment: 162 | Enabled: false 163 | Style/GlobalVars: 164 | Enabled: false 165 | Style/GuardClause: 166 | Enabled: false 167 | Style/IfUnlessModifier: 168 | Enabled: false 169 | Style/IfWithSemicolon: 170 | Enabled: false 171 | Style/InlineComment: 172 | Enabled: false 173 | Style/InverseMethods: 174 | Enabled: false 175 | Style/Lambda: 176 | Enabled: false 177 | Style/LambdaCall: 178 | Enabled: false 179 | Style/LineEndConcatenation: 180 | Enabled: false 181 | Style/MethodCalledOnDoEndBlock: 182 | Enabled: false 183 | Style/ModuleFunction: 184 | Enabled: false 185 | Style/NegatedIf: 186 | Enabled: false 187 | Style/NegatedWhile: 188 | Enabled: false 189 | Style/Next: 190 | Enabled: false 191 | Style/NilComparison: 192 | Enabled: false 193 | Style/Not: 194 | Enabled: false 195 | Style/NumericLiterals: 196 | Enabled: false 197 | Style/NumericPredicate: 198 | Enabled: false 199 | Style/OneLineConditional: 200 | Enabled: false 201 | Style/OptionalBooleanParameter: 202 | Enabled: false 203 | Style/ParenthesesAroundCondition: 204 | Enabled: false 205 | Style/PercentLiteralDelimiters: 206 | Enabled: false 207 | Style/PerlBackrefs: 208 | Enabled: false 209 | Style/PreferredHashMethods: 210 | Enabled: false 211 | Style/Proc: 212 | Enabled: false 213 | Style/RaiseArgs: 214 | Enabled: false 215 | Style/RegexpLiteral: 216 | Enabled: false 217 | Style/SelfAssignment: 218 | Enabled: false 219 | Style/SignalException: 220 | Enabled: false 221 | Style/SingleLineBlockParams: 222 | Enabled: false 223 | Style/SingleLineMethods: 224 | Enabled: false 225 | Style/SpecialGlobalVars: 226 | Enabled: false 227 | Style/StringLiterals: 228 | EnforcedStyle: single_quotes 229 | Style/SymbolArray: 230 | Enabled: false 231 | Style/TrailingCommaInArguments: 232 | EnforcedStyleForMultiline: consistent_comma 233 | Style/TrailingCommaInArrayLiteral: 234 | EnforcedStyleForMultiline: consistent_comma 235 | Style/TrailingCommaInHashLiteral: 236 | EnforcedStyleForMultiline: consistent_comma 237 | Style/TrivialAccessors: 238 | Enabled: false 239 | Style/VariableInterpolation: 240 | Enabled: false 241 | Style/WhenThen: 242 | Enabled: false 243 | Style/WhileUntilModifier: 244 | Enabled: false 245 | Style/WordArray: 246 | Enabled: false 247 | -------------------------------------------------------------------------------- /gemfiles/rails_7_0.gemfile.lock: -------------------------------------------------------------------------------- 1 | GIT 2 | remote: https://github.com/mcmire/snowglobe.git 3 | revision: 408ee4c08f823a4d9f89902fa0fa29aff7cafe6d 4 | ref: 408ee4c08f823a4d9f89902fa0fa29aff7cafe6d 5 | specs: 6 | snowglobe (0.3.0) 7 | 8 | PATH 9 | remote: .. 10 | specs: 11 | shoulda (4.0.0) 12 | shoulda-context (~> 2.0) 13 | shoulda-matchers (~> 5.0) 14 | 15 | GEM 16 | remote: https://rubygems.org/ 17 | specs: 18 | actioncable (7.0.4.2) 19 | actionpack (= 7.0.4.2) 20 | activesupport (= 7.0.4.2) 21 | nio4r (~> 2.0) 22 | websocket-driver (>= 0.6.1) 23 | actionmailbox (7.0.4.2) 24 | actionpack (= 7.0.4.2) 25 | activejob (= 7.0.4.2) 26 | activerecord (= 7.0.4.2) 27 | activestorage (= 7.0.4.2) 28 | activesupport (= 7.0.4.2) 29 | mail (>= 2.7.1) 30 | net-imap 31 | net-pop 32 | net-smtp 33 | actionmailer (7.0.4.2) 34 | actionpack (= 7.0.4.2) 35 | actionview (= 7.0.4.2) 36 | activejob (= 7.0.4.2) 37 | activesupport (= 7.0.4.2) 38 | mail (~> 2.5, >= 2.5.4) 39 | net-imap 40 | net-pop 41 | net-smtp 42 | rails-dom-testing (~> 2.0) 43 | actionpack (7.0.4.2) 44 | actionview (= 7.0.4.2) 45 | activesupport (= 7.0.4.2) 46 | rack (~> 2.0, >= 2.2.0) 47 | rack-test (>= 0.6.3) 48 | rails-dom-testing (~> 2.0) 49 | rails-html-sanitizer (~> 1.0, >= 1.2.0) 50 | actiontext (7.0.4.2) 51 | actionpack (= 7.0.4.2) 52 | activerecord (= 7.0.4.2) 53 | activestorage (= 7.0.4.2) 54 | activesupport (= 7.0.4.2) 55 | globalid (>= 0.6.0) 56 | nokogiri (>= 1.8.5) 57 | actionview (7.0.4.2) 58 | activesupport (= 7.0.4.2) 59 | builder (~> 3.1) 60 | erubi (~> 1.4) 61 | rails-dom-testing (~> 2.0) 62 | rails-html-sanitizer (~> 1.1, >= 1.2.0) 63 | activejob (7.0.4.2) 64 | activesupport (= 7.0.4.2) 65 | globalid (>= 0.3.6) 66 | activemodel (7.0.4.2) 67 | activesupport (= 7.0.4.2) 68 | activerecord (7.0.4.2) 69 | activemodel (= 7.0.4.2) 70 | activesupport (= 7.0.4.2) 71 | activestorage (7.0.4.2) 72 | actionpack (= 7.0.4.2) 73 | activejob (= 7.0.4.2) 74 | activerecord (= 7.0.4.2) 75 | activesupport (= 7.0.4.2) 76 | marcel (~> 1.0) 77 | mini_mime (>= 1.1.0) 78 | activesupport (7.0.4.2) 79 | concurrent-ruby (~> 1.0, >= 1.0.2) 80 | i18n (>= 1.6, < 2) 81 | minitest (>= 5.1) 82 | tzinfo (~> 2.0) 83 | addressable (2.8.1) 84 | public_suffix (>= 2.0.2, < 6.0) 85 | ansi (1.5.0) 86 | appraisal (2.4.1) 87 | bundler 88 | rake 89 | thor (>= 0.14.0) 90 | ast (2.4.2) 91 | bcrypt (3.1.18) 92 | bootsnap (1.16.0) 93 | msgpack (~> 1.2) 94 | builder (3.2.4) 95 | byebug (11.1.3) 96 | capybara (3.38.0) 97 | addressable 98 | matrix 99 | mini_mime (>= 0.1.3) 100 | nokogiri (~> 1.8) 101 | rack (>= 1.6.0) 102 | rack-test (>= 0.6.3) 103 | regexp_parser (>= 1.5, < 3.0) 104 | xpath (~> 3.2) 105 | coderay (1.1.3) 106 | concurrent-ruby (1.2.2) 107 | crass (1.0.6) 108 | date (3.3.3) 109 | diff-lcs (1.5.0) 110 | erubi (1.12.0) 111 | ffi (1.15.5) 112 | globalid (1.1.0) 113 | activesupport (>= 5.0) 114 | i18n (1.12.0) 115 | concurrent-ruby (~> 1.0) 116 | importmap-rails (1.1.5) 117 | actionpack (>= 6.0.0) 118 | railties (>= 6.0.0) 119 | jbuilder (2.11.5) 120 | actionview (>= 5.0.0) 121 | activesupport (>= 5.0.0) 122 | json (2.6.3) 123 | listen (3.8.0) 124 | rb-fsevent (~> 0.10, >= 0.10.3) 125 | rb-inotify (~> 0.9, >= 0.9.10) 126 | loofah (2.19.1) 127 | crass (~> 1.0.2) 128 | nokogiri (>= 1.5.9) 129 | m (1.6.1) 130 | method_source (>= 0.6.7) 131 | rake (>= 0.9.2.2) 132 | mail (2.8.1) 133 | mini_mime (>= 0.1.1) 134 | net-imap 135 | net-pop 136 | net-smtp 137 | marcel (1.0.2) 138 | matrix (0.4.2) 139 | method_source (1.0.0) 140 | mini_mime (1.1.2) 141 | minitest (5.18.0) 142 | minitest-reporters (1.6.0) 143 | ansi 144 | builder 145 | minitest (>= 5.0) 146 | ruby-progressbar 147 | msgpack (1.6.1) 148 | net-imap (0.3.4) 149 | date 150 | net-protocol 151 | net-pop (0.1.2) 152 | net-protocol 153 | net-protocol (0.2.1) 154 | timeout 155 | net-smtp (0.3.3) 156 | net-protocol 157 | nio4r (2.5.8) 158 | nokogiri (1.14.2-arm64-darwin) 159 | racc (~> 1.4) 160 | parallel (1.22.1) 161 | parser (3.2.1.1) 162 | ast (~> 2.4.1) 163 | pg (1.4.6) 164 | pry (0.14.2) 165 | coderay (~> 1.1) 166 | method_source (~> 1.0) 167 | pry-byebug (3.10.1) 168 | byebug (~> 11.0) 169 | pry (>= 0.13, < 0.15) 170 | public_suffix (5.0.1) 171 | puma (5.6.5) 172 | nio4r (~> 2.0) 173 | racc (1.6.2) 174 | rack (2.2.6.4) 175 | rack-test (2.1.0) 176 | rack (>= 1.3) 177 | rails (7.0.4.2) 178 | actioncable (= 7.0.4.2) 179 | actionmailbox (= 7.0.4.2) 180 | actionmailer (= 7.0.4.2) 181 | actionpack (= 7.0.4.2) 182 | actiontext (= 7.0.4.2) 183 | actionview (= 7.0.4.2) 184 | activejob (= 7.0.4.2) 185 | activemodel (= 7.0.4.2) 186 | activerecord (= 7.0.4.2) 187 | activestorage (= 7.0.4.2) 188 | activesupport (= 7.0.4.2) 189 | bundler (>= 1.15.0) 190 | railties (= 7.0.4.2) 191 | rails-controller-testing (1.0.5) 192 | actionpack (>= 5.0.1.rc1) 193 | actionview (>= 5.0.1.rc1) 194 | activesupport (>= 5.0.1.rc1) 195 | rails-dom-testing (2.0.3) 196 | activesupport (>= 4.2.0) 197 | nokogiri (>= 1.6) 198 | rails-html-sanitizer (1.5.0) 199 | loofah (~> 2.19, >= 2.19.1) 200 | railties (7.0.4.2) 201 | actionpack (= 7.0.4.2) 202 | activesupport (= 7.0.4.2) 203 | method_source 204 | rake (>= 12.2) 205 | thor (~> 1.0) 206 | zeitwerk (~> 2.5) 207 | rainbow (3.1.1) 208 | rake (13.0.1) 209 | rb-fsevent (0.11.2) 210 | rb-inotify (0.10.1) 211 | ffi (~> 1.0) 212 | regexp_parser (2.7.0) 213 | rexml (3.2.5) 214 | rspec (3.12.0) 215 | rspec-core (~> 3.12.0) 216 | rspec-expectations (~> 3.12.0) 217 | rspec-mocks (~> 3.12.0) 218 | rspec-core (3.12.1) 219 | rspec-support (~> 3.12.0) 220 | rspec-expectations (3.12.2) 221 | diff-lcs (>= 1.2.0, < 2.0) 222 | rspec-support (~> 3.12.0) 223 | rspec-mocks (3.12.4) 224 | diff-lcs (>= 1.2.0, < 2.0) 225 | rspec-support (~> 3.12.0) 226 | rspec-rails (6.0.1) 227 | actionpack (>= 6.1) 228 | activesupport (>= 6.1) 229 | railties (>= 6.1) 230 | rspec-core (~> 3.11) 231 | rspec-expectations (~> 3.11) 232 | rspec-mocks (~> 3.11) 233 | rspec-support (~> 3.11) 234 | rspec-support (3.12.0) 235 | rubocop (1.48.1) 236 | json (~> 2.3) 237 | parallel (~> 1.10) 238 | parser (>= 3.2.0.0) 239 | rainbow (>= 2.2.2, < 4.0) 240 | regexp_parser (>= 1.8, < 3.0) 241 | rexml (>= 3.2.5, < 4.0) 242 | rubocop-ast (>= 1.26.0, < 2.0) 243 | ruby-progressbar (~> 1.7) 244 | unicode-display_width (>= 2.4.0, < 3.0) 245 | rubocop-ast (1.27.0) 246 | parser (>= 3.2.1.0) 247 | rubocop-packaging (0.5.2) 248 | rubocop (>= 1.33, < 2.0) 249 | rubocop-rails (2.18.0) 250 | activesupport (>= 4.2.0) 251 | rack (>= 1.1) 252 | rubocop (>= 1.33.0, < 2.0) 253 | ruby-progressbar (1.13.0) 254 | rubyzip (2.3.2) 255 | selenium-webdriver (4.8.1) 256 | rexml (~> 3.2, >= 3.2.5) 257 | rubyzip (>= 1.2.2, < 3.0) 258 | websocket (~> 1.0) 259 | shoulda-context (2.0.0) 260 | shoulda-matchers (5.3.0) 261 | activesupport (>= 5.2.0) 262 | spring (2.1.1) 263 | spring-watcher-listen (2.0.1) 264 | listen (>= 2.7, < 4.0) 265 | spring (>= 1.2, < 3.0) 266 | sprockets (4.2.0) 267 | concurrent-ruby (~> 1.0) 268 | rack (>= 2.2.4, < 4) 269 | sprockets-rails (3.4.2) 270 | actionpack (>= 5.2) 271 | activesupport (>= 5.2) 272 | sprockets (>= 3.0.0) 273 | sqlite3 (1.6.1-arm64-darwin) 274 | stimulus-rails (1.2.1) 275 | railties (>= 6.0.0) 276 | thor (1.2.1) 277 | timeout (0.3.2) 278 | turbo-rails (1.4.0) 279 | actionpack (>= 6.0.0) 280 | activejob (>= 6.0.0) 281 | railties (>= 6.0.0) 282 | tzinfo (2.0.6) 283 | concurrent-ruby (~> 1.0) 284 | unicode-display_width (2.4.2) 285 | warnings_logger (0.1.1) 286 | webdrivers (5.2.0) 287 | nokogiri (~> 1.6) 288 | rubyzip (>= 1.3.0) 289 | selenium-webdriver (~> 4.0) 290 | websocket (1.2.9) 291 | websocket-driver (0.7.5) 292 | websocket-extensions (>= 0.1.0) 293 | websocket-extensions (0.1.5) 294 | xpath (3.2.0) 295 | nokogiri (~> 1.8) 296 | zeitwerk (2.6.7) 297 | 298 | PLATFORMS 299 | arm64-darwin-22 300 | 301 | DEPENDENCIES 302 | appraisal 303 | bcrypt (~> 3.1.7) 304 | bootsnap 305 | capybara 306 | importmap-rails 307 | jbuilder 308 | m 309 | minitest (~> 5.0) 310 | minitest-reporters (~> 1.0) 311 | pg (~> 1.1) 312 | pry 313 | pry-byebug 314 | puma (~> 5.0) 315 | rails (= 7.0.4.2) 316 | rails-controller-testing (>= 1.0.1) 317 | rake (= 13.0.1) 318 | rspec (~> 3.9) 319 | rspec-rails (~> 6.0) 320 | rubocop 321 | rubocop-packaging 322 | rubocop-rails 323 | selenium-webdriver 324 | shoulda! 325 | shoulda-context (~> 2.0.0) 326 | snowglobe! 327 | spring 328 | spring-watcher-listen (~> 2.0.0) 329 | sprockets-rails 330 | sqlite3 (~> 1.4) 331 | stimulus-rails 332 | turbo-rails 333 | warnings_logger 334 | webdrivers 335 | 336 | BUNDLED WITH 337 | 2.4.9 338 | -------------------------------------------------------------------------------- /gemfiles/rails_6_1.gemfile.lock: -------------------------------------------------------------------------------- 1 | GIT 2 | remote: https://github.com/mcmire/snowglobe.git 3 | revision: 408ee4c08f823a4d9f89902fa0fa29aff7cafe6d 4 | ref: 408ee4c08f823a4d9f89902fa0fa29aff7cafe6d 5 | specs: 6 | snowglobe (0.3.0) 7 | 8 | PATH 9 | remote: .. 10 | specs: 11 | shoulda (4.0.0) 12 | shoulda-context (~> 2.0) 13 | shoulda-matchers (~> 5.0) 14 | 15 | GEM 16 | remote: https://rubygems.org/ 17 | specs: 18 | actioncable (6.1.7.2) 19 | actionpack (= 6.1.7.2) 20 | activesupport (= 6.1.7.2) 21 | nio4r (~> 2.0) 22 | websocket-driver (>= 0.6.1) 23 | actionmailbox (6.1.7.2) 24 | actionpack (= 6.1.7.2) 25 | activejob (= 6.1.7.2) 26 | activerecord (= 6.1.7.2) 27 | activestorage (= 6.1.7.2) 28 | activesupport (= 6.1.7.2) 29 | mail (>= 2.7.1) 30 | actionmailer (6.1.7.2) 31 | actionpack (= 6.1.7.2) 32 | actionview (= 6.1.7.2) 33 | activejob (= 6.1.7.2) 34 | activesupport (= 6.1.7.2) 35 | mail (~> 2.5, >= 2.5.4) 36 | rails-dom-testing (~> 2.0) 37 | actionpack (6.1.7.2) 38 | actionview (= 6.1.7.2) 39 | activesupport (= 6.1.7.2) 40 | rack (~> 2.0, >= 2.0.9) 41 | rack-test (>= 0.6.3) 42 | rails-dom-testing (~> 2.0) 43 | rails-html-sanitizer (~> 1.0, >= 1.2.0) 44 | actiontext (6.1.7.2) 45 | actionpack (= 6.1.7.2) 46 | activerecord (= 6.1.7.2) 47 | activestorage (= 6.1.7.2) 48 | activesupport (= 6.1.7.2) 49 | nokogiri (>= 1.8.5) 50 | actionview (6.1.7.2) 51 | activesupport (= 6.1.7.2) 52 | builder (~> 3.1) 53 | erubi (~> 1.4) 54 | rails-dom-testing (~> 2.0) 55 | rails-html-sanitizer (~> 1.1, >= 1.2.0) 56 | activejob (6.1.7.2) 57 | activesupport (= 6.1.7.2) 58 | globalid (>= 0.3.6) 59 | activemodel (6.1.7.2) 60 | activesupport (= 6.1.7.2) 61 | activerecord (6.1.7.2) 62 | activemodel (= 6.1.7.2) 63 | activesupport (= 6.1.7.2) 64 | activestorage (6.1.7.2) 65 | actionpack (= 6.1.7.2) 66 | activejob (= 6.1.7.2) 67 | activerecord (= 6.1.7.2) 68 | activesupport (= 6.1.7.2) 69 | marcel (~> 1.0) 70 | mini_mime (>= 1.1.0) 71 | activesupport (6.1.7.2) 72 | concurrent-ruby (~> 1.0, >= 1.0.2) 73 | i18n (>= 1.6, < 2) 74 | minitest (>= 5.1) 75 | tzinfo (~> 2.0) 76 | zeitwerk (~> 2.3) 77 | addressable (2.8.1) 78 | public_suffix (>= 2.0.2, < 6.0) 79 | ansi (1.5.0) 80 | appraisal (2.4.1) 81 | bundler 82 | rake 83 | thor (>= 0.14.0) 84 | ast (2.4.2) 85 | bcrypt (3.1.18) 86 | bootsnap (1.16.0) 87 | msgpack (~> 1.2) 88 | builder (3.2.4) 89 | byebug (11.1.3) 90 | capybara (3.38.0) 91 | addressable 92 | matrix 93 | mini_mime (>= 0.1.3) 94 | nokogiri (~> 1.8) 95 | rack (>= 1.6.0) 96 | rack-test (>= 0.6.3) 97 | regexp_parser (>= 1.5, < 3.0) 98 | xpath (~> 3.2) 99 | coderay (1.1.3) 100 | concurrent-ruby (1.2.2) 101 | crass (1.0.6) 102 | date (3.3.3) 103 | diff-lcs (1.5.0) 104 | erubi (1.12.0) 105 | ffi (1.15.5) 106 | globalid (1.1.0) 107 | activesupport (>= 5.0) 108 | i18n (1.12.0) 109 | concurrent-ruby (~> 1.0) 110 | jbuilder (2.11.5) 111 | actionview (>= 5.0.0) 112 | activesupport (>= 5.0.0) 113 | json (2.6.3) 114 | listen (3.8.0) 115 | rb-fsevent (~> 0.10, >= 0.10.3) 116 | rb-inotify (~> 0.9, >= 0.9.10) 117 | loofah (2.19.1) 118 | crass (~> 1.0.2) 119 | nokogiri (>= 1.5.9) 120 | m (1.6.1) 121 | method_source (>= 0.6.7) 122 | rake (>= 0.9.2.2) 123 | mail (2.8.1) 124 | mini_mime (>= 0.1.1) 125 | net-imap 126 | net-pop 127 | net-smtp 128 | marcel (1.0.2) 129 | matrix (0.4.2) 130 | method_source (1.0.0) 131 | mini_mime (1.1.2) 132 | minitest (5.18.0) 133 | minitest-reporters (1.6.0) 134 | ansi 135 | builder 136 | minitest (>= 5.0) 137 | ruby-progressbar 138 | msgpack (1.6.1) 139 | net-imap (0.3.4) 140 | date 141 | net-protocol 142 | net-pop (0.1.2) 143 | net-protocol 144 | net-protocol (0.2.1) 145 | timeout 146 | net-smtp (0.3.3) 147 | net-protocol 148 | nio4r (2.5.8) 149 | nokogiri (1.14.2-arm64-darwin) 150 | racc (~> 1.4) 151 | parallel (1.22.1) 152 | parser (3.2.1.1) 153 | ast (~> 2.4.1) 154 | pg (1.4.6) 155 | pry (0.14.2) 156 | coderay (~> 1.1) 157 | method_source (~> 1.0) 158 | pry-byebug (3.10.1) 159 | byebug (~> 11.0) 160 | pry (>= 0.13, < 0.15) 161 | psych (3.3.4) 162 | public_suffix (5.0.1) 163 | puma (5.6.5) 164 | nio4r (~> 2.0) 165 | racc (1.6.2) 166 | rack (2.2.6.4) 167 | rack-mini-profiler (2.0.4) 168 | rack (>= 1.2.0) 169 | rack-test (2.1.0) 170 | rack (>= 1.3) 171 | rails (6.1.7.2) 172 | actioncable (= 6.1.7.2) 173 | actionmailbox (= 6.1.7.2) 174 | actionmailer (= 6.1.7.2) 175 | actionpack (= 6.1.7.2) 176 | actiontext (= 6.1.7.2) 177 | actionview (= 6.1.7.2) 178 | activejob (= 6.1.7.2) 179 | activemodel (= 6.1.7.2) 180 | activerecord (= 6.1.7.2) 181 | activestorage (= 6.1.7.2) 182 | activesupport (= 6.1.7.2) 183 | bundler (>= 1.15.0) 184 | railties (= 6.1.7.2) 185 | sprockets-rails (>= 2.0.0) 186 | rails-controller-testing (1.0.5) 187 | actionpack (>= 5.0.1.rc1) 188 | actionview (>= 5.0.1.rc1) 189 | activesupport (>= 5.0.1.rc1) 190 | rails-dom-testing (2.0.3) 191 | activesupport (>= 4.2.0) 192 | nokogiri (>= 1.6) 193 | rails-html-sanitizer (1.5.0) 194 | loofah (~> 2.19, >= 2.19.1) 195 | railties (6.1.7.2) 196 | actionpack (= 6.1.7.2) 197 | activesupport (= 6.1.7.2) 198 | method_source 199 | rake (>= 12.2) 200 | thor (~> 1.0) 201 | rainbow (3.1.1) 202 | rake (13.0.1) 203 | rb-fsevent (0.11.2) 204 | rb-inotify (0.10.1) 205 | ffi (~> 1.0) 206 | regexp_parser (2.7.0) 207 | rexml (3.2.5) 208 | rspec (3.12.0) 209 | rspec-core (~> 3.12.0) 210 | rspec-expectations (~> 3.12.0) 211 | rspec-mocks (~> 3.12.0) 212 | rspec-core (3.12.1) 213 | rspec-support (~> 3.12.0) 214 | rspec-expectations (3.12.2) 215 | diff-lcs (>= 1.2.0, < 2.0) 216 | rspec-support (~> 3.12.0) 217 | rspec-mocks (3.12.4) 218 | diff-lcs (>= 1.2.0, < 2.0) 219 | rspec-support (~> 3.12.0) 220 | rspec-rails (6.0.1) 221 | actionpack (>= 6.1) 222 | activesupport (>= 6.1) 223 | railties (>= 6.1) 224 | rspec-core (~> 3.11) 225 | rspec-expectations (~> 3.11) 226 | rspec-mocks (~> 3.11) 227 | rspec-support (~> 3.11) 228 | rspec-support (3.12.0) 229 | rubocop (1.48.1) 230 | json (~> 2.3) 231 | parallel (~> 1.10) 232 | parser (>= 3.2.0.0) 233 | rainbow (>= 2.2.2, < 4.0) 234 | regexp_parser (>= 1.8, < 3.0) 235 | rexml (>= 3.2.5, < 4.0) 236 | rubocop-ast (>= 1.26.0, < 2.0) 237 | ruby-progressbar (~> 1.7) 238 | unicode-display_width (>= 2.4.0, < 3.0) 239 | rubocop-ast (1.27.0) 240 | parser (>= 3.2.1.0) 241 | rubocop-packaging (0.5.2) 242 | rubocop (>= 1.33, < 2.0) 243 | rubocop-rails (2.18.0) 244 | activesupport (>= 4.2.0) 245 | rack (>= 1.1) 246 | rubocop (>= 1.33.0, < 2.0) 247 | ruby-progressbar (1.13.0) 248 | rubyzip (2.3.2) 249 | sass-rails (6.0.0) 250 | sassc-rails (~> 2.1, >= 2.1.1) 251 | sassc (2.4.0) 252 | ffi (~> 1.9) 253 | sassc-rails (2.1.2) 254 | railties (>= 4.0.0) 255 | sassc (>= 2.0) 256 | sprockets (> 3.0) 257 | sprockets-rails 258 | tilt 259 | selenium-webdriver (4.8.1) 260 | rexml (~> 3.2, >= 3.2.5) 261 | rubyzip (>= 1.2.2, < 3.0) 262 | websocket (~> 1.0) 263 | shoulda-context (2.0.0) 264 | shoulda-matchers (5.3.0) 265 | activesupport (>= 5.2.0) 266 | spring (2.1.1) 267 | spring-watcher-listen (2.0.1) 268 | listen (>= 2.7, < 4.0) 269 | spring (>= 1.2, < 3.0) 270 | sprockets (4.2.0) 271 | concurrent-ruby (~> 1.0) 272 | rack (>= 2.2.4, < 4) 273 | sprockets-rails (3.4.2) 274 | actionpack (>= 5.2) 275 | activesupport (>= 5.2) 276 | sprockets (>= 3.0.0) 277 | sqlite3 (1.6.1-arm64-darwin) 278 | thor (1.2.1) 279 | tilt (2.1.0) 280 | timeout (0.3.2) 281 | turbolinks (5.2.1) 282 | turbolinks-source (~> 5.2) 283 | turbolinks-source (5.2.0) 284 | tzinfo (2.0.6) 285 | concurrent-ruby (~> 1.0) 286 | unicode-display_width (2.4.2) 287 | warnings_logger (0.1.1) 288 | webdrivers (5.2.0) 289 | nokogiri (~> 1.6) 290 | rubyzip (>= 1.3.0) 291 | selenium-webdriver (~> 4.0) 292 | websocket (1.2.9) 293 | websocket-driver (0.7.5) 294 | websocket-extensions (>= 0.1.0) 295 | websocket-extensions (0.1.5) 296 | xpath (3.2.0) 297 | nokogiri (~> 1.8) 298 | zeitwerk (2.6.7) 299 | 300 | PLATFORMS 301 | arm64-darwin-22 302 | 303 | DEPENDENCIES 304 | appraisal 305 | bcrypt (~> 3.1.7) 306 | bootsnap (>= 1.4.4) 307 | capybara (>= 3.26) 308 | jbuilder (~> 2.7) 309 | listen (~> 3.3) 310 | m 311 | minitest (~> 5.0) 312 | minitest-reporters (~> 1.0) 313 | net-smtp 314 | pg (>= 0.18, < 2.0) 315 | pry 316 | pry-byebug 317 | psych (~> 3.0) 318 | puma (~> 5.0) 319 | rack-mini-profiler (~> 2.0.0) 320 | rails (= 6.1.7.2) 321 | rails-controller-testing (>= 1.0.1) 322 | rake (= 13.0.1) 323 | rspec (~> 3.9) 324 | rspec-rails (~> 6.0) 325 | rubocop 326 | rubocop-packaging 327 | rubocop-rails 328 | sass-rails (>= 6) 329 | selenium-webdriver (>= 4.0.0.rc1) 330 | shoulda! 331 | shoulda-context (~> 2.0.0) 332 | snowglobe! 333 | spring 334 | spring-watcher-listen (~> 2.0.0) 335 | sqlite3 (~> 1.4) 336 | turbolinks (~> 5) 337 | warnings_logger 338 | webdrivers 339 | 340 | BUNDLED WITH 341 | 2.4.9 342 | -------------------------------------------------------------------------------- /test/acceptance/integrates_with_rails_test.rb: -------------------------------------------------------------------------------- 1 | require 'acceptance_test_helper' 2 | 3 | class ShouldaIntegratesWithRailsTest < AcceptanceTest 4 | # rubocop:disable Metrics/MethodLength 5 | def setup 6 | app.create 7 | 8 | app.write_file 'db/migrate/1_create_users.rb', <<-FILE 9 | class CreateUsers < #{app.migration_class_name} 10 | def self.up 11 | create_table :categories_users do |t| 12 | t.integer :category_id 13 | t.integer :user_id 14 | end 15 | 16 | create_table :categories do |t| 17 | end 18 | 19 | create_table :cities do |t| 20 | end 21 | 22 | create_table :lives do |t| 23 | t.integer :user_id 24 | end 25 | 26 | create_table :issues do |t| 27 | t.integer :user_id 28 | end 29 | 30 | create_table :users do |t| 31 | t.integer :account_id 32 | t.integer :city_id 33 | t.string :email 34 | t.integer :age 35 | t.integer :status 36 | t.string :aspects 37 | end 38 | 39 | add_index :users, :account_id 40 | end 41 | end 42 | FILE 43 | 44 | app.run_migrations! 45 | 46 | app.write_file 'app/models/category.rb', <<-FILE 47 | class Category < ActiveRecord::Base 48 | end 49 | FILE 50 | 51 | app.write_file 'app/models/city.rb', <<-FILE 52 | class City < ActiveRecord::Base 53 | end 54 | FILE 55 | 56 | app.write_file 'app/models/issue.rb', <<-FILE 57 | class Issue < ActiveRecord::Base 58 | end 59 | FILE 60 | 61 | app.write_file 'app/models/life.rb', <<-FILE 62 | class Life < ActiveRecord::Base 63 | end 64 | FILE 65 | 66 | app.write_file 'app/models/person.rb', <<-FILE 67 | class Person 68 | # Note: All of these validations are listed in the same order as what's 69 | # defined in the test (see below) 70 | 71 | include ActiveModel::Model 72 | include ActiveModel::SecurePassword 73 | 74 | attr_accessor( 75 | :age, 76 | :card_number, 77 | :email, 78 | :foods, 79 | :nothing, 80 | :password_digest, 81 | :some_other_attribute, 82 | :some_other_attribute_confirmation, 83 | :something, 84 | :terms_of_service, 85 | :workouts, 86 | :some_other_attribute, 87 | ) 88 | 89 | validate :email_looks_like_an_email 90 | 91 | delegate :a_method, to: :some_delegate_object 92 | 93 | has_secure_password 94 | 95 | validates_absence_of :nothing 96 | validates_acceptance_of :terms_of_service 97 | validates_confirmation_of :password 98 | validates_exclusion_of :workouts, in: ["biceps"] 99 | validates_inclusion_of :foods, in: ["spaghetti"] 100 | validates_length_of :card_number, maximum: 16 101 | validates_numericality_of :age 102 | validates_presence_of :something 103 | 104 | def some_delegate_object 105 | Object.new.instance_eval do 106 | def a_method; end 107 | end 108 | end 109 | 110 | private 111 | 112 | def email_looks_like_an_email 113 | if email !~ /@/ 114 | errors.add :email, "invalid" 115 | end 116 | end 117 | end 118 | FILE 119 | 120 | app.write_file 'app/models/user.rb', <<-FILE 121 | class User < ActiveRecord::Base 122 | # Note: All of these validations are listed in the same order as what's 123 | # defined in the test (see below) 124 | 125 | belongs_to :city 126 | enum status: { inactive: 0, active: 1 } 127 | attr_readonly :username 128 | has_and_belongs_to_many :categories 129 | has_many :issues 130 | has_one :life 131 | serialize :aspects 132 | validates_uniqueness_of :email 133 | accepts_nested_attributes_for :issues 134 | end 135 | FILE 136 | 137 | app.write_file 'app/controllers/examples_controller.rb', <<-FILE 138 | class ExamplesController < ApplicationController 139 | # Note: All of these validations are listed in the same order as what's 140 | # defined in the test (see below) 141 | 142 | before_action :some_before_action 143 | after_action :some_after_action 144 | around_action :some_around_action 145 | 146 | rescue_from ActiveRecord::RecordNotFound, with: :handle_not_found 147 | 148 | layout "application" 149 | 150 | def index 151 | render :index 152 | head :ok 153 | end 154 | 155 | def create 156 | create_params 157 | flash[:success] = "Example created" 158 | session[:some_key] = "some value" 159 | redirect_to action: :index 160 | end 161 | 162 | def handle_not_found 163 | end 164 | 165 | private 166 | 167 | def some_before_action 168 | end 169 | 170 | def some_after_action 171 | end 172 | 173 | def some_around_action 174 | yield 175 | end 176 | 177 | def create_params 178 | params.require(:user).permit(:email, :password) 179 | end 180 | end 181 | FILE 182 | 183 | app.write_file 'app/views/examples/index.html.erb', <<-FILE 184 | Some content here 185 | FILE 186 | 187 | app.write_file 'config/routes.rb', <<-FILE 188 | Rails.application.routes.draw do 189 | resources :examples, only: [:index, :create] 190 | end 191 | FILE 192 | end 193 | 194 | def test_succeeding_assertions_for_active_model 195 | app.write_file 'test/models/person_test.rb', <<-FILE 196 | require 'test_helper' 197 | 198 | class PersonTest < ActiveSupport::TestCase 199 | # Note: All of these matchers are listed in alphabetical order so we can 200 | # compare with what is listed inside of the shoulda-matchers README 201 | 202 | should allow_value("john@smith.com").for(:email) 203 | should_not allow_value("john").for(:email) 204 | 205 | should delegate_method(:a_method).to(:some_delegate_object) 206 | should_not delegate_method(:some_other_method).to(:some_other_object) 207 | 208 | should have_secure_password 209 | 210 | should validate_absence_of(:nothing) 211 | should_not validate_absence_of(:some_other_attribute) 212 | 213 | should validate_acceptance_of(:terms_of_service) 214 | should_not validate_acceptance_of(:some_other_attribute) 215 | 216 | should validate_confirmation_of(:password) 217 | should_not validate_confirmation_of(:some_other_attribute) 218 | 219 | should validate_exclusion_of(:workouts).in_array(["biceps"]) 220 | should_not validate_exclusion_of(:some_other_attribute). 221 | in_array(["whatever"]) 222 | 223 | should validate_inclusion_of(:foods).in_array(["spaghetti"]) 224 | should_not validate_inclusion_of(:some_other_attribute). 225 | in_array(["whatever"]) 226 | 227 | should validate_length_of(:card_number).is_at_most(16) 228 | should_not validate_length_of(:some_other_attribute).is_at_most(16) 229 | 230 | should validate_numericality_of(:age) 231 | should_not validate_numericality_of(:some_other_attribute) 232 | 233 | should validate_presence_of(:something) 234 | should_not validate_presence_of(:some_other_attribute) 235 | end 236 | FILE 237 | 238 | result = app.run_n_unit_test_suite 239 | 240 | assert_accepts indicate_that_tests_were_run(failures: 0), result 241 | end 242 | 243 | def test_succeeding_assertions_for_active_record 244 | app.write_file 'test/models/user_test.rb', <<-FILE 245 | require 'test_helper' 246 | 247 | class UserTest < ActiveSupport::TestCase 248 | # Note: All of these matchers are listed in alphabetical order so we can 249 | # compare with what is listed inside of the shoulda-matchers README 250 | 251 | should belong_to(:city) 252 | should_not belong_to(:some_other_attribute) 253 | 254 | should define_enum_for(:status).with_values(inactive: 0, active: 1) 255 | should_not define_enum_for(:status).with_values(foo: "bar") 256 | 257 | should have_db_column(:age) 258 | should_not have_db_column(:some_other_attribute) 259 | 260 | should have_db_index(:account_id) 261 | should_not have_db_index(:some_other_attribute) 262 | 263 | should have_readonly_attribute(:username) 264 | should_not have_readonly_attribute(:some_other_attribute) 265 | 266 | should have_and_belong_to_many(:categories) 267 | should_not have_and_belong_to_many(:whatevers) 268 | 269 | should have_many(:issues) 270 | should_not have_many(:whatevers) 271 | 272 | should have_one(:life) 273 | should_not have_one(:whatever) 274 | 275 | should serialize(:aspects) 276 | should_not serialize(:age) 277 | 278 | should validate_uniqueness_of(:email) 279 | should_not validate_uniqueness_of(:some_other_attribute) 280 | 281 | should accept_nested_attributes_for(:issues) 282 | should_not accept_nested_attributes_for(:some_other_attribute) 283 | end 284 | FILE 285 | 286 | result = app.run_n_unit_test_suite 287 | 288 | assert_accepts indicate_that_tests_were_run(failures: 0), result 289 | end 290 | 291 | def test_succeeding_assertions_for_action_controller 292 | app.write_file 'test/controllers/examples_controller_test.rb', <<-FILE 293 | require 'test_helper' 294 | 295 | class ExamplesControllerTest < ActionController::TestCase 296 | context "GET #index" do 297 | setup do 298 | get :index 299 | end 300 | 301 | # Note: All of these matchers are listed in alphabetical order so we 302 | # can compare with what is listed inside of the shoulda-matchers 303 | # README 304 | 305 | should use_before_action(:some_before_action) 306 | should_not use_before_action(:some_other_before_action) 307 | should use_after_action(:some_after_action) 308 | should_not use_after_action(:some_other_after_action) 309 | should use_around_action(:some_around_action) 310 | should_not use_around_action(:some_other_around_action) 311 | 312 | # This is one of the defaults for Rails 313 | should filter_param(:passw) 314 | should_not filter_param(:some_other_param) 315 | 316 | should rescue_from(ActiveRecord::RecordNotFound). 317 | with(:handle_not_found) 318 | should_not rescue_from(ActiveRecord::RecordNotFound). 319 | with(:some_other_method) 320 | 321 | should render_template(:index) 322 | should_not render_template(:some_other_action) 323 | 324 | should render_with_layout("application") 325 | should_not render_with_layout("some_other_layout") 326 | 327 | should respond_with(:ok) 328 | should_not respond_with(:some_other_status) 329 | 330 | should route(:get, "/examples").to(action: :index) 331 | should_not route(:get, "/examples").to(action: :something_else) 332 | end 333 | 334 | context "POST #create" do 335 | setup do 336 | post :create, params: { 337 | user: { 338 | email: "some@email.com", 339 | password: "somepassword" 340 | } 341 | } 342 | end 343 | 344 | should permit(:email, :password). 345 | for(:create, params: { 346 | user: { 347 | email: "some@email.com", 348 | password: "somepassword" 349 | } 350 | }). 351 | on(:user) 352 | should_not permit(:foo, :bar). 353 | for(:create, params: { 354 | user: { 355 | email: "some@email.com", 356 | password: "somepassword" 357 | } 358 | }). 359 | on(:user) 360 | 361 | should redirect_to("/examples") 362 | should_not redirect_to("/something_else") 363 | 364 | should set_flash[:success].to("Example created") 365 | should_not set_flash[:success].to("Something else") 366 | 367 | should set_session[:some_key].to("some value") 368 | should_not set_session[:some_key].to("some other value") 369 | end 370 | end 371 | FILE 372 | 373 | result = app.run_n_unit_test_suite 374 | 375 | assert_accepts indicate_that_tests_were_run(failures: 0), result 376 | end 377 | 378 | def test_failing_assertions_for_active_model 379 | app.write_file 'test/models/person_test.rb', <<-FILE 380 | require 'test_helper' 381 | 382 | class PersonTest < ActiveSupport::TestCase 383 | # Note: All of these matchers are listed in alphabetical order so we can 384 | # compare with what is listed inside of the shoulda-matchers README 385 | 386 | should_not allow_value("john@smith.com").for(:email) 387 | should allow_value("john").for(:email) 388 | 389 | # FIXME: See #1187 in shoulda-matchers 390 | #should_not have_secure_password 391 | 392 | should_not validate_absence_of(:nothing) 393 | should validate_absence_of(:some_other_attribute) 394 | 395 | should_not validate_acceptance_of(:terms_of_service) 396 | should validate_acceptance_of(:some_other_attribute) 397 | 398 | should_not validate_confirmation_of(:password) 399 | should validate_confirmation_of(:some_other_attribute) 400 | 401 | should_not validate_exclusion_of(:workouts).in_array(["biceps"]) 402 | should validate_exclusion_of(:some_other_attribute). 403 | in_array(["whatever"]) 404 | 405 | should_not validate_inclusion_of(:foods).in_array(["spaghetti"]) 406 | should validate_inclusion_of(:some_other_attribute). 407 | in_array(["whatever"]) 408 | 409 | should_not validate_length_of(:card_number).is_at_most(16) 410 | should validate_length_of(:some_other_attribute).is_at_most(16) 411 | 412 | should_not validate_numericality_of(:age) 413 | should validate_numericality_of(:some_other_attribute) 414 | 415 | should_not validate_presence_of(:something) 416 | should validate_presence_of(:some_other_attribute) 417 | 418 | should_not delegate_method(:a_method).to(:some_delegate_object) 419 | should delegate_method(:some_other_method).to(:some_other_object) 420 | end 421 | FILE 422 | 423 | result = app.run_n_unit_test_suite 424 | 425 | assert_accepts indicate_that_tests_were_run(failures: 20), result 426 | end 427 | 428 | def test_failing_assertions_for_active_record 429 | app.write_file 'test/models/user_test.rb', <<-FILE 430 | require 'test_helper' 431 | 432 | class UserTest < ActiveSupport::TestCase 433 | # Note: All of these matchers are listed in alphabetical order so we can 434 | # compare with what is listed inside of the shoulda-matchers README 435 | 436 | should_not belong_to(:city) 437 | should belong_to(:some_other_attribute) 438 | 439 | should_not define_enum_for(:status).with_values(inactive: 0, active: 1) 440 | should define_enum_for(:status).with_values(foo: "bar") 441 | 442 | should_not have_db_column(:age) 443 | should have_db_column(:some_other_attribute) 444 | 445 | should_not have_db_index(:account_id) 446 | should have_db_index(:some_other_attribute) 447 | 448 | should_not have_readonly_attribute(:username) 449 | should have_readonly_attribute(:some_other_attribute) 450 | 451 | should_not have_and_belong_to_many(:categories) 452 | should have_and_belong_to_many(:whatevers) 453 | 454 | should_not have_many(:issues) 455 | should have_many(:whatevers) 456 | 457 | should_not have_one(:life) 458 | should have_one(:whatever) 459 | 460 | should_not serialize(:aspects) 461 | should serialize(:age) 462 | 463 | should_not validate_uniqueness_of(:email) 464 | should validate_uniqueness_of(:some_other_attribute) 465 | 466 | should_not accept_nested_attributes_for(:issues) 467 | should accept_nested_attributes_for(:some_other_attribute) 468 | end 469 | FILE 470 | 471 | result = app.run_n_unit_test_suite 472 | 473 | assert_accepts indicate_that_tests_were_run(failures: 22), result 474 | end 475 | 476 | def test_failing_assertions_for_action_controller 477 | app.write_file 'test/controllers/examples_controller_test.rb', <<-FILE 478 | require 'test_helper' 479 | 480 | class ExamplesControllerTest < ActionController::TestCase 481 | context "GET #index" do 482 | setup do 483 | get :index 484 | end 485 | 486 | # Note: All of these matchers are listed in alphabetical order so we 487 | # can compare with what is listed inside of the shoulda-matchers 488 | # README 489 | 490 | should_not use_before_action(:some_before_action) 491 | should use_before_action(:some_other_before_action) 492 | should_not use_after_action(:some_after_action) 493 | should use_after_action(:some_other_after_action) 494 | should_not use_around_action(:some_around_action) 495 | should use_around_action(:some_other_around_action) 496 | 497 | should_not filter_param(:passw) 498 | should filter_param(:some_other_param) 499 | 500 | should_not rescue_from(ActiveRecord::RecordNotFound). 501 | with(:handle_not_found) 502 | should rescue_from(ActiveRecord::RecordNotFound). 503 | with(:some_other_method) 504 | 505 | should_not render_template(:index) 506 | should render_template(:some_other_action) 507 | 508 | should_not render_with_layout("application") 509 | should render_with_layout("some_other_layout") 510 | 511 | should_not respond_with(:ok) 512 | should respond_with(:some_other_status) 513 | 514 | should_not route(:get, "/examples").to(action: :index) 515 | should route(:get, "/examples").to(action: :something_else) 516 | end 517 | 518 | context "POST #create" do 519 | setup do 520 | if ActionPack::VERSION::STRING.start_with?("4.") 521 | post :create, { 522 | user: { 523 | email: "some@email.com", 524 | password: "somepassword" 525 | } 526 | } 527 | else 528 | post :create, params: { 529 | user: { 530 | email: "some@email.com", 531 | password: "somepassword" 532 | } 533 | } 534 | end 535 | end 536 | 537 | should_not permit(:email, :password). 538 | for(:create, params: { 539 | user: { 540 | email: "some@email.com", 541 | password: "somepassword" 542 | } 543 | }). 544 | on(:user) 545 | should permit(:foo, :bar). 546 | for(:create, params: { 547 | user: { 548 | email: "some@email.com", 549 | password: "somepassword" 550 | } 551 | }). 552 | on(:user) 553 | 554 | should_not redirect_to("/examples") 555 | should redirect_to("/something_else") 556 | 557 | should_not set_flash[:success].to("Example created") 558 | should set_flash[:success].to("Something else") 559 | 560 | should_not set_session[:some_key].to("some value") 561 | should set_session[:some_key].to("some other value") 562 | end 563 | end 564 | FILE 565 | 566 | result = app.run_n_unit_test_suite 567 | 568 | assert_accepts indicate_that_tests_were_run(failures: 26), result 569 | end 570 | # rubocop:enable Metrics/AbcSize, Metrics/MethodLength 571 | end 572 | --------------------------------------------------------------------------------