├── .gemtest ├── .gitignore ├── lib ├── minitest-rails.rb ├── minitest │ ├── rails │ │ ├── version.rb │ │ ├── expectations.rb │ │ ├── assertions.rb │ │ ├── capybara.rb │ │ ├── railtie.rb │ │ ├── parallelize.rb │ │ ├── assertions │ │ │ ├── active_support.rb │ │ │ ├── active_job.rb │ │ │ ├── action_mailer.rb │ │ │ ├── action_cable.rb │ │ │ ├── action_view.rb │ │ │ └── action_dispatch.rb │ │ └── expectations │ │ │ ├── active_support.rb │ │ │ ├── active_job.rb │ │ │ ├── action_mailer.rb │ │ │ ├── action_cable.rb │ │ │ └── action_dispatch.rb │ └── rails.rb └── generators │ ├── minitest │ ├── plugin │ │ ├── templates │ │ │ ├── test_helper.rb │ │ │ └── %file_name%_test.rb.tt │ │ └── plugin_generator.rb │ ├── job │ │ ├── templates │ │ │ ├── unit_test.rb.tt │ │ │ └── unit_spec.rb.tt │ │ └── job_generator.rb │ ├── model │ │ ├── templates │ │ │ ├── unit_test.rb.tt │ │ │ ├── unit_spec.rb.tt │ │ │ └── fixtures.yml.tt │ │ └── model_generator.rb │ ├── integration │ │ ├── templates │ │ │ ├── integration_test.rb.tt │ │ │ └── integration_spec.rb.tt │ │ └── integration_generator.rb │ ├── helper │ │ └── helper_generator.rb │ ├── system │ │ ├── templates │ │ │ ├── system_spec.rb.tt │ │ │ ├── system_test.rb.tt │ │ │ └── application_system_test_case.rb.tt │ │ └── system_generator.rb │ ├── install │ │ ├── templates │ │ │ └── test │ │ │ │ ├── application_system_test_case.rb.tt │ │ │ │ ├── channels │ │ │ │ └── application_cable │ │ │ │ │ └── connection_test.rb.tt │ │ │ │ └── test_helper.rb.tt │ │ └── install_generator.rb │ ├── generator │ │ ├── templates │ │ │ ├── generator_spec.rb.tt │ │ │ └── generator_test.rb.tt │ │ └── generator_generator.rb │ ├── mailer │ │ ├── templates │ │ │ ├── preview.rb.tt │ │ │ ├── functional_test.rb.tt │ │ │ └── functional_spec.rb.tt │ │ └── mailer_generator.rb │ ├── controller │ │ ├── controller_generator.rb │ │ └── templates │ │ │ ├── functional_test.rb.tt │ │ │ └── functional_spec.rb.tt │ └── scaffold │ │ ├── templates │ │ ├── api_functional_test.rb.tt │ │ ├── api_functional_spec.rb.tt │ │ ├── functional_spec.rb.tt │ │ ├── functional_test.rb.tt │ │ ├── system_spec.rb.tt │ │ └── system_test.rb.tt │ │ └── scaffold_generator.rb │ └── minitest.rb ├── Gemfile ├── CHANGELOG.md ├── test ├── test_sanity.rb ├── rails │ ├── active_support │ │ ├── test_expectations.rb │ │ ├── test_spec_type.rb │ │ └── test_assertions.rb │ ├── action_mailer │ │ ├── test_expectations.rb │ │ ├── test_assertions.rb │ │ ├── test_spec_type.rb │ │ └── test_mailers.rb │ ├── action_dispatch │ │ ├── test_assertions.rb │ │ ├── test_expectations.rb │ │ └── test_spec_type.rb │ ├── active_job │ │ ├── test_spec_type.rb │ │ ├── test_expectations.rb │ │ └── test_assertions.rb │ ├── generators │ │ └── test_spec_type.rb │ ├── action_cable │ │ ├── test_expectations.rb │ │ ├── test_assertions.rb │ │ └── test_spec_type.rb │ ├── action_view │ │ ├── test_spec_type.rb │ │ └── test_helpers.rb │ └── test_constant_lookup.rb ├── generators │ ├── test_install_generator.rb │ ├── test_helper_generator.rb │ ├── test_scaffold_generator.rb │ ├── test_job_generator.rb │ ├── test_mailer_generator.rb │ ├── test_generator_generator.rb │ ├── test_controller_generator.rb │ └── test_model_generator.rb └── helper.rb ├── gemfiles └── rails-7.0.0.gemfile ├── .autotest ├── Rakefile ├── LICENSE ├── minitest-rails.gemspec ├── UPDATING.md ├── .github └── workflows │ └── ci.yml ├── .rubocop.yml └── README.md /.gemtest: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | doc 2 | log 3 | pkg 4 | Gemfile.lock 5 | *.gemfile.lock 6 | -------------------------------------------------------------------------------- /lib/minitest-rails.rb: -------------------------------------------------------------------------------- 1 | require "minitest/rails/version" 2 | require "minitest/rails/railtie" 3 | -------------------------------------------------------------------------------- /lib/minitest/rails/version.rb: -------------------------------------------------------------------------------- 1 | module Minitest 2 | module Rails 3 | VERSION = "7.0.0".freeze 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /lib/generators/minitest/plugin/templates/test_helper.rb: -------------------------------------------------------------------------------- 1 | require "active_support/testing/autorun" 2 | require "active_support" 3 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "http://rubygems.org" 2 | 3 | gemspec 4 | 5 | gem "irb" 6 | gem "rails", "~> 7.0.0" 7 | gem "rake" 8 | gem "sqlite3" 9 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changes 2 | 3 | ### 7.0.0 / 2022-04-25 4 | 5 | Support Rails 7.0. 6 | 7 | ### 6.1.0 / 2020-12-14 8 | 9 | Support Rails 6.1. 10 | -------------------------------------------------------------------------------- /test/test_sanity.rb: -------------------------------------------------------------------------------- 1 | require "helper" 2 | 3 | class TestMinitest < Minitest::Test 4 | def test_sanity 5 | assert Minitest::Rails::VERSION 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /lib/generators/minitest/job/templates/unit_test.rb.tt: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | <% module_namespacing do -%> 4 | class <%= class_name %>JobTest < ActiveJob::TestCase 5 | # def test_truth 6 | # assert true 7 | # end 8 | end 9 | <% end -%> 10 | -------------------------------------------------------------------------------- /lib/generators/minitest/model/templates/unit_test.rb.tt: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | <% module_namespacing do -%> 4 | class <%= class_name %>Test < ActiveSupport::TestCase 5 | # def test_truth 6 | # assert true 7 | # end 8 | end 9 | <% end -%> 10 | -------------------------------------------------------------------------------- /lib/generators/minitest/integration/templates/integration_test.rb.tt: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | <% module_namespacing do -%> 4 | class <%= class_name %>Test < ActionDispatch::IntegrationTest 5 | # def test_truth 6 | # assert true 7 | # end 8 | end 9 | <% end -%> 10 | -------------------------------------------------------------------------------- /lib/generators/minitest/job/templates/unit_spec.rb.tt: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | <% module_namespacing do -%> 4 | describe <%= class_name %>Job do 5 | # it "does a thing" do 6 | # <%= spec_expectation_monad %>(1+1).must_equal 2 7 | # end 8 | end 9 | <% end -%> 10 | -------------------------------------------------------------------------------- /lib/generators/minitest/model/templates/unit_spec.rb.tt: -------------------------------------------------------------------------------- 1 | require "test_helper" 2 | 3 | <% module_namespacing do -%> 4 | describe <%= class_name %> do 5 | # it "does a thing" do 6 | # <%= spec_expectation_monad %>(1+1).must_equal 2 7 | # end 8 | end 9 | <% end -%> 10 | -------------------------------------------------------------------------------- /lib/generators/minitest/integration/templates/integration_spec.rb.tt: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | <% module_namespacing do -%> 4 | describe "<%= human_name %>", :integration do 5 | # it "does a thing" do 6 | # <%= spec_expectation_monad %>(1+1).must_equal 2 7 | # end 8 | end 9 | <% end -%> 10 | -------------------------------------------------------------------------------- /lib/generators/minitest/helper/helper_generator.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "generators/minitest" 4 | 5 | module Minitest # :nodoc: 6 | module Generators # :nodoc: 7 | class HelperGenerator < Base # :nodoc: 8 | # Rails does not generate anything here. 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /gemfiles/rails-7.0.0.gemfile: -------------------------------------------------------------------------------- 1 | source "http://rubygems.org" 2 | 3 | gem "minitest-rails", path: "../" 4 | gem "rails", "~> 7.0.0" 5 | gem "rake" 6 | gem "sqlite3" 7 | 8 | gem "minitest-autotest", "~> 1.1" 9 | gem "minitest-focus", "~> 1.3" 10 | gem "minitest-rg", "~> 5.2" 11 | gem "rdoc", "~> 6.4" 12 | gem "rubocop", "~> 1.28.0" 13 | -------------------------------------------------------------------------------- /lib/generators/minitest/system/templates/system_spec.rb.tt: -------------------------------------------------------------------------------- 1 | require "application_system_test_case" 2 | 3 | class <%= class_name.pluralize %>Test < ApplicationSystemTestCase 4 | # test "visiting the index" do 5 | # visit <%= plural_table_name %>_url 6 | # 7 | # assert_selector "h1", text: "<%= class_name %>" 8 | # end 9 | end 10 | -------------------------------------------------------------------------------- /lib/generators/minitest/system/templates/system_test.rb.tt: -------------------------------------------------------------------------------- 1 | require "application_system_test_case" 2 | 3 | class <%= class_name.pluralize %>Test < ApplicationSystemTestCase 4 | # test "visiting the index" do 5 | # visit <%= plural_table_name %>_url 6 | # 7 | # assert_selector "h1", text: "<%= class_name %>" 8 | # end 9 | end 10 | -------------------------------------------------------------------------------- /lib/minitest/rails/expectations.rb: -------------------------------------------------------------------------------- 1 | require "minitest/rails/expectations/active_support" 2 | require "minitest/rails/expectations/action_dispatch" 3 | require "minitest/rails/expectations/active_job" if defined? ActiveJob 4 | require "minitest/rails/expectations/action_cable" if defined? ActionCable 5 | require "minitest/rails/expectations/action_mailer" if defined? ActionMailer 6 | -------------------------------------------------------------------------------- /lib/generators/minitest/system/templates/application_system_test_case.rb.tt: -------------------------------------------------------------------------------- 1 | require "test_helper" 2 | require "minitest/rails/capybara" 3 | 4 | class ApplicationSystemTestCase < ActionDispatch::SystemTestCase 5 | driven_by :selenium, using: :chrome, screen_size: [1400, 1400] 6 | 7 | register_spec_type(self) do |desc, *addl| 8 | addl.include? :system 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /lib/generators/minitest/install/templates/test/application_system_test_case.rb.tt: -------------------------------------------------------------------------------- 1 | require "test_helper" 2 | require "minitest/rails/capybara" 3 | 4 | class ApplicationSystemTestCase < ActionDispatch::SystemTestCase 5 | driven_by :selenium, using: :chrome, screen_size: [1400, 1400] 6 | 7 | register_spec_type(self) do |desc, *addl| 8 | addl.include? :system 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /lib/generators/minitest/plugin/plugin_generator.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "generators/minitest" 4 | 5 | module Minitest # :nodoc: 6 | module Generators # :nodoc: 7 | class PluginGenerator < Base # :nodoc: 8 | check_class_collision suffix: "Test" 9 | 10 | def create_test_files 11 | directory ".", "test" 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/minitest/rails/assertions.rb: -------------------------------------------------------------------------------- 1 | require "minitest/rails/assertions/active_support" 2 | require "minitest/rails/assertions/action_view" 3 | require "minitest/rails/assertions/action_dispatch" 4 | require "minitest/rails/assertions/active_job" if defined? ActiveJob 5 | require "minitest/rails/assertions/action_cable" if defined? ActionCable 6 | require "minitest/rails/assertions/action_mailer" if defined? ActionMailer 7 | -------------------------------------------------------------------------------- /lib/generators/minitest/plugin/templates/%file_name%_test.rb.tt: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | <%- if options[:spec] -%> 4 | describe <%= class_name %> do 5 | # it "does a thing" do 6 | # <%= spec_expectation_monad %>(1+1).must_equal 2 7 | # end 8 | end 9 | <%- else -%> 10 | class <%= class_name %>Test < ActiveSupport::TestCase 11 | # def test_truth 12 | # assert true 13 | # end 14 | end 15 | <%- end -%> 16 | -------------------------------------------------------------------------------- /lib/generators/minitest/generator/templates/generator_spec.rb.tt: -------------------------------------------------------------------------------- 1 | require "test_helper" 2 | require "<%= generator_path %>" 3 | 4 | <% module_namespacing do -%> 5 | describe <%= class_name %>Generator do 6 | #tests <%= class_name %>Generator 7 | destination Rails.root.join("tmp/generators") 8 | setup :prepare_destination 9 | 10 | # it "runs without errors" do 11 | # run_generator ["arguments"] 12 | # end 13 | end 14 | <% end -%> 15 | -------------------------------------------------------------------------------- /lib/minitest/rails/capybara.rb: -------------------------------------------------------------------------------- 1 | require "minitest/rails" 2 | require "capybara/minitest" 3 | require "capybara/minitest/spec" 4 | 5 | class ActionDispatch::SystemTestCase 6 | # Enable Capybara's spec DSL 7 | class << self 8 | alias background before 9 | alias scenario it 10 | alias given let 11 | end 12 | end 13 | 14 | module Kernel # :nodoc: 15 | # Enable Capybara's spec DSL 16 | alias feature describe 17 | end 18 | -------------------------------------------------------------------------------- /lib/generators/minitest/generator/templates/generator_test.rb.tt: -------------------------------------------------------------------------------- 1 | require "test_helper" 2 | require "<%= generator_path %>" 3 | 4 | <% module_namespacing do -%> 5 | class <%= class_name %>GeneratorTest < Rails::Generators::TestCase 6 | tests <%= class_name %>Generator 7 | destination Rails.root.join("tmp/generators") 8 | setup :prepare_destination 9 | 10 | # def test_generator_runs_without_errors 11 | # run_generator ["arguments"] 12 | # end 13 | end 14 | <% end -%> 15 | -------------------------------------------------------------------------------- /lib/generators/minitest/mailer/templates/preview.rb.tt: -------------------------------------------------------------------------------- 1 | <% module_namespacing do -%> 2 | # Preview all emails at http://localhost:3000/rails/mailers/<%= file_path %>_mailer 3 | class <%= class_name %>MailerPreview < ActionMailer::Preview 4 | <% actions.each do |action| -%> 5 | 6 | # Preview this email at http://localhost:3000/rails/mailers/<%= file_path %>_mailer/<%= action %> 7 | def <%= action %> 8 | <%= class_name %>Mailer.<%= action %> 9 | end 10 | <% end -%> 11 | 12 | end 13 | <% end -%> 14 | -------------------------------------------------------------------------------- /.autotest: -------------------------------------------------------------------------------- 1 | # -*- ruby -*- 2 | 3 | require 'autotest/restart' 4 | 5 | # Autotest.add_hook :initialize do |at| 6 | # at.extra_files << "../some/external/dependency.rb" 7 | # 8 | # at.libs << ":../some/external" 9 | # 10 | # at.add_exception 'vendor' 11 | # 12 | # at.add_mapping(/dependency.rb/) do |f, _| 13 | # at.files_matching(/test_.*rb$/) 14 | # end 15 | # 16 | # %w(TestA TestB).each do |klass| 17 | # at.extra_class_map[klass] = "test/test_misc.rb" 18 | # end 19 | # end 20 | 21 | # Autotest.add_hook :run_command do |at| 22 | # system "rake build" 23 | # end 24 | -------------------------------------------------------------------------------- /lib/generators/minitest/job/job_generator.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "generators/minitest" 4 | 5 | module Minitest # :nodoc: 6 | module Generators # :nodoc: 7 | class JobGenerator < Base # :nodoc: 8 | check_class_collision suffix: "JobTest" 9 | 10 | def create_test_file 11 | template "unit_#{test_file_type}.rb", File.join("test/jobs", class_path, "#{file_name}_job_test.rb") 12 | end 13 | 14 | private 15 | 16 | def file_name 17 | @_file_name ||= super.sub(/_job\z/i, "") 18 | end 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/generators/minitest/controller/controller_generator.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "generators/minitest" 4 | 5 | module Minitest # :nodoc: 6 | module Generators # :nodoc: 7 | class ControllerGenerator < Base # :nodoc: 8 | argument :actions, type: :array, default: [], banner: "action action" 9 | check_class_collision suffix: "ControllerTest" 10 | 11 | def create_test_files 12 | template "functional_#{test_file_type}.rb", 13 | File.join("test/controllers", class_path, "#{file_name}_controller_test.rb") 14 | end 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/generators/minitest/integration/integration_generator.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "generators/minitest" 4 | 5 | module Minitest # :nodoc: 6 | module Generators # :nodoc: 7 | class IntegrationGenerator < Base # :nodoc: 8 | check_class_collision suffix: "Test" 9 | 10 | def create_test_files 11 | template "integration_#{test_file_type}.rb", File.join("test/integration", class_path, "#{file_name}_test.rb") 12 | end 13 | 14 | private 15 | 16 | def file_name 17 | @_file_name ||= super.sub(/_test\z/i, "") 18 | end 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/generators/minitest/controller/templates/functional_test.rb.tt: -------------------------------------------------------------------------------- 1 | require "test_helper" 2 | 3 | <% module_namespacing do -%> 4 | class <%= class_name %>ControllerTest < ActionDispatch::IntegrationTest 5 | <% if mountable_engine? -%> 6 | include Engine.routes.url_helpers 7 | 8 | <% end -%> 9 | <% if actions.empty? -%> 10 | # def test_truth 11 | # assert true 12 | # end 13 | <% else -%> 14 | <% actions.each do |action| -%> 15 | def test_get_<%= action %> 16 | get <%= url_helper_prefix %>_<%= action %>_url 17 | assert_response :success 18 | end 19 | 20 | <% end -%> 21 | <% end -%> 22 | end 23 | <% end -%> 24 | -------------------------------------------------------------------------------- /lib/generators/minitest/controller/templates/functional_spec.rb.tt: -------------------------------------------------------------------------------- 1 | require "test_helper" 2 | 3 | <% module_namespacing do -%> 4 | describe <%= class_name %>Controller do 5 | <% if mountable_engine? -%> 6 | include Engine.routes.url_helpers 7 | 8 | <% end -%> 9 | <% if actions.empty? -%> 10 | # it "does a thing" do 11 | # <%= spec_expectation_monad %>(1+1).must_equal 2 12 | # end 13 | <% else -%> 14 | <% actions.each do |action| -%> 15 | it "must get <%= action %>" do 16 | get <%= url_helper_prefix %>_<%= action %>_url 17 | must_respond_with :success 18 | end 19 | 20 | <% end -%> 21 | <% end -%> 22 | end 23 | <% end -%> 24 | -------------------------------------------------------------------------------- /lib/generators/minitest/mailer/templates/functional_test.rb.tt: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | <% module_namespacing do -%> 4 | class <%= class_name %>MailerTest < ActionMailer::TestCase 5 | <% actions.each do |action| -%> 6 | def test_<%= action %> 7 | mail = <%= class_name %>Mailer.<%= action %> 8 | assert_equal <%= action.to_s.humanize.inspect %>, mail.subject 9 | assert_equal ["to@example.org"], mail.to 10 | assert_equal ["from@example.com"], mail.from 11 | assert_match "Hi", mail.body.encoded 12 | end 13 | 14 | <% end -%> 15 | <% if actions.blank? -%> 16 | # def test_truth 17 | # assert true 18 | # end 19 | <% end -%> 20 | end 21 | <% end -%> 22 | -------------------------------------------------------------------------------- /lib/generators/minitest/install/templates/test/channels/application_cable/connection_test.rb.tt: -------------------------------------------------------------------------------- 1 | require "test_helper" 2 | 3 | <%- if options[:spec] -%> 4 | describe "ApplicationCable Connection", :connection do 5 | # it "connects with cookies" do 6 | # cookies.signed[:user_id] = 42 7 | # 8 | # connect 9 | # 10 | # connection.user_id.must_equal "42" 11 | # end 12 | end 13 | <%- else -%> 14 | class ApplicationCable::ConnectionTest < ActionCable::Connection::TestCase 15 | # def test_connects_with_cookies 16 | # cookies.signed[:user_id] = 42 17 | # 18 | # connect 19 | # 20 | # assert_equal connection.user_id, "42" 21 | # end 22 | end 23 | <%- end -%> 24 | -------------------------------------------------------------------------------- /lib/generators/minitest/mailer/templates/functional_spec.rb.tt: -------------------------------------------------------------------------------- 1 | require "test_helper" 2 | 3 | <% module_namespacing do -%> 4 | describe <%= class_name %>Mailer do 5 | <% actions.each do |action| -%> 6 | it "creates <%= action %> email" do 7 | mail = <%= class_name %>Mailer.<%= action %> 8 | mail.subject.must_equal <%= action.to_s.humanize.inspect %> 9 | mail.to.must_equal ["to@example.org"] 10 | mail.from.must_equal ["from@example.com"] 11 | mail.body.encoded.must_equal "Hi" 12 | end 13 | 14 | <% end -%> 15 | <% if actions.blank? -%> 16 | # it "does a thing" do 17 | # <%= spec_expectation_monad %>(1+1).must_equal 2 18 | # end 19 | <% end -%> 20 | end 21 | <% end -%> 22 | -------------------------------------------------------------------------------- /lib/minitest/rails/railtie.rb: -------------------------------------------------------------------------------- 1 | if defined?(Rake.application) && 2 | Rake.application.top_level_tasks.grep(/^test(?::|$)/).any? 3 | ENV["RAILS_ENV"] ||= "test" 4 | end 5 | 6 | require "rails" 7 | 8 | module Minitest 9 | module Rails 10 | class Railtie < ::Rails::Railtie 11 | config.app_generators do |c| 12 | c.test_framework :minitest, 13 | fixture: true, 14 | fixture_replacement: nil 15 | c.integration_tool :minitest 16 | c.fallbacks[:minitest] = :test_unit 17 | end 18 | 19 | rake_tasks do 20 | load "rails/test_unit/testing.rake" unless Rake::Task.task_defined? "test:run" 21 | end 22 | end 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /lib/generators/minitest/system/system_generator.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "generators/minitest" 4 | 5 | module Minitest # :nodoc: 6 | module Generators # :nodoc: 7 | class SystemGenerator < Base # :nodoc: 8 | check_class_collision suffix: "Test" 9 | 10 | def create_test_files 11 | unless File.exist?(File.join("test/application_system_test_case.rb")) 12 | template "application_system_test_case.rb", File.join("test", "application_system_test_case.rb") 13 | end 14 | 15 | template "system_#{test_file_type}.rb", File.join("test/system", class_path, "#{file_name.pluralize}_test.rb") 16 | end 17 | 18 | private 19 | 20 | def file_name 21 | @_file_name ||= super.sub(/_test\z/i, "") 22 | end 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /lib/generators/minitest/install/templates/test/test_helper.rb.tt: -------------------------------------------------------------------------------- 1 | ENV["RAILS_ENV"] ||= "test" 2 | # Consider setting MT_NO_EXPECTATIONS to not add expectations to Object. 3 | # ENV["MT_NO_EXPECTATIONS"] = "true" 4 | require_relative "../config/environment" 5 | require "rails/test_help" 6 | require "minitest/rails" 7 | 8 | class ActiveSupport::TestCase 9 | # Run tests in parallel with specified workers 10 | <% if defined?(JRUBY_VERSION) || Gem.win_platform? -%> 11 | parallelize(workers: :number_of_processors, with: :threads) 12 | <%- else -%> 13 | parallelize(workers: :number_of_processors) 14 | <% end -%> 15 | 16 | <% unless options[:skip_active_record] -%> 17 | # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. 18 | fixtures :all 19 | 20 | <% end -%> 21 | # Add more helper methods to be used by all tests here... 22 | end 23 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require "bundler" 2 | require "bundler/setup" 3 | require "bundler/gem_tasks" 4 | 5 | require "rdoc/task" 6 | RDoc::Task.new do |rdoc| 7 | rdoc.main = "README.md" 8 | rdoc.title = "minitest-rails" 9 | rdoc.rdoc_files.include "README.md", "lib/**/*.rb" 10 | rdoc.rdoc_dir = "doc" 11 | end 12 | 13 | require "rubocop/rake_task" 14 | RuboCop::RakeTask.new 15 | 16 | require "rake/testtask" 17 | desc "Run tests." 18 | Rake::TestTask.new do |t| 19 | t.libs << "test" 20 | t.test_files = FileList["test/**/test_*.rb"] 21 | t.warning = false 22 | t.verbose = false 23 | end 24 | 25 | namespace :test do 26 | desc "Run tests for all Rails versions" 27 | task "all" do 28 | Dir.glob("gemfiles/*.gemfile").each do |gemfile| 29 | Bundler.with_clean_env do 30 | sh "bundle --gemfile=#{gemfile} && bundle exec rake test" 31 | end 32 | end 33 | end 34 | end 35 | 36 | task default: %i[test rubocop] 37 | -------------------------------------------------------------------------------- /lib/generators/minitest/generator/generator_generator.rb: -------------------------------------------------------------------------------- 1 | require "generators/minitest" 2 | 3 | module Minitest 4 | module Generators 5 | class GeneratorGenerator < Base # :nodoc: 6 | check_class_collision suffix: "GeneratorTest" 7 | 8 | class_option :namespace, type: :boolean, default: true, 9 | desc: "Namespace generator under lib/generators/name" 10 | 11 | def create_generator_files 12 | template "generator_#{test_file_type}.rb", File.join("test/lib/generators", class_path, "#{file_name}_generator_test.rb") 13 | end 14 | 15 | private 16 | 17 | def generator_path 18 | if options[:namespace] 19 | File.join("generators", regular_class_path, file_name, "#{file_name}_generator") 20 | else 21 | File.join("generators", regular_class_path, "#{file_name}_generator") 22 | end 23 | end 24 | end 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /lib/generators/minitest/mailer/mailer_generator.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "generators/minitest" 4 | 5 | module Minitest # :nodoc: 6 | module Generators # :nodoc: 7 | class MailerGenerator < Base # :nodoc: 8 | argument :actions, type: :array, default: [], banner: "method method" 9 | 10 | def check_class_collision 11 | class_collisions "#{class_name}MailerTest", "#{class_name}MailerPreview" 12 | end 13 | 14 | def create_test_files 15 | template "functional_#{test_file_type}.rb", File.join("test/mailers", class_path, "#{file_name}_mailer_test.rb") 16 | end 17 | 18 | def create_preview_files 19 | template "preview.rb", File.join("test/mailers/previews", class_path, "#{file_name}_mailer_preview.rb") 20 | end 21 | 22 | private 23 | 24 | def file_name 25 | @_file_name ||= super.sub(/_mailer\z/i, "") 26 | end 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /test/rails/active_support/test_expectations.rb: -------------------------------------------------------------------------------- 1 | require "helper" 2 | 3 | # Can't use describe because there is no spec type to use 4 | class TestActiveSupportExpectations < ActiveSupport::TestCase 5 | def test_must_change 6 | counter = 0 7 | 8 | value { counter += 1 }.must_change "counter", from: 0, to: 1 9 | 10 | value { counter += 3 }.must_change "counter", from: 1, to: 4 11 | 12 | value { counter -= 1 }.must_change "counter", from: 4, to: 3 13 | end 14 | 15 | def test_wont_change 16 | counter = 0 17 | 18 | value { counter = 0 }.wont_change "counter" 19 | end 20 | 21 | def test_must_differ 22 | counter = 0 23 | 24 | value { counter += 1 }.must_differ "counter", +1 25 | 26 | value { counter += 3 }.must_differ "counter", +3 27 | 28 | value { counter -= 1 }.must_differ "counter", -1 29 | end 30 | 31 | def test_wont_differ 32 | counter = 0 33 | 34 | value { counter = 0 }.wont_differ "counter" 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /test/rails/active_support/test_spec_type.rb: -------------------------------------------------------------------------------- 1 | require "helper" 2 | 3 | class SomeRandomModel < ActiveRecord::Base; end 4 | 5 | class TestActiveSupportSpecType < Minitest::Test 6 | def assert_support actual 7 | assert_equal ActiveSupport::TestCase, actual 8 | end 9 | 10 | def refute_support actual 11 | refute_equal ActiveSupport::TestCase, actual 12 | end 13 | 14 | def test_spec_type_resolves_for_actitive_record_constants 15 | assert_support Minitest::Spec.spec_type(SomeRandomModel) 16 | end 17 | 18 | def test_spec_type_doesnt_resolve_random_strings 19 | refute_support Minitest::Spec.spec_type("Unmatched String") 20 | end 21 | 22 | def test_spec_type_resolves_for_additional_desc_model 23 | assert_support Minitest::Spec.spec_type("Unmatched String", :model) 24 | assert_support Minitest::Spec.spec_type("Unmatched String", :model, :other) 25 | assert_support Minitest::Spec.spec_type("Unmatched String", :other, :model) 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /lib/generators/minitest.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "rails/generators/named_base" 4 | 5 | module Minitest 6 | module Generators 7 | class Base < ::Rails::Generators::NamedBase # :nodoc: 8 | class_option :spec, type: :boolean, default: true, 9 | desc: "Use Minitest::Spec DSL" 10 | class_option :spec_expectation_monad, type: :string, default: "value", 11 | desc: "Spec DSL's expectation value mondad (options: value, expect, _)" 12 | 13 | def self.default_source_root 14 | File.expand_path(File.join(File.dirname(__FILE__), "minitest", generator_name, "templates")) 15 | end 16 | 17 | def test_file_type 18 | return "spec" if options[:spec] 19 | 20 | "test" 21 | end 22 | 23 | def spec_expectation_monad 24 | monad = options[:spec_expectation_monad] 25 | return monad if %w[value expect _].include? monad 26 | 27 | "value" 28 | end 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /test/rails/action_mailer/test_expectations.rb: -------------------------------------------------------------------------------- 1 | require "helper" 2 | 3 | class TestActionMailerExpectations < ActionMailer::TestCase 4 | include ActiveSupport::Testing::Stream 5 | tests MyAppMailer 6 | 7 | def test_must_have_emails 8 | must_have_emails 1 do 9 | MyAppMailer.test.deliver_now 10 | end 11 | end 12 | 13 | def test_wont_have_emails 14 | wont_have_emails do 15 | MyAppMailer.test 16 | end 17 | end 18 | 19 | def test_must_have_enqueued_emails 20 | must_have_enqueued_emails 1 do 21 | silence_stream($stdout) do 22 | MyAppMailer.test.deliver_later 23 | end 24 | end 25 | end 26 | 27 | def test_wont_have_enqueued_emails 28 | wont_have_enqueued_emails do 29 | MyAppMailer.test.deliver_now 30 | end 31 | end 32 | 33 | def test_must_enqueue_email_with 34 | skip "The mailer isn't wired up to queue the message." 35 | 36 | must_enqueue_email_with MyAppMailer, :test do 37 | silence_stream($stdout) do 38 | MyAppMailer.test.deliver_later 39 | end 40 | end 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2019 Mike Moore 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /lib/generators/minitest/model/templates/fixtures.yml.tt: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 2 | <% unless attributes.empty? -%> 3 | <% %w(one two).each do |name| %> 4 | <%= name %>: 5 | <% attributes.each do |attribute| -%> 6 | <%- if attribute.password_digest? -%> 7 | password_digest: <%%= BCrypt::Password.create('secret') %> 8 | <%- elsif attribute.reference? -%> 9 | <%= yaml_key_value(attribute.column_name.sub(/_id$/, ''), attribute.default || name) %> 10 | <%- else -%> 11 | <%= yaml_key_value(attribute.column_name, attribute.default) %> 12 | <%- end -%> 13 | <%- if attribute.polymorphic? -%> 14 | <%= yaml_key_value("#{attribute.name}_type", attribute.human_name) %> 15 | <%- end -%> 16 | <% end -%> 17 | <% end -%> 18 | <% else -%> 19 | 20 | # This model initially had no columns defined. If you add columns to the 21 | # model remove the '{}' from the fixture names and add the columns immediately 22 | # below each fixture, per the syntax in the comments below 23 | # 24 | one: {} 25 | # column: value 26 | # 27 | two: {} 28 | # column: value 29 | <% end -%> 30 | -------------------------------------------------------------------------------- /test/rails/action_dispatch/test_assertions.rb: -------------------------------------------------------------------------------- 1 | require "helper" 2 | 3 | class TestIntegrationAssertions < ActionDispatch::IntegrationTest 4 | def test_assert_response 5 | get models_path 6 | assert_response :success 7 | end 8 | 9 | def test_assert_redirected_to 10 | get new_model_path 11 | assert_redirected_to :models 12 | end 13 | 14 | def test_routing_assertions 15 | params = { controller: "models", action: "index" } 16 | path = "/models" 17 | assert_generates path, params 18 | assert_recognizes params, path 19 | assert_routing path, params 20 | end 21 | 22 | def test_assert_dom_equal 23 | apple_link = 'Apples' 24 | apple_link2 = 'Apples' 25 | orange_link = 'Oranges' 26 | 27 | assert_dom_equal apple_link, apple_link2 28 | refute_dom_equal apple_link, orange_link 29 | assert_dom_not_equal apple_link, orange_link 30 | end 31 | 32 | def test_assert_select 33 | get models_path 34 | assert_select "body h1" 35 | assert_select "body" do 36 | assert_select "h1" 37 | end 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /test/rails/action_dispatch/test_expectations.rb: -------------------------------------------------------------------------------- 1 | require "helper" 2 | 3 | class TestIntegrationExpectations < ActionDispatch::IntegrationTest 4 | def test_must_respond_with 5 | get models_path 6 | must_respond_with :success 7 | value(response).must_be :successful? 8 | end 9 | 10 | def test_must_redirect_to 11 | get new_model_path 12 | must_redirect_to :models 13 | end 14 | 15 | def test_routing_expectations 16 | params = { controller: "models", action: "index" } 17 | path = "/models" 18 | value(params).must_route_to path 19 | value(path).must_route_from params 20 | value(params).must_route_for path 21 | end 22 | 23 | def test_must_dom_equal 24 | apple_link = 'Apples' 25 | apple_link2 = 'Apples' 26 | orange_link = 'Oranges' 27 | 28 | value(apple_link).must_dom_equal apple_link2 29 | value(apple_link).wont_dom_equal orange_link 30 | end 31 | 32 | def test_must_select 33 | get models_path 34 | must_select "body h1" 35 | must_select "body" do 36 | must_select "h1" 37 | end 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /test/generators/test_install_generator.rb: -------------------------------------------------------------------------------- 1 | require "helper" 2 | require "generators/minitest/install/install_generator" 3 | 4 | class TestInstallGenerator < GeneratorTest 5 | tests Minitest::Generators::InstallGenerator 6 | 7 | def test_install_generator 8 | output = run_generator %w[myapp] 9 | assert_match %r{create test/test_helper.rb}m, output 10 | 11 | Dir.chdir self.class.destination_root 12 | assert File.exist? "test/test_helper.rb" 13 | 14 | contents = File.read "test/test_helper.rb" 15 | assert_match(%r{require "rails/test_help"}m, contents) 16 | assert_match(%r{require "minitest/rails"}m, contents) 17 | assert_match(/fixtures :all/m, contents) 18 | end 19 | 20 | def test_install_generator_without_active_record 21 | output = run_generator %w[myapp --skip-active-record] 22 | assert_match %r{create test/test_helper.rb}m, output 23 | 24 | Dir.chdir self.class.destination_root 25 | assert File.exist? "test/test_helper.rb" 26 | 27 | contents = File.read "test/test_helper.rb" 28 | assert_match(%r{require "rails/test_help"}m, contents) 29 | assert_match(%r{require "minitest/rails"}m, contents) 30 | refute_match(/fixtures :all/m, contents) 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /lib/generators/minitest/model/model_generator.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "generators/minitest" 4 | 5 | module Minitest # :nodoc: 6 | module Generators # :nodoc: 7 | class ModelGenerator < Base # :nodoc: 8 | RESERVED_YAML_KEYWORDS = %w[y yes n no true false on off null].freeze 9 | 10 | argument :attributes, type: :array, default: [], banner: "field:type field:type" 11 | class_option :fixture, type: :boolean 12 | 13 | check_class_collision suffix: "Test" 14 | 15 | def create_test_file 16 | template "unit_#{test_file_type}.rb", File.join("test/models", class_path, "#{file_name}_test.rb") 17 | end 18 | 19 | hook_for :fixture_replacement 20 | 21 | def create_fixture_file 22 | if options[:fixture] && options[:fixture_replacement].nil? 23 | template "fixtures.yml", File.join("test/fixtures", class_path, "#{fixture_file_name}.yml") 24 | end 25 | end 26 | 27 | private 28 | 29 | def yaml_key_value key, value 30 | if RESERVED_YAML_KEYWORDS.include?(key.downcase) 31 | "'#{key}': #{value}" 32 | else 33 | "#{key}: #{value}" 34 | end 35 | end 36 | end 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /minitest-rails.gemspec: -------------------------------------------------------------------------------- 1 | require File.expand_path("lib/minitest/rails/version", __dir__) 2 | 3 | Gem::Specification.new do |gem| 4 | gem.name = "minitest-rails" 5 | gem.version = Minitest::Rails::VERSION 6 | 7 | gem.authors = ["Mike Moore"] 8 | gem.email = ["mike@blowmage.com"] 9 | gem.description = "Adds Minitest as the default testing library in Rails" 10 | gem.summary = "Minitest integration for Rails" 11 | gem.homepage = "http://blowmage.com/minitest-rails" 12 | gem.license = "MIT" 13 | 14 | gem.files = `git ls-files -- lib/*`.split("\n") + 15 | ["README.md", "UPDATING.md", "CHANGELOG.md", "LICENSE"] 16 | gem.require_paths = ["lib"] 17 | 18 | gem.required_ruby_version = ">= 2.7.0" 19 | 20 | gem.add_dependency "minitest", "~> 5.10" 21 | gem.add_dependency "railties", "~> 7.0.0" 22 | 23 | gem.add_development_dependency "minitest-autotest", "~> 1.1" 24 | gem.add_development_dependency "minitest-focus", "~> 1.3" 25 | gem.add_development_dependency "minitest-rg", "~> 5.2" 26 | gem.add_development_dependency "rdoc", "~> 6.4" 27 | gem.add_development_dependency "rubocop", "~> 1.28.0" 28 | gem.metadata["rubygems_mfa_required"] = "true" 29 | end 30 | -------------------------------------------------------------------------------- /lib/generators/minitest/install/install_generator.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "rails/generators" 4 | require "rails/generators/app_base" 5 | 6 | module Minitest 7 | module Generators 8 | class InstallGenerator < ::Rails::Generators::AppBase 9 | class_option :skip_active_record, type: :boolean, default: false, desc: "Skip Active Record files" 10 | 11 | desc <<~DESC 12 | Description: 13 | Copy minitest files to your application. 14 | DESC 15 | 16 | def self.source_root 17 | @source_root ||= File.expand_path(File.join(File.dirname(__FILE__), "templates")) 18 | end 19 | 20 | def copy_minitest_files 21 | empty_directory_with_keep_file "test/fixtures" 22 | empty_directory_with_keep_file "test/fixtures/files" 23 | empty_directory_with_keep_file "test/controllers" 24 | empty_directory_with_keep_file "test/mailers" 25 | empty_directory_with_keep_file "test/models" 26 | empty_directory_with_keep_file "test/helpers" 27 | empty_directory_with_keep_file "test/integration" 28 | 29 | template "test/channels/application_cable/connection_test.rb" 30 | template "test/application_system_test_case.rb" 31 | template "test/test_helper.rb" 32 | end 33 | end 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /test/rails/action_mailer/test_assertions.rb: -------------------------------------------------------------------------------- 1 | require "helper" 2 | 3 | class TestActionMailerAssertions < ActionMailer::TestCase 4 | include ActiveSupport::Testing::Stream 5 | tests MyAppMailer 6 | 7 | def test_assert_emails 8 | assert_emails 1 do 9 | MyAppMailer.test.deliver_now 10 | end 11 | end 12 | 13 | def test_assert_no_emails 14 | assert_no_emails do 15 | MyAppMailer.test 16 | end 17 | end 18 | 19 | def test_refute_emails 20 | refute_emails do 21 | MyAppMailer.test 22 | end 23 | end 24 | 25 | def test_assert_enqueued_emails 26 | assert_enqueued_emails 1 do 27 | silence_stream($stdout) do 28 | MyAppMailer.test.deliver_later 29 | end 30 | end 31 | end 32 | 33 | def test_assert_no_enqueued_emails 34 | assert_no_enqueued_emails do 35 | MyAppMailer.test.deliver_now 36 | end 37 | end 38 | 39 | def test_refute_enqueued_emails 40 | refute_enqueued_emails do 41 | MyAppMailer.test.deliver_now 42 | end 43 | end 44 | 45 | def test_assert_enqueued_email_with 46 | skip "The mailer isn't wired up to queue the message." 47 | 48 | assert_enqueued_email_with MyAppMailer, :test do 49 | silence_stream($stdout) do 50 | MyAppMailer.test.deliver_later 51 | end 52 | end 53 | end 54 | end 55 | -------------------------------------------------------------------------------- /UPDATING.md: -------------------------------------------------------------------------------- 1 | # Updating from previous versions 2 | 3 | If you are upgrading from previous versions, then there are some subtle changes that you should be aware of. Do you see a change that is not listed in this document? Then please [open an issue](https://github.com/blowmage/minitest-rails/issues/new) to add it. 4 | 5 | ## Spec DSL 6 | 7 | The `describe` block should be passed the actual constant and not a string of the constant's name. This works: 8 | 9 | ```ruby 10 | describe WidgetsController do 11 | ``` 12 | 13 | But this does not: 14 | 15 | ```ruby 16 | describe "WidgetsController" do 17 | ``` 18 | 19 | If you want to pass a string, then you must provide an additional description to tell the Spec DSL what test class to use: 20 | 21 | ```ruby 22 | describe "WidgetsController", :controller do 23 | ``` 24 | 25 | ## Expectations 26 | 27 | The signature for the expectation `must_change` has changed from earlier versions of minitest-rails. This is because the expectation used to refer to the `assert_difference` assertion, but not refers to the `assert_changes` assertion added in Rails 5.1. The expectation for the `assert_difference` assertion is now `must_differ`. 28 | 29 | ## Versioning 30 | 31 | The minitest-rails gem now follows Rails versioning. This means minitest-rails 6.0.x works for rails 6.0.x, and minitest-rails 6.1.x will work for rails 6.1.x. 32 | -------------------------------------------------------------------------------- /test/rails/active_support/test_assertions.rb: -------------------------------------------------------------------------------- 1 | require "helper" 2 | 3 | class TestActiveSupportAssertions < ActiveSupport::TestCase 4 | def test_assert_changes 5 | counter = 0 6 | assert_changes "counter", from: 0, to: 1 do 7 | counter += 1 8 | end 9 | assert_changes "counter", from: 1, to: 2 do 10 | counter += 1 11 | end 12 | assert_changes "counter", from: 2, to: 5 do 13 | 3.times { counter += 1 } 14 | end 15 | end 16 | 17 | def test_refute_changes 18 | counter = 0 19 | refute_changes "counter" do 20 | counter = 0 21 | end 22 | end 23 | 24 | def test_assert_no_changes 25 | counter = 0 26 | assert_no_changes "counter" do 27 | counter = 0 28 | end 29 | end 30 | 31 | def test_assert_difference 32 | counter = 0 33 | assert_difference "counter" do 34 | counter += 1 35 | end 36 | assert_difference "counter", +1 do 37 | counter += 1 38 | end 39 | assert_difference "counter", +3 do 40 | 3.times { counter += 1 } 41 | end 42 | end 43 | 44 | def test_refute_difference 45 | counter = 0 46 | refute_difference "counter" do 47 | counter = 0 48 | end 49 | end 50 | 51 | def test_assert_no_difference 52 | counter = 0 53 | assert_no_difference "counter" do 54 | counter = 0 55 | end 56 | end 57 | end 58 | -------------------------------------------------------------------------------- /lib/generators/minitest/scaffold/templates/api_functional_test.rb.tt: -------------------------------------------------------------------------------- 1 | require "test_helper" 2 | 3 | <% module_namespacing do -%> 4 | class <%= controller_class_name %>ControllerTest < ActionDispatch::IntegrationTest 5 | <%- if mountable_engine? -%> 6 | include Engine.routes.url_helpers 7 | 8 | <%- end -%> 9 | setup do 10 | @<%= singular_table_name %> = <%= fixture_name %>(:one) 11 | end 12 | 13 | def test_get_index 14 | get <%= index_helper %>_url, as: :json 15 | assert_response :success 16 | end 17 | 18 | def test_create_<%= singular_table_name %> 19 | assert_difference("<%= class_name %>.count") do 20 | post <%= index_helper %>_url, params: { <%= "#{singular_table_name}: { #{attributes_string} }" %> }, as: :json 21 | end 22 | 23 | assert_response 201 24 | end 25 | 26 | def test_show_<%= singular_table_name %> 27 | get <%= show_helper %>, as: :json 28 | assert_response :success 29 | end 30 | 31 | def test_update_<%= singular_table_name %> 32 | patch <%= show_helper %>, params: { <%= "#{singular_table_name}: { #{attributes_string} }" %> }, as: :json 33 | assert_response 200 34 | end 35 | 36 | def test_destroy_<%= singular_table_name %> 37 | assert_difference("<%= class_name %>.count", -1) do 38 | delete <%= show_helper %>, as: :json 39 | end 40 | 41 | assert_response 204 42 | end 43 | end 44 | <% end -%> 45 | -------------------------------------------------------------------------------- /test/generators/test_helper_generator.rb: -------------------------------------------------------------------------------- 1 | require "helper" 2 | require "generators/minitest/helper/helper_generator" 3 | 4 | class TestHelperGenerator < GeneratorTest 5 | tests Minitest::Generators::HelperGenerator 6 | 7 | def test_helper_generator 8 | output = run_generator %w[user --no-spec] 9 | refute_match %r{create test/helpers/user_helper_test.rb}m, output 10 | 11 | Dir.chdir self.class.destination_root 12 | refute File.exist? "test/helpers/user_helper_test.rb" 13 | end 14 | 15 | def test_namespaced_helper_generator 16 | output = run_generator %w[admin/user --no-spec] 17 | refute_match %r{create test/helpers/user_helper_test.rb}m, output 18 | 19 | Dir.chdir self.class.destination_root 20 | refute File.exist? "test/helpers/admin/user_helper_test.rb" 21 | end 22 | 23 | def test_helper_generator_spec 24 | output = run_generator %w[user] 25 | refute_match %r{create test/helpers/user_helper_test.rb}m, output 26 | 27 | Dir.chdir self.class.destination_root 28 | refute File.exist? "test/helpers/user_helper_test.rb" 29 | end 30 | 31 | def test_namespaced_helper_generator_spec 32 | output = run_generator %w[admin/user] 33 | refute_match %r{create test/helpers/user_helper_test.rb}m, output 34 | 35 | Dir.chdir self.class.destination_root 36 | refute File.exist? "test/helpers/admin/user_helper_test.rb" 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /test/rails/active_job/test_spec_type.rb: -------------------------------------------------------------------------------- 1 | require "helper" 2 | 3 | class UserInviteJob < ActiveJob::Base; end 4 | class InviteUser < ActiveJob::Base; end 5 | 6 | class TestActiveJobSpecType < Minitest::Test 7 | def assert_job actual 8 | assert_equal ActiveJob::TestCase, actual 9 | end 10 | 11 | def refute_job actual 12 | refute_equal ActiveJob::TestCase, actual 13 | end 14 | 15 | def test_spec_type_resolves_for_class_constants 16 | assert_job Minitest::Spec.spec_type(UserInviteJob) 17 | assert_job Minitest::Spec.spec_type(InviteUser) 18 | end 19 | 20 | def test_spec_type_wont_match_non_space_characters 21 | refute_job Minitest::Spec.spec_type("User Invite Job\tTest") 22 | refute_job Minitest::Spec.spec_type("User Invite Job\rTest") 23 | refute_job Minitest::Spec.spec_type("User Invite Job\nTest") 24 | refute_job Minitest::Spec.spec_type("User Invite Job\fTest") 25 | refute_job Minitest::Spec.spec_type("User Invite JobXTest") 26 | end 27 | 28 | def test_spec_type_doesnt_resolve_random_strings 29 | refute_job Minitest::Spec.spec_type("Unmatched String") 30 | end 31 | 32 | def test_spec_type_resolves_for_additional_desc_job 33 | assert_job Minitest::Spec.spec_type("Unmatched String", :job) 34 | assert_job Minitest::Spec.spec_type("Unmatched String", :job, :other) 35 | assert_job Minitest::Spec.spec_type("Unmatched String", :other, :job) 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /lib/generators/minitest/scaffold/templates/api_functional_spec.rb.tt: -------------------------------------------------------------------------------- 1 | require "test_helper" 2 | 3 | <% module_namespacing do -%> 4 | describe <%= controller_class_name %>Controller do 5 | <%- if mountable_engine? -%> 6 | include Engine.routes.url_helpers 7 | 8 | <%- end -%> 9 | let(:<%= singular_table_name %>) { <%= fixture_name %>(:one) } 10 | 11 | it "should get index" do 12 | get <%= index_helper %>_url, as: :json 13 | must_respond_with :success 14 | end 15 | 16 | it "should create <%= singular_table_name %>" do 17 | <%= spec_expectation_monad %> do 18 | post <%= index_helper %>_url, params: { <%= "#{singular_table_name}: { #{attributes_string} }" %> }, as: :json 19 | end.must_differ "<%= class_name %>.count" 20 | 21 | must_respond_with 201 22 | end 23 | 24 | it "should show <%= singular_table_name %>" do 25 | get <%= show_helper %>, as: :json 26 | must_respond_with :success 27 | end 28 | 29 | it "should update <%= singular_table_name %>" do 30 | patch <%= show_helper %>, params: { <%= "#{singular_table_name}: { #{attributes_string} }" %> }, as: :json 31 | must_respond_with 200 32 | end 33 | 34 | it "should destroy <%= singular_table_name %>" do 35 | <%= spec_expectation_monad %> do 36 | delete <%= show_helper %>, as: :json 37 | end.must_differ "<%= class_name %>.count", -1 38 | 39 | must_respond_with 204 40 | end 41 | end 42 | <% end -%> 43 | -------------------------------------------------------------------------------- /test/rails/generators/test_spec_type.rb: -------------------------------------------------------------------------------- 1 | require "helper" 2 | 3 | class InstallGenerator < Rails::Generators::Base; end 4 | 5 | class TestGeneratorsSpecType < Minitest::Test 6 | def assert_generator actual 7 | assert_equal Rails::Generators::TestCase, actual 8 | end 9 | 10 | def refute_generator actual 11 | refute_equal Rails::Generators::TestCase, actual 12 | end 13 | 14 | def test_spec_type_resolves_for_class_constants 15 | assert_generator Minitest::Spec.spec_type(InstallGenerator) 16 | end 17 | 18 | def test_spec_type_wont_match_non_space_characters 19 | refute_generator Minitest::Spec.spec_type("Install Generator\tTest") 20 | refute_generator Minitest::Spec.spec_type("Install Generator\rTest") 21 | refute_generator Minitest::Spec.spec_type("Install Generator\nTest") 22 | refute_generator Minitest::Spec.spec_type("Install Generator\fTest") 23 | refute_generator Minitest::Spec.spec_type("Install GeneratorXTest") 24 | end 25 | 26 | def test_spec_type_doesnt_resolve_random_strings 27 | refute_generator Minitest::Spec.spec_type("Unmatched String") 28 | end 29 | 30 | def test_spec_type_resolves_for_additional_desc_generator 31 | assert_generator Minitest::Spec.spec_type("Unmatched String", :generator) 32 | assert_generator Minitest::Spec.spec_type("Unmatched String", :generator, :other) 33 | assert_generator Minitest::Spec.spec_type("Unmatched String", :other, :generator) 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /test/rails/action_mailer/test_spec_type.rb: -------------------------------------------------------------------------------- 1 | require "helper" 2 | 3 | class NotificationMailer < ActionMailer::Base; end 4 | class Notifications < ActionMailer::Base; end 5 | 6 | class TestActionMailerSpecType < Minitest::Test 7 | def assert_mailer actual 8 | assert_equal ActionMailer::TestCase, actual 9 | end 10 | 11 | def refute_mailer actual 12 | refute_equal ActionMailer::TestCase, actual 13 | end 14 | 15 | def test_spec_type_resolves_for_class_constants 16 | assert_mailer Minitest::Spec.spec_type(NotificationMailer) 17 | assert_mailer Minitest::Spec.spec_type(Notifications) 18 | end 19 | 20 | def test_spec_type_wont_match_non_space_characters 21 | refute_mailer Minitest::Spec.spec_type("Widget Mailer\tTest") 22 | refute_mailer Minitest::Spec.spec_type("Widget Mailer\rTest") 23 | refute_mailer Minitest::Spec.spec_type("Widget Mailer\nTest") 24 | refute_mailer Minitest::Spec.spec_type("Widget Mailer\fTest") 25 | refute_mailer Minitest::Spec.spec_type("Widget MailerXTest") 26 | end 27 | 28 | def test_spec_type_doesnt_resolve_random_strings 29 | refute_mailer Minitest::Spec.spec_type("Unmatched String") 30 | end 31 | 32 | def test_spec_type_resolves_for_additional_desc_mailer 33 | assert_mailer Minitest::Spec.spec_type("Unmatched String", :mailer) 34 | assert_mailer Minitest::Spec.spec_type("Unmatched String", :mailer, :other) 35 | assert_mailer Minitest::Spec.spec_type("Unmatched String", :other, :mailer) 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /test/rails/active_job/test_expectations.rb: -------------------------------------------------------------------------------- 1 | require "helper" 2 | 3 | module ActiveJobExpectationTests 4 | def test_must_enqueue_jobs 5 | must_enqueue_jobs 0 6 | UserInviteJob.logger.silence { UserInviteJob.perform_later } 7 | must_enqueue_jobs 1 8 | end 9 | 10 | def test_wont_enqueue_jobs 11 | wont_enqueue_jobs 12 | UserInviteJob.new 13 | wont_enqueue_jobs 14 | end 15 | 16 | def test_must_perform_jobs 17 | must_perform_jobs 0 18 | must_perform_jobs 2 do 19 | UserInviteJob.logger.silence do 20 | UserInviteJob.perform_later 21 | UserInviteJob.perform_later 22 | end 23 | end 24 | end 25 | 26 | def test_wont_perform_jobs 27 | wont_perform_jobs 28 | wont_perform_jobs do 29 | UserInviteJob.new 30 | end 31 | end 32 | 33 | def test_must_enqueue_with 34 | must_enqueue_with job: UserInviteJob, args: [209] do 35 | UserInviteJob.logger.silence { UserInviteJob.perform_later(209) } 36 | end 37 | end 38 | 39 | def test_must_perform_with 40 | must_perform_with job: UserInviteJob, args: [107] do 41 | UserInviteJob.logger.silence { UserInviteJob.perform_later(107) } 42 | end 43 | end 44 | end 45 | 46 | class TestActiveJobExpectations < ActiveJob::TestCase 47 | include ActiveJobExpectationTests 48 | end 49 | 50 | class TestActiveJobExpectationInCustomTestCase < ActiveSupport::TestCase 51 | include Minitest::Rails::Expectations::ActiveJob 52 | include ActiveJobExpectationTests 53 | end 54 | -------------------------------------------------------------------------------- /test/rails/active_job/test_assertions.rb: -------------------------------------------------------------------------------- 1 | require "helper" 2 | 3 | class TestActiveJobAssertions < ActiveJob::TestCase 4 | def test_assert_enqueued_jobs 5 | assert_enqueued_jobs 0 6 | UserInviteJob.logger.silence { UserInviteJob.perform_later } 7 | assert_enqueued_jobs 1 8 | end 9 | 10 | def test_assert_no_enqueued_jobs 11 | assert_no_enqueued_jobs 12 | UserInviteJob.new 13 | assert_no_enqueued_jobs 14 | end 15 | 16 | def test_refute_enqueued_jobs 17 | refute_enqueued_jobs 18 | UserInviteJob.new 19 | refute_enqueued_jobs 20 | end 21 | 22 | def test_assert_performed_jobs 23 | assert_performed_jobs 0 24 | assert_performed_jobs 2 do 25 | UserInviteJob.logger.silence do 26 | UserInviteJob.perform_later 27 | UserInviteJob.perform_later 28 | end 29 | end 30 | end 31 | 32 | def test_assert_no_performed_jobs 33 | assert_no_performed_jobs 34 | assert_no_performed_jobs do 35 | UserInviteJob.new 36 | end 37 | end 38 | 39 | def test_refute_performed_jobs 40 | refute_performed_jobs 41 | refute_performed_jobs do 42 | UserInviteJob.new 43 | end 44 | end 45 | 46 | def test_assert_enqueued_with 47 | assert_enqueued_with job: UserInviteJob, args: [209] do 48 | UserInviteJob.logger.silence { UserInviteJob.perform_later(209) } 49 | end 50 | end 51 | 52 | def test_assert_performed_with 53 | assert_performed_with job: UserInviteJob, args: [107] do 54 | UserInviteJob.logger.silence { UserInviteJob.perform_later(107) } 55 | end 56 | end 57 | end 58 | -------------------------------------------------------------------------------- /test/rails/action_dispatch/test_spec_type.rb: -------------------------------------------------------------------------------- 1 | require "helper" 2 | 3 | class ApplicationController < ActionController::Base; end 4 | class ModelsController < ApplicationController; end 5 | 6 | class TestActionDispatchSpecType < Minitest::Test 7 | def assert_dispatch actual 8 | assert_equal ActionDispatch::IntegrationTest, actual 9 | end 10 | 11 | def refute_dispatch actual 12 | refute_equal ActionDispatch::IntegrationTest, actual 13 | end 14 | 15 | def test_spec_type_resolves_for_class_constants 16 | assert_dispatch Minitest::Spec.spec_type(ApplicationController) 17 | assert_dispatch Minitest::Spec.spec_type(ModelsController) 18 | end 19 | 20 | def test_spec_type_wont_match_non_space_characters_integration 21 | refute_dispatch Minitest::Spec.spec_type("Widget Integration\tTest") 22 | refute_dispatch Minitest::Spec.spec_type("Widget Integration\rTest") 23 | refute_dispatch Minitest::Spec.spec_type("Widget Integration\nTest") 24 | refute_dispatch Minitest::Spec.spec_type("Widget Integration\fTest") 25 | refute_dispatch Minitest::Spec.spec_type("Widget IntegrationXTest") 26 | end 27 | 28 | def test_spec_type_doesnt_resolve_random_strings 29 | refute_dispatch Minitest::Spec.spec_type("Unmatched String") 30 | end 31 | 32 | def test_spec_type_resolves_for_additional_desc_integration 33 | assert_dispatch Minitest::Spec.spec_type("Unmatched String", :integration) 34 | assert_dispatch Minitest::Spec.spec_type("Unmatched String", :integration, :other) 35 | assert_dispatch Minitest::Spec.spec_type("Unmatched String", :other, :integration) 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: CI 3 | 4 | # https://github.com/actions/virtual-environments#available-environments 5 | 6 | 'on': [push, pull_request, workflow_dispatch] 7 | 8 | jobs: 9 | test: 10 | name: test 11 | 12 | runs-on: ubuntu-latest 13 | if: | 14 | !( contains(github.event.pull_request.title, '[ci skip]') 15 | || contains(github.event.pull_request.title, '[skip ci]')) 16 | 17 | strategy: 18 | fail-fast: false 19 | matrix: 20 | ruby: 21 | - '2.7' 22 | - '3.0' 23 | - '3.1' 24 | gemfile: 25 | - gemfiles/rails-7.0.0.gemfile 26 | 27 | env: 28 | BUNDLE_GEMFILE: ${{ matrix.gemfile }} 29 | 30 | steps: 31 | - uses: actions/checkout@v2 32 | 33 | - uses: ruby/setup-ruby@v1 34 | with: 35 | ruby-version: ${{ matrix.ruby }} 36 | bundler-cache: true 37 | 38 | - name: rake test 39 | run: | 40 | ruby -v 41 | bundle -v 42 | bundle exec rake test 43 | timeout-minutes: 3 44 | 45 | rubocop: 46 | name: rubocop 47 | 48 | runs-on: ubuntu-latest 49 | if: | 50 | !( contains(github.event.pull_request.title, '[ci skip]') 51 | || contains(github.event.pull_request.title, '[skip ci]')) 52 | 53 | steps: 54 | - uses: actions/checkout@v2 55 | 56 | - uses: ruby/setup-ruby@v1 57 | with: 58 | ruby-version: 2.7 59 | bundler-cache: true 60 | 61 | - name: rubocop 62 | run: | 63 | ruby -v 64 | bundle -v 65 | bundle exec rake rubocop 66 | -------------------------------------------------------------------------------- /test/rails/action_cable/test_expectations.rb: -------------------------------------------------------------------------------- 1 | require "helper" 2 | 3 | class TestActionCableExpectations < ActionCable::TestCase 4 | def test_must_have_broadcasts 5 | must_have_broadcasts("test", 1) do 6 | ActionCable.server.broadcast "test", "message" 7 | end 8 | end 9 | 10 | def test_wont_have_broadcasts 11 | wont_have_broadcasts("test") do 12 | ActionCable.server.broadcast "test2", "message" 13 | end 14 | end 15 | 16 | def test_must_broadcast_on 17 | must_broadcast_on("test", "message") do 18 | ActionCable.server.broadcast "test", "message" 19 | end 20 | end 21 | end 22 | 23 | class TestActionCableChannelExpectations < ActionCable::Channel::TestCase 24 | tests MyAppChannel 25 | 26 | def test_must_have_broadcasts 27 | must_have_broadcasts("test", 1) do 28 | ActionCable.server.broadcast "test", "message" 29 | end 30 | end 31 | 32 | def test_wont_have_broadcasts 33 | wont_have_broadcasts("test") do 34 | ActionCable.server.broadcast "test2", "message" 35 | end 36 | end 37 | 38 | def test_must_broadcast_on 39 | must_broadcast_on("test", "message") do 40 | ActionCable.server.broadcast "test", "message" 41 | end 42 | end 43 | 44 | def test_has_expected_expectations 45 | assert respond_to? :wont_have_streams 46 | assert respond_to? :must_have_streams 47 | assert respond_to? :must_have_stream_for 48 | end 49 | end 50 | 51 | class TestActionCableConnectionExpectations < ActionCable::Connection::TestCase 52 | tests MyAppConnection 53 | 54 | def test_rejects_connection_without_proper_cookie 55 | must_reject_connection { connect } 56 | end 57 | end 58 | -------------------------------------------------------------------------------- /lib/generators/minitest/scaffold/templates/functional_spec.rb.tt: -------------------------------------------------------------------------------- 1 | require "test_helper" 2 | 3 | <% module_namespacing do -%> 4 | describe <%= controller_class_name %>Controller do 5 | <%- if mountable_engine? -%> 6 | include Engine.routes.url_helpers 7 | 8 | <%- end -%> 9 | let(:<%= singular_table_name %>) { <%= fixture_name %>(:one) } 10 | 11 | it "should get index" do 12 | get <%= index_helper %>_url 13 | must_respond_with :success 14 | end 15 | 16 | it "should get new" do 17 | get <%= new_helper %> 18 | must_respond_with :success 19 | end 20 | 21 | it "should create <%= singular_table_name %>" do 22 | assert_difference("<%= class_name %>.count") do 23 | post <%= index_helper %>_url, params: { <%= "#{singular_table_name}: { #{attributes_string} }" %> } 24 | end 25 | 26 | must_redirect_to <%= singular_table_name %>_url(<%= class_name %>.last) 27 | end 28 | 29 | it "should show <%= singular_table_name %>" do 30 | get <%= show_helper %> 31 | must_respond_with :success 32 | end 33 | 34 | it "should get edit" do 35 | get <%= edit_helper %> 36 | must_respond_with :success 37 | end 38 | 39 | it "should update <%= singular_table_name %>" do 40 | patch <%= show_helper %>, params: { <%= "#{singular_table_name}: { #{attributes_string} }" %> } 41 | must_redirect_to <%= singular_table_name %>_url(<%= "#{singular_table_name}" %>) 42 | end 43 | 44 | it "should destroy <%= singular_table_name %>" do 45 | assert_difference("<%= class_name %>.count", -1) do 46 | delete <%= show_helper %> 47 | end 48 | 49 | must_redirect_to <%= index_helper %>_url 50 | end 51 | end 52 | <% end -%> 53 | -------------------------------------------------------------------------------- /lib/generators/minitest/scaffold/templates/functional_test.rb.tt: -------------------------------------------------------------------------------- 1 | require "test_helper" 2 | 3 | <% module_namespacing do -%> 4 | class <%= controller_class_name %>ControllerTest < ActionDispatch::IntegrationTest 5 | <%- if mountable_engine? -%> 6 | include Engine.routes.url_helpers 7 | 8 | <%- end -%> 9 | setup do 10 | @<%= singular_table_name %> = <%= fixture_name %>(:one) 11 | end 12 | 13 | def test_get_index 14 | get <%= index_helper %>_url 15 | assert_response :success 16 | end 17 | 18 | def test_get_new 19 | get <%= new_helper %> 20 | assert_response :success 21 | end 22 | 23 | def test_create_<%= singular_table_name %> 24 | assert_difference("<%= class_name %>.count") do 25 | post <%= index_helper %>_url, params: { <%= "#{singular_table_name}: { #{attributes_string} }" %> } 26 | end 27 | 28 | assert_redirected_to <%= singular_table_name %>_url(<%= class_name %>.last) 29 | end 30 | 31 | def test_show_<%= singular_table_name %> 32 | get <%= show_helper %> 33 | assert_response :success 34 | end 35 | 36 | def test_get_edit 37 | get <%= edit_helper %> 38 | assert_response :success 39 | end 40 | 41 | def test_update_<%= singular_table_name %> 42 | patch <%= show_helper %>, params: { <%= "#{singular_table_name}: { #{attributes_string} }" %> } 43 | assert_redirected_to <%= singular_table_name %>_url(<%= "@#{singular_table_name}" %>) 44 | end 45 | 46 | def test_destroy_<%= singular_table_name %> 47 | assert_difference("<%= class_name %>.count", -1) do 48 | delete <%= show_helper %> 49 | end 50 | 51 | assert_redirected_to <%= index_helper %>_url 52 | end 53 | end 54 | <% end -%> 55 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | AllCops: 2 | TargetRubyVersion: 2.7 3 | NewCops: enable 4 | 5 | Layout/LineLength: 6 | Max: 100 7 | Exclude: 8 | - gemfiles/**/* 9 | - lib/generators/**/* 10 | - lib/minitest/rails/assertions/**/* 11 | - lib/minitest/rails/expectations/**/* 12 | - test/generators/test_scaffold_generator.rb 13 | 14 | Lint/EmptyClass: 15 | Exclude: 16 | - lib/minitest/rails/assertions/action_cable.rb 17 | - test/rails/action_cable/test_spec_type.rb 18 | - test/rails/test_constant_lookup.rb 19 | 20 | Lint/SuppressedException: 21 | Exclude: 22 | - test/helper.rb 23 | 24 | Metrics/AbcSize: 25 | Exclude: 26 | - lib/generators/**/* 27 | - lib/minitest/rails/parallelize.rb 28 | 29 | Metrics/ClassLength: 30 | Enabled: false 31 | 32 | Metrics/MethodLength: 33 | Enabled: false 34 | 35 | Naming/FileName: 36 | Exclude: 37 | - gemfiles/**/* 38 | - lib/minitest-rails.rb 39 | 40 | Naming/MemoizedInstanceVariableName: 41 | Exclude: 42 | - lib/generators/**/* 43 | 44 | Style/AccessModifierDeclarations: 45 | Exclude: 46 | - lib/minitest/rails/parallelize.rb 47 | 48 | Style/Alias: 49 | EnforcedStyle: prefer_alias 50 | 51 | Style/CaseEquality: 52 | Exclude: 53 | - lib/minitest/rails.rb 54 | - test/rails/test_constant_lookup.rb 55 | 56 | Style/ClassAndModuleChildren: 57 | Enabled: false 58 | 59 | Style/Documentation: 60 | Enabled: false 61 | 62 | Style/FrozenStringLiteralComment: 63 | Enabled: false 64 | 65 | Style/GuardClause: 66 | Exclude: 67 | - lib/generators/**/* 68 | 69 | Style/MethodDefParentheses: 70 | EnforcedStyle: require_no_parentheses 71 | 72 | Style/StringLiterals: 73 | EnforcedStyle: double_quotes 74 | -------------------------------------------------------------------------------- /test/generators/test_scaffold_generator.rb: -------------------------------------------------------------------------------- 1 | require "helper" 2 | require "generators/minitest/scaffold/scaffold_generator" 3 | 4 | class TestScaffoldGenerator < GeneratorTest 5 | tests Minitest::Generators::ScaffoldGenerator 6 | 7 | def test_scaffold_generator 8 | output = run_generator %w[User name:string email:string --no-spec] 9 | assert_match %r{create test/controllers/users_controller_test.rb}m, output 10 | 11 | Dir.chdir self.class.destination_root 12 | # assert_output(/create test\/controllers\/users_controller_test.rb/m) do 13 | # Minitest::Generators::ScaffoldGenerator.start ["User", "name:string", "email:string", "--no-spec"] 14 | # end 15 | assert File.exist? "test/controllers/users_controller_test.rb" 16 | 17 | contents = File.read "test/controllers/users_controller_test.rb" 18 | assert_match(/class UsersControllerTest/m, contents) 19 | assert_match(/post users_url, params: { user: { email: @user.email, name: @user.name } }/m, contents) 20 | end 21 | 22 | def test_scaffold_generator_spec 23 | output = run_generator %w[User name:string email:string --spec] 24 | assert_match %r{create test/controllers/users_controller_test.rb}m, output 25 | 26 | Dir.chdir self.class.destination_root 27 | # assert_output(/create test\/controllers\/users_controller_test.rb/m) do 28 | # Minitest::Generators::ScaffoldGenerator.start ["User", "name:string", "email:string"] 29 | # end 30 | assert File.exist? "test/controllers/users_controller_test.rb" 31 | contents = File.read "test/controllers/users_controller_test.rb" 32 | assert_match(/describe UsersController do/m, contents) 33 | assert_match(/post users_url, params: { user: { email: @user.email, name: @user.name } }/m, contents) 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /test/rails/action_view/test_spec_type.rb: -------------------------------------------------------------------------------- 1 | require "helper" 2 | 3 | class TestActionViewSpecType < Minitest::Test 4 | def assert_view actual 5 | assert_equal ActionView::TestCase, actual 6 | end 7 | 8 | def refute_view actual 9 | refute_equal ActionView::TestCase, actual 10 | end 11 | 12 | def test_spec_type_wont_match_models_that_end_in_view 13 | refute_view Minitest::Spec.spec_type("NewsOverviewTest") 14 | refute_view Minitest::Spec.spec_type("News Overview Test") 15 | refute_view Minitest::Spec.spec_type("NewsOverview") 16 | refute_view Minitest::Spec.spec_type("News Overview") 17 | end 18 | 19 | def test_spec_type_wont_match_non_space_characters 20 | refute_view Minitest::Spec.spec_type("Widget Helper\tTest") 21 | refute_view Minitest::Spec.spec_type("Widget Helper\rTest") 22 | refute_view Minitest::Spec.spec_type("Widget Helper\nTest") 23 | refute_view Minitest::Spec.spec_type("Widget Helper\fTest") 24 | refute_view Minitest::Spec.spec_type("Widget HelperXTest") 25 | end 26 | 27 | def test_spec_type_doesnt_resolve_random_strings 28 | refute_view Minitest::Spec.spec_type("Unmatched String") 29 | end 30 | 31 | def test_spec_type_resolves_for_additional_desc_view 32 | assert_view Minitest::Spec.spec_type("Unmatched String", :view) 33 | assert_view Minitest::Spec.spec_type("Unmatched String", :view, :other) 34 | assert_view Minitest::Spec.spec_type("Unmatched String", :other, :view) 35 | end 36 | 37 | def test_spec_type_resolves_for_additional_desc_helper 38 | assert_view Minitest::Spec.spec_type("Unmatched String", :helper) 39 | assert_view Minitest::Spec.spec_type("Unmatched String", :helper, :other) 40 | assert_view Minitest::Spec.spec_type("Unmatched String", :other, :helper) 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /lib/minitest/rails/parallelize.rb: -------------------------------------------------------------------------------- 1 | require "pathname" 2 | require "rails" 3 | 4 | # :stopdoc: 5 | 6 | ## 7 | # These changes are here to support the spec DSL when using Rails parallelize. 8 | # The issue is the spec DSL creates Class objects that are not assigned to 9 | # a Ruby constant. When those Class objects are passed through Drb they are 10 | # wrapped in a DrbObject and cannot be run. The solution is to assign each Class 11 | # object to a constant. Hopefully the constant name is consistent enough that 12 | # the constant can be passed across processes (or even machines). 13 | 14 | module Minitest 15 | module Rails 16 | ## 17 | # This module is a placeholder for all the Test classes created using the 18 | # spec DSL. Normally all classes are created but not assigned to a constant. 19 | # This module is where constants will be created for these classes. 20 | module SpecTests # :nodoc: 21 | end 22 | end 23 | end 24 | 25 | module Kernel # :nodoc: 26 | alias describe_before_minitest_spec_constant_fix describe 27 | private :describe_before_minitest_spec_constant_fix 28 | def describe *args, &block 29 | cls = describe_before_minitest_spec_constant_fix(*args, &block) 30 | cls_const = "Test__#{cls.name.to_s.split(/\W/).reject(&:empty?).join('_'.freeze)}" 31 | if block.source_location 32 | source_path, line_num = block.source_location 33 | source_path = Pathname.new(File.expand_path(source_path)).relative_path_from(Rails.root).to_s 34 | source_path = source_path.split(/\W/).reject(&:empty?).join("_".freeze) 35 | cls_const += "__#{source_path}__#{line_num}" 36 | end 37 | cls_const += "_1" while Minitest::Rails::SpecTests.const_defined? cls_const 38 | Minitest::Rails::SpecTests.const_set cls_const, cls 39 | cls 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /test/rails/action_view/test_helpers.rb: -------------------------------------------------------------------------------- 1 | require "helper" 2 | 3 | module PeopleHelper 4 | def title text 5 | content_tag(:h1, text) 6 | end 7 | 8 | def homepage_path 9 | people_path 10 | end 11 | 12 | def homepage_url 13 | people_url 14 | end 15 | 16 | def link_to_person person 17 | link_to person.name, person 18 | end 19 | end 20 | 21 | # From Rails... 22 | class CrazyHelperTest < ActionView::TestCase 23 | tests PeopleHelper 24 | 25 | def test_helper_class_can_be_set_manually_not_just_inferred 26 | assert_equal PeopleHelper, self.class.helper_class 27 | end 28 | end 29 | 30 | class CrazySymbolHelperTest < ActionView::TestCase 31 | tests :people 32 | 33 | def test_set_helper_class_using_symbol 34 | assert_equal PeopleHelper, self.class.helper_class 35 | end 36 | end 37 | 38 | class CrazyStringHelperTest < ActionView::TestCase 39 | tests "people" 40 | 41 | def test_set_helper_class_using_string 42 | assert_equal PeopleHelper, self.class.helper_class 43 | end 44 | end 45 | 46 | describe PeopleHelper, :helper do 47 | it "resolves the right helper_class" do 48 | assert_equal PeopleHelper, self.class.helper_class 49 | end 50 | end 51 | 52 | describe PeopleHelper, :helper do 53 | describe "even while nested" do 54 | it "resolves the right helper_class" do 55 | assert_equal PeopleHelper, self.class.helper_class 56 | end 57 | end 58 | end 59 | 60 | describe PeopleHelper, :view do 61 | it "resolves the right helper_class" do 62 | assert_equal PeopleHelper, self.class.helper_class 63 | end 64 | end 65 | 66 | describe PeopleHelper, :view do 67 | describe "even while nested" do 68 | it "resolves the right helper_class" do 69 | assert_equal PeopleHelper, self.class.helper_class 70 | end 71 | end 72 | end 73 | -------------------------------------------------------------------------------- /lib/generators/minitest/scaffold/templates/system_spec.rb.tt: -------------------------------------------------------------------------------- 1 | require "application_system_test_case" 2 | 3 | <% module_namespacing do -%> 4 | describe "<%= class_name.pluralize %>", :system do 5 | let(:<%= singular_table_name %>) { <%= fixture_name %>(:one) } 6 | 7 | it "visiting the index" do 8 | visit <%= plural_table_name %>_url 9 | assert_selector "h1", text: "<%= class_name.pluralize.titleize %>" 10 | end 11 | 12 | it "creating a <%= human_name %>" do 13 | visit <%= plural_table_name %>_url 14 | click_on "New <%= class_name.titleize %>" 15 | 16 | <%- attributes_hash.each do |attr, value| -%> 17 | <%- if boolean?(attr) -%> 18 | check "<%= attr.humanize %>" if <%= value %> 19 | <%- else -%> 20 | fill_in "<%= attr.humanize %>", with: <%= value %> 21 | <%- end -%> 22 | <%- end -%> 23 | click_on "Create <%= human_name %>" 24 | 25 | assert_text "<%= human_name %> was successfully created" 26 | click_on "Back" 27 | end 28 | 29 | it "updating a <%= human_name %>" do 30 | visit <%= plural_table_name %>_url 31 | click_on "Edit", match: :first 32 | 33 | <%- attributes_hash.each do |attr, value| -%> 34 | <%- if boolean?(attr) -%> 35 | check "<%= attr.humanize %>" if <%= value %> 36 | <%- else -%> 37 | fill_in "<%= attr.humanize %>", with: <%= value %> 38 | <%- end -%> 39 | <%- end -%> 40 | click_on "Update <%= human_name %>" 41 | 42 | assert_text "<%= human_name %> was successfully updated" 43 | click_on "Back" 44 | end 45 | 46 | it "destroying a <%= human_name %>" do 47 | visit <%= plural_table_name %>_url 48 | page.accept_confirm do 49 | click_on "Destroy", match: :first 50 | end 51 | 52 | assert_text "<%= human_name %> was successfully destroyed" 53 | end 54 | end 55 | <% end -%> 56 | -------------------------------------------------------------------------------- /lib/generators/minitest/scaffold/templates/system_test.rb.tt: -------------------------------------------------------------------------------- 1 | require "application_system_test_case" 2 | 3 | <% module_namespacing do -%> 4 | class <%= class_name.pluralize %>Test < ApplicationSystemTestCase 5 | setup do 6 | @<%= singular_table_name %> = <%= fixture_name %>(:one) 7 | end 8 | 9 | def test_visiting_index 10 | visit <%= plural_table_name %>_url 11 | assert_selector "h1", text: "<%= class_name.pluralize.titleize %>" 12 | end 13 | 14 | def test_creating_<%= human_name %> 15 | visit <%= plural_table_name %>_url 16 | click_on "New <%= class_name.titleize %>" 17 | 18 | <%- attributes_hash.each do |attr, value| -%> 19 | <%- if boolean?(attr) -%> 20 | check "<%= attr.humanize %>" if <%= value %> 21 | <%- else -%> 22 | fill_in "<%= attr.humanize %>", with: <%= value %> 23 | <%- end -%> 24 | <%- end -%> 25 | click_on "Create <%= human_name %>" 26 | 27 | assert_text "<%= human_name %> was successfully created" 28 | click_on "Back" 29 | end 30 | 31 | def test_updating_<%= human_name %> 32 | visit <%= plural_table_name %>_url 33 | click_on "Edit", match: :first 34 | 35 | <%- attributes_hash.each do |attr, value| -%> 36 | <%- if boolean?(attr) -%> 37 | check "<%= attr.humanize %>" if <%= value %> 38 | <%- else -%> 39 | fill_in "<%= attr.humanize %>", with: <%= value %> 40 | <%- end -%> 41 | <%- end -%> 42 | click_on "Update <%= human_name %>" 43 | 44 | assert_text "<%= human_name %> was successfully updated" 45 | click_on "Back" 46 | end 47 | 48 | def test_destroying_<%= human_name %> 49 | visit <%= plural_table_name %>_url 50 | page.accept_confirm do 51 | click_on "Destroy", match: :first 52 | end 53 | 54 | assert_text "<%= human_name %> was successfully destroyed" 55 | end 56 | end 57 | <% end -%> 58 | -------------------------------------------------------------------------------- /test/rails/action_cable/test_assertions.rb: -------------------------------------------------------------------------------- 1 | require "helper" 2 | 3 | class TestActionCableAssertions < ActionCable::TestCase 4 | def test_assert_broadcasts 5 | assert_broadcasts("test", 1) do 6 | ActionCable.server.broadcast "test", "message" 7 | end 8 | end 9 | 10 | def test_assert_no_broadcasts 11 | assert_no_broadcasts("test") do 12 | ActionCable.server.broadcast "test2", "message" 13 | end 14 | end 15 | 16 | def test_refute_broadcasts 17 | refute_broadcasts("test") do 18 | ActionCable.server.broadcast "test2", "message" 19 | end 20 | end 21 | 22 | def test_assert_broadcast_on 23 | assert_broadcast_on("test", "message") do 24 | ActionCable.server.broadcast "test", "message" 25 | end 26 | end 27 | end 28 | 29 | class TestActionCableChannelAssertions < ActionCable::Channel::TestCase 30 | tests MyAppChannel 31 | 32 | def test_assert_broadcasts 33 | assert_broadcasts("test", 1) do 34 | ActionCable.server.broadcast "test", "message" 35 | end 36 | end 37 | 38 | def test_assert_no_broadcasts 39 | assert_no_broadcasts("test") do 40 | ActionCable.server.broadcast "test2", "message" 41 | end 42 | end 43 | 44 | def test_refute_broadcasts 45 | refute_broadcasts("test") do 46 | ActionCable.server.broadcast "test2", "message" 47 | end 48 | end 49 | 50 | def test_assert_broadcast_on 51 | assert_broadcast_on("test", "message") do 52 | ActionCable.server.broadcast "test", "message" 53 | end 54 | end 55 | 56 | def test_has_expected_assertions 57 | assert respond_to? :assert_has_stream 58 | assert respond_to? :assert_no_streams 59 | assert respond_to? :refute_streams 60 | assert respond_to? :assert_has_stream_for 61 | end 62 | end 63 | 64 | class TestActionCableConnectionAssertions < ActionCable::Connection::TestCase 65 | tests MyAppConnection 66 | 67 | def test_rejects_connection_without_proper_cookie 68 | assert_reject_connection { connect } 69 | end 70 | end 71 | -------------------------------------------------------------------------------- /test/rails/test_constant_lookup.rb: -------------------------------------------------------------------------------- 1 | require "helper" 2 | 3 | class Foo; end 4 | 5 | class Bar < Foo 6 | def index; end 7 | 8 | def self.index; end 9 | end 10 | 11 | class Baz < Bar; end 12 | module FooBar; end 13 | 14 | class TestLookup < ActiveSupport::TestCase 15 | def find_foo name 16 | self.class.determine_constant_from_test_name(name) do |constant| 17 | Class === constant && constant < Foo 18 | end 19 | end 20 | 21 | def find_module name 22 | self.class.determine_constant_from_test_name(name) do |constant| 23 | Module === constant 24 | end 25 | end 26 | 27 | def test_find_bar_from_foo 28 | assert_equal Bar, find_foo("Bar") 29 | assert_equal Bar, find_foo("Bar::index") 30 | assert_equal Bar, find_foo("Bar::index::authenticated") 31 | assert_equal Bar, find_foo("BarTest") 32 | assert_equal Bar, find_foo("BarTest::index") 33 | assert_equal Bar, find_foo("BarTest::index::authenticated") 34 | end 35 | 36 | def test_find_module 37 | assert_equal FooBar, find_module("FooBar") 38 | assert_equal FooBar, find_module("FooBar::index") 39 | assert_equal FooBar, find_module("FooBar::index::authenticated") 40 | assert_equal FooBar, find_module("FooBarTest") 41 | assert_equal FooBar, find_module("FooBarTest::index") 42 | assert_equal FooBar, find_module("FooBarTest::index::authenticated") 43 | end 44 | 45 | def test_returns_nil_when_cant_find_foo 46 | assert_nil find_foo("DoesntExist") 47 | assert_nil find_foo("DoesntExistTest") 48 | assert_nil find_foo("DoesntExist::Nadda") 49 | assert_nil find_foo("DoesntExist::Nadda::Nope") 50 | assert_nil find_foo("DoesntExist::Nadda::Nope::NotHere") 51 | end 52 | 53 | def test_returns_nil_when_cant_find_module 54 | assert_nil find_module("DoesntExist") 55 | assert_nil find_module("DoesntExistTest") 56 | assert_nil find_module("DoesntExist::Nadda") 57 | assert_nil find_module("DoesntExist::Nadda::Nope") 58 | assert_nil find_module("DoesntExist::Nadda::Nope::NotHere") 59 | end 60 | end 61 | -------------------------------------------------------------------------------- /lib/generators/minitest/scaffold/scaffold_generator.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "generators/minitest" 4 | require "rails/generators/resource_helpers" 5 | 6 | module Minitest # :nodoc: 7 | module Generators # :nodoc: 8 | class ScaffoldGenerator < Base # :nodoc: 9 | include ::Rails::Generators::ResourceHelpers 10 | 11 | check_class_collision suffix: "ControllerTest" 12 | 13 | class_option :api, type: :boolean, 14 | desc: "Generates API functional tests" 15 | 16 | class_option :system_tests, type: :string, 17 | desc: "Skip system test files" 18 | 19 | argument :attributes, type: :array, default: [], banner: "field:type field:type" 20 | 21 | def create_test_files 22 | template_file = options.api? ? "api_functional_#{test_file_type}.rb" : "functional_#{test_file_type}.rb" 23 | template template_file, 24 | File.join("test/controllers", controller_class_path, "#{controller_file_name}_controller_test.rb") 25 | 26 | if !options.api? && options[:system_tests] 27 | template "system_#{test_file_type}.rb", File.join("test/system", class_path, "#{file_name.pluralize}_test.rb") 28 | end 29 | end 30 | 31 | def fixture_name 32 | @fixture_name ||= 33 | if mountable_engine? 34 | (namespace_dirs + [table_name]).join("_") 35 | else 36 | table_name 37 | end 38 | end 39 | 40 | private 41 | 42 | def attributes_string 43 | attributes_hash.map { |k, v| "#{k}: #{v}" }.join(", ") 44 | end 45 | 46 | def attributes_hash 47 | return {} if attributes_names.empty? 48 | 49 | attributes_names.map do |name| 50 | if %w[password password_confirmation].include?(name) && attributes.any?(&:password_digest?) 51 | [name.to_s, "'secret'"] 52 | else 53 | [name.to_s, "@#{singular_table_name}.#{name}"] 54 | end 55 | end.sort.to_h 56 | end 57 | 58 | def boolean? name 59 | attribute = attributes.find { |attr| attr.name == name } 60 | attribute&.type == :boolean 61 | end 62 | end 63 | end 64 | end 65 | -------------------------------------------------------------------------------- /test/generators/test_job_generator.rb: -------------------------------------------------------------------------------- 1 | require "helper" 2 | require "generators/minitest/job/job_generator" 3 | 4 | class TestJobGenerator < GeneratorTest 5 | tests Minitest::Generators::JobGenerator 6 | 7 | def test_job_generator 8 | output = run_generator %w[user_invite --no-spec] 9 | assert_match %r{create test/jobs/user_invite_job_test.rb}m, output 10 | 11 | Dir.chdir self.class.destination_root 12 | # assert_output(/create test\/jobs\/user_invite_job_test.rb/m) do 13 | # Minitest::Generators::JobGenerator.start ["user_invite", "--no-spec"] 14 | # end 15 | assert File.exist? "test/jobs/user_invite_job_test.rb" 16 | contents = File.read "test/jobs/user_invite_job_test.rb" 17 | assert_match(/class UserInviteJobTest < ActiveJob::TestCase/m, contents) 18 | end 19 | 20 | def test_namespaced_job_generator 21 | output = run_generator %w[admin/user_invite --no-spec] 22 | assert_match %r{create test/jobs/admin/user_invite_job_test.rb}m, output 23 | 24 | Dir.chdir self.class.destination_root 25 | # assert_output(/create test\/jobs\/admin\/user_invite_job_test.rb/m) do 26 | # Minitest::Generators::JobGenerator.start ["admin/user_invite", "--no-spec"] 27 | # end 28 | assert File.exist? "test/jobs/admin/user_invite_job_test.rb" 29 | contents = File.read "test/jobs/admin/user_invite_job_test.rb" 30 | assert_match(/class Admin::UserInviteJobTest < ActiveJob::TestCase/m, contents) 31 | end 32 | 33 | def test_job_generator_spec 34 | output = run_generator %w[user_invite] 35 | assert_match %r{create test/jobs/user_invite_job_test.rb}m, output 36 | 37 | Dir.chdir self.class.destination_root 38 | assert File.exist? "test/jobs/user_invite_job_test.rb" 39 | contents = File.read "test/jobs/user_invite_job_test.rb" 40 | assert_match(/describe UserInviteJob do/m, contents) 41 | end 42 | 43 | def test_namespaced_job_generator_spec 44 | output = run_generator %w[admin/user_invite] 45 | assert_match %r{create test/jobs/admin/user_invite_job_test.rb}m, output 46 | 47 | Dir.chdir self.class.destination_root 48 | assert File.exist? "test/jobs/admin/user_invite_job_test.rb" 49 | contents = File.read "test/jobs/admin/user_invite_job_test.rb" 50 | assert_match(/describe Admin::UserInviteJob do/m, contents) 51 | end 52 | end 53 | -------------------------------------------------------------------------------- /test/generators/test_mailer_generator.rb: -------------------------------------------------------------------------------- 1 | require "helper" 2 | require "generators/minitest/mailer/mailer_generator" 3 | 4 | class TestMailerGenerator < GeneratorTest 5 | tests Minitest::Generators::MailerGenerator 6 | 7 | def test_mailer_generator 8 | output = run_generator %w[notification welcome --no-spec] 9 | assert_match %r{create test/mailers/notification_mailer_test.rb}m, output 10 | 11 | Dir.chdir self.class.destination_root 12 | assert File.exist? "test/mailers/notification_mailer_test.rb" 13 | 14 | contents = File.read "test/mailers/notification_mailer_test.rb" 15 | assert_match(/class NotificationMailerTest/m, contents) 16 | assert_match(/def test_welcome/m, contents) 17 | end 18 | 19 | def test_namespaced_mailer_generator 20 | output = run_generator %w[admin/notification welcome --no-spec] 21 | assert_match %r{create test/mailers/admin/notification_mailer_test.rb}m, output 22 | 23 | Dir.chdir self.class.destination_root 24 | assert File.exist? "test/mailers/admin/notification_mailer_test.rb" 25 | 26 | contents = File.read "test/mailers/admin/notification_mailer_test.rb" 27 | assert_match(/class Admin::NotificationMailerTest/m, contents) 28 | assert_match(/def test_welcome/m, contents) 29 | end 30 | 31 | def test_mailer_generator_spec 32 | output = run_generator %w[notification welcome] 33 | assert_match %r{create test/mailers/notification_mailer_test.rb}m, output 34 | 35 | Dir.chdir self.class.destination_root 36 | assert File.exist? "test/mailers/notification_mailer_test.rb" 37 | 38 | contents = File.read "test/mailers/notification_mailer_test.rb" 39 | assert_match(/describe NotificationMailer do/m, contents) 40 | assert_match(/it "creates welcome email"/m, contents) 41 | end 42 | 43 | def test_namespaced_mailer_generator_spec 44 | output = run_generator %w[admin/notification welcome] 45 | assert_match %r{create test/mailers/admin/notification_mailer_test.rb}m, output 46 | 47 | Dir.chdir self.class.destination_root 48 | assert File.exist? "test/mailers/admin/notification_mailer_test.rb" 49 | 50 | contents = File.read "test/mailers/admin/notification_mailer_test.rb" 51 | assert_match(/describe Admin::NotificationMailer do/m, contents) 52 | assert_match(/it "creates welcome email"/m, contents) 53 | end 54 | end 55 | -------------------------------------------------------------------------------- /lib/minitest/rails/assertions/active_support.rb: -------------------------------------------------------------------------------- 1 | class ActiveSupport::TestCase 2 | ## 3 | # Assertion that the result of evaluating an expression is changed before and 4 | # after invoking the passed in block. 5 | # 6 | # assert_changes "Status.all_good?" do 7 | # post :create, params: { status: { ok: false } } 8 | # end 9 | # 10 | # See also Minitest::Rails::Expectations::ActiveSupport#must_change 11 | # See https://api.rubyonrails.org/v7.0/classes/ActiveSupport/Testing/Assertions.html#method-i-assert_changes 12 | # 13 | # :method: assert_changes 14 | # :call-seq: assert_changes(expression, message = nil, from: UNTRACKED, to: UNTRACKED, &block) 15 | 16 | ## 17 | # Assertion that the result of evaluating an expression is not changed before 18 | # and after invoking the passed in block. 19 | # 20 | # refute_changes "Status.all_good?" do 21 | # post :create, params: { status: { ok: true } } 22 | # end 23 | # 24 | # See also Minitest::Rails::Expectations::ActiveSupport#wont_change 25 | # See https://api.rubyonrails.org/v7.0/classes/ActiveSupport/Testing/Assertions.html#method-i-assert_no_changes 26 | # 27 | # :args: expression, message = nil, &block 28 | alias refute_changes assert_no_changes 29 | 30 | ## 31 | # Test numeric difference between the return value of an expression as a 32 | # result of what is evaluated in the yielded block. 33 | # 34 | # assert_difference "Article.count" do 35 | # post :create, params: { article: {...} } 36 | # end 37 | # 38 | # See also Minitest::Rails::Expectations::ActiveSupport#must_change 39 | # See https://api.rubyonrails.org/v7.0/classes/ActiveSupport/Testing/Assertions.html#method-i-assert_difference 40 | # 41 | # :method: assert_difference 42 | # :call-seq: assert_difference(expression, *args, &block) 43 | 44 | ## 45 | # Assertion that the numeric result of evaluating an expression is not changed 46 | # before and after invoking the passed in block. 47 | # 48 | # refute_difference "Article.count" do 49 | # post :create, params: { article: invalid_attributes } 50 | # end 51 | # 52 | # See also Minitest::Rails::Expectations::ActiveSupport#wont_change 53 | # See https://api.rubyonrails.org/v7.0/classes/ActiveSupport/Testing/Assertions.html#method-i-assert_no_difference 54 | # 55 | # :args: expression, message = nil, &block 56 | alias refute_difference assert_no_difference 57 | end 58 | -------------------------------------------------------------------------------- /test/generators/test_generator_generator.rb: -------------------------------------------------------------------------------- 1 | require "helper" 2 | require "generators/minitest/generator/generator_generator" 3 | 4 | class TestGeneratorGenerator < GeneratorTest 5 | tests Minitest::Generators::GeneratorGenerator 6 | 7 | def test_generator_generator 8 | output = run_generator %w[awesome --no-spec] 9 | assert_match %r{create test/lib/generators/awesome_generator_test.rb}m, output 10 | 11 | Dir.chdir self.class.destination_root 12 | assert File.exist? "test/lib/generators/awesome_generator_test.rb" 13 | 14 | contents = File.read "test/lib/generators/awesome_generator_test.rb" 15 | assert_match(/class AwesomeGeneratorTest/m, contents) 16 | end 17 | 18 | def test_namespaced_generator_generator 19 | output = run_generator %w[rails/awesome --no-spec] 20 | assert_match %r{create test/lib/generators/rails/awesome_generator_test.rb}m, output 21 | 22 | Dir.chdir self.class.destination_root 23 | assert File.exist? "test/lib/generators/rails/awesome_generator_test.rb" 24 | 25 | contents = File.read "test/lib/generators/rails/awesome_generator_test.rb" 26 | assert_match(/class Rails::AwesomeGeneratorTest/m, contents) 27 | end 28 | 29 | if Rails::Generators.respond_to? :namespace 30 | def test_module_namespaced_generator_generator 31 | assert_nil Rails::Generators.namespace 32 | Rails::Generators.namespace = TestApp 33 | 34 | output = run_generator %w[awesome --no-spec] 35 | assert_match %r{create test/lib/generators/test_app/awesome_generator_test.rb}m, output 36 | 37 | Dir.chdir self.class.destination_root 38 | assert File.exist? "test/lib/generators/test_app/awesome_generator_test.rb" 39 | 40 | contents = File.read "test/lib/generators/test_app/awesome_generator_test.rb" 41 | assert_match(/module TestApp/m, contents) 42 | assert_match(/class AwesomeGeneratorTest/m, contents) 43 | ensure 44 | # Restore default namespace 45 | Rails::Generators.namespace = nil 46 | end 47 | end 48 | 49 | def test_generator_generator_spec 50 | output = run_generator %w[awesome] 51 | assert_match %r{create test/lib/generators/awesome_generator_test.rb}m, output 52 | 53 | Dir.chdir self.class.destination_root 54 | assert File.exist? "test/lib/generators/awesome_generator_test.rb" 55 | contents = File.read "test/lib/generators/awesome_generator_test.rb" 56 | assert_match(/describe AwesomeGenerator do/m, contents) 57 | end 58 | 59 | def test_namespaced_generator_generator_spec 60 | output = run_generator %w[rails/awesome] 61 | assert_match %r{create test/lib/generators/rails/awesome_generator_test.rb}m, output 62 | 63 | Dir.chdir self.class.destination_root 64 | assert File.exist? "test/lib/generators/rails/awesome_generator_test.rb" 65 | 66 | contents = File.read "test/lib/generators/rails/awesome_generator_test.rb" 67 | assert_match(/describe Rails::AwesomeGenerator do/m, contents) 68 | end 69 | end 70 | -------------------------------------------------------------------------------- /test/generators/test_controller_generator.rb: -------------------------------------------------------------------------------- 1 | require "helper" 2 | require "generators/minitest/controller/controller_generator" 3 | 4 | class TestControllerGenerator < GeneratorTest 5 | tests Minitest::Generators::ControllerGenerator 6 | 7 | def test_controller_generator 8 | output = run_generator %w[user --no-spec] 9 | assert_match %r{create test/controllers/user_controller_test.rb}m, output 10 | 11 | Dir.chdir self.class.destination_root 12 | assert File.exist? "test/controllers/user_controller_test.rb" 13 | 14 | contents = File.read "test/controllers/user_controller_test.rb" 15 | assert_match(/class UserControllerTest/m, contents) 16 | end 17 | 18 | def test_namespaced_controller_generator 19 | output = run_generator %w[admin/user --no-spec] 20 | assert_match %r{create test/controllers/admin/user_controller_test.rb}m, output 21 | 22 | Dir.chdir self.class.destination_root 23 | assert File.exist? "test/controllers/admin/user_controller_test.rb" 24 | 25 | contents = File.read "test/controllers/admin/user_controller_test.rb" 26 | assert_match(/class Admin::UserControllerTest/m, contents) 27 | end 28 | 29 | if Rails::Generators.respond_to? :namespace 30 | def test_module_namespaced_controller_generator 31 | assert_nil Rails::Generators.namespace 32 | Rails::Generators.namespace = TestApp 33 | 34 | output = run_generator %w[user --no-spec] 35 | assert_match %r{create test/controllers/test_app/user_controller_test.rb}m, output 36 | 37 | Dir.chdir self.class.destination_root 38 | assert File.exist? "test/controllers/test_app/user_controller_test.rb" 39 | 40 | contents = File.read "test/controllers/test_app/user_controller_test.rb" 41 | assert_match(/module TestApp/m, contents) 42 | assert_match(/class UserControllerTest/m, contents) 43 | ensure 44 | # Restore default namespace 45 | Rails::Generators.namespace = nil 46 | end 47 | end 48 | 49 | def test_controller_generator_spec 50 | output = run_generator %w[user] 51 | assert_match %r{create test/controllers/user_controller_test.rb}m, output 52 | 53 | Dir.chdir self.class.destination_root 54 | assert File.exist? "test/controllers/user_controller_test.rb" 55 | 56 | contents = File.read "test/controllers/user_controller_test.rb" 57 | assert_match(/describe UserController do/m, contents) 58 | end 59 | 60 | def test_namespaced_controller_generator_spec 61 | output = run_generator %w[admin/user] 62 | assert_match %r{create test/controllers/admin/user_controller_test.rb}m, output 63 | 64 | Dir.chdir self.class.destination_root 65 | # assert_output(/create test\/controllers\/admin\/user_controller_test.rb/m) do 66 | # Minitest::Generators::ControllerGenerator.start ["admin/user"] 67 | # end 68 | assert File.exist? "test/controllers/admin/user_controller_test.rb" 69 | contents = File.read "test/controllers/admin/user_controller_test.rb" 70 | assert_match(/describe Admin::UserController do/m, contents) 71 | end 72 | end 73 | -------------------------------------------------------------------------------- /test/rails/action_cable/test_spec_type.rb: -------------------------------------------------------------------------------- 1 | require "helper" 2 | 3 | class NotAChannel 4 | end 5 | 6 | class NotAConnection 7 | end 8 | 9 | class TestActionCableSpecType < Minitest::Test 10 | def assert_channel actual 11 | assert_equal ActionCable::Channel::TestCase, actual 12 | end 13 | 14 | def refute_channel actual 15 | refute_equal ActionCable::Channel::TestCase, actual 16 | end 17 | 18 | def assert_connection actual 19 | assert_equal ActionCable::Connection::TestCase, actual 20 | end 21 | 22 | def refute_connection actual 23 | refute_equal ActionCable::Connection::TestCase, actual 24 | end 25 | 26 | def test_spec_type_doesnt_resolve_channel_for_class_constants 27 | refute_channel Minitest::Spec.spec_type(NotAChannel) 28 | refute_channel Minitest::Spec.spec_type(NotAConnection) 29 | end 30 | 31 | def test_spec_type_doesnt_resolve_channel_strings 32 | refute_channel Minitest::Spec.spec_type("Unmatched String") 33 | refute_channel Minitest::Spec.spec_type("ChannelTest") 34 | refute_channel Minitest::Spec.spec_type("ApplicationCable::ChannelTest") 35 | end 36 | 37 | def test_spec_type_resolves_channel_for_class_constant 38 | assert_channel Minitest::Spec.spec_type(MyAppChannel) 39 | end 40 | 41 | def test_spec_type_resolves_channel_for_additional_desc_channel 42 | assert_channel Minitest::Spec.spec_type(NotAChannel, :channel) 43 | assert_channel Minitest::Spec.spec_type(NotAChannel, :channel, :other) 44 | assert_channel Minitest::Spec.spec_type(NotAConnection, :other, :channel) 45 | assert_channel Minitest::Spec.spec_type("Unmatched String", :channel) 46 | assert_channel Minitest::Spec.spec_type("Unmatched String", :channel, :other) 47 | assert_channel Minitest::Spec.spec_type("Unmatched String", :other, :channel) 48 | end 49 | 50 | def test_spec_type_doesnt_resolve_connection_for_class_constants 51 | refute_connection Minitest::Spec.spec_type(NotAConnection) 52 | refute_connection Minitest::Spec.spec_type(NotAChannel) 53 | end 54 | 55 | def test_spec_type_doesnt_resolve_connection_strings 56 | refute_connection Minitest::Spec.spec_type("Unmatched String") 57 | refute_connection Minitest::Spec.spec_type("ConnectionTest") 58 | refute_connection Minitest::Spec.spec_type("ApplicationCable::ConnectionTest") 59 | end 60 | 61 | def test_spec_type_resolves_connection_for_class_constant 62 | assert_connection Minitest::Spec.spec_type(MyAppConnection) 63 | end 64 | 65 | def test_spec_type_resolves_connection_for_additional_desc_connection 66 | assert_connection Minitest::Spec.spec_type(NotAConnection, :connection) 67 | assert_connection Minitest::Spec.spec_type(NotAConnection, :connection, :other) 68 | assert_connection Minitest::Spec.spec_type(NotAChannel, :other, :connection) 69 | assert_connection Minitest::Spec.spec_type("Unmatched String", :connection) 70 | assert_connection Minitest::Spec.spec_type("Unmatched String", :connection, :other) 71 | assert_connection Minitest::Spec.spec_type("Unmatched String", :other, :connection) 72 | end 73 | end 74 | -------------------------------------------------------------------------------- /lib/minitest/rails/expectations/active_support.rb: -------------------------------------------------------------------------------- 1 | module Minitest 2 | module Rails 3 | module Expectations 4 | module ActiveSupport 5 | ## 6 | # Assertion that the result of evaluating an expression is changed before and 7 | # after invoking the passed in block. 8 | # 9 | # value { User.create password: "valid" }.must_change "User.count" 10 | # value { 3.times do 11 | # User.create password: "valid" 12 | # end }.must_change "User.count", from: 5, to: 8 13 | # 14 | # See also ActiveSupport::TestCase#assert_difference 15 | # See https://api.rubyonrails.org/v7.0/classes/ActiveSupport/Testing/Assertions.html#method-i-assert_changes 16 | # 17 | # :method: must_change 18 | # :args: expression, from: UNTRACKED, to: UNTRACKED 19 | infect_an_assertion :assert_changes, :must_change, :block 20 | 21 | ## 22 | # Assertion that the result of evaluating an expression is not changed before 23 | # and after invoking the passed in block. 24 | # 25 | # refute_changes "Status.all_good?" do 26 | # post :create, params: { status: { ok: true } } 27 | # end 28 | # 29 | # See also ActiveSupport::TestCase#assert_difference 30 | # See https://api.rubyonrails.org/v7.0/classes/ActiveSupport/Testing/Assertions.html#method-i-assert_no_changes 31 | # 32 | # :method: wont_change 33 | # :args: expression 34 | infect_an_assertion :refute_changes, :wont_change, :block 35 | 36 | ## 37 | # Test numeric difference between the return value of an expression as a 38 | # result of what is evaluated. 39 | # 40 | # value { User.create password: "valid" }.must_differ "User.count" 41 | # value { 3.times do 42 | # User.create password: "valid" 43 | # end }.must_differ "User.count", 3 44 | # 45 | # See also ActiveSupport::TestCase#assert_difference 46 | # See https://api.rubyonrails.org/v7.0/classes/ActiveSupport/Testing/Assertions.html#method-i-assert_difference 47 | # 48 | # :method: must_differ 49 | # :args: expression, *args 50 | infect_an_assertion :assert_difference, :must_differ, :block 51 | 52 | ## 53 | # Assertion that the numeric result of evaluating an expression is not changed 54 | # before and after invoking. 55 | # 56 | # value { User.new }.wont_differ "User.count" 57 | # 58 | # See also ActiveSupport::TestCase#refute_difference 59 | # See https://api.rubyonrails.org/v7.0/classes/ActiveSupport/Testing/Assertions.html#method-i-assert_no_difference 60 | # 61 | # :method: wont_differ 62 | # :args: expression 63 | infect_an_assertion :refute_difference, :wont_differ, :block 64 | end 65 | end 66 | end 67 | end 68 | 69 | unless ENV["MT_NO_EXPECTATIONS"] 70 | class Object # :nodoc: 71 | include Minitest::Rails::Expectations::ActiveSupport 72 | end 73 | end 74 | -------------------------------------------------------------------------------- /test/rails/action_mailer/test_mailers.rb: -------------------------------------------------------------------------------- 1 | require "helper" 2 | 3 | class TestTestMailer < ActionMailer::Base; end 4 | 5 | # From Rails... 6 | class CrazyNameMailerTest < ActionMailer::TestCase 7 | tests TestTestMailer 8 | 9 | def test_set_mailer_class_manual 10 | assert_equal TestTestMailer, self.class.mailer_class 11 | end 12 | end 13 | 14 | class CrazySymbolNameMailerTest < ActionMailer::TestCase 15 | tests :test_test_mailer 16 | 17 | def test_set_mailer_class_manual_using_symbol 18 | assert_equal TestTestMailer, self.class.mailer_class 19 | end 20 | end 21 | 22 | class CrazyStringNameMailerTest < ActionMailer::TestCase 23 | tests "test_test_mailer" 24 | 25 | def test_set_mailer_class_manual_using_string 26 | assert_equal TestTestMailer, self.class.mailer_class 27 | end 28 | end 29 | 30 | # New tests... 31 | describe TestTestMailer do 32 | it "gets the mailer from the test name" do 33 | assert_equal TestTestMailer, self.class.mailer_class 34 | end 35 | end 36 | 37 | describe TestTestMailer, :action do 38 | it "gets the mailer from the test name" do 39 | assert_equal TestTestMailer, self.class.mailer_class 40 | end 41 | end 42 | 43 | describe TestTestMailer do 44 | describe "nested" do 45 | it "gets the mailer from the test name" do 46 | assert_equal TestTestMailer, self.class.mailer_class 47 | end 48 | end 49 | end 50 | 51 | describe TestTestMailer, :action do 52 | describe "nested" do 53 | it "gets the mailer from the test name" do 54 | assert_equal TestTestMailer, self.class.mailer_class 55 | end 56 | end 57 | end 58 | 59 | describe "TestTestMailer", :mailer do 60 | it "gets the mailer from the test name" do 61 | assert_equal TestTestMailer, self.class.mailer_class 62 | end 63 | end 64 | 65 | describe "TestTestMailer", :mailer do 66 | it "gets the mailer from the test name" do 67 | assert_equal TestTestMailer, self.class.mailer_class 68 | end 69 | end 70 | 71 | describe "AnotherCrazySymbolNameMailer", :mailer do 72 | tests :test_test_mailer 73 | 74 | it "gets the mailer after setting it with a symbol" do 75 | assert_equal TestTestMailer, self.class.mailer_class 76 | end 77 | end 78 | 79 | describe "AnotherCrazyStringNameMailer", :mailer do 80 | tests "test_test_mailer" 81 | 82 | it "gets the mailer after setting it with a string" do 83 | assert_equal TestTestMailer, self.class.mailer_class 84 | end 85 | end 86 | 87 | describe "Another Crazy Name", :mailer do 88 | tests TestTestMailer 89 | 90 | it "gets the mailer after setting it manually" do 91 | assert_equal TestTestMailer, self.class.mailer_class 92 | end 93 | end 94 | 95 | describe "Another Crazy Symbol Name", :mailer do 96 | tests :test_test_mailer 97 | 98 | it "gets the mailer after setting it with a symbol" do 99 | assert_equal TestTestMailer, self.class.mailer_class 100 | end 101 | end 102 | 103 | describe "Another Crazy String Name", :mailer do 104 | tests "test_test_mailer" 105 | 106 | it "gets the mailer after setting it with a string" do 107 | assert_equal TestTestMailer, self.class.mailer_class 108 | end 109 | end 110 | -------------------------------------------------------------------------------- /test/generators/test_model_generator.rb: -------------------------------------------------------------------------------- 1 | require "helper" 2 | require "generators/minitest/model/model_generator" 3 | 4 | class TestModelGenerator < GeneratorTest 5 | tests Minitest::Generators::ModelGenerator 6 | 7 | def test_model_generator 8 | output = run_generator %w[user --no-spec] 9 | assert_match %r{create test/models/user_test.rb}m, output 10 | 11 | Dir.chdir self.class.destination_root 12 | assert File.exist? "test/models/user_test.rb" 13 | 14 | contents = File.read "test/models/user_test.rb" 15 | assert_match(/class UserTest/m, contents) 16 | end 17 | 18 | def test_namespaced_model_generator 19 | output = run_generator %w[admin/user --no-spec] 20 | assert_match %r{create test/models/admin/user_test.rb}m, output 21 | 22 | Dir.chdir self.class.destination_root 23 | assert File.exist? "test/models/admin/user_test.rb" 24 | 25 | contents = File.read "test/models/admin/user_test.rb" 26 | assert_match(/class Admin::UserTest/m, contents) 27 | end 28 | 29 | if Rails::Generators.respond_to? :namespace 30 | def test_module_namespaced_model_generator 31 | assert_nil Rails::Generators.namespace 32 | Rails::Generators.namespace = TestApp 33 | 34 | output = run_generator %w[user --no-spec] 35 | assert_match %r{create test/models/test_app/user_test.rb}m, output 36 | 37 | Dir.chdir self.class.destination_root 38 | assert File.exist? "test/models/test_app/user_test.rb" 39 | 40 | contents = File.read "test/models/test_app/user_test.rb" 41 | assert_match(/module TestApp/m, contents) 42 | assert_match(/class UserTest/m, contents) 43 | ensure 44 | # Restore default namespace 45 | Rails::Generators.namespace = nil 46 | end 47 | end 48 | 49 | def test_model_generator_spec 50 | output = run_generator %w[user] 51 | assert_match %r{create test/models/user_test.rb}m, output 52 | 53 | Dir.chdir self.class.destination_root 54 | assert File.exist? "test/models/user_test.rb" 55 | 56 | contents = File.read "test/models/user_test.rb" 57 | assert_match(/describe User do/m, contents) 58 | end 59 | 60 | def test_namespaced_model_generator_spec 61 | output = run_generator %w[admin/user] 62 | assert_match %r{create test/models/admin/user_test.rb}m, output 63 | 64 | Dir.chdir self.class.destination_root 65 | assert File.exist? "test/models/admin/user_test.rb" 66 | 67 | contents = File.read "test/models/admin/user_test.rb" 68 | assert_match(/describe Admin::User do/m, contents) 69 | end 70 | 71 | def test_model_generator_fixture 72 | output = run_generator %w[user --fixture] 73 | assert_match %r{create test/fixtures/users.yml}m, output 74 | 75 | Dir.chdir self.class.destination_root 76 | assert File.exist? "test/fixtures/users.yml" 77 | end 78 | 79 | def test_namespaced_model_generator_fixture 80 | output = run_generator %w[admin/user --fixture] 81 | assert_match %r{create test/fixtures/admin/users.yml}m, output 82 | 83 | Dir.chdir self.class.destination_root 84 | assert File.exist? "test/fixtures/admin/users.yml" 85 | end 86 | 87 | def test_model_generator_skip_fixture 88 | output = run_generator %w[user --skip-fixture] 89 | refute_match %r{create test/fixtures/users.yml}m, output 90 | 91 | Dir.chdir self.class.destination_root 92 | refute File.exist? "test/fixtures/users.yml" 93 | end 94 | end 95 | -------------------------------------------------------------------------------- /test/helper.rb: -------------------------------------------------------------------------------- 1 | require "minitest/autorun" 2 | require "tmpdir" 3 | 4 | require "rails" 5 | require "rails/generators" 6 | 7 | require "sqlite3" 8 | require "active_record" 9 | 10 | require "action_controller" 11 | require "action_controller/railtie" 12 | 13 | require "action_cable" 14 | require "action_cable/connection/test_case" 15 | 16 | begin 17 | require "active_job" 18 | rescue LoadError 19 | end 20 | 21 | require "action_mailer" 22 | 23 | require "minitest-rails" 24 | require "rails/test_help" 25 | require "minitest/rails" 26 | 27 | require "minitest/focus" 28 | 29 | require "rails/generators/test_case" 30 | class GeneratorTest < ::Rails::Generators::TestCase 31 | setup :set_destination 32 | setup :prepare_destination 33 | teardown :cleanup_destination 34 | 35 | def set_destination 36 | self.class.destination Dir.mktmpdir 37 | end 38 | 39 | def cleanup_destination 40 | # puts "tree #{self.class.destination_root}" 41 | # puts `tree #{self.class.destination_root}` 42 | FileUtils.remove_entry self.class.destination_root 43 | end 44 | end 45 | 46 | module TestApp 47 | class Application < ::Rails::Application 48 | config.active_support.test_order = :random 49 | config.secret_key_base = "abc123" 50 | config.hosts << "www.example.com" 51 | config.eager_load = false 52 | end 53 | end 54 | 55 | TestApp::Application.initialize! 56 | 57 | class ApplicationController < ActionController::Base; end 58 | 59 | class ModelsController < ApplicationController 60 | def index 61 | render html: "Models" \ 62 | "

