├── Manifest.txt ├── Rakefile ├── .autotest ├── test └── minitest │ └── test_focus.rb ├── lib └── minitest │ ├── focus_plugin.rb │ └── focus.rb ├── History.rdoc └── README.rdoc /Manifest.txt: -------------------------------------------------------------------------------- 1 | .autotest 2 | History.rdoc 3 | Manifest.txt 4 | README.rdoc 5 | Rakefile 6 | lib/minitest/focus.rb 7 | lib/minitest/focus_plugin.rb 8 | test/minitest/test_focus.rb 9 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # -*- ruby -*- 2 | 3 | require "rubygems" 4 | require "hoe" 5 | 6 | Hoe.plugin :isolate 7 | Hoe.plugin :seattlerb 8 | 9 | Hoe.add_include_dirs "../../minitest/dev/lib" 10 | 11 | Hoe.spec "minitest-focus" do 12 | developer "Ryan Davis", "ryand-ruby@zenspider.com" 13 | license "MIT" 14 | 15 | dependency "minitest", [">= 4", "< 6"] 16 | end 17 | 18 | # vim: syntax=ruby 19 | -------------------------------------------------------------------------------- /.autotest: -------------------------------------------------------------------------------- 1 | # -*- ruby -*- 2 | 3 | require "autotest/restart" 4 | 5 | Autotest.add_hook :initialize do |at| 6 | at.testlib = "minitest/autorun" 7 | at.add_exception "tmp" 8 | 9 | # at.extra_files << "../some/external/dependency.rb" 10 | # 11 | # at.libs << ":../some/external" 12 | # 13 | # at.add_exception "vendor" 14 | # 15 | # at.add_mapping(/dependency.rb/) do |f, _| 16 | # at.files_matching(/test_.*rb$/) 17 | # end 18 | # 19 | # %w(TestA TestB).each do |klass| 20 | # at.extra_class_map[klass] = "test/test_misc.rb" 21 | # end 22 | end 23 | 24 | # Autotest.add_hook :run_command do |at| 25 | # system "rake build" 26 | # end 27 | -------------------------------------------------------------------------------- /test/minitest/test_focus.rb: -------------------------------------------------------------------------------- 1 | require "minitest/autorun" 2 | require "minitest/focus" 3 | 4 | class MyTest1 < Minitest::Test 5 | def test_fail; flunk; end 6 | focus; def test_method; pass; end 7 | focus def test_method2; pass; end 8 | focus \ 9 | def test_method3; pass; end 10 | def test_method_edgecase; flunk; end 11 | end 12 | 13 | describe "MyTest2" do 14 | it "is ignored" do flunk end 15 | focus; it "does something" do pass end 16 | focus it("does something else") { pass } # stupid block precedence needs {} 17 | it "bombs" do flunk end 18 | focus; it "has non-word ['chars'" do pass end # Will raise invalid RegExp unless correctly escaped 19 | end 20 | -------------------------------------------------------------------------------- /lib/minitest/focus_plugin.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Minitest 4 | def self.plugin_focus_options opts, options 5 | opts.on "--no-focus", "Disable `focus` calls in tests." do |n| 6 | @nofocus = true 7 | end 8 | end 9 | 10 | def self.plugin_focus_init options # :nodoc: 11 | return unless Minitest::Test.respond_to? :filtered_names 12 | return if Minitest::Test.filtered_names.empty? 13 | 14 | if options[:filter] then 15 | order = %w[ `focus` --name ] 16 | a, b = @nofocus ? order : order.reverse 17 | extra = " Use --no-focus to override." unless @nofocus 18 | warn "Ignoring #{a} filters in favor of #{b} filters.#{extra}" 19 | warn "" 20 | end 21 | 22 | return if @nofocus 23 | 24 | re = "/^(#{Regexp.union(Minitest::Test.filtered_names).source})$/" 25 | options[:filter] = re 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /History.rdoc: -------------------------------------------------------------------------------- 1 | === 1.4.0 / 2023-07-11 2 | 3 | * 1 minor enhancement: 4 | 5 | * Added --no-focus flag to disable focus and allow --name args to override. 6 | 7 | === 1.3.1 / 2021-05-26 8 | 9 | * 1 bug fix: 10 | 11 | * Fixed missing require. (ryanseys) 12 | 13 | === 1.3.0 / 2021-05-22 14 | 15 | * 1 major enhancement: 16 | 17 | * Removed minitest4 support. 18 | 19 | * 2 minor enhancements: 20 | 21 | * Added support for `focus def test_method`. 22 | * Improved documentation for both test- and spec-style. 23 | 24 | === 1.2.1 / 2020-06-14 25 | 26 | * 1 bug fix: 27 | 28 | * Prevent a crash if the gem is installed but never required. (dazuma) 29 | 30 | === 1.2.0 / 2020-05-15 31 | 32 | * 1 major enhancement: 33 | 34 | * Converted to a minitest plugin. (jbourassa) 35 | 36 | === 1.1.2 / 2015-07-25 37 | 38 | * 1 bug fix: 39 | 40 | * Fixed focus handling when run under Rake's rake_test_loader.rb. 41 | 42 | === 1.1.1 / 2015-03-12 43 | 44 | * 1 minor enhancement: 45 | 46 | * Escape method names in filter regexp. (ddiachkov) 47 | 48 | === 1.1.0 / 2013-11-07 49 | 50 | * 1 major enhancement: 51 | 52 | * Minitest 5 compatibility. 53 | * Still works on minitest 4. 54 | 55 | === 1.0.0 / 2013-01-07 56 | 57 | * 1 major enhancement 58 | 59 | * Birthday! 60 | -------------------------------------------------------------------------------- /lib/minitest/focus.rb: -------------------------------------------------------------------------------- 1 | require "minitest/test" 2 | 3 | class Minitest::Test # :nodoc: 4 | class Focus # :nodoc: 5 | VERSION = "1.4.0" # :nodoc: 6 | end 7 | 8 | @@filtered_names = [] # :nodoc: 9 | 10 | def self.add_to_filter name 11 | @@filtered_names << "#{self}##{name}" 12 | end 13 | 14 | def self.filtered_names 15 | @@filtered_names 16 | end 17 | 18 | ## 19 | # Focus on the next test defined. Cumulative. Equivalent to 20 | # running with command line arg: -n /test_name|.../ 21 | # 22 | # class MyTest < Minitest::Test 23 | # 24 | # # direct approach 25 | # focus def test_method1 # will run 26 | # ... 27 | # end 28 | # 29 | # # indirect approach 30 | # focus 31 | # def test_method2 # will run 32 | # ... 33 | # end 34 | # 35 | # def test_method3 # will NOT run 36 | # ... 37 | # end 38 | # end 39 | 40 | def self.focus name = nil 41 | if name then 42 | add_to_filter name 43 | else 44 | set_focus_trap 45 | end 46 | end 47 | 48 | ## 49 | # Sets a one-off method_added callback to set focus on the method 50 | # defined next. 51 | 52 | def self.set_focus_trap 53 | meta = class << self; self; end 54 | 55 | meta.send :define_method, :method_added do |name| 56 | add_to_filter name 57 | 58 | meta.send :remove_method, :method_added 59 | end 60 | end 61 | end 62 | -------------------------------------------------------------------------------- /README.rdoc: -------------------------------------------------------------------------------- 1 | = minitest-focus 2 | 3 | home :: https://github.com/seattlerb/minitest-focus 4 | rdoc :: http://docs.seattlerb.org/minitest-focus 5 | 6 | == DESCRIPTION: 7 | 8 | Allows you to focus on a few tests with ease without having to use 9 | command-line arguments. Good for tools like guard that don't have 10 | enough brains to understand test output. Cf. minitest-autotest (an 11 | example of a test runner with strong testing logic). 12 | 13 | Inspired by https://github.com/seattlerb/minitest/issues/213 14 | 15 | == FEATURES/PROBLEMS: 16 | 17 | * `focus` class method allows you to specify that the next test 18 | defined should be run. 19 | * Use --no-focus to temporarily disable or override with --name 20 | arguments. 21 | 22 | == SYNOPSIS: 23 | 24 | require "minitest/autorun" 25 | require "minitest/focus" 26 | 27 | class MyTest < Minitest::Test 28 | def test_unrelated; ...; end # will NOT run 29 | 30 | focus def test_method2; ...; end # will run (direct--preferred) 31 | 32 | focus 33 | def test_method; ...; end # will run (indirect) 34 | 35 | def test_method_edgecase; ...; end # will NOT run 36 | end 37 | 38 | # or, with spec-style: 39 | 40 | describe "MyTest2" do 41 | focus; it "does something" do pass end 42 | focus it("does something else") { pass } # block precedence needs {} 43 | end 44 | 45 | == REQUIREMENTS: 46 | 47 | * minitest 5+ 48 | 49 | == INSTALL: 50 | 51 | * sudo gem install minitest-focus 52 | 53 | == LICENSE: 54 | 55 | (The MIT License) 56 | 57 | Copyright (c) Ryan Davis, seattle.rb 58 | 59 | Permission is hereby granted, free of charge, to any person obtaining 60 | a copy of this software and associated documentation files (the 61 | 'Software'), to deal in the Software without restriction, including 62 | without limitation the rights to use, copy, modify, merge, publish, 63 | distribute, sublicense, and/or sell copies of the Software, and to 64 | permit persons to whom the Software is furnished to do so, subject to 65 | the following conditions: 66 | 67 | The above copyright notice and this permission notice shall be 68 | included in all copies or substantial portions of the Software. 69 | 70 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 71 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 72 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 73 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 74 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 75 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 76 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 77 | --------------------------------------------------------------------------------