From 94be3130833322da7b17a520cc7ed9994f421874 Mon Sep 17 00:00:00 2001 From: 3v0k4 Date: Tue, 23 Dec 2025 13:38:44 +0100 Subject: [PATCH 1/3] feat: support minitest v6 --- CHANGELOG.md | 1 + lib/knapsack_pro/adapters/minitest_adapter.rb | 18 +-- rails-app-with-knapsack_pro/Gemfile | 5 +- rails-app-with-knapsack_pro/Gemfile.lock | 153 +++++++++--------- 4 files changed, 91 insertions(+), 86 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 02564053..975bd9e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ * (minor) Remove the internal `KNAPSACK_PRO_MODE` ENV. For gem development purposes `KNAPSACK_PRO_ENDPOINT` can be used instead. * (patch) Print only `KNAPSACK_PRO_*` ENVs when the connection fails (excluding `TOKEN`). +* (patch) Support minitest v6; this also ensures that timing for shared examples defined in file1 and included in file2 are attributed to file2 ### 9.0.0 diff --git a/lib/knapsack_pro/adapters/minitest_adapter.rb b/lib/knapsack_pro/adapters/minitest_adapter.rb index 35f1ac6b..f099d2b8 100644 --- a/lib/knapsack_pro/adapters/minitest_adapter.rb +++ b/lib/knapsack_pro/adapters/minitest_adapter.rb @@ -9,17 +9,15 @@ class MinitestAdapter < BaseAdapter def self.test_path(obj) # Pick the first public method in the class itself, that starts with "test_" test_method_name = obj.public_methods(false).select{|m| m =~ /^test_/ }.first - if test_method_name.nil? - # case for shared examples - method_object = obj.method(obj.location.sub(/.*?test_/, 'test_')) - else - method_object = obj.method(test_method_name) - end - full_test_path = method_object.source_location.first + source_location = + if test_method_name.nil? # Shared examples + Object.const_source_location(obj.class.to_s) + else + obj.method(test_method_name).source_location + end + full_test_path = source_location.first parent_of_test_dir_regexp = Regexp.new("^#{@@parent_of_test_dir}") - test_path = full_test_path.gsub(parent_of_test_dir_regexp, '.') - # test_path will look like ./test/dir/unit_test.rb - test_path + full_test_path.gsub(parent_of_test_dir_regexp, '.') end # See how to write hooks and plugins diff --git a/rails-app-with-knapsack_pro/Gemfile b/rails-app-with-knapsack_pro/Gemfile index 668dd2db..2eb9e61a 100644 --- a/rails-app-with-knapsack_pro/Gemfile +++ b/rails-app-with-knapsack_pro/Gemfile @@ -1,7 +1,7 @@ source "https://rubygems.org" -# Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main" -gem "rails", "~> 8.1.1" +# NOTE: Need edge Rails to run minitest v6 (https://github.com/rails/rails/pull/56202) +gem "rails", github: "rails/rails", branch: "main" # The modern asset pipeline for Rails [https://github.com/rails/propshaft] gem "propshaft" # Use sqlite3 as the database for Active Record @@ -112,4 +112,3 @@ end gem 'turnip', '~> 4.4' gem 'juniter' -gem 'minitest', '~> 5.27' diff --git a/rails-app-with-knapsack_pro/Gemfile.lock b/rails-app-with-knapsack_pro/Gemfile.lock index a59313b5..eda9f9f3 100644 --- a/rails-app-with-knapsack_pro/Gemfile.lock +++ b/rails-app-with-knapsack_pro/Gemfile.lock @@ -1,37 +1,31 @@ -PATH - remote: .. +GIT + remote: https://github.com/rails/rails.git + revision: 4841b792ae84d6cd3150620202ae4b82117da326 + branch: main specs: - knapsack_pro (9.0.0) - rake - -GEM - remote: https://rubygems.org/ - specs: - action_text-trix (2.1.15) - railties - actioncable (8.1.1) - actionpack (= 8.1.1) - activesupport (= 8.1.1) + actioncable (8.2.0.alpha) + actionpack (= 8.2.0.alpha) + activesupport (= 8.2.0.alpha) nio4r (~> 2.0) websocket-driver (>= 0.6.1) zeitwerk (~> 2.6) - actionmailbox (8.1.1) - actionpack (= 8.1.1) - activejob (= 8.1.1) - activerecord (= 8.1.1) - activestorage (= 8.1.1) - activesupport (= 8.1.1) + actionmailbox (8.2.0.alpha) + actionpack (= 8.2.0.alpha) + activejob (= 8.2.0.alpha) + activerecord (= 8.2.0.alpha) + activestorage (= 8.2.0.alpha) + activesupport (= 8.2.0.alpha) mail (>= 2.8.0) - actionmailer (8.1.1) - actionpack (= 8.1.1) - actionview (= 8.1.1) - activejob (= 8.1.1) - activesupport (= 8.1.1) + actionmailer (8.2.0.alpha) + actionpack (= 8.2.0.alpha) + actionview (= 8.2.0.alpha) + activejob (= 8.2.0.alpha) + activesupport (= 8.2.0.alpha) mail (>= 2.8.0) rails-dom-testing (~> 2.2) - actionpack (8.1.1) - actionview (= 8.1.1) - activesupport (= 8.1.1) + actionpack (8.2.0.alpha) + actionview (= 8.2.0.alpha) + activesupport (= 8.2.0.alpha) nokogiri (>= 1.8.5) rack (>= 2.2.4) rack-session (>= 1.0.1) @@ -39,36 +33,36 @@ GEM rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) useragent (~> 0.16) - actiontext (8.1.1) + actiontext (8.2.0.alpha) action_text-trix (~> 2.1.15) - actionpack (= 8.1.1) - activerecord (= 8.1.1) - activestorage (= 8.1.1) - activesupport (= 8.1.1) + actionpack (= 8.2.0.alpha) + activerecord (= 8.2.0.alpha) + activestorage (= 8.2.0.alpha) + activesupport (= 8.2.0.alpha) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (8.1.1) - activesupport (= 8.1.1) + actionview (8.2.0.alpha) + activesupport (= 8.2.0.alpha) builder (~> 3.1) erubi (~> 1.11) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - activejob (8.1.1) - activesupport (= 8.1.1) + activejob (8.2.0.alpha) + activesupport (= 8.2.0.alpha) globalid (>= 0.3.6) - activemodel (8.1.1) - activesupport (= 8.1.1) - activerecord (8.1.1) - activemodel (= 8.1.1) - activesupport (= 8.1.1) + activemodel (8.2.0.alpha) + activesupport (= 8.2.0.alpha) + activerecord (8.2.0.alpha) + activemodel (= 8.2.0.alpha) + activesupport (= 8.2.0.alpha) timeout (>= 0.4.0) - activestorage (8.1.1) - actionpack (= 8.1.1) - activejob (= 8.1.1) - activerecord (= 8.1.1) - activesupport (= 8.1.1) + activestorage (8.2.0.alpha) + actionpack (= 8.2.0.alpha) + activejob (= 8.2.0.alpha) + activerecord (= 8.2.0.alpha) + activesupport (= 8.2.0.alpha) marcel (~> 1.0) - activesupport (8.1.1) + activesupport (8.2.0.alpha) base64 bigdecimal concurrent-ruby (~> 1.0, >= 1.3.1) @@ -78,9 +72,45 @@ GEM json logger (>= 1.4.2) minitest (>= 5.1) + psych (>= 4) securerandom (>= 0.3) tzinfo (~> 2.0, >= 2.0.5) uri (>= 0.13.1) + rails (8.2.0.alpha) + actioncable (= 8.2.0.alpha) + actionmailbox (= 8.2.0.alpha) + actionmailer (= 8.2.0.alpha) + actionpack (= 8.2.0.alpha) + actiontext (= 8.2.0.alpha) + actionview (= 8.2.0.alpha) + activejob (= 8.2.0.alpha) + activemodel (= 8.2.0.alpha) + activerecord (= 8.2.0.alpha) + activestorage (= 8.2.0.alpha) + activesupport (= 8.2.0.alpha) + bundler (>= 1.15.0) + railties (= 8.2.0.alpha) + railties (8.2.0.alpha) + actionpack (= 8.2.0.alpha) + activesupport (= 8.2.0.alpha) + irb (~> 1.13) + rackup (>= 1.0.0) + rake (>= 12.2) + thor (~> 1.0, >= 1.2.2) + tsort (>= 0.2) + zeitwerk (~> 2.6) + +PATH + remote: .. + specs: + knapsack_pro (9.0.0) + rake + +GEM + remote: https://rubygems.org/ + specs: + action_text-trix (2.1.15) + railties addressable (2.8.8) public_suffix (>= 2.0.2, < 8.0) ast (2.4.3) @@ -255,7 +285,8 @@ GEM mini_magick (5.3.1) logger mini_mime (1.1.5) - minitest (5.27.0) + minitest (6.0.0) + prism (~> 1.5) msgpack (1.8.0) multi_test (1.1.0) net-imap (0.6.2) @@ -319,20 +350,6 @@ GEM rack (>= 1.3) rackup (2.3.1) rack (>= 3) - rails (8.1.1) - actioncable (= 8.1.1) - actionmailbox (= 8.1.1) - actionmailer (= 8.1.1) - actionpack (= 8.1.1) - actiontext (= 8.1.1) - actionview (= 8.1.1) - activejob (= 8.1.1) - activemodel (= 8.1.1) - activerecord (= 8.1.1) - activestorage (= 8.1.1) - activesupport (= 8.1.1) - bundler (>= 1.15.0) - railties (= 8.1.1) rails-controller-testing (1.0.5) actionpack (>= 5.0.1.rc1) actionview (>= 5.0.1.rc1) @@ -344,15 +361,6 @@ GEM rails-html-sanitizer (1.6.2) loofah (~> 2.21) nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0) - railties (8.1.1) - actionpack (= 8.1.1) - activesupport (= 8.1.1) - irb (~> 1.13) - rackup (>= 1.0.0) - rake (>= 12.2) - thor (~> 1.0, >= 1.2.2) - tsort (>= 0.2) - zeitwerk (~> 2.6) rainbow (3.1.1) rake (13.3.1) rb-fsevent (0.11.2) @@ -585,10 +593,9 @@ DEPENDENCIES kamal knapsack_pro! listen - minitest (~> 5.27) propshaft puma (>= 5.0) - rails (~> 8.1.1) + rails! rails-controller-testing rspec-rails rspec-retry From 22714a7273a718fdc503f892fdf4224b43a6a6d9 Mon Sep 17 00:00:00 2001 From: 3v0k4 Date: Tue, 23 Dec 2025 14:21:00 +0100 Subject: [PATCH 2/3] feat: simpler support for minitest v6 --- CHANGELOG.md | 2 +- lib/knapsack_pro/adapters/minitest_adapter.rb | 14 +++----------- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 975bd9e2..fefb3fb7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ * (minor) Remove the internal `KNAPSACK_PRO_MODE` ENV. For gem development purposes `KNAPSACK_PRO_ENDPOINT` can be used instead. * (patch) Print only `KNAPSACK_PRO_*` ENVs when the connection fails (excluding `TOKEN`). -* (patch) Support minitest v6; this also ensures that timing for shared examples defined in file1 and included in file2 are attributed to file2 +* (patch) Support minitest v6 ### 9.0.0 diff --git a/lib/knapsack_pro/adapters/minitest_adapter.rb b/lib/knapsack_pro/adapters/minitest_adapter.rb index f099d2b8..abb2a0be 100644 --- a/lib/knapsack_pro/adapters/minitest_adapter.rb +++ b/lib/knapsack_pro/adapters/minitest_adapter.rb @@ -7,17 +7,9 @@ class MinitestAdapter < BaseAdapter @@parent_of_test_dir = nil def self.test_path(obj) - # Pick the first public method in the class itself, that starts with "test_" - test_method_name = obj.public_methods(false).select{|m| m =~ /^test_/ }.first - source_location = - if test_method_name.nil? # Shared examples - Object.const_source_location(obj.class.to_s) - else - obj.method(test_method_name).source_location - end - full_test_path = source_location.first - parent_of_test_dir_regexp = Regexp.new("^#{@@parent_of_test_dir}") - full_test_path.gsub(parent_of_test_dir_regexp, '.') + test_method_name = obj.class.runnable_methods.first + path, _line = obj.method(test_method_name).source_location + path.gsub(Regexp.new("^#{@@parent_of_test_dir}"), '.') end # See how to write hooks and plugins From 8942c359362acad65b9ea70c1b92a70ce6ed0b25 Mon Sep 17 00:00:00 2001 From: 3v0k4 Date: Tue, 23 Dec 2025 14:42:16 +0100 Subject: [PATCH 3/3] feat: better support for minitest v6 --- CHANGELOG.md | 2 +- lib/knapsack_pro/adapters/minitest_adapter.rb | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fefb3fb7..975bd9e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ * (minor) Remove the internal `KNAPSACK_PRO_MODE` ENV. For gem development purposes `KNAPSACK_PRO_ENDPOINT` can be used instead. * (patch) Print only `KNAPSACK_PRO_*` ENVs when the connection fails (excluding `TOKEN`). -* (patch) Support minitest v6 +* (patch) Support minitest v6; this also ensures that timing for shared examples defined in file1 and included in file2 are attributed to file2 ### 9.0.0 diff --git a/lib/knapsack_pro/adapters/minitest_adapter.rb b/lib/knapsack_pro/adapters/minitest_adapter.rb index abb2a0be..cec9d97a 100644 --- a/lib/knapsack_pro/adapters/minitest_adapter.rb +++ b/lib/knapsack_pro/adapters/minitest_adapter.rb @@ -7,8 +7,13 @@ class MinitestAdapter < BaseAdapter @@parent_of_test_dir = nil def self.test_path(obj) - test_method_name = obj.class.runnable_methods.first - path, _line = obj.method(test_method_name).source_location + path, _line = + begin + Object.const_source_location(obj.class.to_s) + rescue NameError + test_method_name = obj.class.runnable_methods.first + obj.method(test_method_name).source_location + end path.gsub(Regexp.new("^#{@@parent_of_test_dir}"), '.') end