All Models

".html_safe 63 | end 64 | 65 | def new 66 | redirect_to "/models" 67 | end 68 | end 69 | 70 | module Admin 71 | class WidgetsController < ApplicationController; end 72 | end 73 | 74 | TestApp::Application.routes.draw do 75 | # root to: "models#index" 76 | resources :models 77 | namespace :admin do 78 | resources :widgets 79 | end 80 | end 81 | 82 | ActiveRecord::Base.establish_connection adapter: "sqlite3", database: ":memory:" 83 | 84 | class UserInviteJob < ActiveJob::Base 85 | def perform arg = nil; end 86 | end 87 | 88 | # Set test adapter and logger 89 | ActionCable.server.config.cable = { "adapter" => "test" } 90 | ActionCable.server.config.logger = Logger.new(nil) 91 | 92 | class MyAppChannel < ActionCable::Channel::Base 93 | end 94 | 95 | class MyAppConnection < ActionCable::Connection::Base 96 | def connect 97 | reject_unauthorized_connection 98 | end 99 | 100 | def disconnect 101 | # Any cleanup work needed when the cable connection is cut. 102 | end 103 | end 104 | 105 | require "action_mailer/test_case" 106 | 107 | # Emulate AV railtie 108 | require "action_view" 109 | ActionMailer::Base.include(ActionView::Layouts) 110 | 111 | # Show backtraces for deprecated behavior for quicker cleanup. 112 | ActiveSupport::Deprecation.debug = true 113 | 114 | # Disable available locale checks to avoid warnings running the test suite. 115 | I18n.enforce_available_locales = false 116 | 117 | class MyAppMailer < ActionMailer::Base 118 | def test 119 | @world = "Earth" 120 | mail body: render(inline: "Hello, <%= @world %>"), 121 | to: "test@example.com", 122 | from: "tester@example.com" 123 | end 124 | 125 | def test_args recipient, name 126 | mail body: render(inline: "Hello, #{name}"), 127 | to: recipient, 128 | from: "tester@example.com" 129 | end 130 | 131 | def test_parameter_args 132 | mail body: render(inline: "All is #{params[:all]}"), 133 | to: "test@example.com", 134 | from: "tester@example.com" 135 | end 136 | end 137 | 138 | class MyAppDeliveryJob < ActionMailer::MailDeliveryJob 139 | end 140 | 141 | class MyAppDeliveryMailer < MyAppMailer 142 | self.delivery_job = MyAppDeliveryJob 143 | end 144 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # minitest-rails 2 | 3 | Minitest integration for Rails 7.0 4 | 5 | [![CI](https://github.com/blowmage/minitest-rails/actions/workflows/ci.yml/badge.svg)](https://github.com/blowmage/minitest-rails/actions/workflows/ci.yml) 6 | [![Code Climate](https://codeclimate.com/github/blowmage/minitest-rails.png)](https://codeclimate.com/github/blowmage/minitest-rails) 7 | 8 | ## Install 9 | 10 | `gem install minitest-rails` 11 | 12 | This installs the following gems: 13 | 14 | * `minitest` 15 | 16 | ## Configure 17 | 18 | Create a new rails app: 19 | 20 | `rails new MyApp` 21 | 22 | ### Choosing a version 23 | 24 | This gem follows the versioning of Rails. 25 | If you are running Rails 7.0, specify the corresponding 7.0 release in the Gemfile. 26 | For example: 27 | 28 | ```ruby 29 | gem "minitest-rails", "~> 7.0.0" 30 | ``` 31 | 32 | If you are running Rails 6.x, specify the corresponding 6.x release in the Gemfile. 33 | For example, if you are using Rails 6.1 you will specify: 34 | 35 | ```ruby 36 | gem "minitest-rails", "~> 6.1.0" 37 | ``` 38 | 39 | If you are running Rails 5.x, specify the corresponding 5.x release in the Gemfile. 40 | For example, if you are using Rails 5.2 you will specify: 41 | 42 | ```ruby 43 | gem "minitest-rails", "~> 5.2.0" 44 | ``` 45 | 46 | Or, if you prefer to run the previous release for Rails 5.x, specify the 3.x release in the Gemfile: 47 | 48 | ```ruby 49 | gem "minitest-rails", "~> 3.0" 50 | ``` 51 | 52 | If you are running Rails 4.1 or 4.2, specify the 2.x release in the Gemfile: 53 | 54 | ```ruby 55 | gem "minitest-rails", "~> 2.0" 56 | ``` 57 | 58 | If you are running Rails 4.0 or earlier, you really need to upgrade. 59 | But if you are you need to specify the 1.x release in the Gemfile: 60 | 61 | ```ruby 62 | gem "minitest-rails", "~> 1.0" 63 | ``` 64 | 65 | ### Installing 66 | 67 | Next run the installation generator with the following: 68 | 69 | `rails generate minitest:install` 70 | 71 | This will add the `test_helper.rb` file to the `test` directory. 72 | 73 | ## Usage 74 | 75 | This project aims to enable Minitest within the Rails TestCase classes. 76 | Your test will continue to inherit from `ActiveSupport::TestCase`, which will now support the spec DSL. 77 | You can generate test files using the `Minitest::Spec` DSL with the standard model, controller, resource, and other generators: 78 | 79 | `rails generate model User` 80 | 81 | And you can specify generating the tests without the `Minitest::Spec` DSL on any of the generators by providing the `--no-spec` option: 82 | 83 | `rails generate model User --no-spec` 84 | 85 | And you can specify not generating the fixture for a model by providing the `--skip-fixture` option: 86 | 87 | `rails generate model User --skip-fixture` 88 | 89 | You can also set these as defaults by adding the following to the `config/application.rb` file: 90 | 91 | ```ruby 92 | config.generators do |g| 93 | g.test_framework :minitest, spec: false, fixture: false 94 | end 95 | ``` 96 | 97 | ## Running Tests 98 | 99 | To run your tests use the `rails test` that ship with rails. 100 | 101 | ## Get Involved 102 | 103 | Join the mailing list to get help or offer suggestions. 104 | 105 | https://groups.google.com/group/minitest-rails 106 | 107 | ## License 108 | 109 | Copyright (c) 2019 Mike Moore 110 | 111 | Permission is hereby granted, free of charge, to any person obtaining 112 | a copy of this software and associated documentation files (the 113 | "Software"), to deal in the Software without restriction, including 114 | without limitation the rights to use, copy, modify, merge, publish, 115 | distribute, sublicense, and/or sell copies of the Software, and to 116 | permit persons to whom the Software is furnished to do so, subject to 117 | the following conditions: 118 | 119 | The above copyright notice and this permission notice shall be 120 | included in all copies or substantial portions of the Software. 121 | 122 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 123 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 124 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 125 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 126 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 127 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 128 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 129 | -------------------------------------------------------------------------------- /lib/minitest/rails/assertions/active_job.rb: -------------------------------------------------------------------------------- 1 | class ActiveJob::TestCase 2 | # Asserts that the number of enqueued jobs matches the given number. 3 | # 4 | # def test_jobs 5 | # assert_enqueued_jobs 0 6 | # HelloJob.perform_later('david') 7 | # assert_enqueued_jobs 1 8 | # HelloJob.perform_later('abdelkader') 9 | # assert_enqueued_jobs 2 10 | # end 11 | # 12 | # If a block is passed, that block should cause the specified number of 13 | # jobs to be enqueued. 14 | # 15 | # def test_jobs_again 16 | # assert_enqueued_jobs 1 do 17 | # HelloJob.perform_later('cristian') 18 | # end 19 | # 20 | # assert_enqueued_jobs 2 do 21 | # HelloJob.perform_later('aaron') 22 | # HelloJob.perform_later('rafael') 23 | # end 24 | # end 25 | # 26 | # See also Minitest::Rails::Expectations#must_enqueue_jobs 27 | # 28 | # :method: assert_enqueued_jobs 29 | # :call-seq: assert_enqueued_jobs(number) 30 | 31 | ## 32 | # Asserts that no jobs have been enqueued. 33 | # 34 | # def test_jobs 35 | # refute_enqueued_jobs 36 | # HelloJob.perform_later('jeremy') 37 | # assert_enqueued_jobs 1 38 | # end 39 | # 40 | # If a block is passed, that block should not cause any job to be enqueued. 41 | # 42 | # def test_jobs_again 43 | # refute_enqueued_jobs do 44 | # # No job should be enqueued from this block 45 | # end 46 | # end 47 | # 48 | # Note: This assertion is simply a shortcut for: 49 | # 50 | # assert_enqueued_jobs 0, &block 51 | # 52 | # See also Minitest::Rails::Expectations#wont_enqueue_jobs 53 | # 54 | # :args: number 55 | alias refute_enqueued_jobs assert_no_enqueued_jobs 56 | 57 | ## 58 | # Asserts that the number of performed jobs matches the given number. 59 | # If no block is passed, perform_enqueued_jobsd 60 | # must be called around the job call. 61 | # 62 | # def test_jobs 63 | # assert_performed_jobs 0 64 | # 65 | # perform_enqueued_jobs do 66 | # HelloJob.perform_later('xavier') 67 | # end 68 | # assert_performed_jobs 1 69 | # 70 | # perform_enqueued_jobs do 71 | # HelloJob.perform_later('yves') 72 | # assert_performed_jobs 2 73 | # end 74 | # end 75 | # 76 | # If a block is passed, that block should cause the specified number of 77 | # jobs to be performed. 78 | # 79 | # def test_jobs_again 80 | # assert_performed_jobs 1 do 81 | # HelloJob.perform_later('robin') 82 | # end 83 | # 84 | # assert_performed_jobs 2 do 85 | # HelloJob.perform_later('carlos') 86 | # HelloJob.perform_later('sean') 87 | # end 88 | # end 89 | # 90 | # See also Minitest::Rails::Expectations#must_perform_jobs 91 | # 92 | # :method: assert_performed_jobs 93 | # :call-seq: assert_performed_jobs(number) 94 | 95 | ## 96 | # Asserts that no jobs have been performed. 97 | # 98 | # def test_jobs 99 | # refute_performed_jobs 100 | # 101 | # perform_enqueued_jobs do 102 | # HelloJob.perform_later('matthew') 103 | # assert_performed_jobs 1 104 | # end 105 | # end 106 | # 107 | # If a block is passed, that block should not cause any job to be performed. 108 | # 109 | # def test_jobs_again 110 | # refute_performed_jobs do 111 | # # No job should be performed from this block 112 | # end 113 | # end 114 | # 115 | # Note: This assertion is simply a shortcut for: 116 | # 117 | # assert_performed_jobs 0, &block 118 | # 119 | # See also Minitest::Rails::Expectations#wont_perform_jobs 120 | # 121 | # :args: number 122 | alias refute_performed_jobs assert_no_performed_jobs 123 | 124 | ## 125 | # Asserts that the job passed in the block has been enqueued with the given arguments. 126 | # 127 | # def test_assert_enqueued_with 128 | # assert_enqueued_with(job: MyJob, args: [1,2,3], queue: 'low') do 129 | # MyJob.perform_later(1,2,3) 130 | # end 131 | # end 132 | # 133 | # See also Minitest::Rails::Expectations#must_enqueue_with 134 | # 135 | # :method: assert_enqueued_with 136 | # :call-seq: assert_enqueued_with(args) 137 | 138 | ## 139 | # Asserts that the job passed in the block has been performed with the given arguments. 140 | # 141 | # def test_assert_performed_with 142 | # assert_performed_with(job: MyJob, args: [1,2,3], queue: 'high') do 143 | # MyJob.perform_later(1,2,3) 144 | # end 145 | # end 146 | # 147 | # See also Minitest::Rails::Expectations#must_perform_with 148 | # 149 | # :method: assert_performed_with 150 | # :call-seq: assert_performed_with(args) 151 | end 152 | -------------------------------------------------------------------------------- /lib/minitest/rails.rb: -------------------------------------------------------------------------------- 1 | gem "minitest" 2 | require "minitest" 3 | require "minitest/spec" 4 | require "minitest/mock" 5 | require "minitest/hell" if ENV["MT_HELL"] 6 | 7 | require "active_support/test_case" 8 | require "active_support/testing/constant_lookup" 9 | 10 | class ActiveSupport::TestCase 11 | # Add and configure the spec DSL 12 | # Remove describe method if present 13 | if respond_to?(:describe) && 14 | method(:describe).owner == ActiveSupport::TestCase 15 | class << self 16 | remove_method :describe 17 | end 18 | end 19 | 20 | # Add spec DSL 21 | extend Minitest::Spec::DSL 22 | 23 | # Resolve constants from the test name when using the spec DSL 24 | include ActiveSupport::Testing::ConstantLookup 25 | 26 | # Use AS::TC for the base class when describing a model 27 | if defined? ActiveRecord 28 | register_spec_type(self) do |desc| 29 | desc < ActiveRecord::Base if desc.is_a?(Class) 30 | end 31 | end 32 | 33 | # Use AS::TC for the base class when described using :model 34 | register_spec_type(self) do |_desc, *addl| 35 | addl.include? :model 36 | end 37 | end 38 | 39 | require "action_view/test_case" 40 | 41 | class ActionView::TestCase 42 | # Use AV::TC for the base class when described using :view or :helper 43 | register_spec_type(self) do |_desc, *addl| 44 | addl.include?(:view) || addl.include?(:helper) 45 | end 46 | end 47 | 48 | if defined? ActiveJob 49 | # TODO: require? 50 | 51 | class ActiveJob::TestCase 52 | # Use AJ::TC for the base when describing a job 53 | register_spec_type(self) do |desc| 54 | desc < ActiveJob::Base if desc.is_a?(Class) 55 | end 56 | 57 | # Use AJ::TC for the base class when described using :job 58 | register_spec_type(self) do |_desc, *addl| 59 | addl.include? :job 60 | end 61 | end 62 | end 63 | 64 | if defined? ActionMailer 65 | require "action_mailer/test_helper" 66 | require "action_mailer/test_case" 67 | 68 | class ActionMailer::TestCase 69 | # Use AM::TC for the base class when describing a mailer 70 | register_spec_type(self) do |desc| 71 | desc < ActionMailer::Base if desc.is_a?(Class) 72 | end 73 | 74 | # Use AM::TC for the base class when described using :mailer 75 | register_spec_type(self) do |_desc, *addl| 76 | addl.include? :mailer 77 | end 78 | end 79 | end 80 | 81 | require "action_dispatch/testing/integration" 82 | 83 | class ActionDispatch::IntegrationTest 84 | # Use AD:IT for the base class when describing a controller 85 | register_spec_type(self) do |desc| 86 | desc < ActionController::Metal if desc.is_a?(Class) 87 | end 88 | 89 | # Use AD:IT for the base class when described using :integration 90 | register_spec_type(self) do |_desc, *addl| 91 | addl.include? :integration 92 | end 93 | end 94 | 95 | # TODO: Rails::Generators::TestCase require? 96 | 97 | class Rails::Generators::TestCase 98 | # Use R::G::TC for the base class when describing a generator 99 | register_spec_type(self) do |desc| 100 | desc < Rails::Generators::Base if desc.is_a?(Class) 101 | end 102 | 103 | # Use R::G::TC for the base class when described using :generator 104 | register_spec_type(self) do |_desc, *addl| 105 | addl.include? :generator 106 | end 107 | end 108 | 109 | if defined? ActionCable 110 | # TODO: require? 111 | 112 | class ActionCable::Channel::TestCase 113 | # Use AC::Ch::TC for the base class when describing a channel 114 | register_spec_type(self) do |desc| 115 | desc < ActionCable::Channel::Base if desc.is_a?(Class) 116 | end 117 | 118 | # Use AC::Ch::TC for the base class when described using :channel 119 | register_spec_type(self) do |_desc, *addl| 120 | addl.include? :channel 121 | end 122 | end 123 | 124 | class ActionCable::Connection::TestCase 125 | # Use AC::Co::TC for the base class when describing a connection 126 | register_spec_type(self) do |desc| 127 | desc < ActionCable::Connection::Base if desc.is_a?(Class) 128 | end 129 | 130 | # Use AC::Co::TC for the base class when described using :connection 131 | register_spec_type(self) do |_desc, *addl| 132 | addl.include? :connection 133 | end 134 | end 135 | end 136 | 137 | ################################################################################ 138 | # Assertions and Expectations 139 | ################################################################################ 140 | 141 | require "minitest/rails/assertions" 142 | require "minitest/rails/expectations" 143 | 144 | ################################################################################ 145 | # Support Rails parallelize 146 | ################################################################################ 147 | 148 | require "minitest/rails/parallelize" 149 | 150 | # :stopdoc: 151 | 152 | ################################################################################ 153 | # Run load hooks so that other gems can register spec types 154 | ################################################################################ 155 | 156 | ActiveSupport.run_load_hooks(:minitest, ActiveSupport::TestCase) 157 | -------------------------------------------------------------------------------- /lib/minitest/rails/assertions/action_mailer.rb: -------------------------------------------------------------------------------- 1 | class ActionMailer::TestCase 2 | ## 3 | # Asserts that the number of emails sent matches the given number. 4 | # 5 | # def test_emails 6 | # assert_emails 0 7 | # ContactMailer.welcome.deliver_now 8 | # assert_emails 1 9 | # ContactMailer.welcome.deliver_now 10 | # assert_emails 2 11 | # end 12 | # 13 | # If a block is passed, that block should cause the specified number of 14 | # emails to be sent. 15 | # 16 | # def test_emails_again 17 | # assert_emails 1 do 18 | # ContactMailer.welcome.deliver_now 19 | # end 20 | # 21 | # assert_emails 2 do 22 | # ContactMailer.welcome.deliver_now 23 | # ContactMailer.welcome.deliver_later 24 | # end 25 | # end 26 | # 27 | # See also Minitest::Rails::Expectations::ActionMailer#must_have_emails 28 | # See https://api.rubyonrails.org/v7.0/classes/ActionMailer/TestHelper.html#method-i-assert_emails 29 | # 30 | # :method: assert_emails 31 | # :call-seq: assert_emails(number, &block) 32 | 33 | # Asserts that no emails have been sent. 34 | # 35 | # def test_emails 36 | # refute_emails 37 | # ContactMailer.welcome.deliver_now 38 | # assert_emails 1 39 | # end 40 | # 41 | # If a block is passed, that block should not cause any emails to be sent. 42 | # 43 | # def test_emails_again 44 | # refute_emails do 45 | # # No emails should be sent from this block 46 | # end 47 | # end 48 | # 49 | # Note: This assertion is simply a shortcut for: 50 | # 51 | # assert_emails 0, &block 52 | # 53 | # See also Minitest::Rails::Expectations::ActionMailer#wont_have_emails 54 | # See https://api.rubyonrails.org/v7.0/classes/ActionMailer/TestHelper.html#method-i-assert_no_emails 55 | # 56 | # :method: refute_emails 57 | # :call-seq: refute_emails(&block) 58 | alias refute_emails assert_no_emails 59 | 60 | ## 61 | # Asserts that the number of emails enqueued for later delivery matches 62 | # the given number. 63 | # 64 | # def test_emails 65 | # assert_enqueued_emails 0 66 | # ContactMailer.welcome.deliver_later 67 | # assert_enqueued_emails 1 68 | # ContactMailer.welcome.deliver_later 69 | # assert_enqueued_emails 2 70 | # end 71 | # 72 | # If a block is passed, that block should cause the specified number of 73 | # emails to be enqueued. 74 | # 75 | # def test_emails_again 76 | # assert_enqueued_emails 1 do 77 | # ContactMailer.welcome.deliver_later 78 | # end 79 | # 80 | # assert_enqueued_emails 2 do 81 | # ContactMailer.welcome.deliver_later 82 | # ContactMailer.welcome.deliver_later 83 | # end 84 | # end 85 | # 86 | # See also Minitest::Rails::Expectations::ActionMailer#must_have_enqueued_emails 87 | # See https://api.rubyonrails.org/v7.0/classes/ActionMailer/TestHelper.html#method-i-assert_enqueued_emails 88 | # 89 | # :method: assert_enqueued_emails 90 | # :call-seq: assert_enqueued_emails(number, &block) 91 | 92 | ## 93 | # Asserts that a specific email has been enqueued, optionally 94 | # matching arguments. 95 | # 96 | # def test_email 97 | # ContactMailer.welcome.deliver_later 98 | # assert_enqueued_email_with ContactMailer, :welcome 99 | # end 100 | # 101 | # def test_email_with_arguments 102 | # ContactMailer.welcome("Hello", "Goodbye").deliver_later 103 | # assert_enqueued_email_with ContactMailer, :welcome, args: ["Hello", "Goodbye"] 104 | # end 105 | # 106 | # If a block is passed, that block should cause the specified email 107 | # to be enqueued. 108 | # 109 | # def test_email_in_block 110 | # assert_enqueued_email_with ContactMailer, :welcome do 111 | # ContactMailer.welcome.deliver_later 112 | # end 113 | # end 114 | # 115 | # If +args+ is provided as a Hash, a parameterized email is matched. 116 | # 117 | # def test_parameterized_email 118 | # assert_enqueued_email_with ContactMailer, :welcome, 119 | # args: {email: 'user@example.com'} do 120 | # ContactMailer.with(email: 'user@example.com').welcome.deliver_later 121 | # end 122 | # end 123 | # 124 | # See also Minitest::Rails::Expectations::ActionMailer#must_enqueue_email_with 125 | # See https://api.rubyonrails.org/v7.0/classes/ActionMailer/TestHelper.html#method-i-assert_enqueued_email_with 126 | # 127 | # :method: assert_enqueued_email_with 128 | # :call-seq: assert_enqueued_email_with(mailer, method, args: nil, queue: "mailers", &block) 129 | 130 | ## 131 | # Asserts that no emails are enqueued for later delivery. 132 | # 133 | # def test_no_emails 134 | # refute_enqueued_emails 135 | # ContactMailer.welcome.deliver_later 136 | # assert_enqueued_emails 1 137 | # end 138 | # 139 | # If a block is provided, it should not cause any emails to be enqueued. 140 | # 141 | # def test_no_emails 142 | # refute_enqueued_emails do 143 | # # No emails should be enqueued from this block 144 | # end 145 | # end 146 | # 147 | # See also Minitest::Rails::Expectations::ActionMailer#wont_have_enqueued_emails 148 | # See https://api.rubyonrails.org/v7.0/classes/ActionMailer/TestHelper.html#method-i-assert_no_enqueued_emails 149 | # 150 | # :method: refute_enqueued_emails 151 | # :call-seq: refute_enqueued_emails(&block) 152 | alias refute_enqueued_emails assert_no_enqueued_emails 153 | end 154 | -------------------------------------------------------------------------------- /lib/minitest/rails/expectations/active_job.rb: -------------------------------------------------------------------------------- 1 | require "active_support/concern" 2 | 3 | module Minitest 4 | module Rails 5 | module Expectations 6 | # This exists as a module to allow easy mixing into classes 7 | # other than ActiveJob::TestCase where you might want to do 8 | # job testing e.g. in an Active Record model which triggers 9 | # jobs in a callback. 10 | module ActiveJob 11 | ## 12 | # Expects that the number of enqueued jobs matches the given number. 13 | # 14 | # def test_jobs 15 | # must_enqueue_jobs 0 16 | # HelloJob.perform_later('david') 17 | # must_enqueue_jobs 1 18 | # HelloJob.perform_later('abdelkader') 19 | # must_enqueue_jobs 2 20 | # end 21 | # 22 | # If a block is passed, that block should cause the specified number of 23 | # jobs to be enqueued. 24 | # 25 | # def test_jobs_again 26 | # must_enqueue_jobs 1 do 27 | # HelloJob.perform_later('cristian') 28 | # end 29 | # 30 | # must_enqueue_jobs 2 do 31 | # HelloJob.perform_later('aaron') 32 | # HelloJob.perform_later('rafael') 33 | # end 34 | # end 35 | # 36 | # See also ActiveJob::TestCase#assert_enqueued_jobs 37 | # 38 | # :method: must_enqueue_jobs 39 | # :call-seq: must_enqueue_jobs(number) 40 | 41 | ## 42 | # Expects that no jobs have been enqueued. 43 | # 44 | # def test_jobs 45 | # wont_enqueue_jobs 46 | # HelloJob.perform_later('jeremy') 47 | # must_enqueue_jobs 1 48 | # end 49 | # 50 | # If a block is passed, that block should not cause any job to be enqueued. 51 | # 52 | # def test_jobs_again 53 | # wont_enqueue_jobs do 54 | # # No job should be enqueued from this block 55 | # end 56 | # end 57 | # 58 | # Note: This expectation is simply a shortcut for: 59 | # 60 | # must_enqueue_jobs 0, &block 61 | # 62 | # See also ActiveJob::TestCase#refute_enqueued_jobs 63 | # 64 | # :method: wont_enqueue_jobs 65 | # :call-seq: wont_enqueue_jobs(number) 66 | 67 | ## 68 | # Expects that the number of performed jobs matches the given number. 69 | # If no block is passed, perform_enqueued_jobsd 70 | # must be called around the job call. 71 | # 72 | # def test_jobs 73 | # must_perform_jobs 0 74 | # 75 | # perform_enqueued_jobs do 76 | # HelloJob.perform_later('xavier') 77 | # end 78 | # must_perform_jobs 1 79 | # 80 | # perform_enqueued_jobs do 81 | # HelloJob.perform_later('yves') 82 | # must_perform_jobs 2 83 | # end 84 | # end 85 | # 86 | # If a block is passed, that block should cause the specified number of 87 | # jobs to be performed. 88 | # 89 | # def test_jobs_again 90 | # must_perform_jobs 1 do 91 | # HelloJob.perform_later('robin') 92 | # end 93 | # 94 | # must_perform_jobs 2 do 95 | # HelloJob.perform_later('carlos') 96 | # HelloJob.perform_later('sean') 97 | # end 98 | # end 99 | # 100 | # See also ActiveJob::TestCase#assert_performed_jobs 101 | # 102 | # :method: must_perform_jobs 103 | # :call-seq: must_perform_jobs(number) 104 | 105 | ## 106 | # Expects that no jobs have been performed. 107 | # 108 | # def test_jobs 109 | # wont_perform_jobs 110 | # 111 | # perform_enqueued_jobs do 112 | # HelloJob.perform_later('matthew') 113 | # must_perform_jobs 1 114 | # end 115 | # end 116 | # 117 | # If a block is passed, that block should not cause any job to be performed. 118 | # 119 | # def test_jobs_again 120 | # wont_perform_jobs do 121 | # # No job should be performed from this block 122 | # end 123 | # end 124 | # 125 | # Note: This assertion is simply a shortcut for: 126 | # 127 | # must_perform_jobs 0, &block 128 | # 129 | # See also ActiveJob::TestCase#refute_performed_jobs 130 | # 131 | # :method: wont_perform_jobs 132 | # :call-seq: wont_perform_jobs(number) 133 | 134 | ## 135 | # Expects that the job passed in the block has been enqueued with the given arguments. 136 | # 137 | # def test_must_enqueue_with 138 | # must_enqueue_with(job: MyJob, args: [1,2,3], queue: 'low') do 139 | # MyJob.perform_later(1,2,3) 140 | # end 141 | # end 142 | # 143 | # See also Minitest::Rails::Expectations#assert_enqueued_with 144 | # 145 | # :method: must_enqueue_with 146 | # :call-seq: must_enqueue_with(args) 147 | 148 | ## 149 | # Expects that the job passed in the block has been performed with the given arguments. 150 | # 151 | # def test_must_perform_with 152 | # must_perform_with(job: MyJob, args: [1,2,3], queue: 'high') do 153 | # MyJob.perform_later(1,2,3) 154 | # end 155 | # end 156 | # 157 | # See also Minitest::Rails::Expectations#assert_performed_with 158 | # 159 | # :method: must_perform_with 160 | # :call-seq: must_perform_with(args) 161 | 162 | extend ::ActiveSupport::Concern 163 | include ::ActiveJob::TestHelper 164 | 165 | included do 166 | alias_method :must_enqueue_jobs, :assert_enqueued_jobs 167 | alias_method :must_perform_jobs, :assert_performed_jobs 168 | alias_method :wont_enqueue_jobs, :assert_no_enqueued_jobs 169 | alias_method :wont_perform_jobs, :assert_no_performed_jobs 170 | alias_method :must_enqueue_with, :assert_enqueued_with 171 | alias_method :must_perform_with, :assert_performed_with 172 | end 173 | end 174 | end 175 | end 176 | end 177 | 178 | unless ENV["MT_NO_EXPECTATIONS"] 179 | class ActiveJob::TestCase # :nodoc: 180 | include Minitest::Rails::Expectations::ActiveJob 181 | end 182 | end 183 | -------------------------------------------------------------------------------- /lib/minitest/rails/expectations/action_mailer.rb: -------------------------------------------------------------------------------- 1 | require "active_support/concern" 2 | 3 | module Minitest 4 | module Rails 5 | module Expectations 6 | module ActionMailer 7 | ## 8 | # Asserts that the number of emails sent matches the given number. 9 | # 10 | # def test_emails 11 | # must_have_emails 0 12 | # ContactMailer.welcome.deliver_now 13 | # must_have_emails 1 14 | # ContactMailer.welcome.deliver_now 15 | # must_have_emails 2 16 | # end 17 | # 18 | # If a block is passed, that block should cause the specified number of 19 | # emails to be sent. 20 | # 21 | # def test_emails_again 22 | # must_have_emails 1 do 23 | # ContactMailer.welcome.deliver_now 24 | # end 25 | # 26 | # must_have_emails 2 do 27 | # ContactMailer.welcome.deliver_now 28 | # ContactMailer.welcome.deliver_later 29 | # end 30 | # end 31 | # 32 | # See also ActionMailer::TestClass#assert_emails 33 | # See https://api.rubyonrails.org/v7.0/classes/ActionMailer/TestHelper.html#method-i-assert_emails 34 | # 35 | # :method: must_have_emails 36 | # :call-seq: must_have_emails(number, &block) 37 | 38 | # Asserts that no emails have been sent. 39 | # 40 | # def test_emails 41 | # wont_have_emails 42 | # ContactMailer.welcome.deliver_now 43 | # must_have_emails 1 44 | # end 45 | # 46 | # If a block is passed, that block should not cause any emails to be sent. 47 | # 48 | # def test_emails_again 49 | # wont_have_emails do 50 | # # No emails should be sent from this block 51 | # end 52 | # end 53 | # 54 | # Note: This assertion is simply a shortcut for: 55 | # 56 | # must_have_emails 0, &block 57 | # 58 | # See also ActionMailer::TestClass#wont_have_emails 59 | # See https://api.rubyonrails.org/v7.0/classes/ActionMailer/TestHelper.html#method-i-assert_no_emails 60 | # 61 | # :method: wont_have_emails 62 | # :call-seq: wont_have_emails(&block) 63 | 64 | ## 65 | # Asserts that the number of emails enqueued for later delivery matches 66 | # the given number. 67 | # 68 | # def test_emails 69 | # must_have_enqueued_emails 0 70 | # ContactMailer.welcome.deliver_later 71 | # must_have_enqueued_emails 1 72 | # ContactMailer.welcome.deliver_later 73 | # must_have_enqueued_emails 2 74 | # end 75 | # 76 | # If a block is passed, that block should cause the specified number of 77 | # emails to be enqueued. 78 | # 79 | # def test_emails_again 80 | # must_have_enqueued_emails 1 do 81 | # ContactMailer.welcome.deliver_later 82 | # end 83 | # 84 | # must_have_enqueued_emails 2 do 85 | # ContactMailer.welcome.deliver_later 86 | # ContactMailer.welcome.deliver_later 87 | # end 88 | # end 89 | # 90 | # See also ActionMailer::TestClass#assert_enqueued_emails 91 | # See https://api.rubyonrails.org/v7.0/classes/ActionMailer/TestHelper.html#method-i-assert_enqueued_emails 92 | # 93 | # :method: must_have_enqueued_emails 94 | # :call-seq: must_have_enqueued_emails(number, &block) 95 | 96 | ## 97 | # Asserts that a specific email has been enqueued, optionally 98 | # matching arguments. 99 | # 100 | # def test_email 101 | # ContactMailer.welcome.deliver_later 102 | # must_enqueue_email_with ContactMailer, :welcome 103 | # end 104 | # 105 | # def test_email_with_arguments 106 | # ContactMailer.welcome("Hello", "Goodbye").deliver_later 107 | # must_enqueue_email_with ContactMailer, :welcome, args: ["Hello", "Goodbye"] 108 | # end 109 | # 110 | # If a block is passed, that block should cause the specified email 111 | # to be enqueued. 112 | # 113 | # def test_email_in_block 114 | # must_enqueue_email_with ContactMailer, :welcome do 115 | # ContactMailer.welcome.deliver_later 116 | # end 117 | # end 118 | # 119 | # If +args+ is provided as a Hash, a parameterized email is matched. 120 | # 121 | # def test_parameterized_email 122 | # must_enqueue_email_with ContactMailer, :welcome, 123 | # args: {email: 'user@example.com'} do 124 | # ContactMailer.with(email: 'user@example.com').welcome.deliver_later 125 | # end 126 | # end 127 | # 128 | # See also ActionMailer::TestClass#assert_enqueued_email_with 129 | # See https://api.rubyonrails.org/v7.0/classes/ActionMailer/TestHelper.html#method-i-assert_enqueued_email_with 130 | # 131 | # :method: must_enqueue_email_with 132 | # :call-seq: must_enqueue_email_with(mailer, method, args: nil, queue: "mailers", &block) 133 | 134 | ## 135 | # Asserts that no emails are enqueued for later delivery. 136 | # 137 | # def test_no_emails 138 | # wont_have_enqueued_emails 139 | # ContactMailer.welcome.deliver_later 140 | # wont_have_enqueued_emails 1 141 | # end 142 | # 143 | # If a block is provided, it should not cause any emails to be enqueued. 144 | # 145 | # def test_no_emails 146 | # wont_have_enqueued_emails do 147 | # # No emails should be enqueued from this block 148 | # end 149 | # end 150 | # 151 | # See also ActionMailer::TestClass#assert_no_enqueued_emails 152 | # See https://api.rubyonrails.org/v7.0/classes/ActionMailer/TestHelper.html#method-i-assert_no_enqueued_emails 153 | # 154 | # :method: wont_have_enqueued_emails 155 | # :call-seq: wont_have_enqueued_emails(&block) 156 | 157 | extend ::ActiveSupport::Concern 158 | 159 | included do 160 | alias_method :must_have_emails, :assert_emails 161 | alias_method :wont_have_emails, :assert_no_emails 162 | alias_method :must_have_enqueued_emails, :assert_enqueued_emails 163 | alias_method :must_enqueue_email_with, :assert_enqueued_email_with 164 | alias_method :wont_have_enqueued_emails, :assert_no_enqueued_emails 165 | end 166 | end 167 | end 168 | end 169 | end 170 | 171 | unless ENV["MT_NO_EXPECTATIONS"] 172 | class ActionMailer::TestCase # :nodoc: 173 | include Minitest::Rails::Expectations::ActionMailer 174 | end 175 | end 176 | -------------------------------------------------------------------------------- /lib/minitest/rails/expectations/action_cable.rb: -------------------------------------------------------------------------------- 1 | require "active_support/concern" 2 | 3 | module Minitest 4 | module Rails 5 | module Expectations 6 | module ActionCable 7 | module TestHelper 8 | ## 9 | # Asserts that the number of broadcasted messages to the stream matches the given number. 10 | # 11 | # def test_broadcasts 12 | # must_have_broadcasts 'messages', 0 13 | # ActionCable.server.broadcast 'messages', { text: 'hello' } 14 | # must_have_broadcasts 'messages', 1 15 | # ActionCable.server.broadcast 'messages', { text: 'world' } 16 | # must_have_broadcasts 'messages', 2 17 | # end 18 | # 19 | # If a block is passed, that block should cause the specified number of 20 | # messages to be broadcasted. 21 | # 22 | # def test_broadcasts_again 23 | # must_have_broadcasts('messages', 1) do 24 | # ActionCable.server.broadcast 'messages', { text: 'hello' } 25 | # end 26 | # 27 | # must_have_broadcasts('messages', 2) do 28 | # ActionCable.server.broadcast 'messages', { text: 'hi' } 29 | # ActionCable.server.broadcast 'messages', { text: 'how are you?' } 30 | # end 31 | # end 32 | # 33 | # See also ActionCable::TestHelper#assert_broadcasts 34 | # See https://api.rubyonrails.org/v7.0/classes/ActionCable/TestHelper.html#method-i-assert_broadcasts 35 | # 36 | # :method: must_have_broadcasts 37 | # :call-seq: must_have_broadcasts(stream, number) 38 | 39 | ## 40 | # Asserts that no messages have been sent to the stream. 41 | # 42 | # def test_no_broadcasts 43 | # wont_have_broadcasts 'messages' 44 | # ActionCable.server.broadcast 'messages', { text: 'hi' } 45 | # must_have_broadcasts 'messages', 1 46 | # end 47 | # 48 | # If a block is passed, that block should not cause any message to be sent. 49 | # 50 | # def test_broadcasts_again 51 | # wont_have_broadcasts 'messages' do 52 | # # No job messages should be sent from this block 53 | # end 54 | # end 55 | # 56 | # Note: This assertion is simply a shortcut for: 57 | # 58 | # must_have_broadcasts 'messages', 0, &block 59 | # 60 | # See also ActionCable::TestHelper#wont_have_broadcasts 61 | # See https://api.rubyonrails.org/v7.0/classes/ActionCable/TestHelper.html#method-i-assert_no_broadcasts 62 | # 63 | # :method: wont_have_broadcasts 64 | # :call-seq: wont_have_broadcasts(stream, &block) 65 | 66 | ## 67 | # Asserts that the specified message has been sent to the stream. 68 | # 69 | # def test_assert_transmitted_message 70 | # ActionCable.server.broadcast 'messages', text: 'hello' 71 | # must_broadcast_on('messages', text: 'hello') 72 | # end 73 | # 74 | # If a block is passed, that block should cause a message with the specified data to be sent. 75 | # 76 | # def test_assert_broadcast_on_again 77 | # must_broadcast_on('messages', text: 'hello') do 78 | # ActionCable.server.broadcast 'messages', text: 'hello' 79 | # end 80 | # end 81 | # 82 | # See also ActionCable::TestHelper#assert_broadcast_on 83 | # See https://api.rubyonrails.org/v7.0/classes/ActionCable/TestHelper.html#method-i-assert_broadcast_on 84 | # 85 | # :method: must_broadcast_on 86 | # :call-seq: must_broadcast_on(stream, data) 87 | 88 | extend ::ActiveSupport::Concern 89 | 90 | included do 91 | alias_method :must_have_broadcasts, :assert_broadcasts 92 | alias_method :wont_have_broadcasts, :assert_no_broadcasts 93 | alias_method :must_broadcast_on, :assert_broadcast_on 94 | end 95 | end 96 | 97 | module Channel 98 | ## 99 | # Asserts that no streams have been started. 100 | # 101 | # def test_assert_no_started_stream 102 | # subscribe 103 | # wont_have_streams 104 | # end 105 | # 106 | # See also ActionCable::Channel::TestCase#assert_no_streams 107 | # See https://api.rubyonrails.org/v7.0/classes/ActionCable/Channel/TestCase/Behavior.html#method-i-assert_no_streams 108 | # 109 | # :method: wont_have_streams 110 | 111 | ## 112 | # Asserts that the specified stream has been started. 113 | # 114 | # def test_assert_started_stream 115 | # subscribe 116 | # must_have_streams 'messages' 117 | # end 118 | # 119 | # See also ActionCable::Channel::TestCase#assert_has_stream 120 | # See https://api.rubyonrails.org/v7.0/classes/ActionCable/Channel/TestCase/Behavior.html#method-i-assert_has_stream 121 | # 122 | # :method: must_have_streams 123 | # :call-seq: must_have_streams(stream) 124 | 125 | ## 126 | # Asserts that the specified stream for a model has started. 127 | # 128 | # def test_assert_started_stream_for 129 | # subscribe id: 42 130 | # must_have_stream_for User.find(42) 131 | # end 132 | # 133 | # See also ActionCable::Channel::TestCase#assert_has_stream_for 134 | # See https://api.rubyonrails.org/v7.0/classes/ActionCable/Channel/TestCase/Behavior.html#method-i-assert_has_stream_for 135 | # 136 | # :method: must_have_stream_for 137 | # :call-seq: must_have_stream_for(object) 138 | 139 | extend ::ActiveSupport::Concern 140 | 141 | included do 142 | alias_method :wont_have_streams, :assert_no_streams 143 | alias_method :must_have_streams, :assert_has_stream 144 | alias_method :must_have_stream_for, :assert_has_stream_for 145 | end 146 | end 147 | 148 | module Connection 149 | ## 150 | # Asserts that the connection is rejected (via +reject_unauthorized_connection+). 151 | # 152 | # describe "Application Connections", :connection do 153 | # it "connects with proper cookie" do 154 | # # Simulate the connection request with a cookie. 155 | # cookies["user_id"] = users(:john).id 156 | # 157 | # connect 158 | # 159 | # # Assert the connection identifier matches the fixture. 160 | # value(connection.user.id).must_equal users(:john).id 161 | # end 162 | # 163 | # it "rejects connection without proper cookie" do 164 | # must_reject_connection { connect } 165 | # end 166 | # end 167 | # 168 | # See also ActionCable::Connection::TestCase#assert_reject_connection 169 | # See https://api.rubyonrails.org/v7.0/classes/ActionCable/Connection/Assertions.html#method-i-assert_reject_connection 170 | # 171 | # :method: must_reject_connection 172 | 173 | extend ::ActiveSupport::Concern 174 | 175 | included do 176 | alias_method :must_reject_connection, :assert_reject_connection 177 | end 178 | end 179 | end 180 | end 181 | end 182 | end 183 | 184 | unless ENV["MT_NO_EXPECTATIONS"] 185 | class ActionCable::TestCase # :nodoc: 186 | include Minitest::Rails::Expectations::ActionCable::TestHelper 187 | end 188 | 189 | class ActionCable::Channel::TestCase # :nodoc: 190 | include Minitest::Rails::Expectations::ActionCable::TestHelper 191 | include Minitest::Rails::Expectations::ActionCable::Channel 192 | end 193 | 194 | class ActionCable::Connection::TestCase # :nodoc: 195 | include Minitest::Rails::Expectations::ActionCable::Connection 196 | end 197 | end 198 | -------------------------------------------------------------------------------- /lib/minitest/rails/assertions/action_cable.rb: -------------------------------------------------------------------------------- 1 | class ActionCable::TestCase 2 | ## 3 | # Asserts that the number of broadcasted messages to the stream matches the given number. 4 | # 5 | # def test_broadcasts 6 | # assert_broadcasts 'messages', 0 7 | # ActionCable.server.broadcast 'messages', { text: 'hello' } 8 | # assert_broadcasts 'messages', 1 9 | # ActionCable.server.broadcast 'messages', { text: 'world' } 10 | # assert_broadcasts 'messages', 2 11 | # end 12 | # 13 | # If a block is passed, that block should cause the specified number of 14 | # messages to be broadcasted. 15 | # 16 | # def test_broadcasts_again 17 | # assert_broadcasts('messages', 1) do 18 | # ActionCable.server.broadcast 'messages', { text: 'hello' } 19 | # end 20 | # 21 | # assert_broadcasts('messages', 2) do 22 | # ActionCable.server.broadcast 'messages', { text: 'hi' } 23 | # ActionCable.server.broadcast 'messages', { text: 'how are you?' } 24 | # end 25 | # end 26 | # 27 | # See also Minitest::Rails::Expectations::ActionCable::TestHelper#must_have_broadcasts 28 | # See https://api.rubyonrails.org/v7.0/classes/ActionCable/TestHelper.html#method-i-assert_broadcasts 29 | # 30 | # :method: assert_broadcasts 31 | # :call-seq: assert_broadcasts(stream, number) 32 | 33 | ## 34 | # Asserts that no messages have been sent to the stream. 35 | # 36 | # def test_no_broadcasts 37 | # refute_broadcasts 'messages' 38 | # ActionCable.server.broadcast 'messages', { text: 'hi' } 39 | # assert_broadcasts 'messages', 1 40 | # end 41 | # 42 | # If a block is passed, that block should not cause any message to be sent. 43 | # 44 | # def test_broadcasts_again 45 | # refute_broadcasts 'messages' do 46 | # # No job messages should be sent from this block 47 | # end 48 | # end 49 | # 50 | # Note: This assertion is simply a shortcut for: 51 | # 52 | # assert_broadcasts 'messages', 0, &block 53 | # 54 | # See also Minitest::Rails::Expectations::ActionCable::TestHelper#wont_have_broadcasts 55 | # See https://api.rubyonrails.org/v7.0/classes/ActionCable/TestHelper.html#method-i-assert_no_broadcasts 56 | # 57 | # :method: refute_broadcasts 58 | # :call-seq: refute_broadcasts(stream, &block) 59 | alias refute_broadcasts assert_no_broadcasts 60 | 61 | ## 62 | # Asserts that the specified message has been sent to the stream. 63 | # 64 | # def test_assert_transmitted_message 65 | # ActionCable.server.broadcast 'messages', text: 'hello' 66 | # assert_broadcast_on('messages', text: 'hello') 67 | # end 68 | # 69 | # If a block is passed, that block should cause a message with the specified data to be sent. 70 | # 71 | # def test_assert_broadcast_on_again 72 | # assert_broadcast_on('messages', text: 'hello') do 73 | # ActionCable.server.broadcast 'messages', text: 'hello' 74 | # end 75 | # end 76 | # 77 | # See also Minitest::Rails::Expectations::ActionCable::TestHelper#must_broadcast_on 78 | # See https://api.rubyonrails.org/v7.0/classes/ActionCable/TestHelper.html#method-i-assert_broadcast_on 79 | # 80 | # :method: assert_broadcast_on 81 | # :call-seq: assert_broadcast_on(stream, data) 82 | end 83 | 84 | class ActionCable::Channel::TestCase 85 | ## 86 | # Asserts that the number of broadcasted messages to the stream matches the given number. 87 | # 88 | # def test_broadcasts 89 | # assert_broadcasts 'messages', 0 90 | # ActionCable.server.broadcast 'messages', { text: 'hello' } 91 | # assert_broadcasts 'messages', 1 92 | # ActionCable.server.broadcast 'messages', { text: 'world' } 93 | # assert_broadcasts 'messages', 2 94 | # end 95 | # 96 | # If a block is passed, that block should cause the specified number of 97 | # messages to be broadcasted. 98 | # 99 | # def test_broadcasts_again 100 | # assert_broadcasts('messages', 1) do 101 | # ActionCable.server.broadcast 'messages', { text: 'hello' } 102 | # end 103 | # 104 | # assert_broadcasts('messages', 2) do 105 | # ActionCable.server.broadcast 'messages', { text: 'hi' } 106 | # ActionCable.server.broadcast 'messages', { text: 'how are you?' } 107 | # end 108 | # end 109 | # 110 | # See also Minitest::Rails::Expectations::ActionCable::TestHelper#must_have_broadcasts 111 | # See https://api.rubyonrails.org/v7.0/classes/ActionCable/TestHelper.html#method-i-assert_broadcasts 112 | # 113 | # :method: assert_broadcasts 114 | # :call-seq: assert_broadcasts(stream, number) 115 | 116 | ## 117 | # Asserts that no messages have been sent to the stream. 118 | # 119 | # def test_no_broadcasts 120 | # refute_broadcasts 'messages' 121 | # ActionCable.server.broadcast 'messages', { text: 'hi' } 122 | # assert_broadcasts 'messages', 1 123 | # end 124 | # 125 | # If a block is passed, that block should not cause any message to be sent. 126 | # 127 | # def test_broadcasts_again 128 | # refute_broadcasts 'messages' do 129 | # # No job messages should be sent from this block 130 | # end 131 | # end 132 | # 133 | # Note: This assertion is simply a shortcut for: 134 | # 135 | # assert_broadcasts 'messages', 0, &block 136 | # 137 | # See also Minitest::Rails::Expectations::ActionCable::TestHelper#wont_have_broadcasts 138 | # See https://api.rubyonrails.org/v7.0/classes/ActionCable/TestHelper.html#method-i-assert_no_broadcasts 139 | # 140 | # :method: refute_broadcasts 141 | # :call-seq: refute_broadcasts(stream, &block) 142 | alias refute_broadcasts assert_no_broadcasts 143 | 144 | ## 145 | # Asserts that the specified message has been sent to the stream. 146 | # 147 | # def test_assert_transmitted_message 148 | # ActionCable.server.broadcast 'messages', text: 'hello' 149 | # assert_broadcast_on('messages', text: 'hello') 150 | # end 151 | # 152 | # If a block is passed, that block should cause a message with the specified data to be sent. 153 | # 154 | # def test_assert_broadcast_on_again 155 | # assert_broadcast_on('messages', text: 'hello') do 156 | # ActionCable.server.broadcast 'messages', text: 'hello' 157 | # end 158 | # end 159 | # 160 | # See also Minitest::Rails::Expectations::ActionCable::TestHelper#must_broadcast_on 161 | # See https://api.rubyonrails.org/v7.0/classes/ActionCable/TestHelper.html#method-i-assert_broadcast_on 162 | # 163 | # :method: assert_broadcast_on 164 | # :call-seq: assert_broadcast_on(stream, data) 165 | 166 | ## 167 | # Asserts that no streams have been started. 168 | # 169 | # def test_assert_no_started_stream 170 | # subscribe 171 | # assert_no_streams 172 | # end 173 | # 174 | # See also Minitest::Rails::Expectations::ActionCable::Channel#wont_have_streams 175 | # See https://api.rubyonrails.org/v7.0/classes/ActionCable/Channel/TestCase/Behavior.html#method-i-assert_no_streams 176 | # 177 | # :method: refute_streams 178 | alias refute_streams assert_no_streams 179 | 180 | ## 181 | # Asserts that the specified stream has been started. 182 | # 183 | # def test_assert_started_stream 184 | # subscribe 185 | # assert_has_stream 'messages' 186 | # end 187 | # 188 | # See also Minitest::Rails::Expectations::ActionCable::Channel#must_have_streams 189 | # See https://api.rubyonrails.org/v7.0/classes/ActionCable/Channel/TestCase/Behavior.html#method-i-assert_has_stream 190 | # 191 | # :method: assert_has_stream 192 | # :call-seq: assert_has_stream(stream) 193 | 194 | ## 195 | # Asserts that the specified stream for a model has started. 196 | # 197 | # def test_assert_started_stream_for 198 | # subscribe id: 42 199 | # assert_has_stream_for User.find(42) 200 | # end 201 | # 202 | # See also Minitest::Rails::Expectations::ActionCable::Channel#must_have_stream_for 203 | # See https://api.rubyonrails.org/v7.0/classes/ActionCable/Channel/TestCase/Behavior.html#method-i-assert_has_stream_for 204 | # 205 | # :method: assert_has_stream_for 206 | # :call-seq: assert_has_stream_for(object) 207 | end 208 | 209 | class ActionCable::Connection::TestCase 210 | # Asserts that the connection is rejected (via +reject_unauthorized_connection+). 211 | # 212 | # class ApplicationCable::ConnectionTest < ActionCable::Connection::TestCase 213 | # def test_connects_with_proper_cookie 214 | # # Simulate the connection request with a cookie. 215 | # cookies["user_id"] = users(:john).id 216 | # 217 | # connect 218 | # 219 | # # Assert the connection identifier matches the fixture. 220 | # assert_equal users(:john).id, connection.user.id 221 | # end 222 | # 223 | # def test_rejects_connection_without_proper_cookie 224 | # assert_reject_connection { connect } 225 | # end 226 | # end 227 | # 228 | # See also Minitest::Rails::Expectations::ActionCable#must_reject_connection 229 | # See https://api.rubyonrails.org/v7.0/classes/ActionCable/Connection/Assertions.html#method-i-assert_reject_connection 230 | # 231 | # :method: assert_reject_connection 232 | end 233 | -------------------------------------------------------------------------------- /lib/minitest/rails/expectations/action_dispatch.rb: -------------------------------------------------------------------------------- 1 | require "active_support/concern" 2 | require "minitest/rails/expectations/active_support" 3 | 4 | module Minitest 5 | module Rails 6 | module Expectations 7 | # This exists as a module to allow easy mixing into classes other than 8 | # ActionDispatch::IntegrationTest where you might want to do job testing. 9 | module ActionDispatch 10 | ## 11 | # Expects that the provided options can be used to generate the provided path. This is the inverse of +assert_recognizes+. 12 | # The +extras+ parameter is used to tell the request the names and values of additional request parameters that would be in 13 | # a query string. The +message+ parameter allows you to specify a custom error message for assertion failures. 14 | # 15 | # The +defaults+ parameter is unused. 16 | # 17 | # # Expects that the default action is generated for a route with no action 18 | # value({controller: "items", action: "index"}).must_route_from "/items" 19 | # 20 | # # Tests that the list action is properly routed 21 | # value({controller: "items", action: "list"}).must_route_to "/items/list" 22 | # 23 | # # Tests the generation of a route with a parameter 24 | # value({ controller: "items", action: "list", id: "1" }).must_route_from "/items/list/1" 25 | # 26 | # # Expects that the generated route gives us our custom route 27 | # value({ controller: 'scm', action: 'show_diff', revision: "12" }).must_route_from "changesets/12" 28 | # 29 | # See also ActionView::TestCase#assert_generates 30 | # See also ActionDispatch::IntegrationTest#assert_generates 31 | # 32 | # :method: must_route_from 33 | # :call-seq: options.must_route_from(expected_path, defaults={}, extras = {}, message=nil) 34 | infect_an_assertion :assert_generates, :must_route_to 35 | 36 | ## 37 | # Expects that the routing of the given +path+ was handled correctly and that the parsed options (given in the +expected_options+ hash) 38 | # match +path+. Basically, it asserts that \Rails recognizes the route given by +expected_options+. 39 | # 40 | # Pass a hash in the second argument (+path+) to specify the request method. This is useful for routes 41 | # requiring a specific HTTP method. The hash should contain a :path with the incoming request path 42 | # and a :method containing the required HTTP verb. 43 | # 44 | # # assert that POSTing to /items will call the create action on ItemsController 45 | # assert_recognizes({controller: 'items', action: 'create'}, {path: 'items', method: :post}) 46 | # 47 | # You can also pass in +extras+ with a hash containing URL parameters that would normally be in the query string. This can be used 48 | # to assert that values in the query string string will end up in the params hash correctly. To test query strings you must use the 49 | # extras argument, appending the query string on the path directly will not work. For example: 50 | # 51 | # # Expect that a path of '/items/list/1?view=print' returns the correct options 52 | # value('items/list/1').must_route_from({controller: 'items', action: 'list', id: '1', view: 'print'}, { view: "print" }) 53 | # 54 | # The +message+ parameter allows you to pass in an error message that is displayed upon failure. 55 | # 56 | # # Check the default route (i.e., the index action) 57 | # value('items').must_route_from({controller: 'items', action: 'index'}) 58 | # 59 | # # Test a specific action 60 | # value('items/list').must_route_from({controller: 'items', action: 'list'}) 61 | # 62 | # # Test an action with a parameter 63 | # value('items/destroy/1').must_route_from({controller: 'items', action: 'destroy', id: '1'}) 64 | # 65 | # # Test a custom route 66 | # value('view/item1').must_route_from({controller: 'items', action: 'show', id: '1'}) 67 | # 68 | # See also ActionView::TestCase#assert_recognizes 69 | # See also ActionDispatch::IntegrationTest#assert_recognizes 70 | # 71 | # :method: must_route_from 72 | # :call-seq: path.must_route_from(expected_options, extras={}, msg=nil) 73 | infect_an_assertion :assert_recognizes, :must_route_from 74 | 75 | ## 76 | # Expects that path and options match both ways; in other words, it verifies that path generates 77 | # options and then that options generates path. This essentially combines +assert_recognizes+ 78 | # and +assert_generates+ into one step. 79 | # 80 | # The +extras+ hash allows you to specify options that would normally be provided as a query string to the action. The 81 | # +message+ parameter allows you to specify a custom error message to display upon failure. 82 | # 83 | # # Expect a basic route: a controller with the default action (index) 84 | # value({ controller: 'home', action: 'index' }).must_route_for '/home' 85 | # 86 | # # Test a route generated with a specific controller, action, and parameter (id) 87 | # value({ controller: 'entries', action: 'show', id: 23 }).must_route_for '/entries/show/23' 88 | # 89 | # # Expect a basic route (controller + default action), with an error message if it fails 90 | # value({ controller: 'store', action: 'index' }).must_route_for '/store' 91 | # 92 | # # Tests a route, providing a defaults hash 93 | # value({id: "9", item: "square"}).must_route_for 'controller/action/9', {controller: "controller", action: "action"}, {}, {item: "square"} 94 | # 95 | # # Tests a route with a HTTP method 96 | # value({ controller: "product", action: "update", id: "321" }).must_route_for({ method: 'put', path: '/product/321' }) 97 | # 98 | # See also ActionView::TestCase#assert_routing 99 | # See also ActionDispatch::IntegrationTest#assert_routing 100 | # 101 | # :method: must_route_for 102 | # :call-seq: options.must_route_for(path, defaults={}, extras={}, message=nil) 103 | infect_an_assertion :assert_routing, :must_route_for 104 | 105 | # An expectation that selects elements and makes one or more equality tests. 106 | # 107 | # If the first argument is an element, selects all matching elements 108 | # starting from (and including) that element and all its children in 109 | # depth-first order. 110 | # 111 | # If no element if specified, calling +must_select+ selects from the 112 | # response HTML unless +must_select+ is called from within an +must_select+ block. 113 | # 114 | # When called with a block +must_select+ passes an array of selected elements 115 | # to the block. Calling +must_select+ from the block, with no element specified, 116 | # runs the expectation on the complete set of elements selected by the enclosing expectation. 117 | # Alternatively the array may be iterated through so that +must_select+ can be called 118 | # separately for each element. 119 | # 120 | # 121 | # ==== Example 122 | # If the response contains two ordered lists, each with four list elements then: 123 | # must_select "ol" do |elements| 124 | # elements.each do |element| 125 | # must_select element, "li", 4 126 | # end 127 | # end 128 | # 129 | # will pass, as will: 130 | # must_select "ol" do 131 | # must_select "li", 8 132 | # end 133 | # 134 | # The selector may be a CSS selector expression (String), an expression 135 | # with substitution values, or an HTML::Selector object. 136 | # 137 | # === Equality Tests 138 | # 139 | # The equality test may be one of the following: 140 | # * true - Assertion is true if at least one element selected. 141 | # * false - Assertion is true if no element selected. 142 | # * String/Regexp - Assertion is true if the text value of at least 143 | # one element matches the string or regular expression. 144 | # * Integer - Assertion is true if exactly that number of 145 | # elements are selected. 146 | # * Range - Assertion is true if the number of selected 147 | # elements fit the range. 148 | # If no equality test specified, the expectation is true if at least one 149 | # element selected. 150 | # 151 | # To perform more than one equality tests, use a hash with the following keys: 152 | # * :text - Narrow the selection to elements that have this text 153 | # value (string or regexp). 154 | # * :html - Narrow the selection to elements that have this HTML 155 | # content (string or regexp). 156 | # * :count - Assertion is true if the number of selected elements 157 | # is equal to this value. 158 | # * :minimum - Assertion is true if the number of selected 159 | # elements is at least this value. 160 | # * :maximum - Assertion is true if the number of selected 161 | # elements is at most this value. 162 | # 163 | # If the method is called with a block, once all equality tests are 164 | # evaluated the block is called with an array of all matched elements. 165 | # 166 | # # At least one form element 167 | # must_select "form" 168 | # 169 | # # Form element includes four input fields 170 | # must_select "form input", 4 171 | # 172 | # # Page title is "Welcome" 173 | # must_select "title", "Welcome" 174 | # 175 | # # Page title is "Welcome" and there is only one title element 176 | # must_select "title", {count: 1, text: "Welcome"}, 177 | # "Wrong title or more than one title element" 178 | # 179 | # # Page contains no forms 180 | # must_select "form", false, "This page must contain no forms" 181 | # 182 | # # Test the content and style 183 | # must_select "body div.header ul.menu" 184 | # 185 | # # Use substitution values 186 | # must_select "ol>li#?", /item-\d+/ 187 | # 188 | # # All input fields in the form have a name 189 | # must_select "form input" do 190 | # must_select "[name=?]", /.+/ # Not empty 191 | # end 192 | # 193 | # See also ActionView::TestCase#assert_select 194 | # See also ActionDispatch::IntegrationTest#assert_select 195 | # 196 | # :method: must_select 197 | # :call-seq: must_select(*args, &block) 198 | 199 | # Extracts the body of an email and runs nested expectations on it. 200 | # 201 | # You must enable deliveries for this expectation to work, use: 202 | # ActionMailer::Base.perform_deliveries = true 203 | # 204 | # must_select_email do 205 | # must_select "h1", "Email alert" 206 | # end 207 | # 208 | # must_select_email do 209 | # items = must_select "ol>li" 210 | # items.each do 211 | # # Work with items here... 212 | # end 213 | # end 214 | # 215 | # See also ActionView::TestCase#assert_select_email 216 | # See also ActionDispatch::IntegrationTest#assert_select_email 217 | # 218 | # :method: must_select_email 219 | # :call-seq: must_select_email(&block) 220 | 221 | # Extracts the content of an element, treats it as encoded HTML and runs 222 | # nested expectation on it. 223 | # 224 | # You typically call this method within another expectation to operate on 225 | # all currently selected elements. You can also pass an element or array 226 | # of elements. 227 | # 228 | # The content of each element is un-encoded, and wrapped in the root 229 | # element +encoded+. It then calls the block with all un-encoded elements. 230 | # 231 | # # Selects all bold tags from within the title of an Atom feed's entries (perhaps to nab a section name prefix) 232 | # must_select "feed[xmlns='http://www.w3.org/2005/Atom']" do 233 | # # Select each entry item and then the title item 234 | # must_select "entry>title" do 235 | # # Run expectations on the encoded title elements 236 | # must_select_encoded do 237 | # must_select "b" 238 | # end 239 | # end 240 | # end 241 | # 242 | # 243 | # # Selects all paragraph tags from within the description of an RSS feed 244 | # must_select "rss[version=2.0]" do 245 | # # Select description element of each feed item. 246 | # must_select "channel>item>description" do 247 | # # Run expectations on the encoded elements. 248 | # must_select_encoded do 249 | # must_select "p" 250 | # end 251 | # end 252 | # end 253 | # 254 | # See also ActionView::TestCase#assert_select_encoded 255 | # See also ActionDispatch::IntegrationTest#assert_select_encoded 256 | # 257 | # :method: must_select_encoded 258 | # :call-seq: must_select_encoded(element = nil, &block) 259 | 260 | ## 261 | # Checks that two HTML strings are equivalent. That they contain the same elements and attributes with the associated values. 262 | # Checks the numeric difference between the return value of an expression as a result of what is evaluated. 263 | # 264 | # apple_link = 'Apples' 265 | # value(link_to("Apples", "http://www.example.com")).must_dom_equal apple_link 266 | # 267 | # See also ActionView::TestCase#assert_dom_equal 268 | # See also ActionDispatch::IntegrationTest#assert_dom_equal 269 | # 270 | # :method: must_dom_equal 271 | # :args: expected, message = nil 272 | infect_an_assertion :assert_dom_equal, :must_dom_equal 273 | 274 | ## 275 | # Checks that the numeric result of evaluating an expression is not changed before and after invoking. 276 | # 277 | # orange_link = 'Oranges' 278 | # link_to("Apples", "http://www.example.com").wont_dom_equal orange_link 279 | # 280 | # See also ActionView::TestCase#refute_dom_equal 281 | # See also ActionDispatch::IntegrationTest#refute_dom_equal 282 | # See also ActionView::TestCase#assert_dom_not_equal 283 | # See also ActionDispatch::IntegrationTest#assert_dom_not_equal 284 | # 285 | # :method: wont_dom_equal 286 | # :args: expected, message = nil 287 | infect_an_assertion :refute_dom_equal, :wont_dom_equal 288 | 289 | extend ::ActiveSupport::Concern 290 | 291 | included do 292 | alias_method :must_respond_with, :assert_response 293 | alias_method :must_redirect_to, :assert_redirected_to 294 | alias_method :must_select, :assert_select 295 | alias_method :must_select_email, :assert_select_email 296 | alias_method :must_select_encoded, :assert_select_encoded 297 | end 298 | end 299 | end 300 | end 301 | end 302 | 303 | unless ENV["MT_NO_EXPECTATIONS"] 304 | class ActionDispatch::IntegrationTest # :nodoc: 305 | include Minitest::Rails::Expectations::ActionDispatch 306 | end 307 | end 308 | -------------------------------------------------------------------------------- /lib/minitest/rails/assertions/action_view.rb: -------------------------------------------------------------------------------- 1 | class ActionView::TestCase 2 | ## 3 | # Checks the numeric difference between the return value of an expression as a result of what is evaluated. 4 | # 5 | # assert_difference "User.count", +1 do 6 | # User.create 7 | # end 8 | # 9 | # See also Minitest::Rails::Expectations#must_change 10 | # 11 | # :method: assert_difference 12 | # :call-seq: assert_difference(expression, difference = 1, message = nil, &block) 13 | 14 | ## 15 | # Checks that the numeric result of evaluating an expression is not changed before and after invoking. 16 | # 17 | # assert_no_difference "User.count" do 18 | # User.new 19 | # end 20 | # 21 | # See also Minitest::Rails::Expectations#wont_change 22 | # 23 | # :method: assert_no_difference 24 | # :call-seq: assert_no_difference(expression, message = nil, &block) 25 | 26 | ## 27 | # Checks that the numeric result of evaluating an expression is not changed before and after invoking. 28 | # 29 | # refute_difference "User.count", do 30 | # User.new 31 | # end 32 | # 33 | # See also Minitest::Rails::Expectations#wont_change 34 | # 35 | # :args: expression, message = nil, &block 36 | alias refute_difference assert_no_difference 37 | 38 | # Asserts that the response is one of the following types: 39 | # 40 | # * :success - Status code was in the 200-299 range 41 | # * :redirect - Status code was in the 300-399 range 42 | # * :missing - Status code was 404 43 | # * :error - Status code was in the 500-599 range 44 | # 45 | # You can also pass an explicit status number like assert_response(501) 46 | # or its symbolic equivalent assert_response(:not_implemented). 47 | # See Rack::Utils::SYMBOL_TO_STATUS_CODE for a full list. 48 | # 49 | # # assert that the response was a redirection 50 | # assert_response :redirect 51 | # 52 | # # assert that the response code was status code 401 (unauthorized) 53 | # assert_response 401 54 | # 55 | # See also Minitest::Rails::Expectations#must_respond_with 56 | # 57 | # :method: assert_response 58 | # :call-seq: assert_response(type, message = nil) 59 | 60 | ## 61 | # Assert that the redirection options passed in match those of the redirect called in the latest action. 62 | # This match can be partial, such that assert_redirected_to(controller: "weblog") will also 63 | # match the redirection of redirect_to(controller: "weblog", action: "show") and so on. 64 | # 65 | # # assert that the redirection was to the "index" action on the WeblogController 66 | # assert_redirected_to controller: "weblog", action: "index" 67 | # 68 | # # assert that the redirection was to the named route login_url 69 | # assert_redirected_to login_url 70 | # 71 | # # assert that the redirection was to the url for @customer 72 | # assert_redirected_to @customer 73 | # 74 | # # asserts that the redirection matches the regular expression 75 | # assert_redirected_to %r(\Ahttp://example.org) 76 | # 77 | # See also Minitest::Rails::Expectations#must_redirect_to 78 | # 79 | # :method: assert_redirected_to 80 | # :call-seq: assert_redirected_to(options = {}, message=nil) 81 | 82 | ## 83 | # Asserts that the provided options can be used to generate the provided path. This is the inverse of +assert_recognizes+. 84 | # The +extras+ parameter is used to tell the request the names and values of additional request parameters that would be in 85 | # a query string. The +message+ parameter allows you to specify a custom error message for assertion failures. 86 | # 87 | # The +defaults+ parameter is unused. 88 | # 89 | # # Asserts that the default action is generated for a route with no action 90 | # assert_generates "/items", controller: "items", action: "index" 91 | # 92 | # # Tests that the list action is properly routed 93 | # assert_generates "/items/list", controller: "items", action: "list" 94 | # 95 | # # Tests the generation of a route with a parameter 96 | # assert_generates "/items/list/1", { controller: "items", action: "list", id: "1" } 97 | # 98 | # # Asserts that the generated route gives us our custom route 99 | # assert_generates "changesets/12", { controller: 'scm', action: 'show_diff', revision: "12" } 100 | # 101 | # See also Minitest::Rails::Expectations#must_route_to 102 | # 103 | # :method: assert_generates 104 | # :call-seq: assert_generates(expected_path, options, defaults={}, extras = {}, message=nil) 105 | 106 | ## 107 | # Asserts that the routing of the given +path+ was handled correctly and that the parsed options (given in the +expected_options+ hash) 108 | # match +path+. Basically, it asserts that \Rails recognizes the route given by +expected_options+. 109 | # 110 | # Pass a hash in the second argument (+path+) to specify the request method. This is useful for routes 111 | # requiring a specific HTTP method. The hash should contain a :path with the incoming request path 112 | # and a :method containing the required HTTP verb. 113 | # 114 | # # assert that POSTing to /items will call the create action on ItemsController 115 | # assert_recognizes({controller: 'items', action: 'create'}, {path: 'items', method: :post}) 116 | # 117 | # You can also pass in +extras+ with a hash containing URL parameters that would normally be in the query string. This can be used 118 | # to assert that values in the query string string will end up in the params hash correctly. To test query strings you must use the 119 | # extras argument, appending the query string on the path directly will not work. For example: 120 | # 121 | # # assert that a path of '/items/list/1?view=print' returns the correct options 122 | # assert_recognizes({controller: 'items', action: 'list', id: '1', view: 'print'}, 'items/list/1', { view: "print" }) 123 | # 124 | # The +message+ parameter allows you to pass in an error message that is displayed upon failure. 125 | # 126 | # # Check the default route (i.e., the index action) 127 | # assert_recognizes({controller: 'items', action: 'index'}, 'items') 128 | # 129 | # # Test a specific action 130 | # assert_recognizes({controller: 'items', action: 'list'}, 'items/list') 131 | # 132 | # # Test an action with a parameter 133 | # assert_recognizes({controller: 'items', action: 'destroy', id: '1'}, 'items/destroy/1') 134 | # 135 | # # Test a custom route 136 | # assert_recognizes({controller: 'items', action: 'show', id: '1'}, 'view/item1') 137 | # 138 | # See also Minitest::Rails::Expectations#must_route_from 139 | # 140 | # :method: assert_recognizes 141 | # :call-seq: assert_recognizes(expected_options, path, extras={}, msg=nil) 142 | 143 | ## 144 | # Asserts that path and options match both ways; in other words, it verifies that path generates 145 | # options and then that options generates path. This essentially combines +assert_recognizes+ 146 | # and +assert_generates+ into one step. 147 | # 148 | # The +extras+ hash allows you to specify options that would normally be provided as a query string to the action. The 149 | # +message+ parameter allows you to specify a custom error message to display upon failure. 150 | # 151 | # # Assert a basic route: a controller with the default action (index) 152 | # assert_routing '/home', controller: 'home', action: 'index' 153 | # 154 | # # Test a route generated with a specific controller, action, and parameter (id) 155 | # assert_routing '/entries/show/23', controller: 'entries', action: 'show', id: 23 156 | # 157 | # # Assert a basic route (controller + default action), with an error message if it fails 158 | # assert_routing '/store', { controller: 'store', action: 'index' }, {}, {}, 'Route for store index not generated properly' 159 | # 160 | # # Tests a route, providing a defaults hash 161 | # assert_routing 'controller/action/9', {id: "9", item: "square"}, {controller: "controller", action: "action"}, {}, {item: "square"} 162 | # 163 | # # Tests a route with a HTTP method 164 | # assert_routing({ method: 'put', path: '/product/321' }, { controller: "product", action: "update", id: "321" }) 165 | # 166 | # See also Minitest::Rails::Expectations#must_route 167 | # 168 | # :method: assert_routing 169 | # :call-seq: assert_routing(path, options, defaults={}, extras={}, message=nil) 170 | 171 | # An assertion that selects elements and makes one or more equality tests. 172 | # 173 | # If the first argument is an element, selects all matching elements 174 | # starting from (and including) that element and all its children in 175 | # depth-first order. 176 | # 177 | # If no element if specified, calling +assert_select+ selects from the 178 | # response HTML unless +assert_select+ is called from within an +assert_select+ block. 179 | # 180 | # When called with a block +assert_select+ passes an array of selected elements 181 | # to the block. Calling +assert_select+ from the block, with no element specified, 182 | # runs the assertion on the complete set of elements selected by the enclosing assertion. 183 | # Alternatively the array may be iterated through so that +assert_select+ can be called 184 | # separately for each element. 185 | # 186 | # 187 | # ==== Example 188 | # If the response contains two ordered lists, each with four list elements then: 189 | # assert_select "ol" do |elements| 190 | # elements.each do |element| 191 | # assert_select element, "li", 4 192 | # end 193 | # end 194 | # 195 | # will pass, as will: 196 | # assert_select "ol" do 197 | # assert_select "li", 8 198 | # end 199 | # 200 | # The selector may be a CSS selector expression (String), an expression 201 | # with substitution values, or an HTML::Selector object. 202 | # 203 | # === Equality Tests 204 | # 205 | # The equality test may be one of the following: 206 | # * true - Assertion is true if at least one element selected. 207 | # * false - Assertion is true if no element selected. 208 | # * String/Regexp - Assertion is true if the text value of at least 209 | # one element matches the string or regular expression. 210 | # * Integer - Assertion is true if exactly that number of 211 | # elements are selected. 212 | # * Range - Assertion is true if the number of selected 213 | # elements fit the range. 214 | # If no equality test specified, the assertion is true if at least one 215 | # element selected. 216 | # 217 | # To perform more than one equality tests, use a hash with the following keys: 218 | # * :text - Narrow the selection to elements that have this text 219 | # value (string or regexp). 220 | # * :html - Narrow the selection to elements that have this HTML 221 | # content (string or regexp). 222 | # * :count - Assertion is true if the number of selected elements 223 | # is equal to this value. 224 | # * :minimum - Assertion is true if the number of selected 225 | # elements is at least this value. 226 | # * :maximum - Assertion is true if the number of selected 227 | # elements is at most this value. 228 | # 229 | # If the method is called with a block, once all equality tests are 230 | # evaluated the block is called with an array of all matched elements. 231 | # 232 | # # At least one form element 233 | # assert_select "form" 234 | # 235 | # # Form element includes four input fields 236 | # assert_select "form input", 4 237 | # 238 | # # Page title is "Welcome" 239 | # assert_select "title", "Welcome" 240 | # 241 | # # Page title is "Welcome" and there is only one title element 242 | # assert_select "title", {count: 1, text: "Welcome"}, 243 | # "Wrong title or more than one title element" 244 | # 245 | # # Page contains no forms 246 | # assert_select "form", false, "This page must contain no forms" 247 | # 248 | # # Test the content and style 249 | # assert_select "body div.header ul.menu" 250 | # 251 | # # Use substitution values 252 | # assert_select "ol>li#?", /item-\d+/ 253 | # 254 | # # All input fields in the form have a name 255 | # assert_select "form input" do 256 | # assert_select "[name=?]", /.+/ # Not empty 257 | # end 258 | # 259 | # See also Minitest::Rails::Expectations#must_select 260 | # 261 | # :method: assert_select 262 | # :call-seq: assert_select(*args, &block) 263 | 264 | # Extracts the body of an email and runs nested assertions on it. 265 | # 266 | # You must enable deliveries for this assertion to work, use: 267 | # ActionMailer::Base.perform_deliveries = true 268 | # 269 | # assert_select_email do 270 | # assert_select "h1", "Email alert" 271 | # end 272 | # 273 | # assert_select_email do 274 | # items = assert_select "ol>li" 275 | # items.each do 276 | # # Work with items here... 277 | # end 278 | # end 279 | # 280 | # See also Minitest::Rails::Expectations#must_select_email 281 | # 282 | # :method: assert_select_email 283 | # :call-seq: assert_select_email(&block) 284 | 285 | # Extracts the content of an element, treats it as encoded HTML and runs 286 | # nested assertion on it. 287 | # 288 | # You typically call this method within another assertion to operate on 289 | # all currently selected elements. You can also pass an element or array 290 | # of elements. 291 | # 292 | # The content of each element is un-encoded, and wrapped in the root 293 | # element +encoded+. It then calls the block with all un-encoded elements. 294 | # 295 | # # Selects all bold tags from within the title of an Atom feed's entries (perhaps to nab a section name prefix) 296 | # assert_select "feed[xmlns='http://www.w3.org/2005/Atom']" do 297 | # # Select each entry item and then the title item 298 | # assert_select "entry>title" do 299 | # # Run assertions on the encoded title elements 300 | # assert_select_encoded do 301 | # assert_select "b" 302 | # end 303 | # end 304 | # end 305 | # 306 | # 307 | # # Selects all paragraph tags from within the description of an RSS feed 308 | # assert_select "rss[version=2.0]" do 309 | # # Select description element of each feed item. 310 | # assert_select "channel>item>description" do 311 | # # Run assertions on the encoded elements. 312 | # assert_select_encoded do 313 | # assert_select "p" 314 | # end 315 | # end 316 | # end 317 | # 318 | # See also Minitest::Rails::Expectations#must_select_encoded 319 | # 320 | # :method: assert_select_encoded 321 | # :call-seq: assert_select_encoded(element = nil, &block) 322 | 323 | ## 324 | # Checks that two HTML strings are equivalent. That they contain the same elements and attributes with the associated values. 325 | # 326 | # assert_dom_equal 'Apples', 327 | # link_to("Apples", "http://www.example.com") 328 | # 329 | # See also Minitest::Rails::Expectations#must_dom_equal 330 | # 331 | # :method: assert_dom_equal 332 | # :call-seq: assert_dom_equal(expected, actual, message = nil) 333 | 334 | ## 335 | # Checks that two HTML strings are not equivalent. That they do not contain the same elements and attributes with the associated values. 336 | # 337 | # assert_dom_not_equal 'Oranges', 338 | # link_to("Apples", "http://www.example.com") 339 | # 340 | # See also Minitest::Rails::Expectations#wont_dom_equal 341 | # 342 | # :method: assert_dom_not_equal 343 | # :call-seq: assert_dom_not_equal(expected, actual, message = nil) 344 | 345 | ## 346 | # Checks that two HTML strings are not equivalent. That they do not contain the same elements and attributes with the associated values. 347 | # 348 | # refute_dom_equal 'Oranges', 349 | # link_to("Apples", "http://www.example.com") 350 | # 351 | # See also Minitest::Rails::Expectations#wont_dom_equal 352 | # 353 | # :method: assert_dom_equal 354 | # :call-seq: assert_dom_equal(expected, actual, message = nil) 355 | alias refute_dom_equal assert_dom_not_equal 356 | end 357 | -------------------------------------------------------------------------------- /lib/minitest/rails/assertions/action_dispatch.rb: -------------------------------------------------------------------------------- 1 | class ActionDispatch::IntegrationTest 2 | ## 3 | # Checks the numeric difference between the return value of an expression as a result of what is evaluated. 4 | # 5 | # assert_difference "User.count", +1 do 6 | # User.create 7 | # end 8 | # 9 | # See also Minitest::Rails::Expectations#must_change 10 | # 11 | # :method: assert_difference 12 | # :call-seq: assert_difference(expression, difference = 1, message = nil, &block) 13 | 14 | ## 15 | # Checks that the numeric result of evaluating an expression is not changed before and after invoking. 16 | # 17 | # assert_no_difference "User.count" do 18 | # User.new 19 | # end 20 | # 21 | # See also Minitest::Rails::Expectations#wont_change 22 | # 23 | # :method: assert_no_difference 24 | # :call-seq: assert_no_difference(expression, message = nil, &block) 25 | 26 | ## 27 | # Checks that the numeric result of evaluating an expression is not changed before and after invoking. 28 | # 29 | # refute_difference "User.count", do 30 | # User.new 31 | # end 32 | # 33 | # See also Minitest::Rails::Expectations#wont_change 34 | # 35 | # :args: expression, message = nil, &block 36 | alias refute_difference assert_no_difference 37 | 38 | # Asserts that the response is one of the following types: 39 | # 40 | # * :success - Status code was in the 200-299 range 41 | # * :redirect - Status code was in the 300-399 range 42 | # * :missing - Status code was 404 43 | # * :error - Status code was in the 500-599 range 44 | # 45 | # You can also pass an explicit status number like assert_response(501) 46 | # or its symbolic equivalent assert_response(:not_implemented). 47 | # See Rack::Utils::SYMBOL_TO_STATUS_CODE for a full list. 48 | # 49 | # # assert that the response was a redirection 50 | # assert_response :redirect 51 | # 52 | # # assert that the response code was status code 401 (unauthorized) 53 | # assert_response 401 54 | # 55 | # See also Minitest::Rails::Expectations#must_respond_with 56 | # 57 | # :method: assert_response 58 | # :call-seq: assert_response(type, message = nil) 59 | 60 | ## 61 | # Assert that the redirection options passed in match those of the redirect called in the latest action. 62 | # This match can be partial, such that assert_redirected_to(controller: "weblog") will also 63 | # match the redirection of redirect_to(controller: "weblog", action: "show") and so on. 64 | # 65 | # # assert that the redirection was to the "index" action on the WeblogController 66 | # assert_redirected_to controller: "weblog", action: "index" 67 | # 68 | # # assert that the redirection was to the named route login_url 69 | # assert_redirected_to login_url 70 | # 71 | # # assert that the redirection was to the url for @customer 72 | # assert_redirected_to @customer 73 | # 74 | # # asserts that the redirection matches the regular expression 75 | # assert_redirected_to %r(\Ahttp://example.org) 76 | # 77 | # See also Minitest::Rails::Expectations#must_redirect_to 78 | # 79 | # :method: assert_redirected_to 80 | # :call-seq: assert_redirected_to(options = {}, message=nil) 81 | 82 | ## 83 | # Asserts that the provided options can be used to generate the provided path. This is the inverse of +assert_recognizes+. 84 | # The +extras+ parameter is used to tell the request the names and values of additional request parameters that would be in 85 | # a query string. The +message+ parameter allows you to specify a custom error message for assertion failures. 86 | # 87 | # The +defaults+ parameter is unused. 88 | # 89 | # # Asserts that the default action is generated for a route with no action 90 | # assert_generates "/items", controller: "items", action: "index" 91 | # 92 | # # Tests that the list action is properly routed 93 | # assert_generates "/items/list", controller: "items", action: "list" 94 | # 95 | # # Tests the generation of a route with a parameter 96 | # assert_generates "/items/list/1", { controller: "items", action: "list", id: "1" } 97 | # 98 | # # Asserts that the generated route gives us our custom route 99 | # assert_generates "changesets/12", { controller: 'scm', action: 'show_diff', revision: "12" } 100 | # 101 | # See also Minitest::Rails::Expectations#must_route_to 102 | # 103 | # :method: assert_generates 104 | # :call-seq: assert_generates(expected_path, options, defaults={}, extras = {}, message=nil) 105 | 106 | ## 107 | # Asserts that the routing of the given +path+ was handled correctly and that the parsed options (given in the +expected_options+ hash) 108 | # match +path+. Basically, it asserts that \Rails recognizes the route given by +expected_options+. 109 | # 110 | # Pass a hash in the second argument (+path+) to specify the request method. This is useful for routes 111 | # requiring a specific HTTP method. The hash should contain a :path with the incoming request path 112 | # and a :method containing the required HTTP verb. 113 | # 114 | # # assert that POSTing to /items will call the create action on ItemsController 115 | # assert_recognizes({controller: 'items', action: 'create'}, {path: 'items', method: :post}) 116 | # 117 | # You can also pass in +extras+ with a hash containing URL parameters that would normally be in the query string. This can be used 118 | # to assert that values in the query string string will end up in the params hash correctly. To test query strings you must use the 119 | # extras argument, appending the query string on the path directly will not work. For example: 120 | # 121 | # # assert that a path of '/items/list/1?view=print' returns the correct options 122 | # assert_recognizes({controller: 'items', action: 'list', id: '1', view: 'print'}, 'items/list/1', { view: "print" }) 123 | # 124 | # The +message+ parameter allows you to pass in an error message that is displayed upon failure. 125 | # 126 | # # Check the default route (i.e., the index action) 127 | # assert_recognizes({controller: 'items', action: 'index'}, 'items') 128 | # 129 | # # Test a specific action 130 | # assert_recognizes({controller: 'items', action: 'list'}, 'items/list') 131 | # 132 | # # Test an action with a parameter 133 | # assert_recognizes({controller: 'items', action: 'destroy', id: '1'}, 'items/destroy/1') 134 | # 135 | # # Test a custom route 136 | # assert_recognizes({controller: 'items', action: 'show', id: '1'}, 'view/item1') 137 | # 138 | # See also Minitest::Rails::Expectations#must_route_from 139 | # 140 | # :method: assert_recognizes 141 | # :call-seq: assert_recognizes(expected_options, path, extras={}, msg=nil) 142 | 143 | ## 144 | # Asserts that path and options match both ways; in other words, it verifies that path generates 145 | # options and then that options generates path. This essentially combines +assert_recognizes+ 146 | # and +assert_generates+ into one step. 147 | # 148 | # The +extras+ hash allows you to specify options that would normally be provided as a query string to the action. The 149 | # +message+ parameter allows you to specify a custom error message to display upon failure. 150 | # 151 | # # Assert a basic route: a controller with the default action (index) 152 | # assert_routing '/home', controller: 'home', action: 'index' 153 | # 154 | # # Test a route generated with a specific controller, action, and parameter (id) 155 | # assert_routing '/entries/show/23', controller: 'entries', action: 'show', id: 23 156 | # 157 | # # Assert a basic route (controller + default action), with an error message if it fails 158 | # assert_routing '/store', { controller: 'store', action: 'index' }, {}, {}, 'Route for store index not generated properly' 159 | # 160 | # # Tests a route, providing a defaults hash 161 | # assert_routing 'controller/action/9', {id: "9", item: "square"}, {controller: "controller", action: "action"}, {}, {item: "square"} 162 | # 163 | # # Tests a route with a HTTP method 164 | # assert_routing({ method: 'put', path: '/product/321' }, { controller: "product", action: "update", id: "321" }) 165 | # 166 | # See also Minitest::Rails::Expectations#must_route 167 | # 168 | # :method: assert_routing 169 | # :call-seq: assert_routing(path, options, defaults={}, extras={}, message=nil) 170 | 171 | # An assertion that selects elements and makes one or more equality tests. 172 | # 173 | # If the first argument is an element, selects all matching elements 174 | # starting from (and including) that element and all its children in 175 | # depth-first order. 176 | # 177 | # If no element if specified, calling +assert_select+ selects from the 178 | # response HTML unless +assert_select+ is called from within an +assert_select+ block. 179 | # 180 | # When called with a block +assert_select+ passes an array of selected elements 181 | # to the block. Calling +assert_select+ from the block, with no element specified, 182 | # runs the assertion on the complete set of elements selected by the enclosing assertion. 183 | # Alternatively the array may be iterated through so that +assert_select+ can be called 184 | # separately for each element. 185 | # 186 | # 187 | # ==== Example 188 | # If the response contains two ordered lists, each with four list elements then: 189 | # assert_select "ol" do |elements| 190 | # elements.each do |element| 191 | # assert_select element, "li", 4 192 | # end 193 | # end 194 | # 195 | # will pass, as will: 196 | # assert_select "ol" do 197 | # assert_select "li", 8 198 | # end 199 | # 200 | # The selector may be a CSS selector expression (String), an expression 201 | # with substitution values, or an HTML::Selector object. 202 | # 203 | # === Equality Tests 204 | # 205 | # The equality test may be one of the following: 206 | # * true - Assertion is true if at least one element selected. 207 | # * false - Assertion is true if no element selected. 208 | # * String/Regexp - Assertion is true if the text value of at least 209 | # one element matches the string or regular expression. 210 | # * Integer - Assertion is true if exactly that number of 211 | # elements are selected. 212 | # * Range - Assertion is true if the number of selected 213 | # elements fit the range. 214 | # If no equality test specified, the assertion is true if at least one 215 | # element selected. 216 | # 217 | # To perform more than one equality tests, use a hash with the following keys: 218 | # * :text - Narrow the selection to elements that have this text 219 | # value (string or regexp). 220 | # * :html - Narrow the selection to elements that have this HTML 221 | # content (string or regexp). 222 | # * :count - Assertion is true if the number of selected elements 223 | # is equal to this value. 224 | # * :minimum - Assertion is true if the number of selected 225 | # elements is at least this value. 226 | # * :maximum - Assertion is true if the number of selected 227 | # elements is at most this value. 228 | # 229 | # If the method is called with a block, once all equality tests are 230 | # evaluated the block is called with an array of all matched elements. 231 | # 232 | # # At least one form element 233 | # assert_select "form" 234 | # 235 | # # Form element includes four input fields 236 | # assert_select "form input", 4 237 | # 238 | # # Page title is "Welcome" 239 | # assert_select "title", "Welcome" 240 | # 241 | # # Page title is "Welcome" and there is only one title element 242 | # assert_select "title", {count: 1, text: "Welcome"}, 243 | # "Wrong title or more than one title element" 244 | # 245 | # # Page contains no forms 246 | # assert_select "form", false, "This page must contain no forms" 247 | # 248 | # # Test the content and style 249 | # assert_select "body div.header ul.menu" 250 | # 251 | # # Use substitution values 252 | # assert_select "ol>li#?", /item-\d+/ 253 | # 254 | # # All input fields in the form have a name 255 | # assert_select "form input" do 256 | # assert_select "[name=?]", /.+/ # Not empty 257 | # end 258 | # 259 | # See also Minitest::Rails::Expectations#must_select 260 | # 261 | # :method: assert_select 262 | # :call-seq: assert_select(*args, &block) 263 | 264 | # Extracts the body of an email and runs nested assertions on it. 265 | # 266 | # You must enable deliveries for this assertion to work, use: 267 | # ActionMailer::Base.perform_deliveries = true 268 | # 269 | # assert_select_email do 270 | # assert_select "h1", "Email alert" 271 | # end 272 | # 273 | # assert_select_email do 274 | # items = assert_select "ol>li" 275 | # items.each do 276 | # # Work with items here... 277 | # end 278 | # end 279 | # 280 | # See also Minitest::Rails::Expectations#must_select_email 281 | # 282 | # :method: assert_select_email 283 | # :call-seq: assert_select_email(&block) 284 | 285 | # Extracts the content of an element, treats it as encoded HTML and runs 286 | # nested assertion on it. 287 | # 288 | # You typically call this method within another assertion to operate on 289 | # all currently selected elements. You can also pass an element or array 290 | # of elements. 291 | # 292 | # The content of each element is un-encoded, and wrapped in the root 293 | # element +encoded+. It then calls the block with all un-encoded elements. 294 | # 295 | # # Selects all bold tags from within the title of an Atom feed's entries (perhaps to nab a section name prefix) 296 | # assert_select "feed[xmlns='http://www.w3.org/2005/Atom']" do 297 | # # Select each entry item and then the title item 298 | # assert_select "entry>title" do 299 | # # Run assertions on the encoded title elements 300 | # assert_select_encoded do 301 | # assert_select "b" 302 | # end 303 | # end 304 | # end 305 | # 306 | # 307 | # # Selects all paragraph tags from within the description of an RSS feed 308 | # assert_select "rss[version=2.0]" do 309 | # # Select description element of each feed item. 310 | # assert_select "channel>item>description" do 311 | # # Run assertions on the encoded elements. 312 | # assert_select_encoded do 313 | # assert_select "p" 314 | # end 315 | # end 316 | # end 317 | # 318 | # See also Minitest::Rails::Expectations#must_select_encoded 319 | # 320 | # :method: assert_select_encoded 321 | # :call-seq: assert_select_encoded(element = nil, &block) 322 | 323 | ## 324 | # Checks that two HTML strings are equivalent. That they contain the same elements and attributes with the associated values. 325 | # 326 | # assert_dom_equal 'Apples', 327 | # link_to("Apples", "http://www.example.com") 328 | # 329 | # See also Minitest::Rails::Expectations#must_dom_equal 330 | # 331 | # :method: assert_dom_equal 332 | # :call-seq: assert_dom_equal(expected, actual, message = nil) 333 | 334 | ## 335 | # Checks that two HTML strings are not equivalent. That they do not contain the same elements and attributes with the associated values. 336 | # 337 | # assert_dom_not_equal 'Oranges', 338 | # link_to("Apples", "http://www.example.com") 339 | # 340 | # See also Minitest::Rails::Expectations#wont_dom_equal 341 | # 342 | # :method: assert_dom_not_equal 343 | # :call-seq: assert_dom_not_equal(expected, actual, message = nil) 344 | 345 | ## 346 | # Checks that two HTML strings are not equivalent. That they do not contain the same elements and attributes with the associated values. 347 | # 348 | # refute_dom_equal 'Oranges', 349 | # link_to("Apples", "http://www.example.com") 350 | # 351 | # See also Minitest::Rails::Expectations#wont_dom_equal 352 | # 353 | # :method: assert_dom_equal 354 | # :call-seq: assert_dom_equal(expected, actual, message = nil) 355 | alias refute_dom_equal assert_dom_not_equal 356 | end 357 | --------------------------------------------------------------------------------