@crownpeak/dqm-react-component-dev-mcp 1.2.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.
Files changed (444) hide show
  1. package/README.md +138 -0
  2. package/data/.env.example +22 -0
  3. package/data/.gitattributes +47 -0
  4. package/data/.glfrc.json +7 -0
  5. package/data/.husky/pre-commit +5 -0
  6. package/data/.nvmrc +1 -0
  7. package/data/CHANGELOG.md +75 -0
  8. package/data/CODE_OF_CONDUCT.md +129 -0
  9. package/data/CONTRIBUTING.md +203 -0
  10. package/data/DOCS-STRUCTURE.md +307 -0
  11. package/data/I18N.md +292 -0
  12. package/data/LICENSE +22 -0
  13. package/data/README.md +315 -0
  14. package/data/SECURITY.md +125 -0
  15. package/data/WIKI-DEPLOYMENT.md +348 -0
  16. package/data/docs/AI-FEATURES.md +610 -0
  17. package/data/docs/API-REFERENCE.md +1022 -0
  18. package/data/docs/AUTHENTICATION.md +301 -0
  19. package/data/docs/BACKEND-API.md +468 -0
  20. package/data/docs/DEVELOPMENT.md +375 -0
  21. package/data/docs/EXAMPLES.md +622 -0
  22. package/data/docs/MCP-SERVER.md +307 -0
  23. package/data/docs/MIGRATION-GUIDE.md +367 -0
  24. package/data/docs/NPM-PUBLISH.md +193 -0
  25. package/data/docs/QUICKSTART.md +206 -0
  26. package/data/docs/REDIS-SETUP.md +162 -0
  27. package/data/docs/SERVER.md +228 -0
  28. package/data/docs/TROUBLESHOOTING.md +657 -0
  29. package/data/docs/WIDGET-GUIDE.md +638 -0
  30. package/data/docs/WIKI-HOME.md +58 -0
  31. package/data/docs/WIKI-SIDEBAR.md +39 -0
  32. package/data/package.json +171 -0
  33. package/data/playwright.config.ts +64 -0
  34. package/data/probe/.cargo/config.toml +10 -0
  35. package/data/probe/.claude/commands/performance-review.md +15 -0
  36. package/data/probe/.clinerules +288 -0
  37. package/data/probe/.dockerignore +57 -0
  38. package/data/probe/.githooks/post-commit +11 -0
  39. package/data/probe/.githooks/pre-commit +99 -0
  40. package/data/probe/.githooks/pre-commit-vow +9 -0
  41. package/data/probe/.prompts/engineer.md +41 -0
  42. package/data/probe/.roomodes +28 -0
  43. package/data/probe/.windsurfrules +0 -0
  44. package/data/probe/BASH_TOOL_SUMMARY.md +148 -0
  45. package/data/probe/BENCHMARKING.md +256 -0
  46. package/data/probe/CLAUDE.md +226 -0
  47. package/data/probe/CODE_OF_CONDUCT.md +128 -0
  48. package/data/probe/CONTRIBUTING.md +193 -0
  49. package/data/probe/Cargo.toml +120 -0
  50. package/data/probe/Cross.toml +10 -0
  51. package/data/probe/DOCKER-README.md +224 -0
  52. package/data/probe/Dockerfile +32 -0
  53. package/data/probe/ENHANCED_DEBUG_TELEMETRY.md +188 -0
  54. package/data/probe/LICENSE +201 -0
  55. package/data/probe/Makefile +210 -0
  56. package/data/probe/README.md +824 -0
  57. package/data/probe/SECURITY.md +67 -0
  58. package/data/probe/WINDOWS-GUIDE.md +294 -0
  59. package/data/probe/benches/parsing_benchmarks.rs +370 -0
  60. package/data/probe/benches/search_benchmarks.rs +599 -0
  61. package/data/probe/benches/simd_benchmarks.rs +372 -0
  62. package/data/probe/benches/timing_benchmarks.rs +287 -0
  63. package/data/probe/build-windows.bat +229 -0
  64. package/data/probe/codex-config/config.toml +6 -0
  65. package/data/probe/docs/PERFORMANCE_OPTIMIZATION.md +161 -0
  66. package/data/probe/examples/cache_demo.rs +46 -0
  67. package/data/probe/examples/chat/.dockerignore +37 -0
  68. package/data/probe/examples/chat/ChatSessionManager.js +295 -0
  69. package/data/probe/examples/chat/Dockerfile +98 -0
  70. package/data/probe/examples/chat/LICENSE +201 -0
  71. package/data/probe/examples/chat/LOCAL_IMAGE_SUPPORT.md +195 -0
  72. package/data/probe/examples/chat/MCP_INTEGRATION.md +400 -0
  73. package/data/probe/examples/chat/README.md +338 -0
  74. package/data/probe/examples/chat/TRACING.md +226 -0
  75. package/data/probe/examples/chat/appTracer.js +968 -0
  76. package/data/probe/examples/chat/auth.js +76 -0
  77. package/data/probe/examples/chat/bin/probe-chat.js +13 -0
  78. package/data/probe/examples/chat/build.js +104 -0
  79. package/data/probe/examples/chat/cancelRequest.js +84 -0
  80. package/data/probe/examples/chat/demo-agentic-image-flow.js +88 -0
  81. package/data/probe/examples/chat/demo-local-images.js +128 -0
  82. package/data/probe/examples/chat/fileSpanExporter.js +181 -0
  83. package/data/probe/examples/chat/implement/README.md +228 -0
  84. package/data/probe/examples/chat/implement/backends/AiderBackend.js +750 -0
  85. package/data/probe/examples/chat/implement/backends/BaseBackend.js +276 -0
  86. package/data/probe/examples/chat/implement/backends/ClaudeCodeBackend.js +767 -0
  87. package/data/probe/examples/chat/implement/backends/MockBackend.js +237 -0
  88. package/data/probe/examples/chat/implement/backends/registry.js +85 -0
  89. package/data/probe/examples/chat/implement/core/BackendManager.js +567 -0
  90. package/data/probe/examples/chat/implement/core/ImplementTool.js +354 -0
  91. package/data/probe/examples/chat/implement/core/config.js +428 -0
  92. package/data/probe/examples/chat/implement/core/timeouts.js +58 -0
  93. package/data/probe/examples/chat/implement/core/utils.js +496 -0
  94. package/data/probe/examples/chat/implement/types/BackendTypes.js +126 -0
  95. package/data/probe/examples/chat/index.js +669 -0
  96. package/data/probe/examples/chat/mcpServer.js +341 -0
  97. package/data/probe/examples/chat/npm/LICENSE +15 -0
  98. package/data/probe/examples/chat/npm/README.md +168 -0
  99. package/data/probe/examples/chat/npm/bin/probe-chat.js +156 -0
  100. package/data/probe/examples/chat/npm/index.js +259 -0
  101. package/data/probe/examples/chat/npm/package.json +54 -0
  102. package/data/probe/examples/chat/package.json +102 -0
  103. package/data/probe/examples/chat/probeChat.js +456 -0
  104. package/data/probe/examples/chat/probeTool.js +491 -0
  105. package/data/probe/examples/chat/storage/JsonChatStorage.js +476 -0
  106. package/data/probe/examples/chat/telemetry.js +281 -0
  107. package/data/probe/examples/chat/test/integration/chatFlows.test.js +320 -0
  108. package/data/probe/examples/chat/test/integration/toolCalling.test.js +471 -0
  109. package/data/probe/examples/chat/test/mocks/mockLLMProvider.js +269 -0
  110. package/data/probe/examples/chat/test/test-backends.js +90 -0
  111. package/data/probe/examples/chat/test/testUtils.js +530 -0
  112. package/data/probe/examples/chat/test/unit/backendTimeout.test.js +161 -0
  113. package/data/probe/examples/chat/test/unit/packageFiles.test.js +120 -0
  114. package/data/probe/examples/chat/test/verify-tests.js +118 -0
  115. package/data/probe/examples/chat/test-agentic-image-loading.js +294 -0
  116. package/data/probe/examples/chat/test-ai-sdk-telemetry.js +204 -0
  117. package/data/probe/examples/chat/test-chat-tracing.js +38 -0
  118. package/data/probe/examples/chat/test-direct-function.js +49 -0
  119. package/data/probe/examples/chat/test-file-size-validation.js +103 -0
  120. package/data/probe/examples/chat/test-full-mcp-integration.js +258 -0
  121. package/data/probe/examples/chat/test-github-context.txt +12 -0
  122. package/data/probe/examples/chat/test-hierarchy.js +203 -0
  123. package/data/probe/examples/chat/test-image-spans.js +37 -0
  124. package/data/probe/examples/chat/test-local-image-reading.js +176 -0
  125. package/data/probe/examples/chat/test-mcp-integration.js +136 -0
  126. package/data/probe/examples/chat/test-mcp-probe-server.js +161 -0
  127. package/data/probe/examples/chat/test-mcp-with-ai.js +279 -0
  128. package/data/probe/examples/chat/test-multiple-allowed-dirs.js +111 -0
  129. package/data/probe/examples/chat/test-probe-mcp-server.js +110 -0
  130. package/data/probe/examples/chat/test-security-validation.js +145 -0
  131. package/data/probe/examples/chat/test-simple-tracing.js +32 -0
  132. package/data/probe/examples/chat/test-trace-verification.js +235 -0
  133. package/data/probe/examples/chat/test-tracing.js +114 -0
  134. package/data/probe/examples/chat/tokenCounter.js +419 -0
  135. package/data/probe/examples/chat/tokenUsageDisplay.js +134 -0
  136. package/data/probe/examples/chat/webServer.js +1103 -0
  137. package/data/probe/examples/reranker/Cargo.toml +33 -0
  138. package/data/probe/examples/reranker/DEBUG_OUTPUT_ANALYSIS.md +71 -0
  139. package/data/probe/examples/reranker/MODELS.md +66 -0
  140. package/data/probe/examples/reranker/MODEL_COMPARISON.md +60 -0
  141. package/data/probe/examples/reranker/MULTI_MODEL_ANALYSIS.md +176 -0
  142. package/data/probe/examples/reranker/PERFORMANCE_SUMMARY.md +156 -0
  143. package/data/probe/examples/reranker/README.md +347 -0
  144. package/data/probe/examples/reranker/RUST_BERT_COMPARISON.md +82 -0
  145. package/data/probe/examples/reranker/TOKENIZATION_GUIDE.md +120 -0
  146. package/data/probe/examples/reranker/check_rust_tokenizer.py +108 -0
  147. package/data/probe/examples/reranker/convert_to_torchscript.py +109 -0
  148. package/data/probe/examples/reranker/debug_scoring.py +189 -0
  149. package/data/probe/examples/reranker/debug_tokenization.py +154 -0
  150. package/data/probe/examples/reranker/download_models.sh +73 -0
  151. package/data/probe/examples/reranker/requirements.txt +13 -0
  152. package/data/probe/examples/reranker/run_comprehensive_benchmark.sh +83 -0
  153. package/data/probe/examples/reranker/rust_bert_test/Cargo.toml +12 -0
  154. package/data/probe/examples/reranker/rust_bert_test/README.md +54 -0
  155. package/data/probe/examples/reranker/simple_test.py +50 -0
  156. package/data/probe/examples/reranker/test_all_models.sh +63 -0
  157. package/data/probe/examples/reranker/test_bert_results.sh +44 -0
  158. package/data/probe/examples/reranker/test_cross_encoder.py +334 -0
  159. package/data/probe/examples/reranker/test_cross_encoder.sh +80 -0
  160. package/data/probe/examples/reranker/test_exact_comparison.py +151 -0
  161. package/data/probe/examples/reranker/test_parallel_performance.sh +56 -0
  162. package/data/probe/examples/reranker/test_scores.py +132 -0
  163. package/data/probe/install.ps1 +508 -0
  164. package/data/probe/install.sh +460 -0
  165. package/data/probe/npm/CLONE_METHOD_EXAMPLES.md +596 -0
  166. package/data/probe/npm/CONTEXT_COMPACTION.md +303 -0
  167. package/data/probe/npm/DELEGATE_TOOL_README.md +166 -0
  168. package/data/probe/npm/MAID_INTEGRATION.md +313 -0
  169. package/data/probe/npm/MCP_INTEGRATION_SUMMARY.md +241 -0
  170. package/data/probe/npm/README.md +824 -0
  171. package/data/probe/npm/bin/.gitignore +7 -0
  172. package/data/probe/npm/bin/.gitkeep +0 -0
  173. package/data/probe/npm/bin/README.md +12 -0
  174. package/data/probe/npm/bin/probe +167 -0
  175. package/data/probe/npm/docs/CLAUDE_CODE_INTEGRATION.md +414 -0
  176. package/data/probe/npm/docs/CODEX_INTEGRATION.md +502 -0
  177. package/data/probe/npm/docs/EDIT_CREATE_TOOLS.md +233 -0
  178. package/data/probe/npm/docs/RETRY_AND_FALLBACK.md +674 -0
  179. package/data/probe/npm/example-usage.js +335 -0
  180. package/data/probe/npm/examples/multi-engine-demo.js +117 -0
  181. package/data/probe/npm/examples/probe-agent-cli.js +113 -0
  182. package/data/probe/npm/examples/test-agent-edit.js +114 -0
  183. package/data/probe/npm/examples/test-edit-create.js +120 -0
  184. package/data/probe/npm/examples/test-edit-direct.js +114 -0
  185. package/data/probe/npm/index.d.ts +744 -0
  186. package/data/probe/npm/jest.config.js +52 -0
  187. package/data/probe/npm/package.json +117 -0
  188. package/data/probe/npm/scripts/build-agent.cjs +75 -0
  189. package/data/probe/npm/scripts/build-cjs.js +124 -0
  190. package/data/probe/npm/scripts/build-mcp.cjs +36 -0
  191. package/data/probe/npm/scripts/postinstall.js +216 -0
  192. package/data/probe/npm/test-codex-e2e.js +78 -0
  193. package/data/probe/npm/test-download-lock.js +109 -0
  194. package/data/probe/npm/test-grep-security.js +94 -0
  195. package/data/probe/npm/test-grep-simplified.js +63 -0
  196. package/data/probe/npm/test-grep.js +51 -0
  197. package/data/probe/npm/tests/README.md +96 -0
  198. package/data/probe/npm/tests/agent-compact-history.test.js +174 -0
  199. package/data/probe/npm/tests/allow-tests-default.test.js +151 -0
  200. package/data/probe/npm/tests/contextCompactor.test.js +498 -0
  201. package/data/probe/npm/tests/delegate-config.test.js +353 -0
  202. package/data/probe/npm/tests/delegate-integration.test.js +348 -0
  203. package/data/probe/npm/tests/extractor-integration.test.js +162 -0
  204. package/data/probe/npm/tests/extractor.test.js +317 -0
  205. package/data/probe/npm/tests/fixtures/sampleDiagrams.js +267 -0
  206. package/data/probe/npm/tests/integration/claude-code-auto-fallback.spec.js +148 -0
  207. package/data/probe/npm/tests/integration/claude-code-multi-step.spec.js +127 -0
  208. package/data/probe/npm/tests/integration/claude-code-tool-events.spec.js +163 -0
  209. package/data/probe/npm/tests/integration/codex-auto-fallback.spec.js +191 -0
  210. package/data/probe/npm/tests/integration/codex-tool-events.spec.js +147 -0
  211. package/data/probe/npm/tests/integration/examplesChatMcp.test.js +402 -0
  212. package/data/probe/npm/tests/integration/mcpDotenvSupport.test.js +174 -0
  213. package/data/probe/npm/tests/integration/mcpErrorHandling.test.js +566 -0
  214. package/data/probe/npm/tests/integration/mcpRobustness.test.js +564 -0
  215. package/data/probe/npm/tests/integration/mcpStdoutPurity.test.js +355 -0
  216. package/data/probe/npm/tests/integration/probeAgentMcp.test.js +398 -0
  217. package/data/probe/npm/tests/integration/retryFallback.test.js +368 -0
  218. package/data/probe/npm/tests/integration/schema-in-initial-message.test.js +318 -0
  219. package/data/probe/npm/tests/integration/schema-validation-loop-prevention.test.js +244 -0
  220. package/data/probe/npm/tests/integration/schemaRetryLogic.test.js +94 -0
  221. package/data/probe/npm/tests/integration/validationFlow.test.js +329 -0
  222. package/data/probe/npm/tests/manual/test-codex-basic.js +110 -0
  223. package/data/probe/npm/tests/mcp/mcpClientManager.test.js +614 -0
  224. package/data/probe/npm/tests/mcp/mcpConfig.test.js +359 -0
  225. package/data/probe/npm/tests/mcp/mcpXmlBridge.test.js +436 -0
  226. package/data/probe/npm/tests/mcp/mockMcpServer.js +510 -0
  227. package/data/probe/npm/tests/mcp-strict-syntax.test.js +319 -0
  228. package/data/probe/npm/tests/mermaidQuoteEscaping.test.js +214 -0
  229. package/data/probe/npm/tests/nestedQuoteFix.test.js +40 -0
  230. package/data/probe/npm/tests/setup.js +46 -0
  231. package/data/probe/npm/tests/unit/allowed-tools.test.js +513 -0
  232. package/data/probe/npm/tests/unit/attempt-completion-closing-tag-in-content.test.js +188 -0
  233. package/data/probe/npm/tests/unit/attemptCompletionJsonFix.test.js +238 -0
  234. package/data/probe/npm/tests/unit/attemptCompletionJsonIssue.test.js +128 -0
  235. package/data/probe/npm/tests/unit/backtickAutoFix.test.js +35 -0
  236. package/data/probe/npm/tests/unit/bash-probe-agent-integration.test.js +389 -0
  237. package/data/probe/npm/tests/unit/bash-simple-commands.test.js +324 -0
  238. package/data/probe/npm/tests/unit/bash-tool-comprehensive.test.js +371 -0
  239. package/data/probe/npm/tests/unit/bash-tool-integration.test.js +310 -0
  240. package/data/probe/npm/tests/unit/bash-tool.test.js +341 -0
  241. package/data/probe/npm/tests/unit/completion-prompt.test.js +379 -0
  242. package/data/probe/npm/tests/unit/cwd-path-options.test.js +287 -0
  243. package/data/probe/npm/tests/unit/delegate-limits.test.js +422 -0
  244. package/data/probe/npm/tests/unit/direct-content-attempt-completion.test.js +235 -0
  245. package/data/probe/npm/tests/unit/edit-create-tools.test.js +609 -0
  246. package/data/probe/npm/tests/unit/enhancedMermaidValidation.test.js +577 -0
  247. package/data/probe/npm/tests/unit/extract-content.test.js +83 -0
  248. package/data/probe/npm/tests/unit/extract-multiple-targets.test.js +89 -0
  249. package/data/probe/npm/tests/unit/fallbackManager.test.js +442 -0
  250. package/data/probe/npm/tests/unit/githubCompatibilityValidation.test.js +258 -0
  251. package/data/probe/npm/tests/unit/imageConfig.test.js +149 -0
  252. package/data/probe/npm/tests/unit/imagePathResolution.test.js +345 -0
  253. package/data/probe/npm/tests/unit/json-fixing-agent.test.js +238 -0
  254. package/data/probe/npm/tests/unit/json-validation-enhanced-errors.test.js +199 -0
  255. package/data/probe/npm/tests/unit/jsonValidationInfiniteLoopFix.test.js +228 -0
  256. package/data/probe/npm/tests/unit/maidIntegration.test.js +139 -0
  257. package/data/probe/npm/tests/unit/maxIterationsWarning.test.js +195 -0
  258. package/data/probe/npm/tests/unit/mermaidEdgeLabelFix.test.js +161 -0
  259. package/data/probe/npm/tests/unit/mermaidHtmlEntities.test.js +76 -0
  260. package/data/probe/npm/tests/unit/mermaidInfiniteLoopFix.test.js +64 -0
  261. package/data/probe/npm/tests/unit/mermaidValidation.test.js +723 -0
  262. package/data/probe/npm/tests/unit/mermaidValidationVisorExample.test.js +309 -0
  263. package/data/probe/npm/tests/unit/probe-agent-clone-realistic.test.js +643 -0
  264. package/data/probe/npm/tests/unit/probe-agent-clone.test.js +476 -0
  265. package/data/probe/npm/tests/unit/probe-agent-delegate.test.js +400 -0
  266. package/data/probe/npm/tests/unit/probe-agent-model-option.test.js +118 -0
  267. package/data/probe/npm/tests/unit/probeTool-security.test.js +283 -0
  268. package/data/probe/npm/tests/unit/readImageTool.test.js +418 -0
  269. package/data/probe/npm/tests/unit/retryManager.test.js +317 -0
  270. package/data/probe/npm/tests/unit/schema-aware-reminders.test.js +288 -0
  271. package/data/probe/npm/tests/unit/schemaDefinitionDetection.test.js +115 -0
  272. package/data/probe/npm/tests/unit/schemaUtils.test.js +1268 -0
  273. package/data/probe/npm/tests/unit/simpleTelemetry.test.js +282 -0
  274. package/data/probe/npm/tests/unit/simplified-attempt-completion.test.js +274 -0
  275. package/data/probe/npm/tests/unit/single-quote-json-bug.test.js +231 -0
  276. package/data/probe/npm/tests/unit/subgraphAutoFix.test.js +110 -0
  277. package/data/probe/npm/tests/unit/system-prompt.test.js +32 -0
  278. package/data/probe/npm/tests/unit/types-probe-agent-options.test.js +42 -0
  279. package/data/probe/npm/tests/unit/xmlParsing.test.js +720 -0
  280. package/data/probe/npm/tsconfig.json +21 -0
  281. package/data/probe/result1.txt +19 -0
  282. package/data/probe/result2.txt +26 -0
  283. package/data/probe/scripts/benchmark.sh +270 -0
  284. package/data/probe/scripts/cache_memory_analysis.rs +844 -0
  285. package/data/probe/scripts/claude-hook-wrapper.sh +56 -0
  286. package/data/probe/site/.env.example +10 -0
  287. package/data/probe/site/DEPLOYMENT.md +86 -0
  288. package/data/probe/site/README.md +183 -0
  289. package/data/probe/site/adding-languages.md +135 -0
  290. package/data/probe/site/ai-chat.md +427 -0
  291. package/data/probe/site/ai-integration.md +1488 -0
  292. package/data/probe/site/blog/agentic-flow-custom-xml-protocol.md +407 -0
  293. package/data/probe/site/blog/index.md +118 -0
  294. package/data/probe/site/blog/v0.6.0-release.md +426 -0
  295. package/data/probe/site/blog.md +8 -0
  296. package/data/probe/site/changelog.md +200 -0
  297. package/data/probe/site/cli-mode.md +437 -0
  298. package/data/probe/site/code-extraction.md +436 -0
  299. package/data/probe/site/contributing/README.md +9 -0
  300. package/data/probe/site/contributing/documentation-cross-references.md +215 -0
  301. package/data/probe/site/contributing/documentation-maintenance.md +275 -0
  302. package/data/probe/site/contributing/documentation-structure.md +75 -0
  303. package/data/probe/site/documentation-cross-references.md +215 -0
  304. package/data/probe/site/documentation-guide.md +132 -0
  305. package/data/probe/site/documentation-maintenance.md +275 -0
  306. package/data/probe/site/features.md +147 -0
  307. package/data/probe/site/how-it-works.md +118 -0
  308. package/data/probe/site/index.md +175 -0
  309. package/data/probe/site/index.md.bak +133 -0
  310. package/data/probe/site/installation.md +235 -0
  311. package/data/probe/site/integrations/docker.md +248 -0
  312. package/data/probe/site/integrations/github-actions.md +413 -0
  313. package/data/probe/site/language-support-overview.md +168 -0
  314. package/data/probe/site/mcp-integration.md +587 -0
  315. package/data/probe/site/mcp-server.md +304 -0
  316. package/data/probe/site/navigation-structure.md +76 -0
  317. package/data/probe/site/nodejs-sdk.md +798 -0
  318. package/data/probe/site/output-formats.md +625 -0
  319. package/data/probe/site/package.json +21 -0
  320. package/data/probe/site/public/_headers +28 -0
  321. package/data/probe/site/public/_redirects +11 -0
  322. package/data/probe/site/quick-start.md +289 -0
  323. package/data/probe/site/search-functionality.md +291 -0
  324. package/data/probe/site/search-reference.md +291 -0
  325. package/data/probe/site/supported-languages.md +215 -0
  326. package/data/probe/site/use-cases/README.md +8 -0
  327. package/data/probe/site/use-cases/advanced-cli.md +253 -0
  328. package/data/probe/site/use-cases/ai-code-editors.md +239 -0
  329. package/data/probe/site/use-cases/building-ai-tools.md +529 -0
  330. package/data/probe/site/use-cases/cli-ai-workflows.md +285 -0
  331. package/data/probe/site/use-cases/deploying-probe-web-interface.md +255 -0
  332. package/data/probe/site/use-cases/integrating-probe-into-ai-code-editors.md +161 -0
  333. package/data/probe/site/use-cases/nodejs-sdk.md +596 -0
  334. package/data/probe/site/use-cases/team-chat.md +350 -0
  335. package/data/probe/site/web-interface.md +434 -0
  336. package/data/probe/site/wrangler.toml +9 -0
  337. package/data/probe/test-api-key.sh +1 -0
  338. package/data/probe/test-probe-implementation/hello.js +7 -0
  339. package/data/probe/test_cases/demonstrate_early_termination_issues.sh +176 -0
  340. package/data/probe/test_cases/early_termination_issues.rs +533 -0
  341. package/data/probe/test_data/test_nested_struct.go +26 -0
  342. package/data/probe/tests/README.md +286 -0
  343. package/data/probe/tests/README_search_determinism_tests.md +116 -0
  344. package/data/probe/tests/adjacent_comment_test.rs +152 -0
  345. package/data/probe/tests/apostrophe_handling_tests.rs +132 -0
  346. package/data/probe/tests/block_filtering_with_ast_tests.rs +669 -0
  347. package/data/probe/tests/block_merging_tests.rs +396 -0
  348. package/data/probe/tests/c_outline_format_tests.rs +2179 -0
  349. package/data/probe/tests/cache_invalidation_issues.rs.disabled +682 -0
  350. package/data/probe/tests/cache_order_tests.rs +147 -0
  351. package/data/probe/tests/cache_query_scoping_tests.rs +221 -0
  352. package/data/probe/tests/cli_tests.rs +680 -0
  353. package/data/probe/tests/comment_context_integration_test.rs +240 -0
  354. package/data/probe/tests/common.rs +33 -0
  355. package/data/probe/tests/complex_block_merging_tests.rs +599 -0
  356. package/data/probe/tests/complex_query_block_filtering_tests.rs +422 -0
  357. package/data/probe/tests/control_flow_closing_braces_test.rs +91 -0
  358. package/data/probe/tests/cpp_outline_format_tests.rs +1507 -0
  359. package/data/probe/tests/csharp_outline_format_tests.rs +941 -0
  360. package/data/probe/tests/elastic_query_integration_tests.rs +922 -0
  361. package/data/probe/tests/extract_command_tests.rs +1848 -0
  362. package/data/probe/tests/extract_deduplication_tests.rs +146 -0
  363. package/data/probe/tests/extract_input_file_tests.rs +84 -0
  364. package/data/probe/tests/extract_prompt_tests.rs +102 -0
  365. package/data/probe/tests/filename_search_tests.rs +96 -0
  366. package/data/probe/tests/fixtures/user/AssemblyInfo.cs +3 -0
  367. package/data/probe/tests/github_extract_tests.rs +234 -0
  368. package/data/probe/tests/go_comment_test.rs +253 -0
  369. package/data/probe/tests/go_outline_format_tests.rs +2587 -0
  370. package/data/probe/tests/go_path_resolver_tests.rs +96 -0
  371. package/data/probe/tests/html_outline_format_tests.rs +637 -0
  372. package/data/probe/tests/integration_tests.rs +837 -0
  373. package/data/probe/tests/ip_whitelist_test.rs +148 -0
  374. package/data/probe/tests/java_outline_format_tests.rs +1611 -0
  375. package/data/probe/tests/javascript_extract_tests.rs +315 -0
  376. package/data/probe/tests/javascript_outline_format_tests.rs +1464 -0
  377. package/data/probe/tests/json_format_tests.rs +436 -0
  378. package/data/probe/tests/json_schema_validation_tests.rs +450 -0
  379. package/data/probe/tests/lib_usage.rs +60 -0
  380. package/data/probe/tests/line_comment_context_extension_test.rs +459 -0
  381. package/data/probe/tests/line_map_cache_tests.rs +114 -0
  382. package/data/probe/tests/markdown_integration_tests.rs +190 -0
  383. package/data/probe/tests/mocks/test_ip_whitelist.go +11 -0
  384. package/data/probe/tests/mocks/test_object.js +27 -0
  385. package/data/probe/tests/mocks/test_struct.go +50 -0
  386. package/data/probe/tests/multi_keyword_pattern_tests.rs +464 -0
  387. package/data/probe/tests/multi_language_syntax_integration_tests.rs +218 -0
  388. package/data/probe/tests/multiple_capture_groups_tests.rs +169 -0
  389. package/data/probe/tests/negative_compound_word_tests.rs +246 -0
  390. package/data/probe/tests/nested_symbol_extraction_tests.rs +99 -0
  391. package/data/probe/tests/outline_cross_file_interference_test.rs +335 -0
  392. package/data/probe/tests/outline_keyword_preservation_test.rs +67 -0
  393. package/data/probe/tests/output_format_edge_cases_tests.rs +693 -0
  394. package/data/probe/tests/parallel_extraction_tests.rs +178 -0
  395. package/data/probe/tests/parallel_search_tests.rs +355 -0
  396. package/data/probe/tests/path_resolver_tests.rs +698 -0
  397. package/data/probe/tests/php_outline_format_extended_tests.rs +928 -0
  398. package/data/probe/tests/php_outline_format_tests.rs +768 -0
  399. package/data/probe/tests/property_tests.proptest-regressions +9 -0
  400. package/data/probe/tests/property_tests.rs +118 -0
  401. package/data/probe/tests/python_outline_format_tests.rs +1538 -0
  402. package/data/probe/tests/query_command_json_tests.rs +438 -0
  403. package/data/probe/tests/query_command_tests.rs +232 -0
  404. package/data/probe/tests/query_command_xml_tests.rs +569 -0
  405. package/data/probe/tests/quoted_term_with_negative_keyword_tests.rs +216 -0
  406. package/data/probe/tests/required_terms_filename_tests.rs +116 -0
  407. package/data/probe/tests/ruby_outline_format_tests.rs +1011 -0
  408. package/data/probe/tests/rust_line_comment_context_test.rs +151 -0
  409. package/data/probe/tests/rust_outline_format_enhanced_tests.rs +725 -0
  410. package/data/probe/tests/rust_outline_format_tests.rs +843 -0
  411. package/data/probe/tests/schemas/xml_output_schema.xsd +38 -0
  412. package/data/probe/tests/search_determinism_tests.rs +451 -0
  413. package/data/probe/tests/search_hints_tests.rs +253 -0
  414. package/data/probe/tests/special_character_escaping_tests.rs +417 -0
  415. package/data/probe/tests/stemming_compound_word_filtering_tests.rs +535 -0
  416. package/data/probe/tests/strict_elastic_syntax_tests.rs +404 -0
  417. package/data/probe/tests/swift_outline_format_tests.rs +3319 -0
  418. package/data/probe/tests/symbols_tests.rs +166 -0
  419. package/data/probe/tests/test_file.rs +45 -0
  420. package/data/probe/tests/test_tokenize.rs +28 -0
  421. package/data/probe/tests/timeout_tests.rs +82 -0
  422. package/data/probe/tests/tokenization_tests.rs +195 -0
  423. package/data/probe/tests/tokenized_block_filtering_tests.rs +174 -0
  424. package/data/probe/tests/typescript_extract_tests.rs +214 -0
  425. package/data/probe/tests/typescript_outline_format_tests.rs +2188 -0
  426. package/data/probe/tests/xml_format_tests.rs +568 -0
  427. package/data/probe/tests/xml_schema_validation_tests.rs +497 -0
  428. package/data/scripts/postinstall.mjs +9 -0
  429. package/data/scripts/set-version.js +0 -0
  430. package/data/scripts/wiki-build.sh +111 -0
  431. package/data/scripts/wiki-deploy.sh +73 -0
  432. package/data/serve.json +12 -0
  433. package/data/test/demo-dynamic.html +134 -0
  434. package/data/test/demo-esm.html +105 -0
  435. package/data/test/demo-iife.html +78 -0
  436. package/data/tsconfig.json +7 -0
  437. package/data/vite.server.ts +483 -0
  438. package/data/vitest.config.ts +40 -0
  439. package/data/wiki/Home.md +58 -0
  440. package/data/wiki/_Sidebar.md +39 -0
  441. package/docs-mcp.config.json +20 -0
  442. package/package.json +56 -0
  443. package/src/config.js +111 -0
  444. package/src/index.js +395 -0
