cov-loupe 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +329 -0
- data/docs/dev/ARCHITECTURE.md +80 -0
- data/docs/dev/BRANCH_ONLY_COVERAGE.md +158 -0
- data/docs/dev/DEVELOPMENT.md +83 -0
- data/docs/dev/README.md +10 -0
- data/docs/dev/RELEASING.md +146 -0
- data/docs/dev/arch-decisions/001-x-arch-decision.md +95 -0
- data/docs/dev/arch-decisions/002-x-arch-decision.md +159 -0
- data/docs/dev/arch-decisions/003-x-arch-decision.md +165 -0
- data/docs/dev/arch-decisions/004-x-arch-decision.md +203 -0
- data/docs/dev/arch-decisions/005-x-arch-decision.md +189 -0
- data/docs/dev/arch-decisions/README.md +60 -0
- data/docs/dev/presentations/cov-loupe-presentation.md +255 -0
- data/docs/fixtures/demo_project/README.md +9 -0
- data/docs/user/ADVANCED_USAGE.md +777 -0
- data/docs/user/CLI_FALLBACK_FOR_LLMS.md +34 -0
- data/docs/user/CLI_USAGE.md +750 -0
- data/docs/user/ERROR_HANDLING.md +93 -0
- data/docs/user/EXAMPLES.md +588 -0
- data/docs/user/INSTALLATION.md +130 -0
- data/docs/user/LIBRARY_API.md +693 -0
- data/docs/user/MCP_INTEGRATION.md +490 -0
- data/docs/user/README.md +14 -0
- data/docs/user/TROUBLESHOOTING.md +197 -0
- data/docs/user/V2-BREAKING-CHANGES.md +472 -0
- data/exe/cov-loupe +23 -0
- data/lib/cov_loupe/app_config.rb +56 -0
- data/lib/cov_loupe/app_context.rb +26 -0
- data/lib/cov_loupe/base_tool.rb +102 -0
- data/lib/cov_loupe/cli.rb +178 -0
- data/lib/cov_loupe/commands/base_command.rb +67 -0
- data/lib/cov_loupe/commands/command_factory.rb +45 -0
- data/lib/cov_loupe/commands/detailed_command.rb +38 -0
- data/lib/cov_loupe/commands/list_command.rb +13 -0
- data/lib/cov_loupe/commands/raw_command.rb +38 -0
- data/lib/cov_loupe/commands/summary_command.rb +41 -0
- data/lib/cov_loupe/commands/totals_command.rb +53 -0
- data/lib/cov_loupe/commands/uncovered_command.rb +45 -0
- data/lib/cov_loupe/commands/validate_command.rb +60 -0
- data/lib/cov_loupe/commands/version_command.rb +33 -0
- data/lib/cov_loupe/config_parser.rb +32 -0
- data/lib/cov_loupe/constants.rb +22 -0
- data/lib/cov_loupe/coverage_reporter.rb +31 -0
- data/lib/cov_loupe/error_handler.rb +165 -0
- data/lib/cov_loupe/error_handler_factory.rb +31 -0
- data/lib/cov_loupe/errors.rb +191 -0
- data/lib/cov_loupe/formatters/source_formatter.rb +152 -0
- data/lib/cov_loupe/formatters.rb +51 -0
- data/lib/cov_loupe/mcp_server.rb +42 -0
- data/lib/cov_loupe/mode_detector.rb +56 -0
- data/lib/cov_loupe/model.rb +339 -0
- data/lib/cov_loupe/option_normalizers.rb +113 -0
- data/lib/cov_loupe/option_parser_builder.rb +147 -0
- data/lib/cov_loupe/option_parsers/env_options_parser.rb +48 -0
- data/lib/cov_loupe/option_parsers/error_helper.rb +110 -0
- data/lib/cov_loupe/path_relativizer.rb +64 -0
- data/lib/cov_loupe/predicate_evaluator.rb +72 -0
- data/lib/cov_loupe/presenters/base_coverage_presenter.rb +42 -0
- data/lib/cov_loupe/presenters/coverage_detailed_presenter.rb +14 -0
- data/lib/cov_loupe/presenters/coverage_raw_presenter.rb +14 -0
- data/lib/cov_loupe/presenters/coverage_summary_presenter.rb +14 -0
- data/lib/cov_loupe/presenters/coverage_uncovered_presenter.rb +14 -0
- data/lib/cov_loupe/presenters/project_coverage_presenter.rb +50 -0
- data/lib/cov_loupe/presenters/project_totals_presenter.rb +27 -0
- data/lib/cov_loupe/resolvers/coverage_line_resolver.rb +122 -0
- data/lib/cov_loupe/resolvers/resolver_factory.rb +28 -0
- data/lib/cov_loupe/resolvers/resultset_path_resolver.rb +76 -0
- data/lib/cov_loupe/resultset_loader.rb +131 -0
- data/lib/cov_loupe/staleness_checker.rb +247 -0
- data/lib/cov_loupe/table_formatter.rb +64 -0
- data/lib/cov_loupe/tools/all_files_coverage_tool.rb +51 -0
- data/lib/cov_loupe/tools/coverage_detailed_tool.rb +35 -0
- data/lib/cov_loupe/tools/coverage_raw_tool.rb +34 -0
- data/lib/cov_loupe/tools/coverage_summary_tool.rb +34 -0
- data/lib/cov_loupe/tools/coverage_table_tool.rb +50 -0
- data/lib/cov_loupe/tools/coverage_totals_tool.rb +44 -0
- data/lib/cov_loupe/tools/help_tool.rb +115 -0
- data/lib/cov_loupe/tools/uncovered_lines_tool.rb +34 -0
- data/lib/cov_loupe/tools/validate_tool.rb +72 -0
- data/lib/cov_loupe/tools/version_tool.rb +32 -0
- data/lib/cov_loupe/util.rb +88 -0
- data/lib/cov_loupe/version.rb +5 -0
- data/lib/cov_loupe.rb +140 -0
- data/spec/MCP_INTEGRATION_TESTS_README.md +111 -0
- data/spec/TIMESTAMPS.md +48 -0
- data/spec/all_files_coverage_tool_spec.rb +53 -0
- data/spec/app_config_spec.rb +142 -0
- data/spec/base_tool_spec.rb +62 -0
- data/spec/cli/show_default_report_spec.rb +33 -0
- data/spec/cli_enumerated_options_spec.rb +90 -0
- data/spec/cli_error_spec.rb +184 -0
- data/spec/cli_format_spec.rb +123 -0
- data/spec/cli_json_options_spec.rb +50 -0
- data/spec/cli_source_spec.rb +44 -0
- data/spec/cli_spec.rb +192 -0
- data/spec/cli_table_spec.rb +28 -0
- data/spec/cli_usage_spec.rb +42 -0
- data/spec/commands/base_command_spec.rb +107 -0
- data/spec/commands/command_factory_spec.rb +76 -0
- data/spec/commands/detailed_command_spec.rb +34 -0
- data/spec/commands/list_command_spec.rb +28 -0
- data/spec/commands/raw_command_spec.rb +69 -0
- data/spec/commands/summary_command_spec.rb +34 -0
- data/spec/commands/totals_command_spec.rb +34 -0
- data/spec/commands/uncovered_command_spec.rb +55 -0
- data/spec/commands/validate_command_spec.rb +213 -0
- data/spec/commands/version_command_spec.rb +38 -0
- data/spec/constants_spec.rb +61 -0
- data/spec/cov_loupe/formatters/source_formatter_spec.rb +267 -0
- data/spec/cov_loupe/formatters_spec.rb +76 -0
- data/spec/cov_loupe/presenters/base_coverage_presenter_spec.rb +79 -0
- data/spec/cov_loupe_model_spec.rb +454 -0
- data/spec/cov_loupe_module_spec.rb +37 -0
- data/spec/cov_loupe_opts_spec.rb +185 -0
- data/spec/coverage_reporter_spec.rb +102 -0
- data/spec/coverage_table_tool_spec.rb +59 -0
- data/spec/coverage_totals_tool_spec.rb +37 -0
- data/spec/error_handler_spec.rb +197 -0
- data/spec/error_mode_spec.rb +139 -0
- data/spec/errors_edge_cases_spec.rb +312 -0
- data/spec/errors_stale_spec.rb +83 -0
- data/spec/file_based_mcp_tools_spec.rb +99 -0
- data/spec/fixtures/project1/lib/bar.rb +5 -0
- data/spec/fixtures/project1/lib/foo.rb +6 -0
- data/spec/help_tool_spec.rb +26 -0
- data/spec/integration_spec.rb +789 -0
- data/spec/logging_fallback_spec.rb +128 -0
- data/spec/mcp_logging_spec.rb +44 -0
- data/spec/mcp_server_integration_spec.rb +23 -0
- data/spec/mcp_server_spec.rb +106 -0
- data/spec/mode_detector_spec.rb +153 -0
- data/spec/model_error_handling_spec.rb +269 -0
- data/spec/model_staleness_spec.rb +79 -0
- data/spec/option_normalizers_spec.rb +203 -0
- data/spec/option_parsers/env_options_parser_spec.rb +221 -0
- data/spec/option_parsers/error_helper_spec.rb +222 -0
- data/spec/path_relativizer_spec.rb +98 -0
- data/spec/presenters/coverage_detailed_presenter_spec.rb +19 -0
- data/spec/presenters/coverage_raw_presenter_spec.rb +15 -0
- data/spec/presenters/coverage_summary_presenter_spec.rb +15 -0
- data/spec/presenters/coverage_uncovered_presenter_spec.rb +16 -0
- data/spec/presenters/project_coverage_presenter_spec.rb +87 -0
- data/spec/presenters/project_totals_presenter_spec.rb +144 -0
- data/spec/resolvers/coverage_line_resolver_spec.rb +282 -0
- data/spec/resolvers/resolver_factory_spec.rb +61 -0
- data/spec/resolvers/resultset_path_resolver_spec.rb +60 -0
- data/spec/resultset_loader_spec.rb +167 -0
- data/spec/shared_examples/README.md +115 -0
- data/spec/shared_examples/coverage_presenter_examples.rb +66 -0
- data/spec/shared_examples/file_based_mcp_tools.rb +179 -0
- data/spec/shared_examples/formatted_command_examples.rb +64 -0
- data/spec/shared_examples/mcp_tool_text_json_response.rb +16 -0
- data/spec/spec_helper.rb +127 -0
- data/spec/staleness_checker_spec.rb +374 -0
- data/spec/staleness_more_spec.rb +42 -0
- data/spec/support/cli_helpers.rb +22 -0
- data/spec/support/control_flow_helpers.rb +20 -0
- data/spec/support/fake_mcp.rb +40 -0
- data/spec/support/io_helpers.rb +29 -0
- data/spec/support/mcp_helpers.rb +35 -0
- data/spec/support/mcp_runner.rb +66 -0
- data/spec/support/mocking_helpers.rb +30 -0
- data/spec/table_format_spec.rb +70 -0
- data/spec/tools/validate_tool_spec.rb +132 -0
- data/spec/tools_error_handling_spec.rb +130 -0
- data/spec/util_spec.rb +154 -0
- data/spec/version_spec.rb +123 -0
- data/spec/version_tool_spec.rb +141 -0
- metadata +290 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
RSpec.describe 'CovLoupe::VERSION' do
|
|
6
|
+
describe 'constant existence' do
|
|
7
|
+
it 'defines a VERSION constant' do
|
|
8
|
+
expect(CovLoupe.const_defined?(:VERSION)).to be true
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it 'exposes VERSION as a non-empty string' do
|
|
12
|
+
expect(CovLoupe::VERSION).to be_a(String)
|
|
13
|
+
expect(CovLoupe::VERSION).not_to be_empty
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it 'is frozen (immutable)' do
|
|
17
|
+
expect(CovLoupe::VERSION).to be_frozen
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
describe 'semantic versioning compliance' do
|
|
22
|
+
let(:version) { CovLoupe::VERSION }
|
|
23
|
+
# Simplified semantic versioning regex
|
|
24
|
+
# Preserves key semver rules: no leading zeros on numeric parts, optional prerelease/build metadata
|
|
25
|
+
let(:semver_regex) do
|
|
26
|
+
%r{\A
|
|
27
|
+
(?<major>0|[1-9]\d*)\.
|
|
28
|
+
(?<minor>0|[1-9]\d*)\.
|
|
29
|
+
(?<patch>0|[1-9]\d*)
|
|
30
|
+
(?:[.-](?<prerelease>[0-9A-Za-z.-]+))?
|
|
31
|
+
(?:\+(?<buildmetadata>[0-9A-Za-z.-]+))?
|
|
32
|
+
\z}x
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it 'follows semantic versioning format (accepting hyphen or dot pre-release separator)' do
|
|
36
|
+
expect(version).to match(semver_regex)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it 'has valid major.minor.patch core version' do
|
|
40
|
+
match = version.match(semver_regex)
|
|
41
|
+
expect(match).not_to be_nil, "VERSION '#{version}' does not match semantic versioning format"
|
|
42
|
+
|
|
43
|
+
major = match[:major].to_i
|
|
44
|
+
minor = match[:minor].to_i
|
|
45
|
+
patch = match[:patch].to_i
|
|
46
|
+
|
|
47
|
+
expect(major).to be >= 0
|
|
48
|
+
expect(minor).to be >= 0
|
|
49
|
+
expect(patch).to be >= 0
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
context 'when version has prerelease identifier' do
|
|
53
|
+
let(:prerelease_version) { '9.9.9-rc.1' }
|
|
54
|
+
|
|
55
|
+
before do
|
|
56
|
+
stub_const('CovLoupe::VERSION', prerelease_version)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it 'has valid prerelease format' do
|
|
60
|
+
match = version.match(semver_regex)
|
|
61
|
+
prerelease = match[:prerelease]
|
|
62
|
+
expect(prerelease).not_to be_empty
|
|
63
|
+
expect(prerelease).not_to start_with('.')
|
|
64
|
+
expect(prerelease).not_to end_with('.')
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
context 'when version has build metadata' do
|
|
69
|
+
let(:build_metadata_version) { '9.9.9+build.42' }
|
|
70
|
+
|
|
71
|
+
before do
|
|
72
|
+
stub_const('CovLoupe::VERSION', build_metadata_version)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
it 'has valid build metadata format' do
|
|
76
|
+
match = version.match(semver_regex)
|
|
77
|
+
buildmetadata = match[:buildmetadata]
|
|
78
|
+
expect(buildmetadata).not_to be_empty
|
|
79
|
+
expect(buildmetadata).to match(/\A[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*\z/)
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
describe 'version consistency' do
|
|
85
|
+
it 'is accessible via require path' do
|
|
86
|
+
expect { CovLoupe::VERSION }.not_to raise_error
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
it 'matches the version referenced in gemspec' do
|
|
90
|
+
gemspec_path = File.expand_path('../cov-loupe.gemspec', __dir__)
|
|
91
|
+
gemspec_content = File.read(gemspec_path)
|
|
92
|
+
|
|
93
|
+
version_line = gemspec_content.lines.find { |line| line.include?('spec.version') }
|
|
94
|
+
expect(version_line).not_to be_nil, 'Could not find version line in gemspec'
|
|
95
|
+
expect(version_line).to include('CovLoupe::VERSION')
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
describe 'current version sanity check' do
|
|
100
|
+
it 'is not the initial 0.0.0 version' do
|
|
101
|
+
# Ensure this is a real release, not an uninitialized version
|
|
102
|
+
expect(CovLoupe::VERSION).not_to eq('0.0.0')
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
describe 'standalone version file load' do
|
|
107
|
+
it 'defines the module and VERSION constant when only version.rb is loaded' do
|
|
108
|
+
original_version = CovLoupe::VERSION
|
|
109
|
+
|
|
110
|
+
stub_const('CovLoupe', Module.new do
|
|
111
|
+
class << self
|
|
112
|
+
attr_accessor :default_log_file, :active_log_file
|
|
113
|
+
end
|
|
114
|
+
end)
|
|
115
|
+
|
|
116
|
+
version_path = File.expand_path('../lib/cov_loupe/version.rb', __dir__)
|
|
117
|
+
load version_path
|
|
118
|
+
|
|
119
|
+
expect(Object.const_defined?(:CovLoupe)).to be true
|
|
120
|
+
expect(CovLoupe::VERSION).to eq(original_version)
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
require 'cov_loupe/tools/version_tool'
|
|
5
|
+
|
|
6
|
+
RSpec.describe CovLoupe::Tools::VersionTool do
|
|
7
|
+
let(:server_context) { instance_double('ServerContext').as_null_object }
|
|
8
|
+
|
|
9
|
+
before do
|
|
10
|
+
setup_mcp_response_stub
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
describe '.call' do
|
|
14
|
+
it 'returns a text payload with the version string when called without arguments' do
|
|
15
|
+
response = described_class.call(server_context: server_context)
|
|
16
|
+
item = response.payload.first
|
|
17
|
+
expect(item[:type] || item['type']).to eq('text')
|
|
18
|
+
text = item['text']
|
|
19
|
+
expect(text).to eq("CovLoupe version: #{CovLoupe::VERSION}")
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it 'includes the exact version constant value' do
|
|
23
|
+
response = described_class.call(server_context: server_context)
|
|
24
|
+
item = response.payload.first
|
|
25
|
+
text = item['text']
|
|
26
|
+
expect(text).to include(CovLoupe::VERSION)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it 'matches the expected format exactly' do
|
|
30
|
+
expected_format = "CovLoupe version: #{CovLoupe::VERSION}"
|
|
31
|
+
response = described_class.call(server_context: server_context)
|
|
32
|
+
item = response.payload.first
|
|
33
|
+
text = item['text']
|
|
34
|
+
expect(text).to eq(expected_format)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'returns an MCP::Tool::Response object' do
|
|
38
|
+
response = described_class.call(server_context: server_context)
|
|
39
|
+
expect(response).to be_a(MCP::Tool::Response)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it 'has a single payload item' do
|
|
43
|
+
response = described_class.call(server_context: server_context)
|
|
44
|
+
expect(response.payload).to be_an(Array)
|
|
45
|
+
expect(response.payload.size).to eq(1)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
context 'when error_mode is specified' do
|
|
49
|
+
it 'accepts error_mode parameter without affecting output' do
|
|
50
|
+
response = described_class.call(error_mode: 'off', server_context: server_context)
|
|
51
|
+
item = response.payload.first
|
|
52
|
+
text = item['text']
|
|
53
|
+
expect(text).to eq("CovLoupe version: #{CovLoupe::VERSION}")
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it 'accepts error_mode "log" (default)' do
|
|
57
|
+
response = described_class.call(error_mode: 'log', server_context: server_context)
|
|
58
|
+
item = response.payload.first
|
|
59
|
+
expect(item[:type] || item['type']).to eq('text')
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it 'accepts error_mode "debug"' do
|
|
63
|
+
response = described_class.call(error_mode: 'debug', server_context: server_context)
|
|
64
|
+
item = response.payload.first
|
|
65
|
+
expect(item[:type] || item['type']).to eq('text')
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
context 'when additional arguments are passed' do
|
|
70
|
+
it 'ignores additional arguments gracefully' do
|
|
71
|
+
response = described_class.call(
|
|
72
|
+
server_context: server_context,
|
|
73
|
+
extra_arg: 'value',
|
|
74
|
+
another: { nested: 'data' }
|
|
75
|
+
)
|
|
76
|
+
item = response.payload.first
|
|
77
|
+
text = item['text']
|
|
78
|
+
expect(text).to eq("CovLoupe version: #{CovLoupe::VERSION}")
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
context 'when an error occurs' do
|
|
83
|
+
it 'handles VERSION constant access errors and returns structured error response' do
|
|
84
|
+
# Force an error by hiding VERSION so const_missing is triggered
|
|
85
|
+
hide_const('CovLoupe::VERSION')
|
|
86
|
+
allow(CovLoupe).to receive(:const_missing).with(:VERSION)
|
|
87
|
+
.and_raise(StandardError, 'Version access error')
|
|
88
|
+
|
|
89
|
+
response = described_class.call(error_mode: 'log', server_context: server_context)
|
|
90
|
+
|
|
91
|
+
# Should return error response in MCP format
|
|
92
|
+
expect(response).to be_a(MCP::Tool::Response)
|
|
93
|
+
item = response.payload.first
|
|
94
|
+
expect(item[:type] || item['type']).to eq('text')
|
|
95
|
+
|
|
96
|
+
error_text = item['text']
|
|
97
|
+
expect(error_text).to include('Error')
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
it 'handles errors in the response creation process' do
|
|
101
|
+
# Force an error by mocking string interpolation to fail
|
|
102
|
+
version_obj = double('VERSION')
|
|
103
|
+
allow(version_obj).to receive(:to_s).and_raise(StandardError, 'String conversion error')
|
|
104
|
+
|
|
105
|
+
# Replace VERSION with our mock object
|
|
106
|
+
stub_const('CovLoupe::VERSION', version_obj)
|
|
107
|
+
|
|
108
|
+
response = described_class.call(error_mode: 'log', server_context: server_context)
|
|
109
|
+
|
|
110
|
+
# Should return error response in MCP format via the rescue block
|
|
111
|
+
expect(response).to be_a(MCP::Tool::Response)
|
|
112
|
+
item = response.payload.first
|
|
113
|
+
expect(item[:type] || item['type']).to eq('text')
|
|
114
|
+
|
|
115
|
+
error_text = item['text']
|
|
116
|
+
expect(error_text).to include('Error')
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
it 'respects error_mode setting when handling errors' do
|
|
120
|
+
# Force an error using a mock VERSION that raises an exception
|
|
121
|
+
version_obj = double('VERSION')
|
|
122
|
+
allow(version_obj).to receive(:to_s).and_raise(StandardError, 'Version error')
|
|
123
|
+
stub_const('CovLoupe::VERSION', version_obj)
|
|
124
|
+
|
|
125
|
+
# Test error_mode 'off' (should be silent but still return structured response)
|
|
126
|
+
response = described_class.call(error_mode: 'off', server_context: server_context)
|
|
127
|
+
expect(response).to be_a(MCP::Tool::Response)
|
|
128
|
+
item = response.payload.first
|
|
129
|
+
expect(item[:type] || item['type']).to eq('text')
|
|
130
|
+
|
|
131
|
+
# Test error_mode 'debug' (should include more detail)
|
|
132
|
+
response = described_class.call(error_mode: 'debug', server_context: server_context)
|
|
133
|
+
expect(response).to be_a(MCP::Tool::Response)
|
|
134
|
+
item = response.payload.first
|
|
135
|
+
expect(item[:type] || item['type']).to eq('text')
|
|
136
|
+
error_text = item['text']
|
|
137
|
+
expect(error_text).to include('Error')
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: cov-loupe
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 3.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Keith R. Bennett
|
|
8
|
+
bindir: exe
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: awesome_print
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '1.9'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '1.9'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: mcp
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - "~>"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '0.3'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '0.3'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: simplecov
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - ">="
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '0.21'
|
|
47
|
+
- - "<"
|
|
48
|
+
- !ruby/object:Gem::Version
|
|
49
|
+
version: '1.0'
|
|
50
|
+
type: :runtime
|
|
51
|
+
prerelease: false
|
|
52
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
53
|
+
requirements:
|
|
54
|
+
- - ">="
|
|
55
|
+
- !ruby/object:Gem::Version
|
|
56
|
+
version: '0.21'
|
|
57
|
+
- - "<"
|
|
58
|
+
- !ruby/object:Gem::Version
|
|
59
|
+
version: '1.0'
|
|
60
|
+
description: Provides an MCP (Model Context Protocol) server and a CLI to inspect
|
|
61
|
+
SimpleCov coverage, including per-file summaries and uncovered lines.
|
|
62
|
+
email:
|
|
63
|
+
- keithrbennett@gmail.com
|
|
64
|
+
executables:
|
|
65
|
+
- cov-loupe
|
|
66
|
+
extensions: []
|
|
67
|
+
extra_rdoc_files: []
|
|
68
|
+
files:
|
|
69
|
+
- LICENSE
|
|
70
|
+
- README.md
|
|
71
|
+
- docs/dev/ARCHITECTURE.md
|
|
72
|
+
- docs/dev/BRANCH_ONLY_COVERAGE.md
|
|
73
|
+
- docs/dev/DEVELOPMENT.md
|
|
74
|
+
- docs/dev/README.md
|
|
75
|
+
- docs/dev/RELEASING.md
|
|
76
|
+
- docs/dev/arch-decisions/001-x-arch-decision.md
|
|
77
|
+
- docs/dev/arch-decisions/002-x-arch-decision.md
|
|
78
|
+
- docs/dev/arch-decisions/003-x-arch-decision.md
|
|
79
|
+
- docs/dev/arch-decisions/004-x-arch-decision.md
|
|
80
|
+
- docs/dev/arch-decisions/005-x-arch-decision.md
|
|
81
|
+
- docs/dev/arch-decisions/README.md
|
|
82
|
+
- docs/dev/presentations/cov-loupe-presentation.md
|
|
83
|
+
- docs/fixtures/demo_project/README.md
|
|
84
|
+
- docs/user/ADVANCED_USAGE.md
|
|
85
|
+
- docs/user/CLI_FALLBACK_FOR_LLMS.md
|
|
86
|
+
- docs/user/CLI_USAGE.md
|
|
87
|
+
- docs/user/ERROR_HANDLING.md
|
|
88
|
+
- docs/user/EXAMPLES.md
|
|
89
|
+
- docs/user/INSTALLATION.md
|
|
90
|
+
- docs/user/LIBRARY_API.md
|
|
91
|
+
- docs/user/MCP_INTEGRATION.md
|
|
92
|
+
- docs/user/README.md
|
|
93
|
+
- docs/user/TROUBLESHOOTING.md
|
|
94
|
+
- docs/user/V2-BREAKING-CHANGES.md
|
|
95
|
+
- exe/cov-loupe
|
|
96
|
+
- lib/cov_loupe.rb
|
|
97
|
+
- lib/cov_loupe/app_config.rb
|
|
98
|
+
- lib/cov_loupe/app_context.rb
|
|
99
|
+
- lib/cov_loupe/base_tool.rb
|
|
100
|
+
- lib/cov_loupe/cli.rb
|
|
101
|
+
- lib/cov_loupe/commands/base_command.rb
|
|
102
|
+
- lib/cov_loupe/commands/command_factory.rb
|
|
103
|
+
- lib/cov_loupe/commands/detailed_command.rb
|
|
104
|
+
- lib/cov_loupe/commands/list_command.rb
|
|
105
|
+
- lib/cov_loupe/commands/raw_command.rb
|
|
106
|
+
- lib/cov_loupe/commands/summary_command.rb
|
|
107
|
+
- lib/cov_loupe/commands/totals_command.rb
|
|
108
|
+
- lib/cov_loupe/commands/uncovered_command.rb
|
|
109
|
+
- lib/cov_loupe/commands/validate_command.rb
|
|
110
|
+
- lib/cov_loupe/commands/version_command.rb
|
|
111
|
+
- lib/cov_loupe/config_parser.rb
|
|
112
|
+
- lib/cov_loupe/constants.rb
|
|
113
|
+
- lib/cov_loupe/coverage_reporter.rb
|
|
114
|
+
- lib/cov_loupe/error_handler.rb
|
|
115
|
+
- lib/cov_loupe/error_handler_factory.rb
|
|
116
|
+
- lib/cov_loupe/errors.rb
|
|
117
|
+
- lib/cov_loupe/formatters.rb
|
|
118
|
+
- lib/cov_loupe/formatters/source_formatter.rb
|
|
119
|
+
- lib/cov_loupe/mcp_server.rb
|
|
120
|
+
- lib/cov_loupe/mode_detector.rb
|
|
121
|
+
- lib/cov_loupe/model.rb
|
|
122
|
+
- lib/cov_loupe/option_normalizers.rb
|
|
123
|
+
- lib/cov_loupe/option_parser_builder.rb
|
|
124
|
+
- lib/cov_loupe/option_parsers/env_options_parser.rb
|
|
125
|
+
- lib/cov_loupe/option_parsers/error_helper.rb
|
|
126
|
+
- lib/cov_loupe/path_relativizer.rb
|
|
127
|
+
- lib/cov_loupe/predicate_evaluator.rb
|
|
128
|
+
- lib/cov_loupe/presenters/base_coverage_presenter.rb
|
|
129
|
+
- lib/cov_loupe/presenters/coverage_detailed_presenter.rb
|
|
130
|
+
- lib/cov_loupe/presenters/coverage_raw_presenter.rb
|
|
131
|
+
- lib/cov_loupe/presenters/coverage_summary_presenter.rb
|
|
132
|
+
- lib/cov_loupe/presenters/coverage_uncovered_presenter.rb
|
|
133
|
+
- lib/cov_loupe/presenters/project_coverage_presenter.rb
|
|
134
|
+
- lib/cov_loupe/presenters/project_totals_presenter.rb
|
|
135
|
+
- lib/cov_loupe/resolvers/coverage_line_resolver.rb
|
|
136
|
+
- lib/cov_loupe/resolvers/resolver_factory.rb
|
|
137
|
+
- lib/cov_loupe/resolvers/resultset_path_resolver.rb
|
|
138
|
+
- lib/cov_loupe/resultset_loader.rb
|
|
139
|
+
- lib/cov_loupe/staleness_checker.rb
|
|
140
|
+
- lib/cov_loupe/table_formatter.rb
|
|
141
|
+
- lib/cov_loupe/tools/all_files_coverage_tool.rb
|
|
142
|
+
- lib/cov_loupe/tools/coverage_detailed_tool.rb
|
|
143
|
+
- lib/cov_loupe/tools/coverage_raw_tool.rb
|
|
144
|
+
- lib/cov_loupe/tools/coverage_summary_tool.rb
|
|
145
|
+
- lib/cov_loupe/tools/coverage_table_tool.rb
|
|
146
|
+
- lib/cov_loupe/tools/coverage_totals_tool.rb
|
|
147
|
+
- lib/cov_loupe/tools/help_tool.rb
|
|
148
|
+
- lib/cov_loupe/tools/uncovered_lines_tool.rb
|
|
149
|
+
- lib/cov_loupe/tools/validate_tool.rb
|
|
150
|
+
- lib/cov_loupe/tools/version_tool.rb
|
|
151
|
+
- lib/cov_loupe/util.rb
|
|
152
|
+
- lib/cov_loupe/version.rb
|
|
153
|
+
- spec/MCP_INTEGRATION_TESTS_README.md
|
|
154
|
+
- spec/TIMESTAMPS.md
|
|
155
|
+
- spec/all_files_coverage_tool_spec.rb
|
|
156
|
+
- spec/app_config_spec.rb
|
|
157
|
+
- spec/base_tool_spec.rb
|
|
158
|
+
- spec/cli/show_default_report_spec.rb
|
|
159
|
+
- spec/cli_enumerated_options_spec.rb
|
|
160
|
+
- spec/cli_error_spec.rb
|
|
161
|
+
- spec/cli_format_spec.rb
|
|
162
|
+
- spec/cli_json_options_spec.rb
|
|
163
|
+
- spec/cli_source_spec.rb
|
|
164
|
+
- spec/cli_spec.rb
|
|
165
|
+
- spec/cli_table_spec.rb
|
|
166
|
+
- spec/cli_usage_spec.rb
|
|
167
|
+
- spec/commands/base_command_spec.rb
|
|
168
|
+
- spec/commands/command_factory_spec.rb
|
|
169
|
+
- spec/commands/detailed_command_spec.rb
|
|
170
|
+
- spec/commands/list_command_spec.rb
|
|
171
|
+
- spec/commands/raw_command_spec.rb
|
|
172
|
+
- spec/commands/summary_command_spec.rb
|
|
173
|
+
- spec/commands/totals_command_spec.rb
|
|
174
|
+
- spec/commands/uncovered_command_spec.rb
|
|
175
|
+
- spec/commands/validate_command_spec.rb
|
|
176
|
+
- spec/commands/version_command_spec.rb
|
|
177
|
+
- spec/constants_spec.rb
|
|
178
|
+
- spec/cov_loupe/formatters/source_formatter_spec.rb
|
|
179
|
+
- spec/cov_loupe/formatters_spec.rb
|
|
180
|
+
- spec/cov_loupe/presenters/base_coverage_presenter_spec.rb
|
|
181
|
+
- spec/cov_loupe_model_spec.rb
|
|
182
|
+
- spec/cov_loupe_module_spec.rb
|
|
183
|
+
- spec/cov_loupe_opts_spec.rb
|
|
184
|
+
- spec/coverage_reporter_spec.rb
|
|
185
|
+
- spec/coverage_table_tool_spec.rb
|
|
186
|
+
- spec/coverage_totals_tool_spec.rb
|
|
187
|
+
- spec/error_handler_spec.rb
|
|
188
|
+
- spec/error_mode_spec.rb
|
|
189
|
+
- spec/errors_edge_cases_spec.rb
|
|
190
|
+
- spec/errors_stale_spec.rb
|
|
191
|
+
- spec/file_based_mcp_tools_spec.rb
|
|
192
|
+
- spec/fixtures/project1/lib/bar.rb
|
|
193
|
+
- spec/fixtures/project1/lib/foo.rb
|
|
194
|
+
- spec/help_tool_spec.rb
|
|
195
|
+
- spec/integration_spec.rb
|
|
196
|
+
- spec/logging_fallback_spec.rb
|
|
197
|
+
- spec/mcp_logging_spec.rb
|
|
198
|
+
- spec/mcp_server_integration_spec.rb
|
|
199
|
+
- spec/mcp_server_spec.rb
|
|
200
|
+
- spec/mode_detector_spec.rb
|
|
201
|
+
- spec/model_error_handling_spec.rb
|
|
202
|
+
- spec/model_staleness_spec.rb
|
|
203
|
+
- spec/option_normalizers_spec.rb
|
|
204
|
+
- spec/option_parsers/env_options_parser_spec.rb
|
|
205
|
+
- spec/option_parsers/error_helper_spec.rb
|
|
206
|
+
- spec/path_relativizer_spec.rb
|
|
207
|
+
- spec/presenters/coverage_detailed_presenter_spec.rb
|
|
208
|
+
- spec/presenters/coverage_raw_presenter_spec.rb
|
|
209
|
+
- spec/presenters/coverage_summary_presenter_spec.rb
|
|
210
|
+
- spec/presenters/coverage_uncovered_presenter_spec.rb
|
|
211
|
+
- spec/presenters/project_coverage_presenter_spec.rb
|
|
212
|
+
- spec/presenters/project_totals_presenter_spec.rb
|
|
213
|
+
- spec/resolvers/coverage_line_resolver_spec.rb
|
|
214
|
+
- spec/resolvers/resolver_factory_spec.rb
|
|
215
|
+
- spec/resolvers/resultset_path_resolver_spec.rb
|
|
216
|
+
- spec/resultset_loader_spec.rb
|
|
217
|
+
- spec/shared_examples/README.md
|
|
218
|
+
- spec/shared_examples/coverage_presenter_examples.rb
|
|
219
|
+
- spec/shared_examples/file_based_mcp_tools.rb
|
|
220
|
+
- spec/shared_examples/formatted_command_examples.rb
|
|
221
|
+
- spec/shared_examples/mcp_tool_text_json_response.rb
|
|
222
|
+
- spec/spec_helper.rb
|
|
223
|
+
- spec/staleness_checker_spec.rb
|
|
224
|
+
- spec/staleness_more_spec.rb
|
|
225
|
+
- spec/support/cli_helpers.rb
|
|
226
|
+
- spec/support/control_flow_helpers.rb
|
|
227
|
+
- spec/support/fake_mcp.rb
|
|
228
|
+
- spec/support/io_helpers.rb
|
|
229
|
+
- spec/support/mcp_helpers.rb
|
|
230
|
+
- spec/support/mcp_runner.rb
|
|
231
|
+
- spec/support/mocking_helpers.rb
|
|
232
|
+
- spec/table_format_spec.rb
|
|
233
|
+
- spec/tools/validate_tool_spec.rb
|
|
234
|
+
- spec/tools_error_handling_spec.rb
|
|
235
|
+
- spec/util_spec.rb
|
|
236
|
+
- spec/version_spec.rb
|
|
237
|
+
- spec/version_tool_spec.rb
|
|
238
|
+
homepage: https://github.com/keithrbennett/cov-loupe
|
|
239
|
+
licenses:
|
|
240
|
+
- MIT
|
|
241
|
+
metadata:
|
|
242
|
+
rubygems_mfa_required: 'true'
|
|
243
|
+
post_install_message: |
|
|
244
|
+
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
|
245
|
+
┃ V3.0.0 - GEM RENAMED: simplecov-mcp → cov-loupe ┃
|
|
246
|
+
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
|
247
|
+
┃ ┃
|
|
248
|
+
┃ This gem has been renamed! If upgrading from simplecov-mcp: ┃
|
|
249
|
+
┃ ┃
|
|
250
|
+
┃ • Executable: simplecov-mcp → cov-loupe ┃
|
|
251
|
+
┃ • Environment: SIMPLECOV_MCP_OPTS → COV_LOUPE_OPTS ┃
|
|
252
|
+
┃ • Log file: simplecov_mcp.log → cov_loupe.log ┃
|
|
253
|
+
┃ • Alias: smcp → clp (in documentation) ┃
|
|
254
|
+
┃ ┃
|
|
255
|
+
┃ Module name (CovLoupe) and require path (cov_loupe) unchanged. ┃
|
|
256
|
+
┃ ┃
|
|
257
|
+
┃ Uninstall old gem: gem uninstall simplecov-mcp ┃
|
|
258
|
+
┃ ┃
|
|
259
|
+
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
|
260
|
+
┃ V2.0.0 BREAKING CHANGES (if upgrading from v1.x) ┃
|
|
261
|
+
┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
|
262
|
+
┃ ┃
|
|
263
|
+
┃ • Options must now come BEFORE subcommands ┃
|
|
264
|
+
┃ • --stale renamed to --staleness (-S still works) ┃
|
|
265
|
+
┃ • --json replaced with --format json ┃
|
|
266
|
+
┃ • Error modes renamed: 'on' → 'log', 'trace' → 'debug' ┃
|
|
267
|
+
┃ • --success-predicate moved to 'validate' subcommand ┃
|
|
268
|
+
┃ • Default sort order changed from ascending to descending ┃
|
|
269
|
+
┃ ┃
|
|
270
|
+
┃ See docs/user/V2-BREAKING-CHANGES.md for complete migration guide. ┃
|
|
271
|
+
┃ ┃
|
|
272
|
+
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
|
273
|
+
rdoc_options: []
|
|
274
|
+
require_paths:
|
|
275
|
+
- lib
|
|
276
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
277
|
+
requirements:
|
|
278
|
+
- - ">="
|
|
279
|
+
- !ruby/object:Gem::Version
|
|
280
|
+
version: '3.2'
|
|
281
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
282
|
+
requirements:
|
|
283
|
+
- - ">="
|
|
284
|
+
- !ruby/object:Gem::Version
|
|
285
|
+
version: '0'
|
|
286
|
+
requirements: []
|
|
287
|
+
rubygems_version: 3.7.2
|
|
288
|
+
specification_version: 4
|
|
289
|
+
summary: MCP server + CLI for SimpleCov coverage data
|
|
290
|
+
test_files: []
|