simplecov-mcp 1.0.0 → 1.0.1
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 +4 -4
- data/lib/simplecov_mcp/errors.rb +20 -1
- data/lib/simplecov_mcp/model.rb +7 -2
- data/lib/simplecov_mcp/version.rb +1 -1
- data/spec/integration_spec.rb +14 -12
- data/spec/model_error_handling_spec.rb +4 -6
- data/spec/simplecov_mcp_model_spec.rb +2 -2
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 95c9d9edb894cafc89610f2d171e7452ec092a484666cfb15eac0314a1189963
|
|
4
|
+
data.tar.gz: bdb9d23aa1a53adfde9abe953fbeb21e1c998435a9fa63e7150f8ab7d26c8184
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5f2c42c2f48e5fecf6c7e7392dd384b7255a2b3b48ccb5fcc89fb423918ff9f5028b57f6ce68b4c03f288c23665a23d08d7cf48f9e36eaebab753cd4f2aa7ec6
|
|
7
|
+
data.tar.gz: 4a96af4e01a259d194a902e9ea45c98058ffc06c5ed4313cf6785e7fc40929b3a186b6ccd9bbb078b9907f84173223096eafb278bbb696c3df414495b1e672d4
|
data/lib/simplecov_mcp/errors.rb
CHANGED
|
@@ -63,7 +63,26 @@ module SimpleCovMcp
|
|
|
63
63
|
class FileNotFoundError < FileError; end
|
|
64
64
|
class FilePermissionError < FileError; end
|
|
65
65
|
class NotAFileError < FileError; end
|
|
66
|
-
|
|
66
|
+
|
|
67
|
+
class ResultsetNotFoundError < FileError
|
|
68
|
+
def user_friendly_message
|
|
69
|
+
base = "File error: #{message}"
|
|
70
|
+
|
|
71
|
+
# Only add helpful tips in CLI and library modes, not MCP mode
|
|
72
|
+
unless SimpleCovMcp.context.mcp_mode?
|
|
73
|
+
base += <<~HELP
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
Try one of the following:
|
|
77
|
+
- cd to a directory containing coverage/.resultset.json
|
|
78
|
+
- Specify a resultset: simplecov-mcp -r PATH
|
|
79
|
+
- Use -h for help: simplecov-mcp -h
|
|
80
|
+
HELP
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
base
|
|
84
|
+
end
|
|
85
|
+
end
|
|
67
86
|
|
|
68
87
|
# Coverage data related errors
|
|
69
88
|
class CoverageDataError < Error
|
data/lib/simplecov_mcp/model.rb
CHANGED
|
@@ -49,7 +49,7 @@ module SimpleCovMcp
|
|
|
49
49
|
timestamp: @cov_timestamp
|
|
50
50
|
)
|
|
51
51
|
rescue Errno::ENOENT => e
|
|
52
|
-
raise
|
|
52
|
+
raise ResultsetNotFoundError.new("Coverage data not found at #{resultset || @root}")
|
|
53
53
|
rescue JSON::ParserError => e
|
|
54
54
|
raise CoverageDataError.new("Invalid coverage data format: #{e.message}")
|
|
55
55
|
rescue Errno::EACCES => e
|
|
@@ -62,7 +62,12 @@ module SimpleCovMcp
|
|
|
62
62
|
raise CoverageDataError.new("Invalid path in coverage data: #{e.message}")
|
|
63
63
|
rescue RuntimeError => e
|
|
64
64
|
# RuntimeError from find_resultset or other operations
|
|
65
|
-
|
|
65
|
+
# Check if it's a resultset not found error
|
|
66
|
+
if e.message.downcase.include?('resultset')
|
|
67
|
+
raise ResultsetNotFoundError.new(e.message)
|
|
68
|
+
else
|
|
69
|
+
raise CoverageDataError.new("Failed to load coverage data: #{e.message}")
|
|
70
|
+
end
|
|
66
71
|
end
|
|
67
72
|
end
|
|
68
73
|
|
data/spec/integration_spec.rb
CHANGED
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
require 'spec_helper'
|
|
4
4
|
|
|
5
5
|
RSpec.describe 'SimpleCov MCP Integration Tests' do
|
|
6
|
+
# Timeout for MCP server operations (increased for JRuby compatibility)
|
|
7
|
+
MCP_TIMEOUT = 5
|
|
8
|
+
|
|
6
9
|
let(:project_root) { (FIXTURES_DIR / 'project1').to_s }
|
|
7
10
|
let(:coverage_dir) { File.join(project_root, 'coverage') }
|
|
8
11
|
let(:resultset_path) { File.join(coverage_dir, '.resultset.json') }
|
|
@@ -257,7 +260,7 @@ RSpec.describe 'SimpleCov MCP Integration Tests' do
|
|
|
257
260
|
it 'handles invalid resultset paths gracefully' do
|
|
258
261
|
expect do
|
|
259
262
|
SimpleCovMcp::CoverageModel.new(root: project_root, resultset: '/nonexistent/path')
|
|
260
|
-
end.to raise_error(SimpleCovMcp::
|
|
263
|
+
end.to raise_error(SimpleCovMcp::ResultsetNotFoundError, /Specified resultset not found/)
|
|
261
264
|
end
|
|
262
265
|
|
|
263
266
|
it 'provides helpful CLI error messages' do
|
|
@@ -332,7 +335,7 @@ RSpec.describe 'SimpleCov MCP Integration Tests' do
|
|
|
332
335
|
end
|
|
333
336
|
|
|
334
337
|
# Run the MCP executable with a single JSON-RPC request hash and return the captured streams.
|
|
335
|
-
def run_mcp_json(request_hash, env: default_env, timeout:
|
|
338
|
+
def run_mcp_json(request_hash, env: default_env, timeout: MCP_TIMEOUT)
|
|
336
339
|
Spec::Support::McpRunner.call_json(
|
|
337
340
|
request_hash,
|
|
338
341
|
**runner_args(env: env, timeout: timeout)
|
|
@@ -340,7 +343,7 @@ RSpec.describe 'SimpleCov MCP Integration Tests' do
|
|
|
340
343
|
end
|
|
341
344
|
|
|
342
345
|
# Run the MCP executable with a sequence of JSON-RPC requests (one per line).
|
|
343
|
-
def run_mcp_json_stream(request_hashes, env: default_env, timeout:
|
|
346
|
+
def run_mcp_json_stream(request_hashes, env: default_env, timeout: MCP_TIMEOUT)
|
|
344
347
|
Spec::Support::McpRunner.call_json_stream(
|
|
345
348
|
request_hashes,
|
|
346
349
|
**runner_args(env: env, timeout: timeout)
|
|
@@ -348,7 +351,7 @@ RSpec.describe 'SimpleCov MCP Integration Tests' do
|
|
|
348
351
|
end
|
|
349
352
|
|
|
350
353
|
# Run the MCP executable with a raw string payload (already encoded as needed).
|
|
351
|
-
def run_mcp_input(input, env: default_env, timeout:
|
|
354
|
+
def run_mcp_input(input, env: default_env, timeout: MCP_TIMEOUT)
|
|
352
355
|
Spec::Support::McpRunner.call(
|
|
353
356
|
input: input,
|
|
354
357
|
**runner_args(env: env, timeout: timeout)
|
|
@@ -594,7 +597,7 @@ RSpec.describe 'SimpleCov MCP Integration Tests' do
|
|
|
594
597
|
malformed_request = "{'jsonrpc': '2.0', 'id': 999, 'method': 'invalid'}"
|
|
595
598
|
|
|
596
599
|
env = { 'RUBY_LIB' => lib_path }
|
|
597
|
-
result = run_mcp_input(malformed_request, env: env
|
|
600
|
+
result = run_mcp_input(malformed_request, env: env)
|
|
598
601
|
|
|
599
602
|
# Should handle gracefully without crashing
|
|
600
603
|
# May return error response or empty output
|
|
@@ -615,8 +618,7 @@ RSpec.describe 'SimpleCov MCP Integration Tests' do
|
|
|
615
618
|
|
|
616
619
|
result = run_mcp_json(
|
|
617
620
|
request,
|
|
618
|
-
env: default_env.merge('SIMPLECOV_MCP_OPTS' => '--log-file stderr')
|
|
619
|
-
timeout: 3
|
|
621
|
+
env: default_env.merge('SIMPLECOV_MCP_OPTS' => '--log-file stderr')
|
|
620
622
|
)
|
|
621
623
|
|
|
622
624
|
response = parse_jsonrpc_response(result[:stdout])
|
|
@@ -631,7 +633,7 @@ RSpec.describe 'SimpleCov MCP Integration Tests' do
|
|
|
631
633
|
'SIMPLECOV_MCP_OPTS' => '--log-file stdout'
|
|
632
634
|
}
|
|
633
635
|
|
|
634
|
-
result = run_mcp_input(nil, env: env
|
|
636
|
+
result = run_mcp_input(nil, env: env)
|
|
635
637
|
|
|
636
638
|
combined_output = result[:stdout] + result[:stderr]
|
|
637
639
|
expect(combined_output).to include('stdout').and include('not permitted')
|
|
@@ -645,7 +647,7 @@ RSpec.describe 'SimpleCov MCP Integration Tests' do
|
|
|
645
647
|
params: { name: 'version_tool', arguments: {} } }
|
|
646
648
|
]
|
|
647
649
|
|
|
648
|
-
result = run_mcp_json_stream(requests
|
|
650
|
+
result = run_mcp_json_stream(requests)
|
|
649
651
|
|
|
650
652
|
responses = result[:stdout].lines.map do |line|
|
|
651
653
|
next if line.strip.empty?
|
|
@@ -811,7 +813,7 @@ RSpec.describe 'SimpleCov MCP Integration Tests' do
|
|
|
811
813
|
it 'handles completely invalid JSON input' do
|
|
812
814
|
invalid_json = 'this is not JSON at all'
|
|
813
815
|
|
|
814
|
-
result = run_mcp_input(invalid_json, env: default_env
|
|
816
|
+
result = run_mcp_input(invalid_json, env: default_env)
|
|
815
817
|
|
|
816
818
|
# Should not crash with unhandled exception
|
|
817
819
|
combined = result[:stdout] + result[:stderr]
|
|
@@ -825,7 +827,7 @@ RSpec.describe 'SimpleCov MCP Integration Tests' do
|
|
|
825
827
|
end
|
|
826
828
|
|
|
827
829
|
it 'handles empty input gracefully' do
|
|
828
|
-
result = run_mcp_input('', env: default_env
|
|
830
|
+
result = run_mcp_input('', env: default_env)
|
|
829
831
|
|
|
830
832
|
# Empty input should be handled without crash
|
|
831
833
|
expect(result[:stderr]).not_to include('NameError')
|
|
@@ -835,7 +837,7 @@ RSpec.describe 'SimpleCov MCP Integration Tests' do
|
|
|
835
837
|
it 'handles partial JSON input' do
|
|
836
838
|
partial_json = '{"jsonrpc": "2.0", "id": 300, "method":'
|
|
837
839
|
|
|
838
|
-
result = run_mcp_input(partial_json, env: default_env
|
|
840
|
+
result = run_mcp_input(partial_json, env: default_env)
|
|
839
841
|
|
|
840
842
|
# Should handle gracefully without crashing
|
|
841
843
|
expect(result[:stderr]).not_to include('uninitialized constant')
|
|
@@ -187,23 +187,21 @@ RSpec.describe SimpleCovMcp::CoverageModel, 'error handling' do
|
|
|
187
187
|
|
|
188
188
|
expect do
|
|
189
189
|
SimpleCovMcp::CoverageModel.new(root: root, resultset: '/nonexistent/path')
|
|
190
|
-
end.to raise_error(SimpleCovMcp::
|
|
191
|
-
expect(error.message).to include('Failed to load coverage data')
|
|
190
|
+
end.to raise_error(SimpleCovMcp::ResultsetNotFoundError) do |error|
|
|
192
191
|
expect(error.message).to include('Specified resultset not found')
|
|
193
192
|
end
|
|
194
193
|
end
|
|
195
194
|
|
|
196
195
|
it 'handles RuntimeError with generic messages' do
|
|
197
|
-
# Test RuntimeError with any generic message
|
|
196
|
+
# Test RuntimeError with any generic message that includes 'resultset'
|
|
198
197
|
allow(SimpleCovMcp::CovUtil).to receive(:find_resultset).and_raise(
|
|
199
198
|
RuntimeError.new('Something went wrong during resultset lookup')
|
|
200
199
|
)
|
|
201
200
|
|
|
202
201
|
expect do
|
|
203
202
|
SimpleCovMcp::CoverageModel.new(root: root, resultset: 'coverage')
|
|
204
|
-
end.to raise_error(SimpleCovMcp::
|
|
205
|
-
expect(error.message).to include('
|
|
206
|
-
expect(error.message).to include('Something went wrong')
|
|
203
|
+
end.to raise_error(SimpleCovMcp::ResultsetNotFoundError) do |error|
|
|
204
|
+
expect(error.message).to include('Something went wrong during resultset lookup')
|
|
207
205
|
end
|
|
208
206
|
end
|
|
209
207
|
end
|
|
@@ -19,10 +19,10 @@ RSpec.describe SimpleCovMcp::CoverageModel do
|
|
|
19
19
|
end.to raise_error(SimpleCovMcp::FileError, /Coverage data not found/)
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
-
it 'raises
|
|
22
|
+
it 'raises ResultsetNotFoundError when resultset file does not exist' do
|
|
23
23
|
expect do
|
|
24
24
|
described_class.new(root: root, resultset: '/nonexistent/path/.resultset.json')
|
|
25
|
-
end.to raise_error(SimpleCovMcp::
|
|
25
|
+
end.to raise_error(SimpleCovMcp::ResultsetNotFoundError, /Specified resultset not found/)
|
|
26
26
|
end
|
|
27
27
|
end
|
|
28
28
|
|