cov-loupe 3.0.0 → 4.0.0.pre

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.
Files changed (281) hide show
  1. checksums.yaml +4 -4
  2. data/AGENTS.md +230 -0
  3. data/CLAUDE.md +5 -0
  4. data/CODE_OF_CONDUCT.md +62 -0
  5. data/CONTRIBUTING.md +102 -0
  6. data/GEMINI.md +5 -0
  7. data/README.md +154 -51
  8. data/RELEASE_NOTES.md +452 -0
  9. data/dev/images/cov-loupe-icon-lores.png +0 -0
  10. data/dev/images/cov-loupe-icon-square.png +0 -0
  11. data/dev/images/cov-loupe-icon.png +0 -0
  12. data/dev/images/cov-loupe-logo.png +0 -0
  13. data/dev/prompts/README.md +74 -0
  14. data/dev/prompts/archive/architectural-review-and-actions-prompt.md +53 -0
  15. data/dev/prompts/archive/investigate-and-report-issues-prompt.md +33 -0
  16. data/dev/prompts/archive/produce-action-items-prompt.md +25 -0
  17. data/dev/prompts/guidelines/ai-code-evaluator-guidelines.md +337 -0
  18. data/dev/prompts/improve/refactor-test-suite.md +18 -0
  19. data/dev/prompts/improve/simplify-code-logic.md +133 -0
  20. data/dev/prompts/improve/update-documentation.md +21 -0
  21. data/dev/prompts/review/comprehensive-codebase-review.md +176 -0
  22. data/dev/prompts/review/identify-action-items.md +143 -0
  23. data/dev/prompts/review/verify-code-changes.md +54 -0
  24. data/dev/prompts/validate/create-screencast-outline.md +234 -0
  25. data/dev/prompts/validate/test-documentation-examples.md +180 -0
  26. data/docs/QUICKSTART.md +63 -0
  27. data/docs/assets/images/cov-loupe-logo-lores.png +0 -0
  28. data/docs/assets/images/cov-loupe-logo.png +0 -0
  29. data/docs/assets/images/favicon.png +0 -0
  30. data/docs/assets/stylesheets/branding.css +16 -0
  31. data/docs/assets/stylesheets/extra.css +15 -0
  32. data/docs/code_of_conduct.md +1 -0
  33. data/docs/contributing.md +1 -0
  34. data/docs/dev/ARCHITECTURE.md +56 -11
  35. data/docs/dev/DEVELOPMENT.md +116 -12
  36. data/docs/dev/FUTURE_ENHANCEMENTS.md +14 -0
  37. data/docs/dev/README.md +3 -2
  38. data/docs/dev/RELEASING.md +2 -0
  39. data/docs/dev/arch-decisions/README.md +10 -7
  40. data/docs/dev/arch-decisions/application-architecture.md +259 -0
  41. data/docs/dev/arch-decisions/coverage-data-quality.md +193 -0
  42. data/docs/dev/arch-decisions/output-character-mode.md +217 -0
  43. data/docs/dev/arch-decisions/path-resolution.md +90 -0
  44. data/docs/dev/arch-decisions/{004-x-arch-decision.md → policy-validation.md} +32 -28
  45. data/docs/dev/arch-decisions/{005-x-arch-decision.md → simplecov-integration.md} +47 -44
  46. data/docs/dev/presentations/cov-loupe-presentation.md +15 -13
  47. data/docs/examples/mcp-inputs.md +3 -0
  48. data/docs/examples/prompts.md +3 -0
  49. data/docs/examples/success_predicates.md +3 -0
  50. data/docs/fixtures/demo_project/.resultset.json +170 -0
  51. data/docs/fixtures/demo_project/README.md +6 -0
  52. data/docs/fixtures/demo_project/app/controllers/admin/audit_logs_controller.rb +19 -0
  53. data/docs/fixtures/demo_project/app/controllers/orders_controller.rb +26 -0
  54. data/docs/fixtures/demo_project/app/models/order.rb +20 -0
  55. data/docs/fixtures/demo_project/app/models/user.rb +19 -0
  56. data/docs/fixtures/demo_project/lib/api/client.rb +22 -0
  57. data/docs/fixtures/demo_project/lib/ops/jobs/cleanup_job.rb +16 -0
  58. data/docs/fixtures/demo_project/lib/ops/jobs/report_job.rb +17 -0
  59. data/docs/fixtures/demo_project/lib/payments/processor.rb +15 -0
  60. data/docs/fixtures/demo_project/lib/payments/refund_service.rb +15 -0
  61. data/docs/fixtures/demo_project/lib/payments/reporting/exporter.rb +16 -0
  62. data/docs/index.md +1 -0
  63. data/docs/license.md +3 -0
  64. data/docs/release_notes.md +3 -0
  65. data/docs/user/ADVANCED_USAGE.md +208 -115
  66. data/docs/user/CLI_FALLBACK_FOR_LLMS.md +2 -0
  67. data/docs/user/CLI_USAGE.md +276 -101
  68. data/docs/user/ERROR_HANDLING.md +4 -4
  69. data/docs/user/EXAMPLES.md +121 -128
  70. data/docs/user/INSTALLATION.md +9 -28
  71. data/docs/user/LIBRARY_API.md +227 -122
  72. data/docs/user/MCP_INTEGRATION.md +114 -203
  73. data/docs/user/README.md +5 -1
  74. data/docs/user/TROUBLESHOOTING.md +49 -27
  75. data/docs/user/installing-a-prelease-version-of-covloupe.md +43 -0
  76. data/docs/user/{V2-BREAKING-CHANGES.md → migrations/MIGRATING_TO_V2.md} +62 -72
  77. data/docs/user/migrations/MIGRATING_TO_V3.md +72 -0
  78. data/docs/user/migrations/MIGRATING_TO_V4.md +591 -0
  79. data/docs/user/migrations/README.md +22 -0
  80. data/docs/user/prompts/README.md +9 -0
  81. data/docs/user/prompts/non-web-coverage-analysis-prompt.md +103 -0
  82. data/docs/user/prompts/rails-coverage-analysis-prompt.md +94 -0
  83. data/docs/user/prompts/use-cli-not-mcp-prompt.md +53 -0
  84. data/examples/cli_demo.sh +77 -0
  85. data/examples/filter_and_table_demo-output.md +114 -0
  86. data/examples/filter_and_table_demo.rb +174 -0
  87. data/examples/fixtures/demo_project/coverage/.resultset.json +10 -0
  88. data/examples/mcp-inputs/README.md +66 -0
  89. data/examples/mcp-inputs/coverage_detailed.json +1 -0
  90. data/examples/mcp-inputs/coverage_raw.json +1 -0
  91. data/examples/mcp-inputs/coverage_summary.json +1 -0
  92. data/examples/mcp-inputs/list.json +1 -0
  93. data/examples/mcp-inputs/uncovered_lines.json +1 -0
  94. data/examples/prompts/README.md +27 -0
  95. data/examples/prompts/custom_resultset.txt +2 -0
  96. data/examples/prompts/detailed_with_source.txt +2 -0
  97. data/examples/prompts/list_lowest.txt +2 -0
  98. data/examples/prompts/summary.txt +2 -0
  99. data/examples/prompts/uncovered.txt +2 -0
  100. data/examples/success_predicates/README.md +198 -0
  101. data/examples/success_predicates/all_files_above_threshold_predicate.rb +21 -0
  102. data/examples/success_predicates/directory_specific_thresholds_predicate.rb +30 -0
  103. data/examples/success_predicates/project_coverage_minimum_predicate.rb +6 -0
  104. data/lib/cov_loupe/base_tool.rb +229 -20
  105. data/lib/cov_loupe/cli.rb +132 -23
  106. data/lib/cov_loupe/commands/base_command.rb +25 -6
  107. data/lib/cov_loupe/commands/command_factory.rb +0 -1
  108. data/lib/cov_loupe/commands/detailed_command.rb +10 -5
  109. data/lib/cov_loupe/commands/list_command.rb +2 -1
  110. data/lib/cov_loupe/commands/raw_command.rb +7 -5
  111. data/lib/cov_loupe/commands/summary_command.rb +12 -7
  112. data/lib/cov_loupe/commands/totals_command.rb +74 -10
  113. data/lib/cov_loupe/commands/uncovered_command.rb +7 -5
  114. data/lib/cov_loupe/commands/validate_command.rb +11 -3
  115. data/lib/cov_loupe/commands/version_command.rb +6 -4
  116. data/lib/cov_loupe/{app_config.rb → config/app_config.rb} +13 -5
  117. data/lib/cov_loupe/config/app_context.rb +43 -0
  118. data/lib/cov_loupe/config/boolean_type.rb +91 -0
  119. data/lib/cov_loupe/config/logger.rb +92 -0
  120. data/lib/cov_loupe/{option_normalizers.rb → config/option_normalizers.rb} +55 -24
  121. data/lib/cov_loupe/{option_parser_builder.rb → config/option_parser_builder.rb} +46 -24
  122. data/lib/cov_loupe/coverage/coverage_calculator.rb +53 -0
  123. data/lib/cov_loupe/coverage/coverage_reporter.rb +63 -0
  124. data/lib/cov_loupe/coverage/coverage_table_formatter.rb +133 -0
  125. data/lib/cov_loupe/{error_handler.rb → errors/error_handler.rb} +21 -33
  126. data/lib/cov_loupe/{errors.rb → errors/errors.rb} +48 -71
  127. data/lib/cov_loupe/formatters/formatters.rb +75 -0
  128. data/lib/cov_loupe/formatters/source_formatter.rb +18 -7
  129. data/lib/cov_loupe/formatters/table_formatter.rb +80 -0
  130. data/lib/cov_loupe/loaders/all.rb +15 -0
  131. data/lib/cov_loupe/loaders/all_cli.rb +10 -0
  132. data/lib/cov_loupe/loaders/all_mcp.rb +23 -0
  133. data/lib/cov_loupe/loaders/resultset_loader.rb +147 -0
  134. data/lib/cov_loupe/mcp_server.rb +3 -2
  135. data/lib/cov_loupe/model/model.rb +520 -0
  136. data/lib/cov_loupe/model/model_data.rb +13 -0
  137. data/lib/cov_loupe/model/model_data_cache.rb +116 -0
  138. data/lib/cov_loupe/option_parsers/env_options_parser.rb +17 -6
  139. data/lib/cov_loupe/option_parsers/error_helper.rb +16 -10
  140. data/lib/cov_loupe/output_chars.rb +192 -0
  141. data/lib/cov_loupe/paths/glob_utils.rb +100 -0
  142. data/lib/cov_loupe/{path_relativizer.rb → paths/path_relativizer.rb} +5 -13
  143. data/lib/cov_loupe/paths/path_utils.rb +265 -0
  144. data/lib/cov_loupe/paths/volume_case_sensitivity.rb +173 -0
  145. data/lib/cov_loupe/presenters/base_coverage_presenter.rb +9 -13
  146. data/lib/cov_loupe/presenters/coverage_payload_presenter.rb +21 -0
  147. data/lib/cov_loupe/presenters/payload_caching.rb +23 -0
  148. data/lib/cov_loupe/presenters/project_coverage_presenter.rb +73 -21
  149. data/lib/cov_loupe/presenters/project_totals_presenter.rb +16 -10
  150. data/lib/cov_loupe/repositories/coverage_repository.rb +149 -0
  151. data/lib/cov_loupe/resolvers/coverage_line_resolver.rb +90 -76
  152. data/lib/cov_loupe/resolvers/{resolver_factory.rb → resolver_helpers.rb} +6 -5
  153. data/lib/cov_loupe/resolvers/resultset_path_resolver.rb +40 -12
  154. data/lib/cov_loupe/scripts/command_execution.rb +113 -0
  155. data/lib/cov_loupe/scripts/latest_ci_status.rb +97 -0
  156. data/lib/cov_loupe/scripts/pre_release_check.rb +164 -0
  157. data/lib/cov_loupe/scripts/setup_doc_server.rb +23 -0
  158. data/lib/cov_loupe/scripts/start_doc_server.rb +24 -0
  159. data/lib/cov_loupe/staleness/stale_status.rb +23 -0
  160. data/lib/cov_loupe/staleness/staleness_checker.rb +328 -0
  161. data/lib/cov_loupe/staleness/staleness_message_formatter.rb +91 -0
  162. data/lib/cov_loupe/tools/coverage_detailed_tool.rb +14 -15
  163. data/lib/cov_loupe/tools/coverage_raw_tool.rb +14 -14
  164. data/lib/cov_loupe/tools/coverage_summary_tool.rb +16 -16
  165. data/lib/cov_loupe/tools/coverage_table_tool.rb +139 -21
  166. data/lib/cov_loupe/tools/coverage_totals_tool.rb +31 -13
  167. data/lib/cov_loupe/tools/help_tool.rb +16 -20
  168. data/lib/cov_loupe/tools/list_tool.rb +65 -0
  169. data/lib/cov_loupe/tools/uncovered_lines_tool.rb +14 -14
  170. data/lib/cov_loupe/tools/validate_tool.rb +18 -24
  171. data/lib/cov_loupe/tools/version_tool.rb +8 -3
  172. data/lib/cov_loupe/version.rb +1 -1
  173. data/lib/cov_loupe.rb +83 -55
  174. metadata +184 -154
  175. data/docs/dev/BRANCH_ONLY_COVERAGE.md +0 -158
  176. data/docs/dev/arch-decisions/001-x-arch-decision.md +0 -95
  177. data/docs/dev/arch-decisions/002-x-arch-decision.md +0 -159
  178. data/docs/dev/arch-decisions/003-x-arch-decision.md +0 -165
  179. data/lib/cov_loupe/app_context.rb +0 -26
  180. data/lib/cov_loupe/constants.rb +0 -22
  181. data/lib/cov_loupe/coverage_reporter.rb +0 -31
  182. data/lib/cov_loupe/formatters.rb +0 -51
  183. data/lib/cov_loupe/mode_detector.rb +0 -56
  184. data/lib/cov_loupe/model.rb +0 -339
  185. data/lib/cov_loupe/presenters/coverage_detailed_presenter.rb +0 -14
  186. data/lib/cov_loupe/presenters/coverage_raw_presenter.rb +0 -14
  187. data/lib/cov_loupe/presenters/coverage_summary_presenter.rb +0 -14
  188. data/lib/cov_loupe/presenters/coverage_uncovered_presenter.rb +0 -14
  189. data/lib/cov_loupe/resultset_loader.rb +0 -131
  190. data/lib/cov_loupe/staleness_checker.rb +0 -247
  191. data/lib/cov_loupe/table_formatter.rb +0 -64
  192. data/lib/cov_loupe/tools/all_files_coverage_tool.rb +0 -51
  193. data/lib/cov_loupe/util.rb +0 -88
  194. data/spec/MCP_INTEGRATION_TESTS_README.md +0 -111
  195. data/spec/TIMESTAMPS.md +0 -48
  196. data/spec/all_files_coverage_tool_spec.rb +0 -53
  197. data/spec/app_config_spec.rb +0 -142
  198. data/spec/base_tool_spec.rb +0 -62
  199. data/spec/cli/show_default_report_spec.rb +0 -33
  200. data/spec/cli_enumerated_options_spec.rb +0 -90
  201. data/spec/cli_error_spec.rb +0 -184
  202. data/spec/cli_format_spec.rb +0 -123
  203. data/spec/cli_json_options_spec.rb +0 -50
  204. data/spec/cli_source_spec.rb +0 -44
  205. data/spec/cli_spec.rb +0 -192
  206. data/spec/cli_table_spec.rb +0 -28
  207. data/spec/cli_usage_spec.rb +0 -42
  208. data/spec/commands/base_command_spec.rb +0 -107
  209. data/spec/commands/command_factory_spec.rb +0 -76
  210. data/spec/commands/detailed_command_spec.rb +0 -34
  211. data/spec/commands/list_command_spec.rb +0 -28
  212. data/spec/commands/raw_command_spec.rb +0 -69
  213. data/spec/commands/summary_command_spec.rb +0 -34
  214. data/spec/commands/totals_command_spec.rb +0 -34
  215. data/spec/commands/uncovered_command_spec.rb +0 -55
  216. data/spec/commands/validate_command_spec.rb +0 -213
  217. data/spec/commands/version_command_spec.rb +0 -38
  218. data/spec/constants_spec.rb +0 -61
  219. data/spec/cov_loupe/formatters/source_formatter_spec.rb +0 -267
  220. data/spec/cov_loupe/formatters_spec.rb +0 -76
  221. data/spec/cov_loupe/presenters/base_coverage_presenter_spec.rb +0 -79
  222. data/spec/cov_loupe_model_spec.rb +0 -454
  223. data/spec/cov_loupe_module_spec.rb +0 -37
  224. data/spec/cov_loupe_opts_spec.rb +0 -185
  225. data/spec/coverage_reporter_spec.rb +0 -102
  226. data/spec/coverage_table_tool_spec.rb +0 -59
  227. data/spec/coverage_totals_tool_spec.rb +0 -37
  228. data/spec/error_handler_spec.rb +0 -197
  229. data/spec/error_mode_spec.rb +0 -139
  230. data/spec/errors_edge_cases_spec.rb +0 -312
  231. data/spec/errors_stale_spec.rb +0 -83
  232. data/spec/file_based_mcp_tools_spec.rb +0 -99
  233. data/spec/help_tool_spec.rb +0 -26
  234. data/spec/integration_spec.rb +0 -789
  235. data/spec/logging_fallback_spec.rb +0 -128
  236. data/spec/mcp_logging_spec.rb +0 -44
  237. data/spec/mcp_server_integration_spec.rb +0 -23
  238. data/spec/mcp_server_spec.rb +0 -106
  239. data/spec/mode_detector_spec.rb +0 -153
  240. data/spec/model_error_handling_spec.rb +0 -269
  241. data/spec/model_staleness_spec.rb +0 -79
  242. data/spec/option_normalizers_spec.rb +0 -203
  243. data/spec/option_parsers/env_options_parser_spec.rb +0 -221
  244. data/spec/option_parsers/error_helper_spec.rb +0 -222
  245. data/spec/path_relativizer_spec.rb +0 -98
  246. data/spec/presenters/coverage_detailed_presenter_spec.rb +0 -19
  247. data/spec/presenters/coverage_raw_presenter_spec.rb +0 -15
  248. data/spec/presenters/coverage_summary_presenter_spec.rb +0 -15
  249. data/spec/presenters/coverage_uncovered_presenter_spec.rb +0 -16
  250. data/spec/presenters/project_coverage_presenter_spec.rb +0 -87
  251. data/spec/presenters/project_totals_presenter_spec.rb +0 -144
  252. data/spec/resolvers/coverage_line_resolver_spec.rb +0 -282
  253. data/spec/resolvers/resolver_factory_spec.rb +0 -61
  254. data/spec/resolvers/resultset_path_resolver_spec.rb +0 -60
  255. data/spec/resultset_loader_spec.rb +0 -167
  256. data/spec/shared_examples/README.md +0 -115
  257. data/spec/shared_examples/coverage_presenter_examples.rb +0 -66
  258. data/spec/shared_examples/file_based_mcp_tools.rb +0 -179
  259. data/spec/shared_examples/formatted_command_examples.rb +0 -64
  260. data/spec/shared_examples/mcp_tool_text_json_response.rb +0 -16
  261. data/spec/spec_helper.rb +0 -127
  262. data/spec/staleness_checker_spec.rb +0 -374
  263. data/spec/staleness_more_spec.rb +0 -42
  264. data/spec/support/cli_helpers.rb +0 -22
  265. data/spec/support/control_flow_helpers.rb +0 -20
  266. data/spec/support/fake_mcp.rb +0 -40
  267. data/spec/support/io_helpers.rb +0 -29
  268. data/spec/support/mcp_helpers.rb +0 -35
  269. data/spec/support/mcp_runner.rb +0 -66
  270. data/spec/support/mocking_helpers.rb +0 -30
  271. data/spec/table_format_spec.rb +0 -70
  272. data/spec/tools/validate_tool_spec.rb +0 -132
  273. data/spec/tools_error_handling_spec.rb +0 -130
  274. data/spec/util_spec.rb +0 -154
  275. data/spec/version_spec.rb +0 -123
  276. data/spec/version_tool_spec.rb +0 -141
  277. /data/{spec/fixtures/project1 → examples/fixtures/demo_project}/lib/bar.rb +0 -0
  278. /data/{spec/fixtures/project1 → examples/fixtures/demo_project}/lib/foo.rb +0 -0
  279. /data/lib/cov_loupe/{config_parser.rb → config/config_parser.rb} +0 -0
  280. /data/lib/cov_loupe/{predicate_evaluator.rb → config/predicate_evaluator.rb} +0 -0
  281. /data/lib/cov_loupe/{error_handler_factory.rb → errors/error_handler_factory.rb} +0 -0