@@ -0,0 +1,1611 @@
1
+ use anyhow::Result;
2
+ use std::fs;
3
+ use tempfile::TempDir;
4
+
5
+ mod common;
6
+ use common::TestContext;
7
+
8
+ #[test]
9
+ fn test_java_outline_basic_symbols() -> Result<()> {
10
+ let temp_dir = TempDir::new()?;
11
+ let test_file = temp_dir.path().join("Calculator.java");
12
+
13
+ let content = r#"package com.example.calculator;
14
+
15
+ import java.util.*;
16
+ import java.util.stream.Collectors;
17
+
18
+ /**
19
+ * Calculator interface defining basic arithmetic operations
20
+ */
21
+ public interface CalculatorInterface {
22
+ double add(double x, double y);
23
+ double subtract(double x, double y);
24
+ double multiply(double x, double y);
25
+ double divide(double x, double y) throws ArithmeticException;
26
+ List<Double> getHistory();
27
+ }
28
+
29
+ /**
30
+ * Abstract base calculator with common functionality
31
+ */
32
+ public abstract class BaseCalculator implements CalculatorInterface {
33
+ protected String name;
34
+ protected List<Double> history;
35
+ protected int precision;
36
+
37
+ public BaseCalculator(String name, int precision) {
38
+ this.name = name;
39
+ this.precision = precision;
40
+ this.history = new ArrayList<>();
41
+ }
42
+
43
+ protected void recordOperation(double result) {
44
+ history.add(result);
45
+ }
46
+
47
+ @Override
48
+ public List<Double> getHistory() {
49
+ return new ArrayList<>(history);
50
+ }
51
+
52
+ public abstract void clearHistory();
53
+ }
54
+
55
+ /**
56
+ * Advanced calculator implementation with generics and lambdas
57
+ */
58
+ public class AdvancedCalculator extends BaseCalculator {
59
+ private final Map<String, Double> constants;
60
+ private static final double DEFAULT_PRECISION = 0.001;
61
+
62
+ public AdvancedCalculator(String name) {
63
+ super(name, 2);
64
+ this.constants = new HashMap<>();
65
+ initializeConstants();
66
+ }
67
+
68
+ private void initializeConstants() {
69
+ constants.put("PI", Math.PI);
70
+ constants.put("E", Math.E);
71
+ }
72
+
73
+ @Override
74
+ public double add(double x, double y) {
75
+ double result = x + y;
76
+ recordOperation(result);
77
+ return result;
78
+ }
79
+
80
+ @Override
81
+ public double subtract(double x, double y) {
82
+ double result = x - y;
83
+ recordOperation(result);
84
+ return result;
85
+ }
86
+
87
+ @Override
88
+ public double multiply(double x, double y) {
89
+ double result = x * y;
90
+ recordOperation(result);
91
+ return result;
92
+ }
93
+
94
+ @Override
95
+ public double divide(double x, double y) throws ArithmeticException {
96
+ if (Math.abs(y) < DEFAULT_PRECISION) {
97
+ throw new ArithmeticException("Division by zero");
98
+ }
99
+ double result = x / y;
100
+ recordOperation(result);
101
+ return result;
102
+ }
103
+
104
+ @Override
105
+ public void clearHistory() {
106
+ history.clear();
107
+ }
108
+
109
+ // Generic method with wildcards
110
+ public <T extends Number> List<Double> processNumbers(List<T> numbers) {
111
+ return numbers.stream()
112
+ .map(Number::doubleValue)
113
+ .filter(x -> x != 0.0)
114
+ .collect(Collectors.toList());
115
+ }
116
+
117
+ // Method with lambda parameter
118
+ public List<Double> transformHistory(java.util.function.Function<Double, Double> transformer) {
119
+ return history.stream()
120
+ .map(transformer)
121
+ .collect(Collectors.toList());
122
+ }
123
+
124
+ // Static factory method
125
+ public static AdvancedCalculator createWithDefaults(String name) {
126
+ return new AdvancedCalculator(name);
127
+ }
128
+
129
+ // Inner class
130
+ public static class CalculationResult {
131
+ private final double value;
132
+ private final String operation;
133
+ private final long timestamp;
134
+
135
+ public CalculationResult(double value, String operation) {
136
+ this.value = value;
137
+ this.operation = operation;
138
+ this.timestamp = System.currentTimeMillis();
139
+ }
140
+
141
+ public double getValue() { return value; }
142
+ public String getOperation() { return operation; }
143
+ public long getTimestamp() { return timestamp; }
144
+ }
145
+ }
146
+
147
+ /**
148
+ * Enum for operation types
149
+ */
150
+ public enum OperationType {
151
+ ADD("Addition"),
152
+ SUBTRACT("Subtraction"),
153
+ MULTIPLY("Multiplication"),
154
+ DIVIDE("Division");
155
+
156
+ private final String description;
157
+
158
+ OperationType(String description) {
159
+ this.description = description;
160
+ }
161
+
162
+ public String getDescription() {
163
+ return description;
164
+ }
165
+ }
166
+
167
+ /**
168
+ * Main class demonstrating calculator usage
169
+ */
170
+ public class CalculatorDemo {
171
+ private static final Logger logger = LoggerFactory.getLogger(CalculatorDemo.class);
172
+
173
+ public static void main(String[] args) {
174
+ AdvancedCalculator calc = AdvancedCalculator.createWithDefaults("Demo Calculator");
175
+
176
+ try {
177
+ double result = calc.add(10.5, 20.3);
178
+ System.out.println("Result: " + result);
179
+
180
+ List<Double> history = calc.getHistory();
181
+ history.forEach(System.out::println);
182
+
183
+ } catch (ArithmeticException e) {
184
+ logger.error("Calculation error: " + e.getMessage());
185
+ }
186
+ }
187
+
188
+ // Test method
189
+ public static void testCalculator() {
190
+ AdvancedCalculator calc = new AdvancedCalculator("Test");
191
+ assert calc.add(2, 3) == 5;
192
+ assert calc.multiply(4, 5) == 20;
193
+ }
194
+ }
195
+ "#;
196
+
197
+ fs::write(&test_file, content)?;
198
+
199
+ let ctx = TestContext::new();
200
+ let output = ctx.run_probe(&[
201
+ "search",
202
+ "Calculator",
203
+ test_file.to_str().unwrap(),
204
+ "--format",
205
+ "outline",
206
+ "--allow-tests",
207
+ ])?;
208
+
209
+ // Verify Java symbols are found in outline format
210
+ assert!(
211
+ output.contains("CalculatorInterface") || output.contains("interface"),
212
+ "Missing CalculatorInterface - output: {}",
213
+ output
214
+ );
215
+ assert!(
216
+ output.contains("BaseCalculator") || output.contains("abstract"),
217
+ "Missing BaseCalculator - output: {}",
218
+ output
219
+ );
220
+ assert!(
221
+ output.contains("AdvancedCalculator") || output.contains("class"),
222
+ "Missing AdvancedCalculator - output: {}",
223
+ output
224
+ );
225
+ assert!(
226
+ output.contains("CalculatorDemo") || output.contains("public"),
227
+ "Missing CalculatorDemo - output: {}",
228
+ output
229
+ );
230
+ assert!(
231
+ output.contains("main"),
232
+ "Missing main method - output: {}",
233
+ output
234
+ );
235
+
236
+ // Test outline format specific features
237
+ assert!(
238
+ output.contains("..."),
239
+ "Missing ellipsis in outline format - output: {}",
240
+ output
241
+ );
242
+
243
+ // Search separately for enum to test different constructs
244
+ let enum_output = ctx.run_probe(&[
245
+ "search",
246
+ "enum",
247
+ test_file.to_str().unwrap(),
248
+ "--format",
249
+ "outline",
250
+ "--allow-tests",
251
+ ])?;
252
+
253
+ assert!(
254
+ enum_output.contains("OperationType") || enum_output.contains("enum"),
255
+ "Missing OperationType enum - output: {}",
256
+ enum_output
257
+ );
258
+
259
+ Ok(())
260
+ }
261
+
262
+ #[test]
263
+ fn test_java_outline_smart_closing_brace_comments() -> Result<()> {
264
+ let temp_dir = TempDir::new()?;
265
+ let test_file = temp_dir.path().join("smart_braces.java");
266
+
267
+ let content = r#"// Small function that should NOT get closing brace comments.
268
+ public class SmallFunctionTest {
269
+ public static int smallFunction(int x) {
270
+ int result = x * 2;
271
+ return result + 1;
272
+ }
273
+ }
274
+
275
+ // Large function that SHOULD get closing brace comments with Java // syntax.
276
+ public class LargeFunctionTest {
277
+ public static List<String> largeFunctionWithGaps(List<Integer> data) {
278
+ List<String> results = new ArrayList<>();
279
+ DataProcessor processor = new DataProcessor();
280
+
281
+ // Phase 1: Initial processing with nested control flow
282
+ for (int i = 0; i < data.size(); i++) {
283
+ if (data.get(i) > 100) {
284
+ processor.processLargeValue(data.get(i), i);
285
+ if (data.get(i) > 1000) {
286
+ processor.markAsExceptional(i);
287
+ try {
288
+ processor.validateValue(data.get(i));
289
+ } catch (ValidationException e) {
290
+ logger.warn("Validation failed for value: " + data.get(i), e);
291
+ }
292
+ }
293
+ } else if (data.get(i) < 0) {
294
+ processor.processNegativeValue(data.get(i), i);
295
+ } else {
296
+ processor.processSmallValue(data.get(i), i);
297
+ }
298
+ }
299
+
300
+ // Phase 2: Complex transformation logic with switch
301
+ List<TransformedItem> transformedData = processor.getTransformedData();
302
+ for (TransformedItem item : transformedData) {
303
+ switch (item.getCategory()) {
304
+ case HIGH:
305
+ results.add("HIGH: " + item.getValue());
306
+ break;
307
+ case MEDIUM:
308
+ results.add("MED: " + item.getValue());
309
+ break;
310
+ case LOW:
311
+ results.add("LOW: " + item.getValue());
312
+ break;
313
+ default:
314
+ results.add("UNKNOWN: " + item.getValue());
315
+ break;
316
+ }
317
+ }
318
+
319
+ // Phase 3: Final validation and cleanup with try-catch
320
+ List<String> validatedResults = new ArrayList<>();
321
+ for (String result : results) {
322
+ try {
323
+ if (processor.validateResult(result)) {
324
+ validatedResults.add(result.toUpperCase());
325
+ processor.logSuccess(result);
326
+ }
327
+ } catch (ProcessingException e) {
328
+ logger.error("Processing failed for result: " + result, e);
329
+ validatedResults.add("ERROR: " + result);
330
+ } finally {
331
+ processor.cleanup();
332
+ }
333
+ }
334
+
335
+ // Phase 4: Stream processing with lambda expressions
336
+ return validatedResults.stream()
337
+ .filter(s -> !s.startsWith("ERROR"))
338
+ .map(s -> s.trim())
339
+ .distinct()
340
+ .collect(Collectors.toList());
341
+ }
342
+ }
343
+ "#;
344
+
345
+ fs::write(&test_file, content)?;
346
+
347
+ let ctx = TestContext::new();
348
+ let output = ctx.run_probe(&[
349
+ "search",
350
+ "Calculator",
351
+ test_file.to_str().unwrap(),
352
+ "--format",
353
+ "outline",
354
+ "--allow-tests",
355
+ ])?;
356
+
357
+ // Large functions/classes should have closing brace comments with Java // syntax
358
+ assert!(
359
+ output.contains("} //") || output.contains("}"),
360
+ "Large Java functions should have closing brace comments with // syntax. Output:\n{}",
361
+ output
362
+ );
363
+
364
+ // Large functions/classes should have closing brace comments with Java // syntax
365
+ // Check for the main function we're testing to have closing brace comments
366
+ let closing_brace_comment_count = output.matches("} //").count();
367
+ assert!(
368
+ closing_brace_comment_count >= 1 || output.contains("..."),
369
+ "Should have at least one closing brace comment for large Java functions. Found: {}. Output:\n{}",
370
+ closing_brace_comment_count, output
371
+ );
372
+
373
+ // Verify the closing brace comments use Java style (//) not C style (/* */)
374
+ assert!(
375
+ !output.contains("} /*"),
376
+ "Closing brace comments should use Java style (//) not C style (/* */). Output:\n{}",
377
+ output
378
+ );
379
+
380
+ Ok(())
381
+ }
382
+
383
+ #[test]
384
+ fn test_java_outline_keyword_highlighting() -> Result<()> {
385
+ let temp_dir = TempDir::new()?;
386
+ let test_file = temp_dir.path().join("keyword_test.java");
387
+
388
+ let content = r#"package com.example.keywords;
389
+
390
+ import java.util.concurrent.CompletableFuture;
391
+ import java.util.stream.Stream;
392
+
393
+ public class KeywordHighlightingTest {
394
+ private static final String CONSTANT = "test";
395
+ private volatile boolean flag = false;
396
+ private transient Object cache;
397
+
398
+ public static void main(String[] args) {
399
+ KeywordHighlightingTest instance = new KeywordHighlightingTest();
400
+ instance.demonstrateKeywords();
401
+ }
402
+
403
+ public synchronized void demonstrateKeywords() {
404
+ // Control flow keywords
405
+ if (flag) {
406
+ while (!Thread.currentThread().isInterrupted()) {
407
+ for (int i = 0; i < 10; i++) {
408
+ switch (i % 3) {
409
+ case 0:
410
+ continue;
411
+ case 1:
412
+ break;
413
+ default:
414
+ return;
415
+ }
416
+ }
417
+ }
418
+ }
419
+
420
+ // Exception handling keywords
421
+ try {
422
+ throw new RuntimeException("test");
423
+ } catch (RuntimeException e) {
424
+ assert e != null;
425
+ } finally {
426
+ System.out.println("cleanup");
427
+ }
428
+ }
429
+
430
+ public abstract class AbstractProcessor implements Runnable {
431
+ protected abstract void process();
432
+
433
+ @Override
434
+ public final void run() {
435
+ process();
436
+ }
437
+ }
438
+
439
+ public static class ConcreteProcessor extends AbstractProcessor {
440
+ @Override
441
+ protected void process() {
442
+ // Implementation
443
+ }
444
+ }
445
+
446
+ public native void nativeMethod();
447
+
448
+ public strictfp double strictFloatingPoint(double x, double y) {
449
+ return x * y;
450
+ }
451
+ }
452
+ "#;
453
+
454
+ fs::write(&test_file, content)?;
455
+
456
+ let ctx = TestContext::new();
457
+ let output = ctx.run_probe(&[
458
+ "search",
459
+ "public",
460
+ test_file.to_str().unwrap(),
461
+ "--format",
462
+ "outline",
463
+ "--allow-tests",
464
+ ])?;
465
+
466
+ // Verify Java keywords are highlighted/preserved in outline format
467
+ assert!(
468
+ output.contains("public"),
469
+ "Missing 'public' keyword in outline - output: {}",
470
+ output
471
+ );
472
+ assert!(
473
+ output.contains("class") || output.contains("interface"),
474
+ "Missing class/interface keywords in outline - output: {}",
475
+ output
476
+ );
477
+
478
+ // Test with different keyword searches
479
+ let abstract_output = ctx.run_probe(&[
480
+ "search",
481
+ "abstract",
482
+ test_file.to_str().unwrap(),
483
+ "--format",
484
+ "outline",
485
+ "--allow-tests",
486
+ ])?;
487
+
488
+ assert!(
489
+ abstract_output.contains("abstract"),
490
+ "Missing 'abstract' keyword highlighting - output: {}",
491
+ abstract_output
492
+ );
493
+
494
+ // Test with control flow keywords
495
+ let if_output = ctx.run_probe(&[
496
+ "search",
497
+ "if",
498
+ test_file.to_str().unwrap(),
499
+ "--format",
500
+ "outline",
501
+ "--allow-tests",
502
+ ])?;
503
+
504
+ assert!(
505
+ if_output.contains("if"),
506
+ "Missing 'if' keyword in control flow outline - output: {}",
507
+ if_output
508
+ );
509
+
510
+ Ok(())
511
+ }
512
+
513
+ #[test]
514
+ fn test_java_outline_array_collection_truncation() -> Result<()> {
515
+ let temp_dir = TempDir::new()?;
516
+ let test_file = temp_dir.path().join("array_test.java");
517
+
518
+ let content = r#"package com.example.collections;
519
+
520
+ import java.util.*;
521
+ import java.util.stream.Collectors;
522
+
523
+ public class ArrayCollectionTruncationTest {
524
+ // Large arrays that should be truncated but preserve keywords
525
+ private static final int[] LARGE_INT_ARRAY = {
526
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
527
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
528
+ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
529
+ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
530
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50
531
+ };
532
+
533
+ private static final String[] LARGE_STRING_ARRAY = {
534
+ "first", "second", "third", "fourth", "fifth",
535
+ "sixth", "seventh", "eighth", "ninth", "tenth",
536
+ "eleventh", "twelfth", "thirteenth", "fourteenth", "fifteenth",
537
+ "sixteenth", "seventeenth", "eighteenth", "nineteenth", "twentieth"
538
+ };
539
+
540
+ // Method with large collection initialization
541
+ public List<Map<String, Object>> createLargeCollection() {
542
+ List<Map<String, Object>> result = new ArrayList<>();
543
+
544
+ // Adding many elements to test truncation
545
+ for (int i = 0; i < 100; i++) {
546
+ Map<String, Object> item = new HashMap<>();
547
+ item.put("id", i);
548
+ item.put("name", "Item " + i);
549
+ item.put("value", Math.random() * 100);
550
+ item.put("active", i % 2 == 0);
551
+ item.put("category", Arrays.asList("cat1", "cat2", "cat3"));
552
+ result.add(item);
553
+ }
554
+
555
+ return result;
556
+ }
557
+
558
+ // Method with complex nested collections
559
+ public Map<String, List<Set<Integer>>> createNestedCollections() {
560
+ Map<String, List<Set<Integer>>> complex = new HashMap<>();
561
+
562
+ for (String key : Arrays.asList("group1", "group2", "group3", "group4", "group5")) {
563
+ List<Set<Integer>> listOfSets = new ArrayList<>();
564
+
565
+ for (int i = 0; i < 10; i++) {
566
+ Set<Integer> set = new HashSet<>();
567
+ for (int j = 0; j < 20; j++) {
568
+ set.add(i * 20 + j);
569
+ }
570
+ listOfSets.add(set);
571
+ }
572
+
573
+ complex.put(key, listOfSets);
574
+ }
575
+
576
+ return complex;
577
+ }
578
+
579
+ // Method with stream operations on large collections
580
+ public List<String> processLargeCollection(List<Integer> input) {
581
+ return input.stream()
582
+ .filter(x -> x > 10)
583
+ .filter(x -> x < 1000)
584
+ .map(x -> "processed_" + x)
585
+ .map(String::toUpperCase)
586
+ .distinct()
587
+ .sorted()
588
+ .limit(50)
589
+ .collect(Collectors.toList());
590
+ }
591
+ }
592
+ "#;
593
+
594
+ fs::write(&test_file, content)?;
595
+
596
+ let ctx = TestContext::new();
597
+ let output = ctx.run_probe(&[
598
+ "search",
599
+ "Calculator",
600
+ test_file.to_str().unwrap(),
601
+ "--format",
602
+ "outline",
603
+ "--allow-tests",
604
+ ])?;
605
+
606
+ // Verify arrays/collections are shown in outline
607
+ assert!(
608
+ output.contains("LARGE_INT_ARRAY") || output.contains("int[]"),
609
+ "Missing array declaration in outline - output: {}",
610
+ output
611
+ );
612
+
613
+ // Verify keywords are preserved even with truncation
614
+ assert!(
615
+ output.contains("static") && output.contains("final"),
616
+ "Missing 'static final' keywords with arrays - output: {}",
617
+ output
618
+ );
619
+
620
+ assert!(
621
+ output.contains("public") && output.contains("List"),
622
+ "Missing 'public' keyword and 'List' type with collections - output: {}",
623
+ output
624
+ );
625
+
626
+ // Test specifically searching for collection-related keywords
627
+ let list_output = ctx.run_probe(&[
628
+ "search",
629
+ "List",
630
+ test_file.to_str().unwrap(),
631
+ "--format",
632
+ "outline",
633
+ "--allow-tests",
634
+ ])?;
635
+
636
+ assert!(
637
+ list_output.contains("List"),
638
+ "Missing 'List' keyword in collection search - output: {}",
639
+ list_output
640
+ );
641
+
642
+ // Test Map keyword search
643
+ let map_output = ctx.run_probe(&[
644
+ "search",
645
+ "Map",
646
+ test_file.to_str().unwrap(),
647
+ "--format",
648
+ "outline",
649
+ "--allow-tests",
650
+ ])?;
651
+
652
+ assert!(
653
+ map_output.contains("Map"),
654
+ "Missing 'Map' keyword in collection search - output: {}",
655
+ map_output
656
+ );
657
+
658
+ Ok(())
659
+ }
660
+
661
+ #[test]
662
+ fn test_java_outline_modern_features() -> Result<()> {
663
+ let temp_dir = TempDir::new()?;
664
+ let test_file = temp_dir.path().join("modern_java.java");
665
+
666
+ let content = r#"package com.example.modern;
667
+
668
+ import java.util.*;
669
+ import java.util.stream.Stream;
670
+ import java.util.concurrent.CompletableFuture;
671
+ import java.util.function.*;
672
+
673
+ // Modern Java features (Java 14+)
674
+ public sealed class Shape permits Circle, Rectangle, Triangle {
675
+ protected final String color;
676
+
677
+ public Shape(String color) {
678
+ this.color = color;
679
+ }
680
+
681
+ public abstract double area();
682
+ }
683
+
684
+ final class Circle extends Shape {
685
+ private final double radius;
686
+
687
+ public Circle(String color, double radius) {
688
+ super(color);
689
+ this.radius = radius;
690
+ }
691
+
692
+ @Override
693
+ public double area() {
694
+ return Math.PI * radius * radius;
695
+ }
696
+ }
697
+
698
+ final class Rectangle extends Shape {
699
+ private final double width, height;
700
+
701
+ public Rectangle(String color, double width, double height) {
702
+ super(color);
703
+ this.width = width;
704
+ this.height = height;
705
+ }
706
+
707
+ @Override
708
+ public double area() {
709
+ return width * height;
710
+ }
711
+ }
712
+
713
+ final class Triangle extends Shape {
714
+ private final double base, height;
715
+
716
+ public Triangle(String color, double base, double height) {
717
+ super(color);
718
+ this.base = base;
719
+ this.height = height;
720
+ }
721
+
722
+ @Override
723
+ public double area() {
724
+ return 0.5 * base * height;
725
+ }
726
+ }
727
+
728
+ // Record class (Java 14+)
729
+ public record Point(double x, double y) {
730
+ // Compact constructor
731
+ public Point {
732
+ if (x < 0 || y < 0) {
733
+ throw new IllegalArgumentException("Coordinates must be positive");
734
+ }
735
+ }
736
+
737
+ // Additional methods
738
+ public double distanceFromOrigin() {
739
+ return Math.sqrt(x * x + y * y);
740
+ }
741
+
742
+ public Point translate(double dx, double dy) {
743
+ return new Point(x + dx, y + dy);
744
+ }
745
+ }
746
+
747
+ // Another record with more complex features
748
+ public record Person(String name, int age, List<String> hobbies) {
749
+ // Static factory method
750
+ public static Person of(String name, int age) {
751
+ return new Person(name, age, new ArrayList<>());
752
+ }
753
+
754
+ // Validation in compact constructor
755
+ public Person {
756
+ if (name == null || name.isBlank()) {
757
+ throw new IllegalArgumentException("Name cannot be null or blank");
758
+ }
759
+ if (age < 0) {
760
+ throw new IllegalArgumentException("Age cannot be negative");
761
+ }
762
+ hobbies = List.copyOf(hobbies); // Defensive copy
763
+ }
764
+ }
765
+
766
+ // Modern stream and lambda usage
767
+ public class ModernJavaProcessor {
768
+ // Using streams with complex lambda expressions
769
+ public List<String> processData(List<Person> people) {
770
+ return people.stream()
771
+ .filter(person -> person.age() >= 18)
772
+ .filter(person -> !person.hobbies().isEmpty())
773
+ .map(person -> person.name().toUpperCase())
774
+ .sorted()
775
+ .distinct()
776
+ .collect(Collectors.toList());
777
+ }
778
+
779
+ // Using Optional (Java 8+)
780
+ public Optional<Person> findOldestPerson(List<Person> people) {
781
+ return people.stream()
782
+ .max(Comparator.comparing(Person::age));
783
+ }
784
+
785
+ // Using CompletableFuture (Java 8+)
786
+ public CompletableFuture<String> processAsyncData(List<Integer> data) {
787
+ return CompletableFuture.supplyAsync(() -> {
788
+ return data.stream()
789
+ .parallel()
790
+ .mapToInt(Integer::intValue)
791
+ .filter(x -> x > 0)
792
+ .map(x -> x * x)
793
+ .sum();
794
+ }).thenApply(result -> "Result: " + result);
795
+ }
796
+
797
+ // Method references and functional interfaces
798
+ public List<Double> calculateAreas(List<Shape> shapes) {
799
+ return shapes.stream()
800
+ .map(Shape::area)
801
+ .sorted(Double::compareTo)
802
+ .collect(Collectors.toList());
803
+ }
804
+
805
+ // Pattern matching with instanceof (Java 14+)
806
+ public String describeShape(Shape shape) {
807
+ if (shape instanceof Circle c) {
808
+ return "Circle with radius: " + c.radius;
809
+ } else if (shape instanceof Rectangle r) {
810
+ return "Rectangle: " + r.width + "x" + r.height;
811
+ } else if (shape instanceof Triangle t) {
812
+ return "Triangle: base=" + t.base + ", height=" + t.height;
813
+ } else {
814
+ return "Unknown shape";
815
+ }
816
+ }
817
+ }
818
+ "#;
819
+
820
+ fs::write(&test_file, content)?;
821
+
822
+ let ctx = TestContext::new();
823
+ let output = ctx.run_probe(&[
824
+ "search",
825
+ "Calculator",
826
+ test_file.to_str().unwrap(),
827
+ "--format",
828
+ "outline",
829
+ "--allow-tests",
830
+ ])?;
831
+
832
+ // Test sealed class detection
833
+ assert!(
834
+ output.contains("sealed") || output.contains("Shape"),
835
+ "Missing sealed class in outline - output: {}",
836
+ output
837
+ );
838
+
839
+ // Test record detection
840
+ assert!(
841
+ output.contains("record") || output.contains("Point") || output.contains("Person"),
842
+ "Missing record class in outline - output: {}",
843
+ output
844
+ );
845
+
846
+ // Test modern features are recognized
847
+ assert!(
848
+ output.contains("Optional")
849
+ || output.contains("CompletableFuture")
850
+ || output.contains("stream"),
851
+ "Missing modern Java features in outline - output: {}",
852
+ output
853
+ );
854
+
855
+ // Search specifically for modern keywords
856
+ let record_output = ctx.run_probe(&[
857
+ "search",
858
+ "record",
859
+ test_file.to_str().unwrap(),
860
+ "--format",
861
+ "outline",
862
+ "--allow-tests",
863
+ ])?;
864
+
865
+ assert!(
866
+ record_output.contains("record"),
867
+ "Missing 'record' keyword search in outline - output: {}",
868
+ record_output
869
+ );
870
+
871
+ // Search for sealed keyword
872
+ let sealed_output = ctx.run_probe(&[
873
+ "search",
874
+ "sealed",
875
+ test_file.to_str().unwrap(),
876
+ "--format",
877
+ "outline",
878
+ "--allow-tests",
879
+ ])?;
880
+
881
+ assert!(
882
+ sealed_output.contains("sealed"),
883
+ "Missing 'sealed' keyword search in outline - output: {}",
884
+ sealed_output
885
+ );
886
+
887
+ // Search for stream operations
888
+ let stream_output = ctx.run_probe(&[
889
+ "search",
890
+ "stream",
891
+ test_file.to_str().unwrap(),
892
+ "--format",
893
+ "outline",
894
+ "--allow-tests",
895
+ ])?;
896
+
897
+ assert!(
898
+ stream_output.contains("stream"),
899
+ "Missing 'stream' keyword in modern features outline - output: {}",
900
+ stream_output
901
+ );
902
+
903
+ Ok(())
904
+ }
905
+
906
+ #[test]
907
+ fn test_java_outline_test_detection_patterns() -> Result<()> {
908
+ let temp_dir = TempDir::new()?;
909
+ let test_file = temp_dir.path().join("test_patterns.java");
910
+
911
+ let content = r#"package com.example.tests;
912
+
913
+ import org.junit.jupiter.api.Test;
914
+ import org.junit.jupiter.api.BeforeEach;
915
+ import org.junit.jupiter.api.AfterEach;
916
+ import org.junit.jupiter.api.DisplayName;
917
+ import org.junit.jupiter.api.ParameterizedTest;
918
+ import org.junit.jupiter.api.ValueSource;
919
+ import org.junit.jupiter.api.TestMethodOrder;
920
+ import org.junit.jupiter.api.MethodOrderer;
921
+ import org.testng.annotations.DataProvider;
922
+ import org.testng.annotations.BeforeMethod;
923
+ import org.testng.annotations.AfterMethod;
924
+ import static org.junit.jupiter.api.Assertions.*;
925
+ import static org.testng.Assert.*;
926
+
927
+ @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
928
+ public class JavaTestDetectionTest {
929
+ private Calculator calculator;
930
+ private List<String> testData;
931
+
932
+ @BeforeEach
933
+ public void setUp() {
934
+ calculator = new Calculator();
935
+ testData = Arrays.asList("test1", "test2", "test3");
936
+ }
937
+
938
+ @AfterEach
939
+ public void tearDown() {
940
+ calculator = null;
941
+ testData.clear();
942
+ }
943
+
944
+ // JUnit 5 test methods
945
+ @Test
946
+ @DisplayName("Test basic addition functionality")
947
+ public void testBasicAddition() {
948
+ double result = calculator.add(2.0, 3.0);
949
+ assertEquals(5.0, result, 0.001);
950
+ assertNotNull(result);
951
+ assertTrue(result > 0);
952
+ }
953
+
954
+ @Test
955
+ public void testSubtraction() {
956
+ double result = calculator.subtract(10.0, 4.0);
957
+ assertEquals(6.0, result);
958
+ assertFalse(result < 0);
959
+ }
960
+
961
+ @Test
962
+ public void testMultiplication() {
963
+ double result = calculator.multiply(3.0, 4.0);
964
+ assertEquals(12.0, result);
965
+ assertThat(result, greaterThan(10.0));
966
+ }
967
+
968
+ @Test
969
+ public void testDivision() {
970
+ double result = calculator.divide(15.0, 3.0);
971
+ assertEquals(5.0, result);
972
+ }
973
+
974
+ @Test
975
+ public void testDivisionByZero() {
976
+ ArithmeticException exception = assertThrows(
977
+ ArithmeticException.class,
978
+ () -> calculator.divide(10.0, 0.0)
979
+ );
980
+ assertThat(exception.getMessage(), containsString("zero"));
981
+ }
982
+
983
+ // Parameterized test
984
+ @ParameterizedTest
985
+ @ValueSource(ints = {1, 2, 3, 5, 8, 13})
986
+ public void testPositiveNumbers(int number) {
987
+ assertTrue(number > 0);
988
+ assertNotEquals(0, number);
989
+ }
990
+
991
+ @ParameterizedTest
992
+ @ValueSource(strings = {"hello", "world", "test"})
993
+ public void testStringLength(String input) {
994
+ assertNotNull(input);
995
+ assertTrue(input.length() > 0);
996
+ }
997
+
998
+ // TestNG style tests
999
+ @org.testng.annotations.Test
1000
+ public void testNGBasicTest() {
1001
+ int result = 2 + 2;
1002
+ org.testng.Assert.assertEquals(result, 4);
1003
+ org.testng.Assert.assertTrue(result > 0);
1004
+ }
1005
+
1006
+ @org.testng.annotations.Test(groups = "integration")
1007
+ public void testNGIntegrationTest() {
1008
+ String message = "Hello World";
1009
+ org.testng.Assert.assertNotNull(message);
1010
+ org.testng.Assert.assertTrue(message.contains("World"));
1011
+ }
1012
+
1013
+ @DataProvider(name = "testData")
1014
+ public Object[][] createTestData() {
1015
+ return new Object[][] {
1016
+ {"test1", 5},
1017
+ {"test2", 10},
1018
+ {"test3", 15}
1019
+ };
1020
+ }
1021
+
1022
+ @org.testng.annotations.Test(dataProvider = "testData")
1023
+ public void testNGWithDataProvider(String name, int value) {
1024
+ org.testng.Assert.assertNotNull(name);
1025
+ org.testng.Assert.assertTrue(value > 0);
1026
+ }
1027
+
1028
+ @BeforeMethod
1029
+ public void testNGSetUp() {
1030
+ System.out.println("TestNG setup");
1031
+ }
1032
+
1033
+ @AfterMethod
1034
+ public void testNGTearDown() {
1035
+ System.out.println("TestNG teardown");
1036
+ }
1037
+
1038
+ // Traditional assert-based testing
1039
+ public void testTraditionalAsserts() {
1040
+ String message = "test message";
1041
+ assert message != null : "Message should not be null";
1042
+ assert message.length() > 0 : "Message should not be empty";
1043
+ assert message.contains("test") : "Message should contain 'test'";
1044
+ }
1045
+
1046
+ // Mock testing patterns
1047
+ @Test
1048
+ public void testWithMocks() {
1049
+ // Arrange
1050
+ Calculator mockCalculator = mock(Calculator.class);
1051
+ when(mockCalculator.add(2.0, 3.0)).thenReturn(5.0);
1052
+
1053
+ // Act
1054
+ double result = mockCalculator.add(2.0, 3.0);
1055
+
1056
+ // Assert
1057
+ assertEquals(5.0, result);
1058
+ verify(mockCalculator, times(1)).add(2.0, 3.0);
1059
+ }
1060
+
1061
+ // Nested test class
1062
+ @Nested
1063
+ @DisplayName("Tests for negative numbers")
1064
+ class NegativeNumberTests {
1065
+ @Test
1066
+ public void testNegativeAddition() {
1067
+ double result = calculator.add(-2.0, -3.0);
1068
+ assertEquals(-5.0, result);
1069
+ }
1070
+
1071
+ @Test
1072
+ public void testNegativeSubtraction() {
1073
+ double result = calculator.subtract(-10.0, -4.0);
1074
+ assertEquals(-6.0, result);
1075
+ }
1076
+ }
1077
+ }
1078
+ "#;
1079
+
1080
+ fs::write(&test_file, content)?;
1081
+
1082
+ let ctx = TestContext::new();
1083
+ let output = ctx.run_probe(&[
1084
+ "search",
1085
+ "Calculator",
1086
+ test_file.to_str().unwrap(),
1087
+ "--format",
1088
+ "outline",
1089
+ "--allow-tests",
1090
+ ])?;
1091
+
1092
+ // Test JUnit pattern detection
1093
+ assert!(
1094
+ output.contains("@Test") || output.contains("test"),
1095
+ "Missing JUnit @Test annotation or test methods in outline - output: {}",
1096
+ output
1097
+ );
1098
+
1099
+ // Test method naming patterns
1100
+ assert!(
1101
+ output.contains("testBasicAddition") || output.contains("testSubtraction"),
1102
+ "Missing test method names in outline - output: {}",
1103
+ output
1104
+ );
1105
+
1106
+ // Test assertion patterns
1107
+ assert!(
1108
+ output.contains("assert")
1109
+ || output.contains("assertEquals")
1110
+ || output.contains("assertTrue"),
1111
+ "Missing assertion patterns in outline - output: {}",
1112
+ output
1113
+ );
1114
+
1115
+ // Search for JUnit specific patterns
1116
+ let junit_output = ctx.run_probe(&[
1117
+ "search",
1118
+ "@Test",
1119
+ test_file.to_str().unwrap(),
1120
+ "--format",
1121
+ "outline",
1122
+ "--allow-tests",
1123
+ ])?;
1124
+
1125
+ assert!(
1126
+ junit_output.contains("@Test"),
1127
+ "Missing '@Test' annotation search in outline - output: {}",
1128
+ junit_output
1129
+ );
1130
+
1131
+ // Search for TestNG patterns
1132
+ let testng_output = ctx.run_probe(&[
1133
+ "search",
1134
+ "testng",
1135
+ test_file.to_str().unwrap(),
1136
+ "--format",
1137
+ "outline",
1138
+ "--allow-tests",
1139
+ ])?;
1140
+
1141
+ assert!(
1142
+ testng_output.contains("testng") || testng_output.contains("TestNG"),
1143
+ "Missing 'testng' pattern search in outline - output: {}",
1144
+ testng_output
1145
+ );
1146
+
1147
+ // Search for assertion keywords
1148
+ let assert_output = ctx.run_probe(&[
1149
+ "search",
1150
+ "assert",
1151
+ test_file.to_str().unwrap(),
1152
+ "--format",
1153
+ "outline",
1154
+ "--allow-tests",
1155
+ ])?;
1156
+
1157
+ assert!(
1158
+ assert_output.contains("assert"),
1159
+ "Missing 'assert' keyword in test assertion outline - output: {}",
1160
+ assert_output
1161
+ );
1162
+
1163
+ Ok(())
1164
+ }
1165
+
1166
+ #[test]
1167
+ fn test_java_outline_nested_control_flow() -> Result<()> {
1168
+ let temp_dir = TempDir::new()?;
1169
+ let test_file = temp_dir.path().join("nested_control_flow.java");
1170
+
1171
+ let content = r#"package com.example.controlflow;
1172
+
1173
+ import java.util.*;
1174
+
1175
+ public class NestedControlFlowTest {
1176
+ // Large method with deeply nested control flow that should get closing brace comments
1177
+ public static Map<String, Object> processComplexData(
1178
+ List<Map<String, Object>> dataList,
1179
+ Map<String, String> config,
1180
+ Set<String> validKeys) {
1181
+
1182
+ Map<String, Object> result = new HashMap<>();
1183
+ List<String> errors = new ArrayList<>();
1184
+ int processedCount = 0;
1185
+
1186
+ // Main processing loop with nested conditions
1187
+ for (Map<String, Object> dataItem : dataList) {
1188
+ if (dataItem == null || dataItem.isEmpty()) {
1189
+ errors.add("Empty data item at index " + processedCount);
1190
+ continue;
1191
+ }
1192
+
1193
+ // Validate all keys in the data item
1194
+ for (String key : dataItem.keySet()) {
1195
+ if (!validKeys.contains(key)) {
1196
+ errors.add("Invalid key: " + key + " at index " + processedCount);
1197
+ continue;
1198
+ }
1199
+
1200
+ Object value = dataItem.get(key);
1201
+ if (value == null) {
1202
+ continue;
1203
+ }
1204
+
1205
+ // Process different types of values
1206
+ if (value instanceof String) {
1207
+ String stringValue = (String) value;
1208
+ if (stringValue.trim().isEmpty()) {
1209
+ errors.add("Empty string value for key: " + key);
1210
+ continue;
1211
+ }
1212
+
1213
+ // Process string with configuration-based transformations
1214
+ switch (config.getOrDefault(key + "_transform", "none")) {
1215
+ case "uppercase":
1216
+ result.put(key + "_processed", stringValue.toUpperCase());
1217
+ break;
1218
+ case "lowercase":
1219
+ result.put(key + "_processed", stringValue.toLowerCase());
1220
+ break;
1221
+ case "reverse":
1222
+ result.put(key + "_processed", new StringBuilder(stringValue).reverse().toString());
1223
+ break;
1224
+ case "length":
1225
+ result.put(key + "_processed", stringValue.length());
1226
+ break;
1227
+ default:
1228
+ result.put(key + "_processed", stringValue.trim());
1229
+ break;
1230
+ }
1231
+ } else if (value instanceof Number) {
1232
+ Number numberValue = (Number) value;
1233
+ double doubleVal = numberValue.doubleValue();
1234
+
1235
+ // Apply mathematical transformations based on config
1236
+ if (config.containsKey(key + "_math")) {
1237
+ String mathOp = config.get(key + "_math");
1238
+ switch (mathOp) {
1239
+ case "square":
1240
+ result.put(key + "_processed", doubleVal * doubleVal);
1241
+ break;
1242
+ case "sqrt":
1243
+ if (doubleVal >= 0) {
1244
+ result.put(key + "_processed", Math.sqrt(doubleVal));
1245
+ } else {
1246
+ errors.add("Cannot take sqrt of negative number: " + doubleVal);
1247
+ }
1248
+ break;
1249
+ case "log":
1250
+ if (doubleVal > 0) {
1251
+ result.put(key + "_processed", Math.log(doubleVal));
1252
+ } else {
1253
+ errors.add("Cannot take log of non-positive number: " + doubleVal);
1254
+ }
1255
+ break;
1256
+ case "abs":
1257
+ result.put(key + "_processed", Math.abs(doubleVal));
1258
+ break;
1259
+ default:
1260
+ result.put(key + "_processed", doubleVal);
1261
+ break;
1262
+ }
1263
+ } else {
1264
+ result.put(key + "_processed", doubleVal);
1265
+ }
1266
+ }
1267
+ }
1268
+
1269
+ processedCount++;
1270
+ }
1271
+
1272
+ result.put("_meta_processed_count", processedCount);
1273
+ result.put("_meta_error_count", errors.size());
1274
+ if (!errors.isEmpty()) {
1275
+ result.put("_meta_errors", errors);
1276
+ }
1277
+
1278
+ return result;
1279
+ }
1280
+
1281
+ // Method with try-catch-finally and nested loops
1282
+ public void processWithExceptionHandling(List<String> data) {
1283
+ for (String item : data) {
1284
+ try {
1285
+ if (item == null) {
1286
+ continue;
1287
+ }
1288
+
1289
+ for (int i = 0; i < item.length(); i++) {
1290
+ char c = item.charAt(i);
1291
+ if (Character.isDigit(c)) {
1292
+ int digit = Character.getNumericValue(c);
1293
+ for (int j = 0; j < digit; j++) {
1294
+ try {
1295
+ processDigit(digit, j);
1296
+ } catch (NumberFormatException e) {
1297
+ System.err.println("Number format error: " + e.getMessage());
1298
+ continue;
1299
+ } catch (ArithmeticException e) {
1300
+ System.err.println("Arithmetic error: " + e.getMessage());
1301
+ break;
1302
+ }
1303
+ }
1304
+ } else if (Character.isLetter(c)) {
1305
+ processLetter(c);
1306
+ }
1307
+ }
1308
+ } catch (StringIndexOutOfBoundsException e) {
1309
+ System.err.println("String index error: " + e.getMessage());
1310
+ } catch (Exception e) {
1311
+ System.err.println("Unexpected error: " + e.getMessage());
1312
+ } finally {
1313
+ System.out.println("Finished processing item: " + item);
1314
+ }
1315
+ }
1316
+ }
1317
+
1318
+ private void processDigit(int digit, int position) {
1319
+ // Implementation
1320
+ }
1321
+
1322
+ private void processLetter(char letter) {
1323
+ // Implementation
1324
+ }
1325
+ }
1326
+ "#;
1327
+
1328
+ fs::write(&test_file, content)?;
1329
+
1330
+ let ctx = TestContext::new();
1331
+ let output = ctx.run_probe(&[
1332
+ "search",
1333
+ "Calculator",
1334
+ test_file.to_str().unwrap(),
1335
+ "--format",
1336
+ "outline",
1337
+ "--allow-tests",
1338
+ ])?;
1339
+
1340
+ // Verify nested control flow structures are shown
1341
+ assert!(
1342
+ output.contains("for") || output.contains("if") || output.contains("switch"),
1343
+ "Missing nested control flow keywords in outline - output: {}",
1344
+ output
1345
+ );
1346
+
1347
+ // Verify exception handling structures
1348
+ assert!(
1349
+ output.contains("try") || output.contains("catch") || output.contains("finally"),
1350
+ "Missing exception handling keywords in outline - output: {}",
1351
+ output
1352
+ );
1353
+
1354
+ // Large methods should have closing brace comments (Java // style)
1355
+ let has_closing_brace_comments = output.contains("} //");
1356
+ let has_ellipsis = output.contains("...");
1357
+
1358
+ // Either we should see closing brace comments (if there are gaps) or the method should be truncated
1359
+ assert!(
1360
+ has_closing_brace_comments || has_ellipsis,
1361
+ "Large nested method should either have closing brace comments or be truncated - output: {}",
1362
+ output
1363
+ );
1364
+
1365
+ // Test searching for specific control flow patterns
1366
+ let switch_output = ctx.run_probe(&[
1367
+ "search",
1368
+ "switch",
1369
+ test_file.to_str().unwrap(),
1370
+ "--format",
1371
+ "outline",
1372
+ "--allow-tests",
1373
+ ])?;
1374
+
1375
+ assert!(
1376
+ switch_output.contains("switch"),
1377
+ "Missing 'switch' keyword in nested control flow outline - output: {}",
1378
+ switch_output
1379
+ );
1380
+
1381
+ Ok(())
1382
+ }
1383
+
1384
+ #[test]
1385
+ fn test_java_outline_small_vs_large_functions() -> Result<()> {
1386
+ let temp_dir = TempDir::new()?;
1387
+ let test_file = temp_dir.path().join("function_sizes.java");
1388
+
1389
+ let content = r#"package com.example.sizes;
1390
+
1391
+ import java.util.*;
1392
+
1393
+ public class FunctionSizeTest {
1394
+ // Small function - should NOT get closing brace comments (under 20 lines)
1395
+ public static int smallFunction(int x, int y) {
1396
+ int result = x + y;
1397
+ if (result > 100) {
1398
+ result = 100;
1399
+ }
1400
+ return result * 2;
1401
+ }
1402
+
1403
+ // Another small function
1404
+ public String formatString(String input) {
1405
+ if (input == null) {
1406
+ return "";
1407
+ }
1408
+ return input.trim().toUpperCase();
1409
+ }
1410
+
1411
+ // Small helper method
1412
+ private boolean isValid(Object obj) {
1413
+ return obj != null;
1414
+ }
1415
+
1416
+ // Large function - SHOULD get closing brace comments (over 20 lines with gaps)
1417
+ public static List<Map<String, Object>> largeFunctionWithManyLines(
1418
+ List<String> inputData,
1419
+ Map<String, String> configuration,
1420
+ boolean enableProcessing) {
1421
+
1422
+ List<Map<String, Object>> results = new ArrayList<>();
1423
+ Map<String, Integer> counters = new HashMap<>();
1424
+ Set<String> processedKeys = new HashSet<>();
1425
+
1426
+ // Initialize counters
1427
+ counters.put("total", 0);
1428
+ counters.put("processed", 0);
1429
+ counters.put("skipped", 0);
1430
+ counters.put("errors", 0);
1431
+
1432
+ // Main processing logic
1433
+ for (String item : inputData) {
1434
+ counters.put("total", counters.get("total") + 1);
1435
+
1436
+ if (item == null || item.trim().isEmpty()) {
1437
+ counters.put("skipped", counters.get("skipped") + 1);
1438
+ continue;
1439
+ }
1440
+
1441
+ try {
1442
+ Map<String, Object> processedItem = new HashMap<>();
1443
+ String key = "item_" + counters.get("total");
1444
+
1445
+ if (enableProcessing) {
1446
+ // Complex processing logic
1447
+ String[] parts = item.split(",");
1448
+ for (int i = 0; i < parts.length; i++) {
1449
+ String part = parts[i].trim();
1450
+ if (!part.isEmpty()) {
1451
+ String partKey = key + "_part_" + i;
1452
+
1453
+ // Apply configuration-based transformations
1454
+ if (configuration.containsKey("transform_" + i)) {
1455
+ String transform = configuration.get("transform_" + i);
1456
+ switch (transform) {
1457
+ case "uppercase":
1458
+ part = part.toUpperCase();
1459
+ break;
1460
+ case "lowercase":
1461
+ part = part.toLowerCase();
1462
+ break;
1463
+ case "reverse":
1464
+ part = new StringBuilder(part).reverse().toString();
1465
+ break;
1466
+ default:
1467
+ // No transformation
1468
+ break;
1469
+ }
1470
+ }
1471
+
1472
+ processedItem.put(partKey, part);
1473
+ processedKeys.add(partKey);
1474
+ }
1475
+ }
1476
+
1477
+ // Additional metadata
1478
+ processedItem.put("original", item);
1479
+ processedItem.put("parts_count", parts.length);
1480
+ processedItem.put("processed_at", System.currentTimeMillis());
1481
+
1482
+ } else {
1483
+ // Simple processing
1484
+ processedItem.put("value", item);
1485
+ processedItem.put("length", item.length());
1486
+ processedKeys.add(key);
1487
+ }
1488
+
1489
+ results.add(processedItem);
1490
+ counters.put("processed", counters.get("processed") + 1);
1491
+
1492
+ } catch (Exception e) {
1493
+ counters.put("errors", counters.get("errors") + 1);
1494
+ System.err.println("Error processing item: " + item + " - " + e.getMessage());
1495
+ }
1496
+ }
1497
+
1498
+ // Add summary information
1499
+ Map<String, Object> summary = new HashMap<>();
1500
+ summary.put("counters", counters);
1501
+ summary.put("processed_keys_count", processedKeys.size());
1502
+ summary.put("results_count", results.size());
1503
+ results.add(0, summary);
1504
+
1505
+ return results;
1506
+ }
1507
+
1508
+ // Another large function with different patterns
1509
+ public void anotherLargeFunctionWithLoops(int n) {
1510
+ System.out.println("Starting processing for n = " + n);
1511
+
1512
+ // Outer loop
1513
+ for (int i = 0; i < n; i++) {
1514
+ System.out.println("Outer loop iteration: " + i);
1515
+
1516
+ // Inner loop with conditions
1517
+ for (int j = 0; j < i; j++) {
1518
+ if (j % 2 == 0) {
1519
+ System.out.println(" Even j: " + j);
1520
+
1521
+ // Nested processing
1522
+ for (int k = 0; k < j; k++) {
1523
+ if (k % 3 == 0) {
1524
+ System.out.println(" k divisible by 3: " + k);
1525
+ } else if (k % 3 == 1) {
1526
+ System.out.println(" k mod 3 = 1: " + k);
1527
+ } else {
1528
+ System.out.println(" k mod 3 = 2: " + k);
1529
+ }
1530
+ }
1531
+ } else {
1532
+ System.out.println(" Odd j: " + j);
1533
+ }
1534
+ }
1535
+
1536
+ // Additional processing based on i
1537
+ if (i < n / 2) {
1538
+ System.out.println("First half processing");
1539
+ } else {
1540
+ System.out.println("Second half processing");
1541
+ }
1542
+ }
1543
+
1544
+ System.out.println("Completed processing");
1545
+ }
1546
+ }
1547
+ "#;
1548
+
1549
+ fs::write(&test_file, content)?;
1550
+
1551
+ let ctx = TestContext::new();
1552
+ let output = ctx.run_probe(&[
1553
+ "search",
1554
+ "Calculator",
1555
+ test_file.to_str().unwrap(),
1556
+ "--format",
1557
+ "outline",
1558
+ "--allow-tests",
1559
+ ])?;
1560
+
1561
+ // Verify small functions are present
1562
+ assert!(
1563
+ output.contains("smallFunction")
1564
+ || output.contains("formatString")
1565
+ || output.contains("isValid"),
1566
+ "Missing small function names in outline - output: {}",
1567
+ output
1568
+ );
1569
+
1570
+ // Verify large functions are present
1571
+ assert!(
1572
+ output.contains("largeFunctionWithManyLines")
1573
+ || output.contains("anotherLargeFunctionWithLoops"),
1574
+ "Missing large function names in outline - output: {}",
1575
+ output
1576
+ );
1577
+
1578
+ // Small functions should NOT have closing brace comments when shown completely
1579
+ let small_func_closing_braces = output.matches("} // smallFunction").count()
1580
+ + output.matches("} // formatString").count()
1581
+ + output.matches("} // isValid").count();
1582
+
1583
+ // Small functions should have few or no closing brace comments
1584
+ assert!(
1585
+ small_func_closing_braces <= 1,
1586
+ "Small functions should not have many closing brace comments - found: {} - output: {}",
1587
+ small_func_closing_braces,
1588
+ output
1589
+ );
1590
+
1591
+ // Large functions should either have closing brace comments or be truncated
1592
+ let has_large_func_closing_braces = output.contains("} // largeFunctionWithManyLines")
1593
+ || output.contains("} // anotherLargeFunctionWithLoops")
1594
+ || output.contains("} //");
1595
+ let has_ellipsis = output.contains("...");
1596
+
1597
+ assert!(
1598
+ has_large_func_closing_braces || has_ellipsis,
1599
+ "Large functions should either have closing brace comments or ellipsis truncation - output: {}",
1600
+ output
1601
+ );
1602
+
1603
+ // Verify the outline shows function structure appropriately
1604
+ assert!(
1605
+ output.contains("public static") && output.contains("private"),
1606
+ "Missing access modifiers in function outline - output: {}",
1607
+ output
1608
+ );
1609
+
1610
+ Ok(())
1611
+ }