From 76bf1c1a762e7264ce31672fa3d74296c6df25f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Pacana?= Date: Wed, 29 Apr 2026 18:02:35 +0200 Subject: [PATCH 1/3] Follow structure of minitest integration One integration, one subdirectory with Gemfile versions. This would further allow nesting integration-specific tests under integration root. --- ruby/spec/integration/mutant/rspec_spec.rb | 2 +- ruby/test_app/{rspec3.10/Gemfile => rspec/Gemfile.rspec_3_10} | 0 .../{rspec3.10/Gemfile.lock => rspec/Gemfile.rspec_3_10.lock} | 0 ruby/test_app/{rspec3.11/Gemfile => rspec/Gemfile.rspec_3_11} | 0 .../{rspec3.11/Gemfile.lock => rspec/Gemfile.rspec_3_11.lock} | 0 ruby/test_app/{rspec3.12/Gemfile => rspec/Gemfile.rspec_3_12} | 0 .../{rspec3.12/Gemfile.lock => rspec/Gemfile.rspec_3_12.lock} | 0 ruby/test_app/{rspec3.13/Gemfile => rspec/Gemfile.rspec_3_13} | 0 .../{rspec3.13/Gemfile.lock => rspec/Gemfile.rspec_3_13.lock} | 0 ruby/test_app/{rspec3.8/Gemfile => rspec/Gemfile.rspec_3_8} | 0 .../{rspec3.8/Gemfile.lock => rspec/Gemfile.rspec_3_8.lock} | 0 ruby/test_app/{rspec3.9/Gemfile => rspec/Gemfile.rspec_3_9} | 0 .../{rspec3.9/Gemfile.lock => rspec/Gemfile.rspec_3_9.lock} | 0 ruby/test_app/{rspec4.0/Gemfile => rspec/Gemfile.rspec_4_0} | 0 .../{rspec4.0/Gemfile.lock => rspec/Gemfile.rspec_4_0.lock} | 0 15 files changed, 1 insertion(+), 1 deletion(-) rename ruby/test_app/{rspec3.10/Gemfile => rspec/Gemfile.rspec_3_10} (100%) rename ruby/test_app/{rspec3.10/Gemfile.lock => rspec/Gemfile.rspec_3_10.lock} (100%) rename ruby/test_app/{rspec3.11/Gemfile => rspec/Gemfile.rspec_3_11} (100%) rename ruby/test_app/{rspec3.11/Gemfile.lock => rspec/Gemfile.rspec_3_11.lock} (100%) rename ruby/test_app/{rspec3.12/Gemfile => rspec/Gemfile.rspec_3_12} (100%) rename ruby/test_app/{rspec3.12/Gemfile.lock => rspec/Gemfile.rspec_3_12.lock} (100%) rename ruby/test_app/{rspec3.13/Gemfile => rspec/Gemfile.rspec_3_13} (100%) rename ruby/test_app/{rspec3.13/Gemfile.lock => rspec/Gemfile.rspec_3_13.lock} (100%) rename ruby/test_app/{rspec3.8/Gemfile => rspec/Gemfile.rspec_3_8} (100%) rename ruby/test_app/{rspec3.8/Gemfile.lock => rspec/Gemfile.rspec_3_8.lock} (100%) rename ruby/test_app/{rspec3.9/Gemfile => rspec/Gemfile.rspec_3_9} (100%) rename ruby/test_app/{rspec3.9/Gemfile.lock => rspec/Gemfile.rspec_3_9.lock} (100%) rename ruby/test_app/{rspec4.0/Gemfile => rspec/Gemfile.rspec_4_0} (100%) rename ruby/test_app/{rspec4.0/Gemfile.lock => rspec/Gemfile.rspec_4_0.lock} (100%) diff --git a/ruby/spec/integration/mutant/rspec_spec.rb b/ruby/spec/integration/mutant/rspec_spec.rb index aa2fdaead..a65eea421 100644 --- a/ruby/spec/integration/mutant/rspec_spec.rb +++ b/ruby/spec/integration/mutant/rspec_spec.rb @@ -13,7 +13,7 @@ %w[3.8 3.9 3.10 3.11 3.12 3.13 4.0].each do |version| context "RSpec #{version}" do - let(:gemfile) { "rspec#{version}/Gemfile" } + let(:gemfile) { "rspec/Gemfile.rspec_#{version.tr('.', '_')}" } it_behaves_like 'framework integration' diff --git a/ruby/test_app/rspec3.10/Gemfile b/ruby/test_app/rspec/Gemfile.rspec_3_10 similarity index 100% rename from ruby/test_app/rspec3.10/Gemfile rename to ruby/test_app/rspec/Gemfile.rspec_3_10 diff --git a/ruby/test_app/rspec3.10/Gemfile.lock b/ruby/test_app/rspec/Gemfile.rspec_3_10.lock similarity index 100% rename from ruby/test_app/rspec3.10/Gemfile.lock rename to ruby/test_app/rspec/Gemfile.rspec_3_10.lock diff --git a/ruby/test_app/rspec3.11/Gemfile b/ruby/test_app/rspec/Gemfile.rspec_3_11 similarity index 100% rename from ruby/test_app/rspec3.11/Gemfile rename to ruby/test_app/rspec/Gemfile.rspec_3_11 diff --git a/ruby/test_app/rspec3.11/Gemfile.lock b/ruby/test_app/rspec/Gemfile.rspec_3_11.lock similarity index 100% rename from ruby/test_app/rspec3.11/Gemfile.lock rename to ruby/test_app/rspec/Gemfile.rspec_3_11.lock diff --git a/ruby/test_app/rspec3.12/Gemfile b/ruby/test_app/rspec/Gemfile.rspec_3_12 similarity index 100% rename from ruby/test_app/rspec3.12/Gemfile rename to ruby/test_app/rspec/Gemfile.rspec_3_12 diff --git a/ruby/test_app/rspec3.12/Gemfile.lock b/ruby/test_app/rspec/Gemfile.rspec_3_12.lock similarity index 100% rename from ruby/test_app/rspec3.12/Gemfile.lock rename to ruby/test_app/rspec/Gemfile.rspec_3_12.lock diff --git a/ruby/test_app/rspec3.13/Gemfile b/ruby/test_app/rspec/Gemfile.rspec_3_13 similarity index 100% rename from ruby/test_app/rspec3.13/Gemfile rename to ruby/test_app/rspec/Gemfile.rspec_3_13 diff --git a/ruby/test_app/rspec3.13/Gemfile.lock b/ruby/test_app/rspec/Gemfile.rspec_3_13.lock similarity index 100% rename from ruby/test_app/rspec3.13/Gemfile.lock rename to ruby/test_app/rspec/Gemfile.rspec_3_13.lock diff --git a/ruby/test_app/rspec3.8/Gemfile b/ruby/test_app/rspec/Gemfile.rspec_3_8 similarity index 100% rename from ruby/test_app/rspec3.8/Gemfile rename to ruby/test_app/rspec/Gemfile.rspec_3_8 diff --git a/ruby/test_app/rspec3.8/Gemfile.lock b/ruby/test_app/rspec/Gemfile.rspec_3_8.lock similarity index 100% rename from ruby/test_app/rspec3.8/Gemfile.lock rename to ruby/test_app/rspec/Gemfile.rspec_3_8.lock diff --git a/ruby/test_app/rspec3.9/Gemfile b/ruby/test_app/rspec/Gemfile.rspec_3_9 similarity index 100% rename from ruby/test_app/rspec3.9/Gemfile rename to ruby/test_app/rspec/Gemfile.rspec_3_9 diff --git a/ruby/test_app/rspec3.9/Gemfile.lock b/ruby/test_app/rspec/Gemfile.rspec_3_9.lock similarity index 100% rename from ruby/test_app/rspec3.9/Gemfile.lock rename to ruby/test_app/rspec/Gemfile.rspec_3_9.lock diff --git a/ruby/test_app/rspec4.0/Gemfile b/ruby/test_app/rspec/Gemfile.rspec_4_0 similarity index 100% rename from ruby/test_app/rspec4.0/Gemfile rename to ruby/test_app/rspec/Gemfile.rspec_4_0 diff --git a/ruby/test_app/rspec4.0/Gemfile.lock b/ruby/test_app/rspec/Gemfile.rspec_4_0.lock similarity index 100% rename from ruby/test_app/rspec4.0/Gemfile.lock rename to ruby/test_app/rspec/Gemfile.rspec_4_0.lock From f6494185e6bdcb96bf4834104512244c0c97ef3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Pacana?= Date: Wed, 29 Apr 2026 18:09:14 +0200 Subject: [PATCH 2/3] Nest integration-specific tests under integration root This allows differentiating test cases with same patterns (i.e. **/test_*.rb) belonging to different test framework, which would break otherwise. --- ruby/spec/integration/mutant/minitest_spec.rb | 6 +++--- ruby/spec/integration/mutant/rspec_spec.rb | 6 +++--- ruby/spec/shared/framework_integration_behavior.rb | 4 ++-- .../{ => minitest}/test/unit/test_app/literal_test.rb | 0 ruby/test_app/{ => rspec}/spec/spec_helper.rb | 0 ruby/test_app/{ => rspec}/spec/unit/test_app/invalid.rb | 0 .../test_app/{ => rspec}/spec/unit/test_app/literal_spec.rb | 0 7 files changed, 8 insertions(+), 8 deletions(-) rename ruby/test_app/{ => minitest}/test/unit/test_app/literal_test.rb (100%) rename ruby/test_app/{ => rspec}/spec/spec_helper.rb (100%) rename ruby/test_app/{ => rspec}/spec/unit/test_app/invalid.rb (100%) rename ruby/test_app/{ => rspec}/spec/unit/test_app/literal_spec.rb (100%) diff --git a/ruby/spec/integration/mutant/minitest_spec.rb b/ruby/spec/integration/mutant/minitest_spec.rb index eefb8fcb1..76e54481a 100644 --- a/ruby/spec/integration/mutant/minitest_spec.rb +++ b/ruby/spec/integration/mutant/minitest_spec.rb @@ -5,14 +5,14 @@ %w[ bundle exec mutant run --include test - --include lib + --include ../lib --require test_app --integration minitest --usage opensource ] end - let(:gemfile) { 'minitest/Gemfile' } + let(:gemfile) { 'Gemfile' } - it_behaves_like 'framework integration' + it_behaves_like 'framework integration', :minitest end diff --git a/ruby/spec/integration/mutant/rspec_spec.rb b/ruby/spec/integration/mutant/rspec_spec.rb index a65eea421..106afa8e9 100644 --- a/ruby/spec/integration/mutant/rspec_spec.rb +++ b/ruby/spec/integration/mutant/rspec_spec.rb @@ -4,7 +4,7 @@ let(:base_cmd) do %w[ bundle exec mutant run - --include lib + --include ../lib --integration rspec --require test_app --usage opensource @@ -13,9 +13,9 @@ %w[3.8 3.9 3.10 3.11 3.12 3.13 4.0].each do |version| context "RSpec #{version}" do - let(:gemfile) { "rspec/Gemfile.rspec_#{version.tr('.', '_')}" } + let(:gemfile) { "Gemfile.rspec_#{version.tr('.', '_')}" } - it_behaves_like 'framework integration' + it_behaves_like 'framework integration', :rspec it 'handles invalid rspec' do Dir.chdir('test_app') do diff --git a/ruby/spec/shared/framework_integration_behavior.rb b/ruby/spec/shared/framework_integration_behavior.rb index 41aaa7769..b0821b573 100644 --- a/ruby/spec/shared/framework_integration_behavior.rb +++ b/ruby/spec/shared/framework_integration_behavior.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -RSpec.shared_examples_for 'framework integration' do +RSpec.shared_examples_for 'framework integration' do |integration_name| def system_with_gemfile(*command) Kernel.system( { @@ -14,7 +14,7 @@ def system_with_gemfile(*command) around do |example| Bundler.with_unbundled_env do - Dir.chdir(TestApp.root) do + Dir.chdir(File.join(TestApp.root, integration_name.to_s)) do Kernel.system( { 'BUNDLE_PATH' => 'vendor/bundle' }, 'bundle', 'install', '--gemfile', gemfile diff --git a/ruby/test_app/test/unit/test_app/literal_test.rb b/ruby/test_app/minitest/test/unit/test_app/literal_test.rb similarity index 100% rename from ruby/test_app/test/unit/test_app/literal_test.rb rename to ruby/test_app/minitest/test/unit/test_app/literal_test.rb diff --git a/ruby/test_app/spec/spec_helper.rb b/ruby/test_app/rspec/spec/spec_helper.rb similarity index 100% rename from ruby/test_app/spec/spec_helper.rb rename to ruby/test_app/rspec/spec/spec_helper.rb diff --git a/ruby/test_app/spec/unit/test_app/invalid.rb b/ruby/test_app/rspec/spec/unit/test_app/invalid.rb similarity index 100% rename from ruby/test_app/spec/unit/test_app/invalid.rb rename to ruby/test_app/rspec/spec/unit/test_app/invalid.rb diff --git a/ruby/test_app/spec/unit/test_app/literal_spec.rb b/ruby/test_app/rspec/spec/unit/test_app/literal_spec.rb similarity index 100% rename from ruby/test_app/spec/unit/test_app/literal_spec.rb rename to ruby/test_app/rspec/spec/unit/test_app/literal_spec.rb From f6b6f88a0c766916a2c221892ae00e397810d83f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Pacana?= Date: Wed, 29 Apr 2026 16:03:10 +0200 Subject: [PATCH 3/3] Add tldr integration --- .github/workflows/ci.yml | 1 + manager/src/ruby.rs | 11 + ruby/.rubocop.yml | 1 + ruby/lib/mutant/integration/tldr.rb | 197 ++++++++++++++++++ ruby/lib/mutant/tldr/coverage.rb | 51 +++++ ruby/mutant-tldr.gemspec | 26 +++ ruby/mutant.gemspec | 2 +- ruby/spec/integration/mutant/tldr_spec.rb | 18 ++ ruby/test_app/tldr/Gemfile | 7 + ruby/test_app/tldr/Gemfile.lock | 109 ++++++++++ .../tldr/test/unit/test_app/literal_test.rb | 17 ++ 11 files changed, 439 insertions(+), 1 deletion(-) create mode 100644 ruby/lib/mutant/integration/tldr.rb create mode 100644 ruby/lib/mutant/tldr/coverage.rb create mode 100644 ruby/mutant-tldr.gemspec create mode 100644 ruby/spec/integration/mutant/tldr_spec.rb create mode 100644 ruby/test_app/tldr/Gemfile create mode 100644 ruby/test_app/tldr/Gemfile.lock create mode 100644 ruby/test_app/tldr/test/unit/test_app/literal_test.rb diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 569ad5142..a97a9295d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -77,6 +77,7 @@ jobs: - rspec integration minitest - rspec integration misc - rspec integration rspec + - rspec integration tldr - rspec unit - rubocop include: diff --git a/manager/src/ruby.rs b/manager/src/ruby.rs index e04b65d47..e39a012f4 100644 --- a/manager/src/ruby.rs +++ b/manager/src/ruby.rs @@ -278,6 +278,11 @@ pub mod rspec { /// Additional arguments arguments: Vec, }, + /// Run tldr integration specs + Tldr { + /// Additional arguments + arguments: Vec, + }, /// Run rspec integration specs Rspec { /// Additional arguments @@ -524,6 +529,12 @@ impl Runtime { &arguments, )) } + Some(rspec::integration::Command::Tldr { arguments }) => { + CommandConfig::ruby(bundle_exec_arguments( + &["rspec", "spec/integration", "-e", "tldr"], + &arguments, + )) + } Some(rspec::integration::Command::Rspec { arguments }) => { CommandConfig::ruby(bundle_exec_arguments( &["rspec", "spec/integration", "-e", "rspec"], diff --git a/ruby/.rubocop.yml b/ruby/.rubocop.yml index cf5a06f2e..caf21e460 100644 --- a/ruby/.rubocop.yml +++ b/ruby/.rubocop.yml @@ -214,4 +214,5 @@ Style/EndlessMethod: Style/OneClassPerFile: Exclude: - 'lib/mutant/integration/minitest.rb' + - 'lib/mutant/integration/tldr.rb' - 'spec/spec_helper.rb' diff --git a/ruby/lib/mutant/integration/tldr.rb b/ruby/lib/mutant/integration/tldr.rb new file mode 100644 index 000000000..3666bcf24 --- /dev/null +++ b/ruby/lib/mutant/integration/tldr.rb @@ -0,0 +1,197 @@ +# frozen_string_literal: true + +require 'mutant' +require 'tldr' +require 'mutant/tldr/coverage' + +class TLDR + module Run + # Prevent autorun from running tests when the VM closes. + # + # Mutant needs control about the exit status of the VM and the moment of test + # execution. + # + # @api private + # + # @return [nil] + def self.at_exit!(*); end + end # Run + + # Defang argv parsing — `tldr/autorun` evaluates `ArgvParser.new.parse(ARGV)` + # eagerly before passing the result to the no-op'd `at_exit!`, which would + # raise on mutant's own CLI flags. + class ArgvParser + def parse(*); end + end # ArgvParser +end # TLDR + +module Mutant + class Integration + # tldr integration + class Tldr < self + TEST_FILE_PATTERN = './test/**/{test_*,*_test}.rb' + IDENTIFICATION_FORMAT = 'tldr:%s#%s' + CONFIG_OPTIONS = { + cli_defaults: false, + config_path: nil, + emoji: false, + fail_fast: false, + helper_paths: [], + load_paths: [], + no_helper: true, + no_prepend: true, + parallel: false, + prepend_paths: [], + reporter: 'Mutant::Integration::Tldr::Reporter', + timeout: -1, + warnings: false + }.freeze + + # Quiet tldr reporter + class Reporter + def after_test(*) = nil + end # Reporter + + # Compose a test class with one of its test methods + class TestCase + include Adamantium, Anima.new(:tldr_test) + + # Identification string + # + # @return [String] + def identification = IDENTIFICATION_FORMAT % [klass, test_method] + memoize :identification + + # Run test case + # + # TLDR::Runner terminates via Kernel.exit after every run. Kernel.exit + # raises SystemExit, so we can safely catch that here and convert the + # runner status into mutant's boolean result. Timeouts and fail-fast are + # disabled in the config, avoiding TLDR's hard-exit paths. + # + # @param [TLDR::Config] config + # @param [TLDR::Strategizer::Strategy] strategy + # + # @return [Boolean] + def call(config, strategy) + runner = ::TLDR::Runner.new + runner.run(config, ::TLDR::Plan.new([tldr_test], strategy)) + rescue SystemExit => exception + exception.status.zero? + rescue StandardError + false + end + + # Parse expressions + # + # @param [ExpressionParser] parser + # + # @return [Array] + def expressions(parser) + klass.resolve_cover_expressions.to_a.map do |value| + parser.call(expand_constant(value)).from_right + end + end + + def klass = tldr_test.test_class + + def test_method = tldr_test.method_name.to_sym + + private + + def expand_constant(value) + case value + when Class, Module + "#{value.name}*" + else + value + end + end + end # TestCase + + private_constant(*constants(false)) + + # Setup integration + # + # @return [self] + def setup + plan + + self + end + + # Call test integration + # + # @param [Array] tests + # + # @return [Result::Test] + def call(tests) + test_cases = tests.map(&all_tests_index.public_method(:fetch)) + start = timer.now + + passed = test_cases.all? { |test_case| test_case.call(config, sequential_strategy) } + + Result::Test.new( + job_index: nil, + output: LogCapture::String.new(content: ''), + passed:, + runtime: timer.now - start + ) + end + + # All tests exposed by this integration + # + # @return [Array] + def all_tests = all_tests_index.keys + memoize :all_tests + + alias_method :available_tests, :all_tests + + private + + def all_tests_index + all_test_cases.to_h do |test_case| + [construct_test(test_case), test_case] + end + end + memoize :all_tests_index + + def construct_test(test_case) + Test.new( + id: test_case.identification, + expressions: test_case.expressions(expression_parser) + ) + end + + def all_test_cases + plan.tests.map do |test| + TestCase.new(tldr_test: test) + end + end + + def test_paths + Pathname.glob(TEST_FILE_PATTERN).map(&:to_s) + end + memoize :test_paths + + def config + ::TLDR::Config.new( + **CONFIG_OPTIONS, + paths: test_paths, + seed: world.random.srand + ).freeze + end + memoize :config + + def plan + ::TLDR::Planner.new.plan(config) + end + memoize :plan + + def sequential_strategy + ::TLDR::Strategizer::Strategy.new(parallel?: false) + end + memoize :sequential_strategy + end # Tldr + end # Integration +end # Mutant diff --git a/ruby/lib/mutant/tldr/coverage.rb b/ruby/lib/mutant/tldr/coverage.rb new file mode 100644 index 000000000..4a5439fb9 --- /dev/null +++ b/ruby/lib/mutant/tldr/coverage.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +require 'tldr' + +module Mutant + module Tldr + module Coverage + # Setup coverage declaration for current class + # + # @param [String] + # + # @example + # + # class MyTest < TLDR + # cover 'MyCode*' + # + # def test_some_stuff + # end + # end + # + # @api public + def cover(expression) + @cover_expressions = Set.new unless defined?(@cover_expressions) + + @cover_expressions << expression + end + + # Effective coverage expression + # + # @return [Set] + # + # @api private + def resolve_cover_expressions + return @cover_expressions if defined?(@cover_expressions) + + try_superclass_cover_expressions + end + + private + + def try_superclass_cover_expressions + return unless superclass.respond_to?(:resolve_cover_expressions) + + superclass.resolve_cover_expressions + end + + end # Coverage + end # Tldr +end # Mutant + +TLDR.extend(Mutant::Tldr::Coverage) diff --git a/ruby/mutant-tldr.gemspec b/ruby/mutant-tldr.gemspec new file mode 100644 index 000000000..2e395a831 --- /dev/null +++ b/ruby/mutant-tldr.gemspec @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +require_relative 'lib/mutant/version' + +Gem::Specification.new do |gem| + gem.name = 'mutant-tldr' + gem.version = Mutant::VERSION.dup + gem.authors = ['Markus Schirp'] + gem.email = %w[mbj@schirp-dso.com] + gem.description = 'tldr integration for mutant' + gem.summary = gem.description + gem.homepage = 'https://github.com/mbj/mutant' + gem.license = 'Nonstandard' + + gem.require_paths = %w[lib] + gem.files = %w[lib/mutant/tldr/coverage.rb lib/mutant/integration/tldr.rb] + + gem.extra_rdoc_files = %w[LICENSE] + + gem.required_ruby_version = '>= 3.3' + + gem.metadata['rubygems_mfa_required'] = 'true' + + gem.add_dependency('mutant', "= #{gem.version}") + gem.add_dependency('tldr', '~> 1.0') +end diff --git a/ruby/mutant.gemspec b/ruby/mutant.gemspec index 5d1d32ac4..d74710a78 100644 --- a/ruby/mutant.gemspec +++ b/ruby/mutant.gemspec @@ -14,7 +14,7 @@ Gem::Specification.new do |gem| gem.require_paths = %w[lib] - exclusion = Dir.glob('lib/mutant/{integration/{minitest,rspec}.rb,minitest/**.rb}') + exclusion = Dir.glob('lib/mutant/{integration/{minitest,rspec,tldr}.rb,{minitest,tldr}/**.rb}') gem.files = Dir.glob('{VERSION,lib/**/*}') - exclusion gem.extra_rdoc_files = %w[LICENSE] diff --git a/ruby/spec/integration/mutant/tldr_spec.rb b/ruby/spec/integration/mutant/tldr_spec.rb new file mode 100644 index 000000000..ce2d5cd77 --- /dev/null +++ b/ruby/spec/integration/mutant/tldr_spec.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +RSpec.describe 'tldr integration', mutant: false do + let(:base_cmd) do + %w[ + bundle exec mutant run + --include test + --include ../lib + --require test_app + --integration tldr + --usage opensource + ] + end + + let(:gemfile) { 'Gemfile' } + + it_behaves_like 'framework integration', :tldr +end diff --git a/ruby/test_app/tldr/Gemfile b/ruby/test_app/tldr/Gemfile new file mode 100644 index 000000000..0838fd434 --- /dev/null +++ b/ruby/test_app/tldr/Gemfile @@ -0,0 +1,7 @@ +source 'https://rubygems.org' + +gem 'mutant', path: '../../' +gem 'mutant-tldr', path: '../../' +gem 'tldr', '~> 1.0' + +eval_gemfile File.expand_path('../../../Gemfile.shared', __FILE__) diff --git a/ruby/test_app/tldr/Gemfile.lock b/ruby/test_app/tldr/Gemfile.lock new file mode 100644 index 000000000..534303922 --- /dev/null +++ b/ruby/test_app/tldr/Gemfile.lock @@ -0,0 +1,109 @@ +PATH + remote: ../.. + specs: + mutant (0.16.2) + diff-lcs (>= 1.6, < 3) + irb (~> 1.15) + parser (~> 3.3.10) + regexp_parser (~> 2.10) + securerandom (>= 0.3) + sorbet-runtime (~> 0.6.0) + unparser (>= 0.8.2, < 0.10) + mutant-tldr (0.16.2) + mutant (= 0.16.2) + tldr (~> 1.0) + +GEM + remote: https://rubygems.org/ + specs: + ast (2.4.3) + attr_extras (7.1.0) + concurrent-ruby (1.3.6) + date (3.5.1) + diff-lcs (2.0.0) + erb (6.0.4) + io-console (0.8.2) + irb (1.18.0) + pp (>= 0.6.0) + prism (>= 1.3.0) + rdoc (>= 4.0.0) + reline (>= 0.4.2) + optimist (3.2.1) + parser (3.3.11.1) + ast (~> 2.4.1) + racc + patience_diff (1.2.0) + optimist (~> 3.0) + pp (0.6.3) + prettyprint + prettyprint (0.2.0) + prism (1.9.0) + psych (5.3.1) + date + stringio + racc (1.8.1) + rdoc (7.2.0) + erb + psych (>= 4.0.0) + tsort + regexp_parser (2.12.0) + reline (0.6.3) + io-console (~> 0.5) + securerandom (0.4.1) + sorbet-runtime (0.6.13169) + stringio (3.2.0) + super_diff (0.18.0) + attr_extras (>= 6.2.4) + diff-lcs + patience_diff + tldr (1.1.1) + concurrent-ruby (~> 1.2) + irb (~> 1.10) + super_diff (~> 0.10) + tsort (0.2.0) + unparser (0.9.0) + diff-lcs (>= 1.6, < 3) + parser (>= 3.3.0) + prism (>= 1.5.1) + +PLATFORMS + arm64-darwin-25 + ruby + +DEPENDENCIES + mutant! + mutant-tldr! + tldr (~> 1.0) + +CHECKSUMS + ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 + attr_extras (7.1.0) sha256=d96fc9a9dd5d85ba2d37762440a816f840093959ae26bb90da994c2d9f1fc827 + concurrent-ruby (1.3.6) sha256=6b56837e1e7e5292f9864f34b69c5a2cbc75c0cf5338f1ce9903d10fa762d5ab + date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0 + diff-lcs (2.0.0) sha256=708a5d52ec2945b50f8f53a181174aa1ef2c496edf81c05957fe956dabb363d5 + erb (6.0.4) sha256=38e3803694be357fe2bfe312487c74beaf9fb4e5beb3e22498952fe1645b95d9 + io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc + irb (1.18.0) sha256=de9454a0703a54704b9811a5ef31a60c86949fbf4013fcf244fabc7c775248e3 + mutant (0.16.2) + mutant-tldr (0.16.2) + optimist (3.2.1) sha256=8cf8a0fd69f3aa24ab48885d3a666717c27bc3d9edd6e976e18b9d771e72e34e + parser (3.3.11.1) sha256=d17ace7aabe3e72c3cc94043714be27cc6f852f104d81aa284c2281aecc65d54 + patience_diff (1.2.0) sha256=f492094486af02fff4a80070fa6b4d0ebbcf4d42fb38bba29d095eef43f6822c + pp (0.6.3) sha256=2951d514450b93ccfeb1df7d021cae0da16e0a7f95ee1e2273719669d0ab9df6 + prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193 + prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85 + psych (5.3.1) sha256=eb7a57cef10c9d70173ff74e739d843ac3b2c019a003de48447b2963d81b1974 + racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f + rdoc (7.2.0) sha256=8650f76cd4009c3b54955eb5d7e3a075c60a57276766ebf36f9085e8c9f23192 + regexp_parser (2.12.0) sha256=35a916a1d63190ab5c9009457136ae5f3c0c7512d60291d0d1378ba18ce08ebb + reline (0.6.3) sha256=1198b04973565b36ec0f11542ab3f5cfeeec34823f4e54cebde90968092b1835 + securerandom (0.4.1) sha256=cc5193d414a4341b6e225f0cb4446aceca8e50d5e1888743fac16987638ea0b1 + sorbet-runtime (0.6.13169) sha256=6c520bc1ba75d9d982003d957548ec8a941dfa3c3342322a2db20bc28f174b3e + stringio (3.2.0) sha256=c37cb2e58b4ffbd33fe5cd948c05934af997b36e0b6ca6fdf43afa234cf222e1 + super_diff (0.18.0) sha256=9f5e77464fa75150619f7783174fbbe1bbac50a1eaf157cd39ad5584b0eac142 + tldr (1.1.1) sha256=fbf6386d9689eee1f18fe2bd5b565bff2b19832dc22fdb02e7acddca220edf8c + tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f + unparser (0.9.0) sha256=4331f174a73a23b69250b13d47da3794ed1449711ee0f9ed8947dc020ba76067 + +BUNDLED WITH + 4.0.10 diff --git a/ruby/test_app/tldr/test/unit/test_app/literal_test.rb b/ruby/test_app/tldr/test/unit/test_app/literal_test.rb new file mode 100644 index 000000000..bb6721132 --- /dev/null +++ b/ruby/test_app/tldr/test/unit/test_app/literal_test.rb @@ -0,0 +1,17 @@ +require 'tldr/autorun' +require 'mutant/tldr/coverage' + +class LiteralTest < TLDR + cover 'TestApp::Literal*' + cover 'TestApp::Literal#string' + + def test_command + object = ::TestApp::Literal.new + + assert_equal(object, object.command('x')) + end + + def test_string + assert_equal('string', ::TestApp::Literal.new.string) + end +end