@@ -0,0 +1,103 @@
1
+ # Test Coverage Analysis Prompt for Ruby Applications
2
+
3
+ [Back to main README](../../index.md)
4
+
5
+ Use the cov-loupe MCP server tool to analyze the test coverage data generated by simplecov for this Ruby project.
6
+
7
+ Generate a detailed coverage analysis report and output it to a markdown file named `test_coverage_analysis.md`.
8
+
9
+ The report should include:
10
+
11
+ ## 1. Executive Summary
12
+ - Overall coverage percentage and trend direction
13
+ - High-level assessment of testing health across the application
14
+ - Key strengths and critical gaps at a glance
15
+
16
+ ## 2. Coverage by Application Component
17
+ Detailed analysis of coverage across different application layers:
18
+ - **Core Domain Logic**: Business logic classes, domain models, and entities
19
+ - **Services/Commands**: Service objects, command patterns, and use cases
20
+ - **Data Access Layer**: Repository patterns, data mappers, database interactions
21
+ - **External Integrations**: API clients, third-party service wrappers
22
+ - **Utilities/Helpers**: Helper modules, utility classes, and shared functions
23
+ - **CLI Components**: Command-line interface handlers and argument parsers (if applicable)
24
+ - **Configuration**: Configuration classes and initialization logic
25
+ - **Lib files**: Custom libraries and reusable modules
26
+ - **Concerns/Mixins**: Shared modules and concerns
27
+
28
+ ## 3. Well-Tested Areas
29
+ - What's working well and why
30
+ - Testing patterns and practices to replicate
31
+ - Examples of strong test coverage with specific file references
32
+
33
+ ## 4. Poorly-Tested Areas
34
+ Organize by:
35
+ - **Complexity to Test**: Simple/Moderate/Complex (considering dependencies, I/O operations, external services, etc.)
36
+ - **Risk Level**: High/Medium/Low (impact on data integrity, system reliability, business logic correctness)
37
+ - **Coverage Gap Size**: Percentage of uncovered lines and number of untested methods
38
+
39
+ ## 5. Priority Issues Table
40
+ Create a markdown table with these columns:
41
+ - File/Module Path
42
+ - Component Type (Service/Domain/Integration/etc.)
43
+ - Current Coverage %
44
+ - Uncovered Lines Count
45
+ - Risk Level (High/Medium/Low)
46
+ - Complexity to Fix (High/Medium/Low)
47
+ - Priority Score (1-10, with 10 being highest priority)
48
+ - Recommended Action (specific next steps)
49
+
50
+ Sort by Priority Score descending.
51
+
52
+ ## 6. Ruby Application Testing Analysis
53
+ - **Domain Logic Testing**: Coverage of business rules, validations, calculations, state transitions
54
+ - **Service Layer Testing**: Coverage of orchestration logic, error handling, transaction boundaries
55
+ - **Data Access Testing**: Coverage of queries, data transformations, persistence operations
56
+ - **Integration Testing**: Testing of interactions between components and external systems
57
+ - **API Client Testing**: Coverage of HTTP requests, response parsing, error handling
58
+ - **File I/O Operations**: Testing of file reading/writing, parsing, serialization
59
+ - **Concurrency/Threading**: Coverage of thread-safe operations, race conditions (if applicable)
60
+ - **Error Handling**: Testing of exception handling, retry logic, fallback mechanisms
61
+ - **Security**: Testing of input validation, data sanitization, authentication/authorization
62
+ - **Missing Test Types**: Identify gaps in unit/integration/end-to-end tests
63
+
64
+ ## 7. Common Ruby Testing Anti-Patterns Detected
65
+ - Over-mocking leading to brittle tests
66
+ - Missing edge case coverage in core domain logic
67
+ - Untested error handling and failure scenarios
68
+ - Missing tests for external service integrations
69
+ - Lack of integration tests for critical workflows
70
+ - Untested concurrency or threading logic (if applicable)
71
+ - Insufficient testing of data transformation pipelines
72
+ - Missing tests for CLI argument parsing and validation
73
+
74
+ ## 8. Actionable Testing Roadmap
75
+ Prioritized list of specific issues to resolve, organized by effort level:
76
+ - **Quick Wins** (< 2 hours): Simple tests with high impact
77
+ - **Sprint 1** (2-8 hours): Medium complexity, high priority
78
+ - **Sprint 2** (1-2 days): Complex but critical coverage gaps
79
+ - **Long-term** (> 2 days): Large refactoring or architectural test improvements
80
+
81
+ Include specific file paths, method names, and recommended testing approaches for each item.
82
+
83
+ ## 9. Metrics Dashboard
84
+ Key numbers:
85
+ - Overall coverage percentage
86
+ - Number of files at 0% coverage
87
+ - Number of files at 100% coverage
88
+ - Number of files above 90% coverage
89
+ - Number of files below 50% coverage
90
+ - Coverage by component type (Domain %, Services %, Integrations %, etc.)
91
+ - Trend direction (if historical data available)
92
+ - Lines of code vs lines of test code ratio
93
+ - Average cyclomatic complexity of untested methods (if available)
94
+
95
+ ## 10. Risk Assessment
96
+ - **Critical Paths**: Identify core business workflows and their test coverage
97
+ - **High-Risk Untested Code**: Data processing, financial calculations, authentication, data deletion, etc.
98
+ - **Security Implications**: Areas where lack of tests could lead to vulnerabilities
99
+ - **Technical Debt**: Old code with no tests that should be prioritized for coverage
100
+ - **External Dependencies**: Integration points with poor test coverage
101
+ - **Data Integrity Risks**: Operations that modify or delete data without adequate test coverage
102
+
103
+ Include specific file paths, line numbers, and code examples where relevant. Focus on actionable insights rather than just reporting numbers. Provide concrete recommendations for improving the test suite architecture and coverage strategy.
@@ -0,0 +1,94 @@
1
+ # Test Coverage Analysis Prompt for Ruby on Rails Project
2
+
3
+ [Back to main README](../../index.md)
4
+
5
+ Use the cov-loupe MCP server tool to analyze the test coverage data generated by simplecov for this Ruby on Rails project. Generate a detailed coverage analysis report and output it to a markdown file named `test_coverage_analysis.md`.
6
+
7
+ The report should include:
8
+
9
+ ## 1. Executive Summary
10
+ - Overall coverage percentage and trend direction
11
+ - High-level assessment of testing health across the Rails application
12
+ - Key strengths and critical gaps at a glance
13
+
14
+ ## 2. Coverage by Rails Component
15
+ Detailed analysis of coverage across different Rails layers:
16
+ - **Models**: ActiveRecord models, validations, scopes, associations, callbacks
17
+ - **Controllers**: Actions, before_actions, strong parameters, response handling
18
+ - **Views**: View helpers, partials, component logic
19
+ - **Mailers**: Email templates and delivery logic
20
+ - **Jobs**: ActiveJob background jobs and queue handlers
21
+ - **Services/POROs**: Business logic classes and service objects
22
+ - **Concerns**: Shared modules and mixins
23
+ - **Lib files**: Custom libraries and utilities
24
+ - **Configuration**: Initializers and config files (if applicable)
25
+
26
+ ## 3. Well-Tested Areas
27
+ - What's working well and why
28
+ - Testing patterns and practices to replicate
29
+ - Examples of strong test coverage with specific file references
30
+
31
+ ## 4. Poorly-Tested Areas
32
+ Organize by:
33
+ - **Complexity to Test**: Simple/Moderate/Complex (considering Rails dependencies, database setup, external services, etc.)
34
+ - **Risk Level**: High/Medium/Low (impact on user experience, data integrity, security)
35
+ - **Coverage Gap Size**: Percentage of uncovered lines and number of untested methods
36
+
37
+ ## 5. Priority Issues Table
38
+ Create a markdown table with these columns:
39
+ - File/Module Path
40
+ - Component Type (Model/Controller/Job/etc.)
41
+ - Current Coverage %
42
+ - Uncovered Lines Count
43
+ - Risk Level (High/Medium/Low)
44
+ - Complexity to Fix (High/Medium/Low)
45
+ - Priority Score (1-10, with 10 being highest priority)
46
+ - Recommended Action (specific next steps)
47
+
48
+ Sort by Priority Score descending.
49
+
50
+ ## 6. Rails-Specific Testing Analysis
51
+ - **Model Testing**: Coverage of validations, associations, scopes, callbacks, custom methods
52
+ - **Controller Testing**: Coverage of happy paths vs error handling, authentication/authorization
53
+ - **Integration Testing**: Request specs, feature specs, system tests
54
+ - **API Testing**: Coverage of JSON/XML responses, API versioning
55
+ - **Database Operations**: Testing of migrations, seeds, complex queries
56
+ - **Background Jobs**: Coverage of job execution, retry logic, error handling
57
+ - **Security**: Testing of authentication, authorization, input sanitization, CSRF protection
58
+ - **Missing Test Types**: Identify gaps in unit/integration/system/feature tests
59
+
60
+ ## 7. Common Rails Testing Anti-Patterns Detected
61
+ - Over-reliance on controller tests vs request specs
62
+ - Missing edge case coverage in models
63
+ - Untested error handling and failure scenarios
64
+ - Missing tests for background jobs and mailers
65
+ - Lack of integration tests for critical user flows
66
+ - Untested authorization/permission logic
67
+
68
+ ## 8. Actionable Testing Roadmap
69
+ Prioritized list of specific issues to resolve, organized by effort level:
70
+ - **Quick Wins** (< 2 hours): Simple tests with high impact
71
+ - **Sprint 1** (2-8 hours): Medium complexity, high priority
72
+ - **Sprint 2** (1-2 days): Complex but critical coverage gaps
73
+ - **Long-term** (> 2 days): Large refactoring or architectural test improvements
74
+
75
+ Include specific file paths, method names, and recommended testing approaches for each item.
76
+
77
+ ## 9. Metrics Dashboard
78
+ Key numbers:
79
+ - Overall coverage percentage
80
+ - Number of files at 0% coverage
81
+ - Number of files at 100% coverage
82
+ - Number of files above 90% coverage
83
+ - Number of files below 50% coverage
84
+ - Coverage by component type (Models %, Controllers %, etc.)
85
+ - Trend direction (if historical data available)
86
+ - Lines of code vs lines of test code ratio
87
+
88
+ ## 10. Risk Assessment
89
+ - **Critical Paths**: Identify core user journeys and their test coverage
90
+ - **High-Risk Untested Code**: Payment processing, authentication, data deletion, etc.
91
+ - **Security Implications**: Areas where lack of tests could lead to vulnerabilities
92
+ - **Technical Debt**: Old code with no tests that should be prioritized for coverage
93
+
94
+ Include specific file paths, line numbers, and code examples where relevant. Focus on actionable insights rather than just reporting numbers. Provide concrete recommendations for improving the test suite architecture and coverage strategy.
@@ -0,0 +1,53 @@
1
+ # Use the 'cov-loupe' application as a command line utility.
2
+
3
+ [Back to main README](../../index.md)
4
+
5
+ The `cov-loupe` application provides precise test coverage information for your Ruby application.
6
+
7
+ It reads the `.resultset.json` file generated by SimpleCov, and offers multiple ways to analyze and display its information.
8
+
9
+ Below is the help for version 4.0.0.pre, but run `cov-loupe --help` to make sure you get the most up-to-date information.
10
+
11
+ ----
12
+ ```bash
13
+ -------------------------------------------------------------------------------
14
+ Usage: cov-loupe [options] [subcommand] [args] (default subcommand: list)
15
+ Repository: https://github.com/keithrbennett/cov-loupe
16
+ Documentation (Web): https://keithrbennett.github.io/cov-loupe/
17
+ Documentation (Local): /home/kbennett/code/cov-loupe/**/*.md
18
+ Version: 4.0.0.pre
19
+ -------------------------------------------------------------------------------
20
+
21
+ Subcommands:
22
+ detailed <path> Show per-line rows with hits/covered
23
+ list Show files coverage (default: table, or use --format)
24
+ raw <path> Show the SimpleCov 'lines' array
25
+ summary <path> Show covered/total/% for a file
26
+ totals Show aggregated line totals and average %
27
+ uncovered <path> Show uncovered lines and a summary
28
+ validate <file> Evaluate coverage policy from file (exit 0=pass, 1=fail, 2=error)
29
+ validate -i <code> Evaluate coverage policy from code string
30
+ version Show version information
31
+
32
+ Options:
33
+ -r, --resultset PATH Path or directory that contains .resultset.json (default: coverage/.resultset.json)
34
+ -R, --root PATH Project root (default: .)
35
+ -f, --format FORMAT Output format: t[able]|j[son]|pretty-json|y[aml]|a[wesome-print] (default: table)
36
+ -o, --sort-order ORDER Sort order for list: a[scending]|d[escending] (default descending)
37
+ -s, --source MODE Source display: f[ull]|u[ncovered]
38
+ -c, --context-lines N Context lines around uncovered lines (non-negative, default: 2)
39
+ -C, --color BOOLEAN Enable/disable ANSI colors for source output (default: true). Accepts: yes/no/y/n/true/false/t/f/on/off/+/-/1/0
40
+ -S, --raise-on-stale BOOLEAN Raise error if coverage is stale (default: false). Accepts: yes/no/y/n/true/false/t/f/on/off/+/-/1/0
41
+ -g, --tracked-globs x,y,z Globs for filtering files (list/totals subcommands)
42
+ -h, --help Show help
43
+ -l, --log-file PATH Log file path (default ./cov_loupe.log, use stdout/stderr for streams)
44
+ -m, --mode MODE Execution mode: cli|mcp (default: cli)
45
+ -e, --error-mode MODE Error handling mode: o[ff]|l[og]|d[ebug] (default log). off (silent), log (log errors to file), debug (verbose with backtraces)
46
+ -v, --version Show version information and exit.
47
+
48
+ Examples:
49
+ cov-loupe --resultset coverage list
50
+ cov-loupe --format json --resultset coverage summary lib/foo.rb
51
+ cov-loupe --source uncovered --context-lines 2 uncovered lib/foo.rb
52
+ cov-loupe totals --format json
53
+ ```
@@ -0,0 +1,77 @@
1
+ #!/usr/bin/env bash
2
+ # Demo script for cov-loupe CLI subcommands and options
3
+ # Runs against the included fixture project at spec/fixtures/project1.
4
+
5
+ set -euo pipefail
6
+
7
+ ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
8
+ cd "$ROOT_DIR"
9
+ CLI=("exe/cov-loupe")
10
+ PROJ="examples/fixtures/demo_project"
11
+ RESULTSET_DIR="coverage" # directory containing .resultset.json under PROJ
12
+
13
+ run() {
14
+ cat <<BANNER
15
+
16
+
17
+
18
+ -------------------------------------------------------------------------------
19
+ + ${CLI[*]} $*
20
+ -------------------------------------------------------------------------------
21
+
22
+ BANNER
23
+ "${CLI[@]}" "$@"
24
+
25
+ }
26
+
27
+ cat <<INTRO
28
+ == cov-loupe CLI demo ==
29
+
30
+ Note: Project root and resultset JSON file normally do not need to be specified.
31
+ We set --root here to use the examples/fixtures/demo_project nondefault location,
32
+ and later demonstrate a nondefault resultset via the --resultset option.
33
+
34
+ Project root: $PROJ
35
+ Resultset (dir): $RESULTSET_DIR
36
+
37
+ INTRO
38
+
39
+ # 1) List all files (table)
40
+ run list --root "$PROJ"
41
+
42
+ # 2) List as JSON, descending sort
43
+ run list --root "$PROJ" --sort-order descending --json
44
+
45
+ # 3) Summary for a file (text and JSON)
46
+ run summary lib/foo.rb --root "$PROJ"
47
+ run summary lib/foo.rb --root "$PROJ" --json
48
+
49
+ # 4) Include source with summary (full and uncovered-only with context)
50
+ run summary lib/foo.rb --root "$PROJ" --source
51
+ run summary lib/foo.rb --root "$PROJ" --source=uncovered --source-context 1
52
+
53
+ # 5) Uncovered lines (text with source and JSON)
54
+ run uncovered lib/foo.rb --root "$PROJ" --source=uncovered --source-context 2
55
+ run uncovered lib/foo.rb --root "$PROJ" --json
56
+
57
+ # 6) Detailed per-line data (text and JSON), with source
58
+ run detailed lib/foo.rb --root "$PROJ" --source -C false
59
+ run detailed lib/foo.rb --root "$PROJ" --json
60
+
61
+ # 7) Raw lines array (JSON)
62
+ run raw lib/foo.rb --root "$PROJ" --json
63
+
64
+ # 8) Using environment variable for a NONDEFAULT resultset location
65
+ # Copy the default resultset into a simple alt directory to simulate a custom layout.
66
+ ALT_DIR="$PROJ/alt_resultset"
67
+ mkdir -p "$ALT_DIR"
68
+ cp -f "$PROJ/coverage/.resultset.json" "$ALT_DIR/.resultset.json"
69
+ echo
70
+ echo "+ ${CLI[*]} list --root $PROJ --resultset $PROJ/alt_resultset"
71
+ "${CLI[@]}" list --root "$PROJ" --resultset "$PROJ/alt_resultset"
72
+
73
+ echo
74
+ echo "== Done =="
75
+
76
+ # Cleanup files created for the nondefault resultset demo
77
+ rm -rf "$ALT_DIR"
@@ -0,0 +1,114 @@
1
+ # cov-loupe Library Usage Examples
2
+ =============================================
3
+
4
+ ## 1. Full Coverage Table
5
+ ```
6
+ ┌────────────────────────────────────────────────┬──────────┬───────────┬─────────┬───────┐
7
+ │ File │ % │ Covered │ Total │ Stale │
8
+ ├────────────────────────────────────────────────┼──────────┼───────────┼─────────┼───────┤
9
+ │ /home/kbennett/code/cov-loupe/lib/bar.rb │ 33.33% │ 1 │ 3 │ ! │
10
+ │ /home/kbennett/code/cov-loupe/lib/foo.rb │ 66.67% │ 2 │ 3 │ ! │
11
+ └────────────────────────────────────────────────┴──────────┴───────────┴─────────┴───────┘
12
+ Files: total 2, ok 0, stale 2
13
+ ```
14
+
15
+ ## 2. Filter by Directory (lib/ only)
16
+ ```ruby
17
+ # Filter files by directory (e.g., only show files in lib/)
18
+ files_data = model.list
19
+ lib_files = files_data.select { |file| file["file"].include?("/lib/") }
20
+ lib_files_table = model.format_table(lib_files)
21
+ # => formatted table showing only files from lib/ directory
22
+ ```
23
+
24
+ Result:
25
+ ```
26
+ ┌────────────────────────────────────────────────┬──────────┬───────────┬─────────┬───────┐
27
+ │ File │ % │ Covered │ Total │ Stale │
28
+ ├────────────────────────────────────────────────┼──────────┼───────────┼─────────┼───────┤
29
+ │ /home/kbennett/code/cov-loupe/lib/bar.rb │ 33.33% │ 1 │ 3 │ ! │
30
+ │ /home/kbennett/code/cov-loupe/lib/foo.rb │ 66.67% │ 2 │ 3 │ ! │
31
+ └────────────────────────────────────────────────┴──────────┴───────────┴─────────┴───────┘
32
+ Files: total 2, ok 0, stale 2
33
+ ```
34
+
35
+ ## 3. Filter by Pattern (files with specific naming)
36
+ ```ruby
37
+ # Filter by pattern (e.g., only show files with "foo" in name)
38
+ foo_files = files_data.select { |file| file["file"].include?("foo") }
39
+ foo_table = model.format_table(foo_files)
40
+ # => formatted table showing only files with 'foo' in filename
41
+ ```
42
+ check_coverage_data
43
+
44
+ Result:
45
+ ```
46
+ ┌────────────────────────────────────────────────┬──────────┬───────────┬─────────┬───────┐
47
+ │ File │ % │ Covered │ Total │ Stale │
48
+ ├────────────────────────────────────────────────┼──────────┼───────────┼─────────┼───────┤
49
+ │ /home/kbennett/code/cov-loupe/lib/foo.rb │ 66.67% │ 2 │ 3 │ ! │
50
+ └────────────────────────────────────────────────┴──────────┴───────────┴─────────┴───────┘
51
+ Files: total 1, ok 0, stale 1
52
+ ```
53
+
54
+ ## 4. Filter by Coverage Threshold (only high-coverage files)
55
+ ```ruby
56
+ # Filter by coverage percentage (e.g., only files >= 50% coverage)
57
+ high_coverage_files = files_data.select { |file| file["percentage"] >= 50.0 }
58
+ high_coverage_table = model.format_table(high_coverage_files)
59
+ # => formatted table showing only well-covered files
60
+ ```
61
+
62
+ Result:
63
+ ```
64
+ ┌────────────────────────────────────────────────┬──────────┬───────────┬─────────┬───────┐
65
+ │ File │ % │ Covered │ Total │ Stale │
66
+ ├────────────────────────────────────────────────┼──────────┼───────────┼─────────┼───────┤
67
+ │ /home/kbennett/code/cov-loupe/lib/foo.rb │ 66.67% │ 2 │ 3 │ ! │
68
+ └────────────────────────────────────────────────┴──────────┴───────────┴─────────┴───────┘
69
+ Files: total 1, ok 0, stale 1
70
+ ```
71
+
72
+ ## 5. Staleness Analysis
73
+ ```ruby
74
+ # Analyze coverage staleness to find potentially problematic files
75
+ stale_files, healthy_files = files_data.partition { |file| file["stale"] }
76
+
77
+ puts "## Potentially Stale Coverage Files"
78
+ puts model.format_table(stale_files, sort_order: :descending)
79
+
80
+ puts "## Healthy Coverage Files"
81
+ puts model.format_table(healthy_files, sort_order: :descending)
82
+ ```
83
+
84
+ Result:
85
+ ```
86
+ ## Potentially Stale Coverage Files
87
+ ┌────────────────────────────────────────────────┬──────────┬───────────┬─────────┬───────┐
88
+ │ File │ % │ Covered │ Total │ Stale │
89
+ ├────────────────────────────────────────────────┼──────────┼───────────┼─────────┼───────┤
90
+ │ /home/kbennett/code/cov-loupe/lib/foo.rb │ 66.67% │ 2 │ 3 │ ! │
91
+ │ /home/kbennett/code/cov-loupe/lib/bar.rb │ 33.33% │ 1 │ 3 │ ! │
92
+ └────────────────────────────────────────────────┴──────────┴───────────┴─────────┴───────┘
93
+ Files: total 2, ok 0, stale 2
94
+
95
+ ## Healthy Coverage Files
96
+ (No healthy files found)
97
+ ```
98
+
99
+ NOTE: To see staleness analysis in action with both stale and healthy files,
100
+ try modifying file timestamps:
101
+ - Make one file appear older: `touch -t 202401010000 spec/fixtures/project1/lib/foo.rb`
102
+ - Or make one file appear newer: `touch spec/fixtures/project1/lib/bar.rb`
103
+ Then run this script again to see partition results change.
104
+
105
+ ## Summary
106
+ This example demonstrates how cov-loupe can be used as a library to:
107
+ - Load and query coverage data
108
+ - Filter files by various criteria (directory, filename, coverage threshold)
109
+ - Perform staleness analysis to identify potentially problematic files
110
+ - Generate CI/CD integration reports with exit codes for monitoring
111
+ - Create custom reports tailored to specific needs
112
+
113
+ The table formatting functionality (format_table) is now accessible
114
+ directly in library mode, not just through the CLI!
@@ -0,0 +1,174 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # Example: Using cov-loupe as a library to filter and format coverage tables
5
+ # This demonstrates filtering files by directory and other criteria, then generating tables
6
+
7
+ require_relative '../lib/cov_loupe'
8
+
9
+ def check_coverage_data
10
+ unless File.exist?('spec/fixtures/project1/coverage/.resultset.json')
11
+ puts <<~DOC
12
+ Error: Coverage data file not found.
13
+
14
+ Please run this script from project root directory:
15
+
16
+ examples/filter_and_table_demo.rb
17
+
18
+ If coverage data is missing, run tests first to generate it:
19
+
20
+ bundle exec rspec
21
+ DOC
22
+ exit 1
23
+ end
24
+ end
25
+
26
+ def output_examples
27
+ puts <<~DOC
28
+ # cov-loupe Library Usage Examples
29
+ =============================================
30
+
31
+ DOC
32
+
33
+ # Initialize coverage model
34
+ # Using the built-in coverage data from running specs
35
+ model = CovLoupe::CoverageModel.new(
36
+ root: '.',
37
+ resultset: 'spec/fixtures/project1/coverage'
38
+ )
39
+
40
+ puts <<~DOC
41
+ ## 1. Full Coverage Table
42
+ ```
43
+ #{model.format_table}
44
+ ```
45
+
46
+ DOC
47
+
48
+ puts <<~DOC
49
+ ## 2. Filter by Directory (lib/ only)
50
+ ```ruby
51
+ # Filter files by directory (e.g., only show files in lib/)
52
+ files_data = model.list['files']
53
+ lib_files = files_data.select { |file| file["file"].include?("/lib/") }
54
+ lib_files_table = model.format_table(lib_files)
55
+ # => formatted table showing only files from lib/ directory
56
+ ```
57
+
58
+ DOC
59
+
60
+ # Execute the code
61
+ files_data = model.list['files']
62
+ lib_files = files_data.select { |file| file['file'].include?('/lib/') }
63
+ lib_files_table = model.format_table(lib_files)
64
+ puts <<~DOC
65
+ Result:
66
+ ```
67
+ #{lib_files_table}
68
+ ```
69
+
70
+ DOC
71
+
72
+ puts <<~DOC
73
+ ## 3. Filter by Pattern (files with specific naming)
74
+ ```ruby
75
+ # Filter by pattern (e.g., only show files with "foo" in name)
76
+ # Note: files_data is the array from model.list['files']
77
+ foo_files = files_data.select { |file| file["file"].include?("foo") }
78
+ foo_table = model.format_table(foo_files)
79
+ # => formatted table showing only files with 'foo' in filename
80
+ ```
81
+
82
+ DOC
83
+
84
+ # Execute the code
85
+ foo_files = files_data.select { |file| file['file'].include?('foo') }
86
+ foo_table = model.format_table(foo_files)
87
+ puts <<~DOC
88
+ Result:
89
+ ```
90
+ #{foo_table}
91
+ ```
92
+
93
+ DOC
94
+
95
+ puts <<~DOC
96
+ ## 4. Filter by Coverage Threshold (only high-coverage files)
97
+ ```ruby
98
+ # Filter by coverage percentage (e.g., only files >= 50% coverage)
99
+ # Note: files_data is the array from model.list['files']
100
+ high_coverage_files = files_data.select { |file| file["percentage"] >= 50.0 }
101
+ high_coverage_table = model.format_table(high_coverage_files)
102
+ # => formatted table showing only well-covered files
103
+ ```
104
+
105
+ DOC
106
+
107
+ # Execute the code
108
+ high_coverage_files = files_data.select { |file| file['percentage'] >= 50.0 }
109
+ high_coverage_table = model.format_table(high_coverage_files)
110
+ puts <<~DOC
111
+ Result:
112
+ ```
113
+ #{high_coverage_table}
114
+ ```
115
+
116
+ DOC
117
+
118
+ puts <<~DOC
119
+ ## 5. Staleness Analysis
120
+ ```ruby
121
+ # Analyze coverage staleness to find potentially problematic files
122
+ # Note: files_data is the array from model.list['files']
123
+ stale_files, healthy_files = files_data.partition { |file| file["stale"] }
124
+
125
+ puts "## Potentially Stale Coverage Files"
126
+ puts model.format_table(stale_files, sort_order: :descending)
127
+
128
+ puts "## Healthy Coverage Files"
129
+ puts model.format_table(healthy_files, sort_order: :descending)
130
+ ```
131
+
132
+ DOC
133
+
134
+ # Execute the stale analysis
135
+ stale_files, healthy_files = files_data.partition { |file| file['stale'] }
136
+
137
+ puts 'Result:'
138
+ puts '```'
139
+ puts '## Potentially Stale Coverage Files'
140
+ puts model.format_table(stale_files, sort_order: :descending) if stale_files.any?
141
+ puts '(No stale files found)' if stale_files.empty?
142
+ puts
143
+ puts '## Healthy Coverage Files'
144
+ puts model.format_table(healthy_files, sort_order: :descending) if healthy_files.any?
145
+ puts '(No healthy files found)' if healthy_files.empty?
146
+ puts '```'
147
+ puts
148
+ puts 'NOTE: To see staleness analysis in action with both stale and healthy files,'
149
+ puts 'try modifying file timestamps:'
150
+ puts ' - Make one file appear older: `touch -t 202401010000 spec/fixtures/project1/lib/foo.rb`'
151
+ puts ' - Or make one file appear newer: `touch spec/fixtures/project1/lib/bar.rb`'
152
+ puts 'Then run this script again to see partition results change.'
153
+ puts
154
+
155
+ puts <<~DOC
156
+ ## Summary
157
+ This example demonstrates how cov-loupe can be used as a library to:
158
+ - Load and query coverage data
159
+ - Filter files by various criteria (directory, filename, coverage threshold)
160
+ - Perform staleness analysis to identify potentially problematic files
161
+ - Generate CI/CD integration reports with exit codes for monitoring
162
+ - Create custom reports tailored to specific needs
163
+
164
+ The table formatting functionality (format_table) is now accessible
165
+ directly in library mode, not just through the CLI!
166
+ DOC
167
+ end
168
+
169
+ def main
170
+ check_coverage_data
171
+ output_examples
172
+ end
173
+
174
+ main if __FILE__ == $PROGRAM_NAME
@@ -0,0 +1,10 @@
1
+ {
2
+ "RSpec": {
3
+ "timestamp": 1720000000,
4
+ "coverage": {
5
+ "lib/foo.rb": { "lines": [1, 0, null, 2] },
6
+ "lib/bar.rb": { "lines": [0, 0, 1] }
7
+ }
8
+ }
9
+ }
10
+