diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4d9d05a3..c0319ea5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,7 +5,11 @@
* [CHORE] ...
* [FEATURE] ...
+* [CHANGE] Bump but also loosen MarkdownLint dependency (by [@faisal][])
+* [CHORE] Bump Mocha and Rake dependencies (by [@faisal][])
+* [CHANGE] Replace Aruba with direct API calls in specs (by [@faisal][])
* [CHANGE] Replace all Cucumber features with Minitest/Spec specs (by [@faisal][])
+* [BUGFIX] Add `lang="en"` to the report's `` element, give the menu-toggle anchor an `aria-label`, and make the per-rating summary IDs unique. Fixes 17 WCAG 2.1 AA structural errors on `overview.html`. (by [@MarcusAl][])
# v5.0.0 / 2026-01-26 [(commits)](https://github.com/whitesmith/rubycritic/compare/v4.12.0...v5.0.0)
@@ -504,3 +508,4 @@
[@fbuys]: https://github.com/fbuys
[@exoego]: https://github.com/exoego
[@raff-s]: https://github.com/raff-s
+[@MarcusAl]: https://github.com/MarcusAl
diff --git a/lib/rubycritic/generators/html/templates/layouts/application.html.erb b/lib/rubycritic/generators/html/templates/layouts/application.html.erb
index fae2e5e8..1c1f328a 100644
--- a/lib/rubycritic/generators/html/templates/layouts/application.html.erb
+++ b/lib/rubycritic/generators/html/templates/layouts/application.html.erb
@@ -1,5 +1,5 @@
-
+
@@ -16,7 +16,7 @@
-
+
RUBYCRITIC
<% if Config.compare_branches_mode? %>
diff --git a/lib/rubycritic/generators/html/templates/overview.html.erb b/lib/rubycritic/generators/html/templates/overview.html.erb
index 081b0138..84b64f54 100644
--- a/lib/rubycritic/generators/html/templates/overview.html.erb
+++ b/lib/rubycritic/generators/html/templates/overview.html.erb
@@ -49,9 +49,9 @@
- <%= @summary[rating][:files] %>
files
- <%= @summary[rating][:churns] %>
churns
- <%= @summary[rating][:smells] %>
smells
+ <%= @summary[rating][:files] %>
files
+ <%= @summary[rating][:churns] %>
churns
+ <%= @summary[rating][:smells] %>
smells
diff --git a/rubycritic.gemspec b/rubycritic.gemspec
index 88051dca..1da8b1ce 100644
--- a/rubycritic.gemspec
+++ b/rubycritic.gemspec
@@ -45,7 +45,6 @@ Gem::Specification.new do |spec|
spec.add_dependency 'tty-which', '~> 0.5.0'
spec.add_dependency 'virtus', '~> 2.0'
- spec.add_development_dependency 'aruba', '~> 2.3.1', '>= 2.3.1'
spec.add_development_dependency 'bundler', '>= 2.0.0'
if RUBY_PLATFORM == 'java'
spec.add_development_dependency 'jar-dependencies', '~> 0.5.5'
@@ -53,14 +52,14 @@ Gem::Specification.new do |spec|
else
spec.add_development_dependency 'byebug', '~> 13.0', '>= 10.0'
end
- spec.add_development_dependency 'diff-lcs', '~> 1.3'
+ spec.add_development_dependency 'diff-lcs', '~> 2.0'
spec.add_development_dependency 'fakefs', '~> 3.2.0'
- spec.add_development_dependency 'mdl', '~> 0.15.0', '>= 0.12.0'
+ spec.add_development_dependency 'mdl', '>= 0.12.0'
spec.add_development_dependency 'minitest', '~> 6.0.0'
spec.add_development_dependency 'minitest-around', '~> 0.6.0'
spec.add_development_dependency 'minitest-mock'
- spec.add_development_dependency 'mocha', '~> 3.0.0'
- spec.add_development_dependency 'rake', '~> 13.3.0', '>= 11.0.0'
+ spec.add_development_dependency 'mocha', '~> 3.1.0'
+ spec.add_development_dependency 'rake', '~> 13.4.2', '>= 11.0.0'
spec.add_development_dependency 'rdoc'
spec.add_development_dependency 'rexml', '>= 3.2.0'
spec.add_development_dependency 'rubocop', '>= 1.72.0', '< 2.0'
diff --git a/test/integration/integration_test_helper.rb b/test/integration/integration_test_helper.rb
index 6c356880..33298f58 100644
--- a/test/integration/integration_test_helper.rb
+++ b/test/integration/integration_test_helper.rb
@@ -1,21 +1,41 @@
# frozen_string_literal: true
require_relative '../test_helper'
-require 'aruba/api'
+require 'open3'
+require 'timeout'
+require 'tmpdir'
+require 'fileutils'
require_relative '../../lib/rubycritic'
require_relative '../../lib/rubycritic/cli/application'
require_relative '../../lib/rubycritic/commands/status_reporter'
-Aruba.configure { |config| config.exit_timeout = 30 }
-
module IntegrationTestHelper
- include Aruba::Api
+ GEM_ROOT = File.expand_path('../..', __dir__)
+ COMMAND_TIMEOUT = 30
+
+ CommandResult = Struct.new(:stdout, :stderr, :exit_status)
+
+ def before_setup
+ super
+ @sandbox_dir = Dir.mktmpdir('rubycritic-spec-')
+ @original_pwd = Dir.pwd
+ Dir.chdir(@sandbox_dir)
+ end
+
+ def after_teardown
+ Dir.chdir(@original_pwd) if @original_pwd
+ FileUtils.remove_entry(@sandbox_dir) if @sandbox_dir && File.directory?(@sandbox_dir)
+ @sandbox_dir = nil
+ @original_pwd = nil
+ super
+ end
+
+ def write_file(name, contents)
+ File.write(File.join(Dir.pwd, name), contents)
+ end
def rubycritic(args)
- run_command_and_stop(
- "rubycritic #{args} --no-browser",
- fail_on_error: false
- )
+ run_command("rubycritic #{args} --no-browser")
end
def rake(name, task_def)
@@ -25,10 +45,7 @@ def rake(name, task_def)
RUBY
write_file 'Rakefile', header + task_def
- run_command_and_stop(
- "rake #{name}",
- fail_on_error: false
- )
+ run_command("rake #{name}")
end
def create_smelly_file
@@ -61,4 +78,26 @@ def foo; end
def create_empty_file
write_file('empty.rb', '')
end
+
+ private
+
+ def run_command(command)
+ env = { 'PATH' => "#{File.join(GEM_ROOT, 'bin')}#{File::PATH_SEPARATOR}#{ENV.fetch('PATH', '')}" }
+ Open3.popen3(env, command) do |stdin, stdout, stderr, wait_thr|
+ stdin.close
+ out = err = nil
+ begin
+ Timeout.timeout(COMMAND_TIMEOUT) do
+ out = stdout.read
+ err = stderr.read
+ wait_thr.join
+ end
+ rescue Timeout::Error
+ Process.kill('KILL', wait_thr.pid)
+ wait_thr.join
+ raise
+ end
+ return CommandResult.new(out, err, wait_thr.value.exitstatus)
+ end
+ end
end
diff --git a/test/integration/minimum_score_spec.rb b/test/integration/minimum_score_spec.rb
index 48b79c0e..7e8e7c9d 100644
--- a/test/integration/minimum_score_spec.rb
+++ b/test/integration/minimum_score_spec.rb
@@ -5,61 +5,57 @@
describe 'Minimum score' do
include IntegrationTestHelper
- before do
- setup_aruba
- end
-
describe 'Status indicates a success when not using --minimum-score' do
it 'succeeds without minimum score' do
create_smelly_file
- rubycritic('smelly.rb')
+ result = rubycritic('smelly.rb')
- _(last_command_started.exit_status).must_equal RubyCritic::Command::StatusReporter::SUCCESS
+ _(result.exit_status).must_equal RubyCritic::Command::StatusReporter::SUCCESS
end
end
describe 'Status indicates an error when score below the minimum' do
it 'fails when score below minimum' do
create_smelly_file
- rubycritic('--minimum-score 100 smelly.rb')
+ result = rubycritic('--minimum-score 100 smelly.rb')
- _(last_command_started.exit_status).must_equal RubyCritic::Command::StatusReporter::SCORE_BELOW_MINIMUM
+ _(result.exit_status).must_equal RubyCritic::Command::StatusReporter::SCORE_BELOW_MINIMUM
end
end
describe 'Status indicates a success when score is above the minimum' do
it 'succeeds when score above minimum' do
create_smelly_file
- rubycritic('--minimum-score 93 smelly.rb')
+ result = rubycritic('--minimum-score 93 smelly.rb')
- _(last_command_started.exit_status).must_equal RubyCritic::Command::StatusReporter::SUCCESS
+ _(result.exit_status).must_equal RubyCritic::Command::StatusReporter::SUCCESS
end
end
describe 'Status indicates a success when score is equal the minimum' do
it 'succeeds when score equals minimum' do
create_clean_file
- rubycritic('--minimum-score 100 clean.rb')
+ result = rubycritic('--minimum-score 100 clean.rb')
- _(last_command_started.exit_status).must_equal RubyCritic::Command::StatusReporter::SUCCESS
+ _(result.exit_status).must_equal RubyCritic::Command::StatusReporter::SUCCESS
end
end
describe 'Prints the score on output' do
it 'prints score' do
create_smelly_file
- rubycritic('smelly.rb')
+ result = rubycritic('smelly.rb')
- _(last_command_started.stdout).must_include 'Score: 93.19'
+ _(result.stdout).must_include 'Score: 93.19'
end
end
describe 'Prints a message informing the score is below the minimum' do
it 'prints below minimum message' do
create_empty_file
- rubycritic('--minimum-score 101 empty.rb')
+ result = rubycritic('--minimum-score 101 empty.rb')
- _(last_command_started.stdout).must_include 'Score (100.0) is below the minimum 101.0'
+ _(result.stdout).must_include 'Score (100.0) is below the minimum 101.0'
end
end
end
diff --git a/test/integration/options_spec.rb b/test/integration/options_spec.rb
index 9f5bb09a..5db4bcea 100644
--- a/test/integration/options_spec.rb
+++ b/test/integration/options_spec.rb
@@ -5,34 +5,30 @@
describe 'Command line options' do
include IntegrationTestHelper
- before do
- setup_aruba
- end
-
describe 'return non-zero status on bad option' do
it 'fails on bad option' do
- rubycritic('--no-such-option')
+ result = rubycritic('--no-such-option')
- _(last_command_started.exit_status).must_equal RubyCritic::Command::StatusReporter::SCORE_BELOW_MINIMUM
- _(last_command_started.stderr).must_include 'Error: invalid option: --no-such-option'
- _(last_command_started.stdout).must_equal ''
+ _(result.exit_status).must_equal RubyCritic::Command::StatusReporter::SCORE_BELOW_MINIMUM
+ _(result.stderr).must_include 'Error: invalid option: --no-such-option'
+ _(result.stdout).must_equal ''
end
end
describe 'display the current version number' do
it 'shows version' do
- rubycritic('--version')
+ result = rubycritic('--version')
- _(last_command_started.exit_status).must_equal RubyCritic::Command::StatusReporter::SUCCESS
- _(last_command_started.stdout).must_include "RubyCritic #{RubyCritic::VERSION}"
+ _(result.exit_status).must_equal RubyCritic::Command::StatusReporter::SUCCESS
+ _(result.stdout).must_include "RubyCritic #{RubyCritic::VERSION}"
end
end
describe 'display the help information' do
it 'shows help' do
- rubycritic('--help')
+ result = rubycritic('--help')
- _(last_command_started.exit_status).must_equal RubyCritic::Command::StatusReporter::SUCCESS
+ _(result.exit_status).must_equal RubyCritic::Command::StatusReporter::SUCCESS
expected_help = <<~HELP
Usage: rubycritic [options] [paths]
-p, --path [PATH] Set path where report will be saved (tmp/rubycritic by default)
@@ -67,7 +63,7 @@
-h, --help Show this message
HELP
- _(last_command_started.stdout).must_include expected_help
+ _(result.stdout).must_include expected_help
end
end
end
diff --git a/test/integration/rake_task_spec.rb b/test/integration/rake_task_spec.rb
index 53b1b4f9..0a9661a5 100644
--- a/test/integration/rake_task_spec.rb
+++ b/test/integration/rake_task_spec.rb
@@ -5,29 +5,25 @@
describe 'Rake task' do
include IntegrationTestHelper
- before do
- setup_aruba
- end
-
describe 'paths attribute is respected' do
it 'runs rake rubycritic with paths' do
create_smelly_file
- rake('rubycritic', <<~RUBY)
+ result = rake('rubycritic', <<~RUBY)
RubyCritic::RakeTask.new do |t|
t.paths = FileList['smelly.*']
t.options = '--no-browser -f console'
end
RUBY
- _(last_command_started.stdout).must_include '(HighComplexity) AllTheMethods#method_missing has a flog score of 27'
- _(last_command_started.exit_status).must_equal RubyCritic::Command::StatusReporter::SUCCESS
+ _(result.stdout).must_include '(HighComplexity) AllTheMethods#method_missing has a flog score of 27'
+ _(result.exit_status).must_equal RubyCritic::Command::StatusReporter::SUCCESS
end
end
describe 'name option changes the task name' do
it 'runs rake silky' do
create_smelly_file
- rake('silky', <<~RUBY)
+ result = rake('silky', <<~RUBY)
RubyCritic::RakeTask.new('silky') do |t|
t.paths = FileList['smelly.*']
t.verbose = true
@@ -35,14 +31,14 @@
end
RUBY
- _(last_command_started.stdout).must_include 'Running `silky` rake command'
+ _(result.stdout).must_include 'Running `silky` rake command'
end
end
describe 'verbose prints details about the execution' do
it 'runs rake rubycritic with verbose' do
create_smelly_file
- rake('rubycritic', <<~RUBY)
+ result = rake('rubycritic', <<~RUBY)
RubyCritic::RakeTask.new do |t|
t.paths = FileList['smelly.*']
t.verbose = true
@@ -50,15 +46,15 @@
end
RUBY
- _(last_command_started.stdout).must_include '!!! Running `rubycritic` rake command'
- _(last_command_started.stdout).must_include '!!! Inspecting smelly.rb with options --no-browser'
+ _(result.stdout).must_include '!!! Running `rubycritic` rake command'
+ _(result.stdout).must_include '!!! Inspecting smelly.rb with options --no-browser'
end
end
describe 'respect --minimum-score' do
it 'fails when score below minimum' do
create_smelly_file
- rake('rubycritic', <<~RUBY)
+ result = rake('rubycritic', <<~RUBY)
RubyCritic::RakeTask.new do |t|
t.paths = FileList['smelly.*']
t.verbose = true
@@ -66,15 +62,15 @@
end
RUBY
- _(last_command_started.stdout).must_include 'Score (93.19) is below the minimum 95'
- _(last_command_started.exit_status).must_equal RubyCritic::Command::StatusReporter::SCORE_BELOW_MINIMUM
+ _(result.stdout).must_include 'Score (93.19) is below the minimum 95'
+ _(result.exit_status).must_equal RubyCritic::Command::StatusReporter::SCORE_BELOW_MINIMUM
end
end
describe 'fail_on_error when false will exit 0 even when RubyCritic fails' do
it 'succeeds despite low score' do
create_smelly_file
- rake('rubycritic', <<~RUBY)
+ result = rake('rubycritic', <<~RUBY)
RubyCritic::RakeTask.new do |t|
t.paths = FileList['smelly.*']
t.fail_on_error = false
@@ -82,8 +78,8 @@
end
RUBY
- _(last_command_started.stdout).must_include 'Score (93.19) is below the minimum 95'
- _(last_command_started.exit_status).must_equal RubyCritic::Command::StatusReporter::SUCCESS
+ _(result.stdout).must_include 'Score (93.19) is below the minimum 95'
+ _(result.exit_status).must_equal RubyCritic::Command::StatusReporter::SUCCESS
end
end
end
diff --git a/test/samples/simple_cov_index.html b/test/samples/simple_cov_index.html
index 1c596517..e062a9aa 100644
--- a/test/samples/simple_cov_index.html
+++ b/test/samples/simple_cov_index.html
@@ -1,5 +1,5 @@
-
+
@@ -16,7 +16,7 @@