@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.
- package/README.md +138 -0
- package/data/.env.example +22 -0
- package/data/.gitattributes +47 -0
- package/data/.glfrc.json +7 -0
- package/data/.husky/pre-commit +5 -0
- package/data/.nvmrc +1 -0
- package/data/CHANGELOG.md +75 -0
- package/data/CODE_OF_CONDUCT.md +129 -0
- package/data/CONTRIBUTING.md +203 -0
- package/data/DOCS-STRUCTURE.md +307 -0
- package/data/I18N.md +292 -0
- package/data/LICENSE +22 -0
- package/data/README.md +315 -0
- package/data/SECURITY.md +125 -0
- package/data/WIKI-DEPLOYMENT.md +348 -0
- package/data/docs/AI-FEATURES.md +610 -0
- package/data/docs/API-REFERENCE.md +1022 -0
- package/data/docs/AUTHENTICATION.md +301 -0
- package/data/docs/BACKEND-API.md +468 -0
- package/data/docs/DEVELOPMENT.md +375 -0
- package/data/docs/EXAMPLES.md +622 -0
- package/data/docs/MCP-SERVER.md +307 -0
- package/data/docs/MIGRATION-GUIDE.md +367 -0
- package/data/docs/NPM-PUBLISH.md +193 -0
- package/data/docs/QUICKSTART.md +206 -0
- package/data/docs/REDIS-SETUP.md +162 -0
- package/data/docs/SERVER.md +228 -0
- package/data/docs/TROUBLESHOOTING.md +657 -0
- package/data/docs/WIDGET-GUIDE.md +638 -0
- package/data/docs/WIKI-HOME.md +58 -0
- package/data/docs/WIKI-SIDEBAR.md +39 -0
- package/data/package.json +171 -0
- package/data/playwright.config.ts +64 -0
- package/data/probe/.cargo/config.toml +10 -0
- package/data/probe/.claude/commands/performance-review.md +15 -0
- package/data/probe/.clinerules +288 -0
- package/data/probe/.dockerignore +57 -0
- package/data/probe/.githooks/post-commit +11 -0
- package/data/probe/.githooks/pre-commit +99 -0
- package/data/probe/.githooks/pre-commit-vow +9 -0
- package/data/probe/.prompts/engineer.md +41 -0
- package/data/probe/.roomodes +28 -0
- package/data/probe/.windsurfrules +0 -0
- package/data/probe/BASH_TOOL_SUMMARY.md +148 -0
- package/data/probe/BENCHMARKING.md +256 -0
- package/data/probe/CLAUDE.md +226 -0
- package/data/probe/CODE_OF_CONDUCT.md +128 -0
- package/data/probe/CONTRIBUTING.md +193 -0
- package/data/probe/Cargo.toml +120 -0
- package/data/probe/Cross.toml +10 -0
- package/data/probe/DOCKER-README.md +224 -0
- package/data/probe/Dockerfile +32 -0
- package/data/probe/ENHANCED_DEBUG_TELEMETRY.md +188 -0
- package/data/probe/LICENSE +201 -0
- package/data/probe/Makefile +210 -0
- package/data/probe/README.md +824 -0
- package/data/probe/SECURITY.md +67 -0
- package/data/probe/WINDOWS-GUIDE.md +294 -0
- package/data/probe/benches/parsing_benchmarks.rs +370 -0
- package/data/probe/benches/search_benchmarks.rs +599 -0
- package/data/probe/benches/simd_benchmarks.rs +372 -0
- package/data/probe/benches/timing_benchmarks.rs +287 -0
- package/data/probe/build-windows.bat +229 -0
- package/data/probe/codex-config/config.toml +6 -0
- package/data/probe/docs/PERFORMANCE_OPTIMIZATION.md +161 -0
- package/data/probe/examples/cache_demo.rs +46 -0
- package/data/probe/examples/chat/.dockerignore +37 -0
- package/data/probe/examples/chat/ChatSessionManager.js +295 -0
- package/data/probe/examples/chat/Dockerfile +98 -0
- package/data/probe/examples/chat/LICENSE +201 -0
- package/data/probe/examples/chat/LOCAL_IMAGE_SUPPORT.md +195 -0
- package/data/probe/examples/chat/MCP_INTEGRATION.md +400 -0
- package/data/probe/examples/chat/README.md +338 -0
- package/data/probe/examples/chat/TRACING.md +226 -0
- package/data/probe/examples/chat/appTracer.js +968 -0
- package/data/probe/examples/chat/auth.js +76 -0
- package/data/probe/examples/chat/bin/probe-chat.js +13 -0
- package/data/probe/examples/chat/build.js +104 -0
- package/data/probe/examples/chat/cancelRequest.js +84 -0
- package/data/probe/examples/chat/demo-agentic-image-flow.js +88 -0
- package/data/probe/examples/chat/demo-local-images.js +128 -0
- package/data/probe/examples/chat/fileSpanExporter.js +181 -0
- package/data/probe/examples/chat/implement/README.md +228 -0
- package/data/probe/examples/chat/implement/backends/AiderBackend.js +750 -0
- package/data/probe/examples/chat/implement/backends/BaseBackend.js +276 -0
- package/data/probe/examples/chat/implement/backends/ClaudeCodeBackend.js +767 -0
- package/data/probe/examples/chat/implement/backends/MockBackend.js +237 -0
- package/data/probe/examples/chat/implement/backends/registry.js +85 -0
- package/data/probe/examples/chat/implement/core/BackendManager.js +567 -0
- package/data/probe/examples/chat/implement/core/ImplementTool.js +354 -0
- package/data/probe/examples/chat/implement/core/config.js +428 -0
- package/data/probe/examples/chat/implement/core/timeouts.js +58 -0
- package/data/probe/examples/chat/implement/core/utils.js +496 -0
- package/data/probe/examples/chat/implement/types/BackendTypes.js +126 -0
- package/data/probe/examples/chat/index.js +669 -0
- package/data/probe/examples/chat/mcpServer.js +341 -0
- package/data/probe/examples/chat/npm/LICENSE +15 -0
- package/data/probe/examples/chat/npm/README.md +168 -0
- package/data/probe/examples/chat/npm/bin/probe-chat.js +156 -0
- package/data/probe/examples/chat/npm/index.js +259 -0
- package/data/probe/examples/chat/npm/package.json +54 -0
- package/data/probe/examples/chat/package.json +102 -0
- package/data/probe/examples/chat/probeChat.js +456 -0
- package/data/probe/examples/chat/probeTool.js +491 -0
- package/data/probe/examples/chat/storage/JsonChatStorage.js +476 -0
- package/data/probe/examples/chat/telemetry.js +281 -0
- package/data/probe/examples/chat/test/integration/chatFlows.test.js +320 -0
- package/data/probe/examples/chat/test/integration/toolCalling.test.js +471 -0
- package/data/probe/examples/chat/test/mocks/mockLLMProvider.js +269 -0
- package/data/probe/examples/chat/test/test-backends.js +90 -0
- package/data/probe/examples/chat/test/testUtils.js +530 -0
- package/data/probe/examples/chat/test/unit/backendTimeout.test.js +161 -0
- package/data/probe/examples/chat/test/unit/packageFiles.test.js +120 -0
- package/data/probe/examples/chat/test/verify-tests.js +118 -0
- package/data/probe/examples/chat/test-agentic-image-loading.js +294 -0
- package/data/probe/examples/chat/test-ai-sdk-telemetry.js +204 -0
- package/data/probe/examples/chat/test-chat-tracing.js +38 -0
- package/data/probe/examples/chat/test-direct-function.js +49 -0
- package/data/probe/examples/chat/test-file-size-validation.js +103 -0
- package/data/probe/examples/chat/test-full-mcp-integration.js +258 -0
- package/data/probe/examples/chat/test-github-context.txt +12 -0
- package/data/probe/examples/chat/test-hierarchy.js +203 -0
- package/data/probe/examples/chat/test-image-spans.js +37 -0
- package/data/probe/examples/chat/test-local-image-reading.js +176 -0
- package/data/probe/examples/chat/test-mcp-integration.js +136 -0
- package/data/probe/examples/chat/test-mcp-probe-server.js +161 -0
- package/data/probe/examples/chat/test-mcp-with-ai.js +279 -0
- package/data/probe/examples/chat/test-multiple-allowed-dirs.js +111 -0
- package/data/probe/examples/chat/test-probe-mcp-server.js +110 -0
- package/data/probe/examples/chat/test-security-validation.js +145 -0
- package/data/probe/examples/chat/test-simple-tracing.js +32 -0
- package/data/probe/examples/chat/test-trace-verification.js +235 -0
- package/data/probe/examples/chat/test-tracing.js +114 -0
- package/data/probe/examples/chat/tokenCounter.js +419 -0
- package/data/probe/examples/chat/tokenUsageDisplay.js +134 -0
- package/data/probe/examples/chat/webServer.js +1103 -0
- package/data/probe/examples/reranker/Cargo.toml +33 -0
- package/data/probe/examples/reranker/DEBUG_OUTPUT_ANALYSIS.md +71 -0
- package/data/probe/examples/reranker/MODELS.md +66 -0
- package/data/probe/examples/reranker/MODEL_COMPARISON.md +60 -0
- package/data/probe/examples/reranker/MULTI_MODEL_ANALYSIS.md +176 -0
- package/data/probe/examples/reranker/PERFORMANCE_SUMMARY.md +156 -0
- package/data/probe/examples/reranker/README.md +347 -0
- package/data/probe/examples/reranker/RUST_BERT_COMPARISON.md +82 -0
- package/data/probe/examples/reranker/TOKENIZATION_GUIDE.md +120 -0
- package/data/probe/examples/reranker/check_rust_tokenizer.py +108 -0
- package/data/probe/examples/reranker/convert_to_torchscript.py +109 -0
- package/data/probe/examples/reranker/debug_scoring.py +189 -0
- package/data/probe/examples/reranker/debug_tokenization.py +154 -0
- package/data/probe/examples/reranker/download_models.sh +73 -0
- package/data/probe/examples/reranker/requirements.txt +13 -0
- package/data/probe/examples/reranker/run_comprehensive_benchmark.sh +83 -0
- package/data/probe/examples/reranker/rust_bert_test/Cargo.toml +12 -0
- package/data/probe/examples/reranker/rust_bert_test/README.md +54 -0
- package/data/probe/examples/reranker/simple_test.py +50 -0
- package/data/probe/examples/reranker/test_all_models.sh +63 -0
- package/data/probe/examples/reranker/test_bert_results.sh +44 -0
- package/data/probe/examples/reranker/test_cross_encoder.py +334 -0
- package/data/probe/examples/reranker/test_cross_encoder.sh +80 -0
- package/data/probe/examples/reranker/test_exact_comparison.py +151 -0
- package/data/probe/examples/reranker/test_parallel_performance.sh +56 -0
- package/data/probe/examples/reranker/test_scores.py +132 -0
- package/data/probe/install.ps1 +508 -0
- package/data/probe/install.sh +460 -0
- package/data/probe/npm/CLONE_METHOD_EXAMPLES.md +596 -0
- package/data/probe/npm/CONTEXT_COMPACTION.md +303 -0
- package/data/probe/npm/DELEGATE_TOOL_README.md +166 -0
- package/data/probe/npm/MAID_INTEGRATION.md +313 -0
- package/data/probe/npm/MCP_INTEGRATION_SUMMARY.md +241 -0
- package/data/probe/npm/README.md +824 -0
- package/data/probe/npm/bin/.gitignore +7 -0
- package/data/probe/npm/bin/.gitkeep +0 -0
- package/data/probe/npm/bin/README.md +12 -0
- package/data/probe/npm/bin/probe +167 -0
- package/data/probe/npm/docs/CLAUDE_CODE_INTEGRATION.md +414 -0
- package/data/probe/npm/docs/CODEX_INTEGRATION.md +502 -0
- package/data/probe/npm/docs/EDIT_CREATE_TOOLS.md +233 -0
- package/data/probe/npm/docs/RETRY_AND_FALLBACK.md +674 -0
- package/data/probe/npm/example-usage.js +335 -0
- package/data/probe/npm/examples/multi-engine-demo.js +117 -0
- package/data/probe/npm/examples/probe-agent-cli.js +113 -0
- package/data/probe/npm/examples/test-agent-edit.js +114 -0
- package/data/probe/npm/examples/test-edit-create.js +120 -0
- package/data/probe/npm/examples/test-edit-direct.js +114 -0
- package/data/probe/npm/index.d.ts +744 -0
- package/data/probe/npm/jest.config.js +52 -0
- package/data/probe/npm/package.json +117 -0
- package/data/probe/npm/scripts/build-agent.cjs +75 -0
- package/data/probe/npm/scripts/build-cjs.js +124 -0
- package/data/probe/npm/scripts/build-mcp.cjs +36 -0
- package/data/probe/npm/scripts/postinstall.js +216 -0
- package/data/probe/npm/test-codex-e2e.js +78 -0
- package/data/probe/npm/test-download-lock.js +109 -0
- package/data/probe/npm/test-grep-security.js +94 -0
- package/data/probe/npm/test-grep-simplified.js +63 -0
- package/data/probe/npm/test-grep.js +51 -0
- package/data/probe/npm/tests/README.md +96 -0
- package/data/probe/npm/tests/agent-compact-history.test.js +174 -0
- package/data/probe/npm/tests/allow-tests-default.test.js +151 -0
- package/data/probe/npm/tests/contextCompactor.test.js +498 -0
- package/data/probe/npm/tests/delegate-config.test.js +353 -0
- package/data/probe/npm/tests/delegate-integration.test.js +348 -0
- package/data/probe/npm/tests/extractor-integration.test.js +162 -0
- package/data/probe/npm/tests/extractor.test.js +317 -0
- package/data/probe/npm/tests/fixtures/sampleDiagrams.js +267 -0
- package/data/probe/npm/tests/integration/claude-code-auto-fallback.spec.js +148 -0
- package/data/probe/npm/tests/integration/claude-code-multi-step.spec.js +127 -0
- package/data/probe/npm/tests/integration/claude-code-tool-events.spec.js +163 -0
- package/data/probe/npm/tests/integration/codex-auto-fallback.spec.js +191 -0
- package/data/probe/npm/tests/integration/codex-tool-events.spec.js +147 -0
- package/data/probe/npm/tests/integration/examplesChatMcp.test.js +402 -0
- package/data/probe/npm/tests/integration/mcpDotenvSupport.test.js +174 -0
- package/data/probe/npm/tests/integration/mcpErrorHandling.test.js +566 -0
- package/data/probe/npm/tests/integration/mcpRobustness.test.js +564 -0
- package/data/probe/npm/tests/integration/mcpStdoutPurity.test.js +355 -0
- package/data/probe/npm/tests/integration/probeAgentMcp.test.js +398 -0
- package/data/probe/npm/tests/integration/retryFallback.test.js +368 -0
- package/data/probe/npm/tests/integration/schema-in-initial-message.test.js +318 -0
- package/data/probe/npm/tests/integration/schema-validation-loop-prevention.test.js +244 -0
- package/data/probe/npm/tests/integration/schemaRetryLogic.test.js +94 -0
- package/data/probe/npm/tests/integration/validationFlow.test.js +329 -0
- package/data/probe/npm/tests/manual/test-codex-basic.js +110 -0
- package/data/probe/npm/tests/mcp/mcpClientManager.test.js +614 -0
- package/data/probe/npm/tests/mcp/mcpConfig.test.js +359 -0
- package/data/probe/npm/tests/mcp/mcpXmlBridge.test.js +436 -0
- package/data/probe/npm/tests/mcp/mockMcpServer.js +510 -0
- package/data/probe/npm/tests/mcp-strict-syntax.test.js +319 -0
- package/data/probe/npm/tests/mermaidQuoteEscaping.test.js +214 -0
- package/data/probe/npm/tests/nestedQuoteFix.test.js +40 -0
- package/data/probe/npm/tests/setup.js +46 -0
- package/data/probe/npm/tests/unit/allowed-tools.test.js +513 -0
- package/data/probe/npm/tests/unit/attempt-completion-closing-tag-in-content.test.js +188 -0
- package/data/probe/npm/tests/unit/attemptCompletionJsonFix.test.js +238 -0
- package/data/probe/npm/tests/unit/attemptCompletionJsonIssue.test.js +128 -0
- package/data/probe/npm/tests/unit/backtickAutoFix.test.js +35 -0
- package/data/probe/npm/tests/unit/bash-probe-agent-integration.test.js +389 -0
- package/data/probe/npm/tests/unit/bash-simple-commands.test.js +324 -0
- package/data/probe/npm/tests/unit/bash-tool-comprehensive.test.js +371 -0
- package/data/probe/npm/tests/unit/bash-tool-integration.test.js +310 -0
- package/data/probe/npm/tests/unit/bash-tool.test.js +341 -0
- package/data/probe/npm/tests/unit/completion-prompt.test.js +379 -0
- package/data/probe/npm/tests/unit/cwd-path-options.test.js +287 -0
- package/data/probe/npm/tests/unit/delegate-limits.test.js +422 -0
- package/data/probe/npm/tests/unit/direct-content-attempt-completion.test.js +235 -0
- package/data/probe/npm/tests/unit/edit-create-tools.test.js +609 -0
- package/data/probe/npm/tests/unit/enhancedMermaidValidation.test.js +577 -0
- package/data/probe/npm/tests/unit/extract-content.test.js +83 -0
- package/data/probe/npm/tests/unit/extract-multiple-targets.test.js +89 -0
- package/data/probe/npm/tests/unit/fallbackManager.test.js +442 -0
- package/data/probe/npm/tests/unit/githubCompatibilityValidation.test.js +258 -0
- package/data/probe/npm/tests/unit/imageConfig.test.js +149 -0
- package/data/probe/npm/tests/unit/imagePathResolution.test.js +345 -0
- package/data/probe/npm/tests/unit/json-fixing-agent.test.js +238 -0
- package/data/probe/npm/tests/unit/json-validation-enhanced-errors.test.js +199 -0
- package/data/probe/npm/tests/unit/jsonValidationInfiniteLoopFix.test.js +228 -0
- package/data/probe/npm/tests/unit/maidIntegration.test.js +139 -0
- package/data/probe/npm/tests/unit/maxIterationsWarning.test.js +195 -0
- package/data/probe/npm/tests/unit/mermaidEdgeLabelFix.test.js +161 -0
- package/data/probe/npm/tests/unit/mermaidHtmlEntities.test.js +76 -0
- package/data/probe/npm/tests/unit/mermaidInfiniteLoopFix.test.js +64 -0
- package/data/probe/npm/tests/unit/mermaidValidation.test.js +723 -0
- package/data/probe/npm/tests/unit/mermaidValidationVisorExample.test.js +309 -0
- package/data/probe/npm/tests/unit/probe-agent-clone-realistic.test.js +643 -0
- package/data/probe/npm/tests/unit/probe-agent-clone.test.js +476 -0
- package/data/probe/npm/tests/unit/probe-agent-delegate.test.js +400 -0
- package/data/probe/npm/tests/unit/probe-agent-model-option.test.js +118 -0
- package/data/probe/npm/tests/unit/probeTool-security.test.js +283 -0
- package/data/probe/npm/tests/unit/readImageTool.test.js +418 -0
- package/data/probe/npm/tests/unit/retryManager.test.js +317 -0
- package/data/probe/npm/tests/unit/schema-aware-reminders.test.js +288 -0
- package/data/probe/npm/tests/unit/schemaDefinitionDetection.test.js +115 -0
- package/data/probe/npm/tests/unit/schemaUtils.test.js +1268 -0
- package/data/probe/npm/tests/unit/simpleTelemetry.test.js +282 -0
- package/data/probe/npm/tests/unit/simplified-attempt-completion.test.js +274 -0
- package/data/probe/npm/tests/unit/single-quote-json-bug.test.js +231 -0
- package/data/probe/npm/tests/unit/subgraphAutoFix.test.js +110 -0
- package/data/probe/npm/tests/unit/system-prompt.test.js +32 -0
- package/data/probe/npm/tests/unit/types-probe-agent-options.test.js +42 -0
- package/data/probe/npm/tests/unit/xmlParsing.test.js +720 -0
- package/data/probe/npm/tsconfig.json +21 -0
- package/data/probe/result1.txt +19 -0
- package/data/probe/result2.txt +26 -0
- package/data/probe/scripts/benchmark.sh +270 -0
- package/data/probe/scripts/cache_memory_analysis.rs +844 -0
- package/data/probe/scripts/claude-hook-wrapper.sh +56 -0
- package/data/probe/site/.env.example +10 -0
- package/data/probe/site/DEPLOYMENT.md +86 -0
- package/data/probe/site/README.md +183 -0
- package/data/probe/site/adding-languages.md +135 -0
- package/data/probe/site/ai-chat.md +427 -0
- package/data/probe/site/ai-integration.md +1488 -0
- package/data/probe/site/blog/agentic-flow-custom-xml-protocol.md +407 -0
- package/data/probe/site/blog/index.md +118 -0
- package/data/probe/site/blog/v0.6.0-release.md +426 -0
- package/data/probe/site/blog.md +8 -0
- package/data/probe/site/changelog.md +200 -0
- package/data/probe/site/cli-mode.md +437 -0
- package/data/probe/site/code-extraction.md +436 -0
- package/data/probe/site/contributing/README.md +9 -0
- package/data/probe/site/contributing/documentation-cross-references.md +215 -0
- package/data/probe/site/contributing/documentation-maintenance.md +275 -0
- package/data/probe/site/contributing/documentation-structure.md +75 -0
- package/data/probe/site/documentation-cross-references.md +215 -0
- package/data/probe/site/documentation-guide.md +132 -0
- package/data/probe/site/documentation-maintenance.md +275 -0
- package/data/probe/site/features.md +147 -0
- package/data/probe/site/how-it-works.md +118 -0
- package/data/probe/site/index.md +175 -0
- package/data/probe/site/index.md.bak +133 -0
- package/data/probe/site/installation.md +235 -0
- package/data/probe/site/integrations/docker.md +248 -0
- package/data/probe/site/integrations/github-actions.md +413 -0
- package/data/probe/site/language-support-overview.md +168 -0
- package/data/probe/site/mcp-integration.md +587 -0
- package/data/probe/site/mcp-server.md +304 -0
- package/data/probe/site/navigation-structure.md +76 -0
- package/data/probe/site/nodejs-sdk.md +798 -0
- package/data/probe/site/output-formats.md +625 -0
- package/data/probe/site/package.json +21 -0
- package/data/probe/site/public/_headers +28 -0
- package/data/probe/site/public/_redirects +11 -0
- package/data/probe/site/quick-start.md +289 -0
- package/data/probe/site/search-functionality.md +291 -0
- package/data/probe/site/search-reference.md +291 -0
- package/data/probe/site/supported-languages.md +215 -0
- package/data/probe/site/use-cases/README.md +8 -0
- package/data/probe/site/use-cases/advanced-cli.md +253 -0
- package/data/probe/site/use-cases/ai-code-editors.md +239 -0
- package/data/probe/site/use-cases/building-ai-tools.md +529 -0
- package/data/probe/site/use-cases/cli-ai-workflows.md +285 -0
- package/data/probe/site/use-cases/deploying-probe-web-interface.md +255 -0
- package/data/probe/site/use-cases/integrating-probe-into-ai-code-editors.md +161 -0
- package/data/probe/site/use-cases/nodejs-sdk.md +596 -0
- package/data/probe/site/use-cases/team-chat.md +350 -0
- package/data/probe/site/web-interface.md +434 -0
- package/data/probe/site/wrangler.toml +9 -0
- package/data/probe/test-api-key.sh +1 -0
- package/data/probe/test-probe-implementation/hello.js +7 -0
- package/data/probe/test_cases/demonstrate_early_termination_issues.sh +176 -0
- package/data/probe/test_cases/early_termination_issues.rs +533 -0
- package/data/probe/test_data/test_nested_struct.go +26 -0
- package/data/probe/tests/README.md +286 -0
- package/data/probe/tests/README_search_determinism_tests.md +116 -0
- package/data/probe/tests/adjacent_comment_test.rs +152 -0
- package/data/probe/tests/apostrophe_handling_tests.rs +132 -0
- package/data/probe/tests/block_filtering_with_ast_tests.rs +669 -0
- package/data/probe/tests/block_merging_tests.rs +396 -0
- package/data/probe/tests/c_outline_format_tests.rs +2179 -0
- package/data/probe/tests/cache_invalidation_issues.rs.disabled +682 -0
- package/data/probe/tests/cache_order_tests.rs +147 -0
- package/data/probe/tests/cache_query_scoping_tests.rs +221 -0
- package/data/probe/tests/cli_tests.rs +680 -0
- package/data/probe/tests/comment_context_integration_test.rs +240 -0
- package/data/probe/tests/common.rs +33 -0
- package/data/probe/tests/complex_block_merging_tests.rs +599 -0
- package/data/probe/tests/complex_query_block_filtering_tests.rs +422 -0
- package/data/probe/tests/control_flow_closing_braces_test.rs +91 -0
- package/data/probe/tests/cpp_outline_format_tests.rs +1507 -0
- package/data/probe/tests/csharp_outline_format_tests.rs +941 -0
- package/data/probe/tests/elastic_query_integration_tests.rs +922 -0
- package/data/probe/tests/extract_command_tests.rs +1848 -0
- package/data/probe/tests/extract_deduplication_tests.rs +146 -0
- package/data/probe/tests/extract_input_file_tests.rs +84 -0
- package/data/probe/tests/extract_prompt_tests.rs +102 -0
- package/data/probe/tests/filename_search_tests.rs +96 -0
- package/data/probe/tests/fixtures/user/AssemblyInfo.cs +3 -0
- package/data/probe/tests/github_extract_tests.rs +234 -0
- package/data/probe/tests/go_comment_test.rs +253 -0
- package/data/probe/tests/go_outline_format_tests.rs +2587 -0
- package/data/probe/tests/go_path_resolver_tests.rs +96 -0
- package/data/probe/tests/html_outline_format_tests.rs +637 -0
- package/data/probe/tests/integration_tests.rs +837 -0
- package/data/probe/tests/ip_whitelist_test.rs +148 -0
- package/data/probe/tests/java_outline_format_tests.rs +1611 -0
- package/data/probe/tests/javascript_extract_tests.rs +315 -0
- package/data/probe/tests/javascript_outline_format_tests.rs +1464 -0
- package/data/probe/tests/json_format_tests.rs +436 -0
- package/data/probe/tests/json_schema_validation_tests.rs +450 -0
- package/data/probe/tests/lib_usage.rs +60 -0
- package/data/probe/tests/line_comment_context_extension_test.rs +459 -0
- package/data/probe/tests/line_map_cache_tests.rs +114 -0
- package/data/probe/tests/markdown_integration_tests.rs +190 -0
- package/data/probe/tests/mocks/test_ip_whitelist.go +11 -0
- package/data/probe/tests/mocks/test_object.js +27 -0
- package/data/probe/tests/mocks/test_struct.go +50 -0
- package/data/probe/tests/multi_keyword_pattern_tests.rs +464 -0
- package/data/probe/tests/multi_language_syntax_integration_tests.rs +218 -0
- package/data/probe/tests/multiple_capture_groups_tests.rs +169 -0
- package/data/probe/tests/negative_compound_word_tests.rs +246 -0
- package/data/probe/tests/nested_symbol_extraction_tests.rs +99 -0
- package/data/probe/tests/outline_cross_file_interference_test.rs +335 -0
- package/data/probe/tests/outline_keyword_preservation_test.rs +67 -0
- package/data/probe/tests/output_format_edge_cases_tests.rs +693 -0
- package/data/probe/tests/parallel_extraction_tests.rs +178 -0
- package/data/probe/tests/parallel_search_tests.rs +355 -0
- package/data/probe/tests/path_resolver_tests.rs +698 -0
- package/data/probe/tests/php_outline_format_extended_tests.rs +928 -0
- package/data/probe/tests/php_outline_format_tests.rs +768 -0
- package/data/probe/tests/property_tests.proptest-regressions +9 -0
- package/data/probe/tests/property_tests.rs +118 -0
- package/data/probe/tests/python_outline_format_tests.rs +1538 -0
- package/data/probe/tests/query_command_json_tests.rs +438 -0
- package/data/probe/tests/query_command_tests.rs +232 -0
- package/data/probe/tests/query_command_xml_tests.rs +569 -0
- package/data/probe/tests/quoted_term_with_negative_keyword_tests.rs +216 -0
- package/data/probe/tests/required_terms_filename_tests.rs +116 -0
- package/data/probe/tests/ruby_outline_format_tests.rs +1011 -0
- package/data/probe/tests/rust_line_comment_context_test.rs +151 -0
- package/data/probe/tests/rust_outline_format_enhanced_tests.rs +725 -0
- package/data/probe/tests/rust_outline_format_tests.rs +843 -0
- package/data/probe/tests/schemas/xml_output_schema.xsd +38 -0
- package/data/probe/tests/search_determinism_tests.rs +451 -0
- package/data/probe/tests/search_hints_tests.rs +253 -0
- package/data/probe/tests/special_character_escaping_tests.rs +417 -0
- package/data/probe/tests/stemming_compound_word_filtering_tests.rs +535 -0
- package/data/probe/tests/strict_elastic_syntax_tests.rs +404 -0
- package/data/probe/tests/swift_outline_format_tests.rs +3319 -0
- package/data/probe/tests/symbols_tests.rs +166 -0
- package/data/probe/tests/test_file.rs +45 -0
- package/data/probe/tests/test_tokenize.rs +28 -0
- package/data/probe/tests/timeout_tests.rs +82 -0
- package/data/probe/tests/tokenization_tests.rs +195 -0
- package/data/probe/tests/tokenized_block_filtering_tests.rs +174 -0
- package/data/probe/tests/typescript_extract_tests.rs +214 -0
- package/data/probe/tests/typescript_outline_format_tests.rs +2188 -0
- package/data/probe/tests/xml_format_tests.rs +568 -0
- package/data/probe/tests/xml_schema_validation_tests.rs +497 -0
- package/data/scripts/postinstall.mjs +9 -0
- package/data/scripts/set-version.js +0 -0
- package/data/scripts/wiki-build.sh +111 -0
- package/data/scripts/wiki-deploy.sh +73 -0
- package/data/serve.json +12 -0
- package/data/test/demo-dynamic.html +134 -0
- package/data/test/demo-esm.html +105 -0
- package/data/test/demo-iife.html +78 -0
- package/data/tsconfig.json +7 -0
- package/data/vite.server.ts +483 -0
- package/data/vitest.config.ts +40 -0
- package/data/wiki/Home.md +58 -0
- package/data/wiki/_Sidebar.md +39 -0
- package/docs-mcp.config.json +20 -0
- package/package.json +56 -0
- package/src/config.js +111 -0
- package/src/index.js +395 -0
|
@@ -0,0 +1,928 @@
|
|
|
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_php_specific_constructs() -> Result<()> {
|
|
10
|
+
let temp_dir = TempDir::new()?;
|
|
11
|
+
let test_file = temp_dir.path().join("php_constructs.php");
|
|
12
|
+
|
|
13
|
+
let content = r#"<?php
|
|
14
|
+
|
|
15
|
+
namespace App\Core;
|
|
16
|
+
|
|
17
|
+
use Countable;
|
|
18
|
+
use ArrayAccess;
|
|
19
|
+
|
|
20
|
+
trait Cacheable
|
|
21
|
+
{
|
|
22
|
+
private array $cache = [];
|
|
23
|
+
|
|
24
|
+
protected function getCacheKey(string $method, array $args): string
|
|
25
|
+
{
|
|
26
|
+
return md5($method . serialize($args));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
protected function getFromCache(string $key)
|
|
30
|
+
{
|
|
31
|
+
return $this->cache[$key] ?? null;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
protected function putInCache(string $key, $value): void
|
|
35
|
+
{
|
|
36
|
+
$this->cache[$key] = $value;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
trait Searchable
|
|
41
|
+
{
|
|
42
|
+
abstract protected function getSearchableFields(): array;
|
|
43
|
+
|
|
44
|
+
public function search(string $query): array
|
|
45
|
+
{
|
|
46
|
+
$fields = $this->getSearchableFields();
|
|
47
|
+
$results = [];
|
|
48
|
+
|
|
49
|
+
foreach ($fields as $field) {
|
|
50
|
+
if (stripos($this->$field, $query) !== false) {
|
|
51
|
+
$results[] = $field;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return $results;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
abstract class BaseModel implements Countable, ArrayAccess
|
|
60
|
+
{
|
|
61
|
+
use Cacheable, Searchable;
|
|
62
|
+
|
|
63
|
+
protected array $data = [];
|
|
64
|
+
protected array $searchableFields = [];
|
|
65
|
+
|
|
66
|
+
public function __construct(array $data = [])
|
|
67
|
+
{
|
|
68
|
+
$this->data = $data;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Magic methods
|
|
72
|
+
public function __get(string $name)
|
|
73
|
+
{
|
|
74
|
+
return $this->data[$name] ?? null;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
public function __set(string $name, $value): void
|
|
78
|
+
{
|
|
79
|
+
$this->data[$name] = $value;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
public function __isset(string $name): bool
|
|
83
|
+
{
|
|
84
|
+
return isset($this->data[$name]);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
public function __unset(string $name): void
|
|
88
|
+
{
|
|
89
|
+
unset($this->data[$name]);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
public function __toString(): string
|
|
93
|
+
{
|
|
94
|
+
return json_encode($this->data);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
public function __debugInfo(): array
|
|
98
|
+
{
|
|
99
|
+
return ['data' => $this->data, 'searchable' => $this->searchableFields];
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// ArrayAccess implementation
|
|
103
|
+
public function offsetExists($offset): bool
|
|
104
|
+
{
|
|
105
|
+
return isset($this->data[$offset]);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
public function offsetGet($offset)
|
|
109
|
+
{
|
|
110
|
+
return $this->data[$offset] ?? null;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
public function offsetSet($offset, $value): void
|
|
114
|
+
{
|
|
115
|
+
if (is_null($offset)) {
|
|
116
|
+
$this->data[] = $value;
|
|
117
|
+
} else {
|
|
118
|
+
$this->data[$offset] = $value;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
public function offsetUnset($offset): void
|
|
123
|
+
{
|
|
124
|
+
unset($this->data[$offset]);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Countable implementation
|
|
128
|
+
public function count(): int
|
|
129
|
+
{
|
|
130
|
+
return count($this->data);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Abstract methods
|
|
134
|
+
abstract protected function validate(): bool;
|
|
135
|
+
abstract public function save(): bool;
|
|
136
|
+
|
|
137
|
+
protected function getSearchableFields(): array
|
|
138
|
+
{
|
|
139
|
+
return $this->searchableFields;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
interface SearchableInterface
|
|
144
|
+
{
|
|
145
|
+
public function search(string $query): array;
|
|
146
|
+
public function getSearchableFields(): array;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
class User extends BaseModel implements SearchableInterface
|
|
150
|
+
{
|
|
151
|
+
protected array $searchableFields = ['name', 'email', 'bio'];
|
|
152
|
+
|
|
153
|
+
public function __construct(array $data = [])
|
|
154
|
+
{
|
|
155
|
+
parent::__construct($data);
|
|
156
|
+
$this->data['created_at'] = $this->data['created_at'] ?? date('Y-m-d H:i:s');
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
protected function validate(): bool
|
|
160
|
+
{
|
|
161
|
+
return !empty($this->data['name']) && !empty($this->data['email']);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
public function save(): bool
|
|
165
|
+
{
|
|
166
|
+
if (!$this->validate()) {
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Save logic here
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
public function getSearchableFields(): array
|
|
175
|
+
{
|
|
176
|
+
return $this->searchableFields;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
"#;
|
|
180
|
+
|
|
181
|
+
fs::write(&test_file, content)?;
|
|
182
|
+
|
|
183
|
+
let ctx = TestContext::new();
|
|
184
|
+
let output = ctx.run_probe(&[
|
|
185
|
+
"search",
|
|
186
|
+
"class|trait|interface|function",
|
|
187
|
+
test_file.to_str().unwrap(),
|
|
188
|
+
"--format",
|
|
189
|
+
"outline",
|
|
190
|
+
])?;
|
|
191
|
+
|
|
192
|
+
// Should extract PHP-specific constructs
|
|
193
|
+
assert!(
|
|
194
|
+
output.contains("trait") || output.contains("Cacheable"),
|
|
195
|
+
"Should extract traits - output: {}",
|
|
196
|
+
output
|
|
197
|
+
);
|
|
198
|
+
|
|
199
|
+
assert!(
|
|
200
|
+
output.contains("namespace") || output.contains("App\\Core"),
|
|
201
|
+
"Should show namespace - output: {}",
|
|
202
|
+
output
|
|
203
|
+
);
|
|
204
|
+
|
|
205
|
+
assert!(
|
|
206
|
+
output.contains("interface") || output.contains("SearchableInterface"),
|
|
207
|
+
"Should extract interfaces - output: {}",
|
|
208
|
+
output
|
|
209
|
+
);
|
|
210
|
+
|
|
211
|
+
assert!(
|
|
212
|
+
output.contains("abstract") || output.contains("BaseModel"),
|
|
213
|
+
"Should extract abstract classes - output: {}",
|
|
214
|
+
output
|
|
215
|
+
);
|
|
216
|
+
|
|
217
|
+
// Should show magic methods
|
|
218
|
+
assert!(
|
|
219
|
+
output.contains("__get") || output.contains("__set") || output.contains("__construct"),
|
|
220
|
+
"Should show magic methods - output: {}",
|
|
221
|
+
output
|
|
222
|
+
);
|
|
223
|
+
|
|
224
|
+
Ok(())
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
#[test]
|
|
228
|
+
fn test_php_control_flow_closing_braces() -> Result<()> {
|
|
229
|
+
let temp_dir = TempDir::new()?;
|
|
230
|
+
let test_file = temp_dir.path().join("control_flow.php");
|
|
231
|
+
|
|
232
|
+
let content = r#"<?php
|
|
233
|
+
|
|
234
|
+
class FlowController
|
|
235
|
+
{
|
|
236
|
+
public function processData(array $data): array
|
|
237
|
+
{
|
|
238
|
+
$results = [];
|
|
239
|
+
$counter = 0;
|
|
240
|
+
|
|
241
|
+
foreach ($data as $index => $item) {
|
|
242
|
+
if ($item === null) {
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
if (is_array($item)) {
|
|
247
|
+
foreach ($item as $key => $value) {
|
|
248
|
+
if (is_string($value)) {
|
|
249
|
+
$processed = strtolower($value);
|
|
250
|
+
$results[] = $processed;
|
|
251
|
+
$counter++;
|
|
252
|
+
} elseif (is_numeric($value)) {
|
|
253
|
+
$results[] = (float) $value;
|
|
254
|
+
$counter++;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
} else {
|
|
258
|
+
switch (gettype($item)) {
|
|
259
|
+
case 'string':
|
|
260
|
+
$results[] = trim($item);
|
|
261
|
+
break;
|
|
262
|
+
case 'integer':
|
|
263
|
+
case 'double':
|
|
264
|
+
$results[] = $item * 2;
|
|
265
|
+
break;
|
|
266
|
+
default:
|
|
267
|
+
$results[] = 'unknown';
|
|
268
|
+
}
|
|
269
|
+
$counter++;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// Break if we have enough results
|
|
273
|
+
if ($counter >= 100) {
|
|
274
|
+
break;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
return $results;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
public function complexLogic(array $conditions): string
|
|
282
|
+
{
|
|
283
|
+
$result = 'default';
|
|
284
|
+
|
|
285
|
+
try {
|
|
286
|
+
if (!empty($conditions)) {
|
|
287
|
+
foreach ($conditions as $condition) {
|
|
288
|
+
if ($condition['type'] === 'search') {
|
|
289
|
+
$searchTerm = $condition['value'];
|
|
290
|
+
|
|
291
|
+
if (strlen($searchTerm) > 3) {
|
|
292
|
+
$result = 'search: ' . $searchTerm;
|
|
293
|
+
} else {
|
|
294
|
+
$result = 'short_search';
|
|
295
|
+
}
|
|
296
|
+
} elseif ($condition['type'] === 'filter') {
|
|
297
|
+
$filterValue = $condition['value'];
|
|
298
|
+
|
|
299
|
+
if (is_array($filterValue)) {
|
|
300
|
+
foreach ($filterValue as $filter) {
|
|
301
|
+
if (strpos($filter, 'important') !== false) {
|
|
302
|
+
$result = 'important_filter';
|
|
303
|
+
break 2;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
} catch (Exception $e) {
|
|
311
|
+
$result = 'error: ' . $e->getMessage();
|
|
312
|
+
} finally {
|
|
313
|
+
$result .= ' [processed]';
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
return $result;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
"#;
|
|
320
|
+
|
|
321
|
+
fs::write(&test_file, content)?;
|
|
322
|
+
|
|
323
|
+
let ctx = TestContext::new();
|
|
324
|
+
let output = ctx.run_probe(&[
|
|
325
|
+
"search",
|
|
326
|
+
"class|trait|interface|function",
|
|
327
|
+
test_file.to_str().unwrap(),
|
|
328
|
+
"--format",
|
|
329
|
+
"outline",
|
|
330
|
+
])?;
|
|
331
|
+
|
|
332
|
+
// Should show control flow structures
|
|
333
|
+
assert!(
|
|
334
|
+
output.contains("foreach") || output.contains("if") || output.contains("switch"),
|
|
335
|
+
"Should show control flow structures - output: {}",
|
|
336
|
+
output
|
|
337
|
+
);
|
|
338
|
+
|
|
339
|
+
// Should have closing braces for large methods with // comments
|
|
340
|
+
assert!(
|
|
341
|
+
output.contains("//")
|
|
342
|
+
&& (output.contains("processData") || output.contains("complexLogic")),
|
|
343
|
+
"Should have closing brace comments for large methods - output: {}",
|
|
344
|
+
output
|
|
345
|
+
);
|
|
346
|
+
|
|
347
|
+
// Should show try/catch/finally
|
|
348
|
+
assert!(
|
|
349
|
+
output.contains("try") || output.contains("catch") || output.contains("finally"),
|
|
350
|
+
"Should show try/catch/finally structures - output: {}",
|
|
351
|
+
output
|
|
352
|
+
);
|
|
353
|
+
|
|
354
|
+
Ok(())
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
#[test]
|
|
358
|
+
fn test_php_test_detection() -> Result<()> {
|
|
359
|
+
let temp_dir = TempDir::new()?;
|
|
360
|
+
let test_file = temp_dir.path().join("TestCalculator.php");
|
|
361
|
+
|
|
362
|
+
let content = r#"<?php
|
|
363
|
+
|
|
364
|
+
namespace Tests\Unit;
|
|
365
|
+
|
|
366
|
+
use PHPUnit\Framework\TestCase;
|
|
367
|
+
use App\Calculator;
|
|
368
|
+
|
|
369
|
+
class CalculatorTest extends TestCase
|
|
370
|
+
{
|
|
371
|
+
private Calculator $calculator;
|
|
372
|
+
|
|
373
|
+
protected function setUp(): void
|
|
374
|
+
{
|
|
375
|
+
parent::setUp();
|
|
376
|
+
$this->calculator = new Calculator();
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
protected function tearDown(): void
|
|
380
|
+
{
|
|
381
|
+
parent::tearDown();
|
|
382
|
+
unset($this->calculator);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* @test
|
|
387
|
+
*/
|
|
388
|
+
public function it_can_add_two_numbers(): void
|
|
389
|
+
{
|
|
390
|
+
$result = $this->calculator->add(2, 3);
|
|
391
|
+
$this->assertEquals(5, $result);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* @test
|
|
396
|
+
* @dataProvider additionProvider
|
|
397
|
+
*/
|
|
398
|
+
public function it_can_add_with_data_provider(int $a, int $b, int $expected): void
|
|
399
|
+
{
|
|
400
|
+
$result = $this->calculator->add($a, $b);
|
|
401
|
+
$this->assertEquals($expected, $result);
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
public function testMultiplication(): void
|
|
405
|
+
{
|
|
406
|
+
$result = $this->calculator->multiply(4, 5);
|
|
407
|
+
$this->assertSame(20, $result);
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
public function testDivisionByZero(): void
|
|
411
|
+
{
|
|
412
|
+
$this->expectException(InvalidArgumentException::class);
|
|
413
|
+
$this->calculator->divide(10, 0);
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* @test
|
|
418
|
+
* @group integration
|
|
419
|
+
*/
|
|
420
|
+
public function it_handles_complex_calculations(): void
|
|
421
|
+
{
|
|
422
|
+
$result = $this->calculator->add(10, 5);
|
|
423
|
+
$result = $this->calculator->multiply($result, 2);
|
|
424
|
+
$result = $this->calculator->subtract($result, 5);
|
|
425
|
+
|
|
426
|
+
$this->assertEquals(25, $result);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
public function additionProvider(): array
|
|
430
|
+
{
|
|
431
|
+
return [
|
|
432
|
+
[1, 1, 2],
|
|
433
|
+
[2, 3, 5],
|
|
434
|
+
[-1, 1, 0],
|
|
435
|
+
[0, 0, 0],
|
|
436
|
+
];
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
// Simple test functions (non-PHPUnit style)
|
|
441
|
+
function testSimpleAddition(): bool
|
|
442
|
+
{
|
|
443
|
+
$calc = new Calculator();
|
|
444
|
+
return $calc->add(1, 1) === 2;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
function test_snake_case_function(): bool
|
|
448
|
+
{
|
|
449
|
+
$calc = new Calculator();
|
|
450
|
+
return $calc->subtract(5, 3) === 2;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
function validateCalculatorBehavior(): bool
|
|
454
|
+
{
|
|
455
|
+
// This is a test function but doesn't start with 'test'
|
|
456
|
+
$calc = new Calculator();
|
|
457
|
+
return $calc->multiply(2, 3) === 6;
|
|
458
|
+
}
|
|
459
|
+
"#;
|
|
460
|
+
|
|
461
|
+
fs::write(&test_file, content)?;
|
|
462
|
+
|
|
463
|
+
let ctx = TestContext::new();
|
|
464
|
+
let output = ctx.run_probe(&[
|
|
465
|
+
"extract",
|
|
466
|
+
test_file.to_str().unwrap(),
|
|
467
|
+
"--format",
|
|
468
|
+
"outline",
|
|
469
|
+
"--allow-tests",
|
|
470
|
+
])?;
|
|
471
|
+
|
|
472
|
+
// Should detect PHPUnit test class
|
|
473
|
+
assert!(
|
|
474
|
+
output.contains("CalculatorTest") || output.contains("TestCase"),
|
|
475
|
+
"Should detect PHPUnit test class - output: {}",
|
|
476
|
+
output
|
|
477
|
+
);
|
|
478
|
+
|
|
479
|
+
// Should detect test methods with @test annotation
|
|
480
|
+
assert!(
|
|
481
|
+
output.contains("it_can_add_two_numbers") || output.contains("@test"),
|
|
482
|
+
"Should detect @test annotated methods - output: {}",
|
|
483
|
+
output
|
|
484
|
+
);
|
|
485
|
+
|
|
486
|
+
// Should detect testXxx methods
|
|
487
|
+
assert!(
|
|
488
|
+
output.contains("testMultiplication") || output.contains("testDivisionByZero"),
|
|
489
|
+
"Should detect testXxx methods - output: {}",
|
|
490
|
+
output
|
|
491
|
+
);
|
|
492
|
+
|
|
493
|
+
// Should detect simple test functions
|
|
494
|
+
assert!(
|
|
495
|
+
output.contains("testSimpleAddition") || output.contains("test_snake_case_function"),
|
|
496
|
+
"Should detect simple test functions - output: {}",
|
|
497
|
+
output
|
|
498
|
+
);
|
|
499
|
+
|
|
500
|
+
Ok(())
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
#[test]
|
|
504
|
+
fn test_php_modern_features() -> Result<()> {
|
|
505
|
+
let temp_dir = TempDir::new()?;
|
|
506
|
+
let test_file = temp_dir.path().join("modern_php.php");
|
|
507
|
+
|
|
508
|
+
let content = r#"<?php
|
|
509
|
+
|
|
510
|
+
declare(strict_types=1);
|
|
511
|
+
|
|
512
|
+
namespace App\Modern;
|
|
513
|
+
|
|
514
|
+
use Closure;
|
|
515
|
+
|
|
516
|
+
// PHP 8+ Union types and named arguments
|
|
517
|
+
class ModernProcessor
|
|
518
|
+
{
|
|
519
|
+
public function __construct(
|
|
520
|
+
private readonly string $name,
|
|
521
|
+
private readonly array $config = [],
|
|
522
|
+
) {}
|
|
523
|
+
|
|
524
|
+
// Union types (PHP 8.0+)
|
|
525
|
+
public function process(string|array|null $data): int|float|null
|
|
526
|
+
{
|
|
527
|
+
return match ($data) {
|
|
528
|
+
null => null,
|
|
529
|
+
default => is_string($data) ? strlen($data) : count($data),
|
|
530
|
+
};
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
// Arrow functions (PHP 7.4+)
|
|
534
|
+
public function transformArray(array $items): array
|
|
535
|
+
{
|
|
536
|
+
return array_map(
|
|
537
|
+
fn($item) => strtoupper((string) $item),
|
|
538
|
+
array_filter($items, fn($item) => !empty($item))
|
|
539
|
+
);
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
// Nullable return type with arrow function
|
|
543
|
+
public function findFirst(array $items, callable $predicate): mixed
|
|
544
|
+
{
|
|
545
|
+
foreach ($items as $item) {
|
|
546
|
+
if ($predicate($item)) {
|
|
547
|
+
return $item;
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
return null;
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
// Match expression (PHP 8.0+) with search logic
|
|
554
|
+
public function getSearchStrategy(string $type): string
|
|
555
|
+
{
|
|
556
|
+
return match($type) {
|
|
557
|
+
'fuzzy' => 'levenshtein',
|
|
558
|
+
'exact' => 'strict_compare',
|
|
559
|
+
'partial' => 'substring_search',
|
|
560
|
+
'regex' => 'preg_match',
|
|
561
|
+
default => 'default_search',
|
|
562
|
+
};
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
// Named arguments and union types
|
|
566
|
+
public function search(
|
|
567
|
+
string|array $query,
|
|
568
|
+
array $options = [],
|
|
569
|
+
bool $caseSensitive = false,
|
|
570
|
+
int|null $limit = null
|
|
571
|
+
): array {
|
|
572
|
+
$strategy = $this->getSearchStrategy($options['strategy'] ?? 'partial');
|
|
573
|
+
|
|
574
|
+
return [
|
|
575
|
+
'query' => $query,
|
|
576
|
+
'strategy' => $strategy,
|
|
577
|
+
'case_sensitive' => $caseSensitive,
|
|
578
|
+
'limit' => $limit,
|
|
579
|
+
];
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
// Constructor property promotion (PHP 8.0+)
|
|
583
|
+
public static function create(
|
|
584
|
+
string $name,
|
|
585
|
+
array $config = [],
|
|
586
|
+
?string $searchEngine = null
|
|
587
|
+
): self {
|
|
588
|
+
return new self(
|
|
589
|
+
name: $name,
|
|
590
|
+
config: [...$config, 'search_engine' => $searchEngine]
|
|
591
|
+
);
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
// Readonly properties (PHP 8.1+)
|
|
595
|
+
public function getName(): string
|
|
596
|
+
{
|
|
597
|
+
return $this->name;
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
// First-class callable syntax (PHP 8.1+)
|
|
601
|
+
public function getTransformer(): callable
|
|
602
|
+
{
|
|
603
|
+
return $this->transformArray(...);
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
// Enum (PHP 8.1+)
|
|
608
|
+
enum SearchType: string
|
|
609
|
+
{
|
|
610
|
+
case EXACT = 'exact';
|
|
611
|
+
case FUZZY = 'fuzzy';
|
|
612
|
+
case PARTIAL = 'partial';
|
|
613
|
+
case REGEX = 'regex';
|
|
614
|
+
|
|
615
|
+
public function getDescription(): string
|
|
616
|
+
{
|
|
617
|
+
return match($this) {
|
|
618
|
+
self::EXACT => 'Exact match search',
|
|
619
|
+
self::FUZZY => 'Fuzzy search with similarity',
|
|
620
|
+
self::PARTIAL => 'Substring search',
|
|
621
|
+
self::REGEX => 'Regular expression search',
|
|
622
|
+
};
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
// Anonymous class with modern features
|
|
627
|
+
$processor = new class implements Countable {
|
|
628
|
+
private array $data = [];
|
|
629
|
+
|
|
630
|
+
public function add(mixed $item): void {
|
|
631
|
+
$this->data[] = $item;
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
public function count(): int {
|
|
635
|
+
return count($this->data);
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
public function search(string $term): array {
|
|
639
|
+
return array_filter(
|
|
640
|
+
$this->data,
|
|
641
|
+
fn($item) => str_contains(strtolower((string) $item), strtolower($term))
|
|
642
|
+
);
|
|
643
|
+
}
|
|
644
|
+
};
|
|
645
|
+
|
|
646
|
+
// Modern function with arrow function and match
|
|
647
|
+
function processSearchResults(array $results, string $format = 'json'): string
|
|
648
|
+
{
|
|
649
|
+
$processed = array_map(
|
|
650
|
+
fn($result) => is_array($result) ? $result : ['value' => $result],
|
|
651
|
+
$results
|
|
652
|
+
);
|
|
653
|
+
|
|
654
|
+
return match($format) {
|
|
655
|
+
'json' => json_encode($processed),
|
|
656
|
+
'xml' => 'XML output not implemented',
|
|
657
|
+
'csv' => implode(',', array_column($processed, 'value')),
|
|
658
|
+
default => serialize($processed),
|
|
659
|
+
};
|
|
660
|
+
}
|
|
661
|
+
"#;
|
|
662
|
+
|
|
663
|
+
fs::write(&test_file, content)?;
|
|
664
|
+
|
|
665
|
+
let ctx = TestContext::new();
|
|
666
|
+
let output = ctx.run_probe(&[
|
|
667
|
+
"search",
|
|
668
|
+
"search",
|
|
669
|
+
test_file.to_str().unwrap(),
|
|
670
|
+
"--format",
|
|
671
|
+
"outline",
|
|
672
|
+
"--max-results",
|
|
673
|
+
"20",
|
|
674
|
+
])?;
|
|
675
|
+
|
|
676
|
+
// Should contain search-related content
|
|
677
|
+
assert!(
|
|
678
|
+
output.contains("search"),
|
|
679
|
+
"Should contain 'search' keyword - output: {}",
|
|
680
|
+
output
|
|
681
|
+
);
|
|
682
|
+
|
|
683
|
+
// Should show modern PHP features
|
|
684
|
+
assert!(
|
|
685
|
+
output.contains("match") || output.contains("fn") || output.contains("enum"),
|
|
686
|
+
"Should show modern PHP features (match/arrow functions/enum) - output: {}",
|
|
687
|
+
output
|
|
688
|
+
);
|
|
689
|
+
|
|
690
|
+
// Should show union types or modern syntax
|
|
691
|
+
assert!(
|
|
692
|
+
output.contains("string|array") || output.contains("int|float") || output.contains("mixed"),
|
|
693
|
+
"Should show union types or mixed types - output: {}",
|
|
694
|
+
output
|
|
695
|
+
);
|
|
696
|
+
|
|
697
|
+
// Should show functions with search logic
|
|
698
|
+
assert!(
|
|
699
|
+
output.contains("getSearchStrategy") || output.contains("processSearchResults"),
|
|
700
|
+
"Should show functions with search logic - output: {}",
|
|
701
|
+
output
|
|
702
|
+
);
|
|
703
|
+
|
|
704
|
+
Ok(())
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
#[test]
|
|
708
|
+
fn test_php_outline_small_vs_large_functions() -> Result<()> {
|
|
709
|
+
let temp_dir = TempDir::new()?;
|
|
710
|
+
let test_file = temp_dir.path().join("function_sizes.php");
|
|
711
|
+
|
|
712
|
+
let content = r#"<?php
|
|
713
|
+
|
|
714
|
+
// Small function - should NOT get closing brace comment
|
|
715
|
+
function smallFunction(string $input): string
|
|
716
|
+
{
|
|
717
|
+
return strtoupper($input);
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
// Medium function - might get closing brace comment depending on implementation
|
|
721
|
+
function mediumFunction(array $data): array
|
|
722
|
+
{
|
|
723
|
+
$result = [];
|
|
724
|
+
foreach ($data as $key => $value) {
|
|
725
|
+
if (is_string($value)) {
|
|
726
|
+
$result[$key] = trim($value);
|
|
727
|
+
} elseif (is_numeric($value)) {
|
|
728
|
+
$result[$key] = (float) $value;
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
return $result;
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
// Large function - should get closing brace comment
|
|
735
|
+
function largeProcessingFunction(array $data): array
|
|
736
|
+
{
|
|
737
|
+
$results = [];
|
|
738
|
+
$errors = [];
|
|
739
|
+
$processed = 0;
|
|
740
|
+
|
|
741
|
+
foreach ($data as $index => $item) {
|
|
742
|
+
try {
|
|
743
|
+
if (!is_array($item)) {
|
|
744
|
+
$errors[] = "Item at index {$index} is not an array";
|
|
745
|
+
continue;
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
$processedItem = [];
|
|
749
|
+
|
|
750
|
+
foreach ($item as $key => $value) {
|
|
751
|
+
if (empty($key)) {
|
|
752
|
+
continue;
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
switch (gettype($value)) {
|
|
756
|
+
case 'string':
|
|
757
|
+
$processedItem[$key] = trim(strtolower($value));
|
|
758
|
+
break;
|
|
759
|
+
case 'integer':
|
|
760
|
+
case 'double':
|
|
761
|
+
$processedItem[$key] = round((float) $value, 2);
|
|
762
|
+
break;
|
|
763
|
+
case 'boolean':
|
|
764
|
+
$processedItem[$key] = $value ? 1 : 0;
|
|
765
|
+
break;
|
|
766
|
+
case 'array':
|
|
767
|
+
if (!empty($value)) {
|
|
768
|
+
$processedItem[$key] = array_values($value);
|
|
769
|
+
}
|
|
770
|
+
break;
|
|
771
|
+
default:
|
|
772
|
+
$processedItem[$key] = (string) $value;
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
if (!empty($processedItem)) {
|
|
777
|
+
$results[] = $processedItem;
|
|
778
|
+
$processed++;
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
} catch (Exception $e) {
|
|
782
|
+
$errors[] = "Error processing item {$index}: " . $e->getMessage();
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
return [
|
|
787
|
+
'results' => $results,
|
|
788
|
+
'errors' => $errors,
|
|
789
|
+
'processed_count' => $processed,
|
|
790
|
+
'total_count' => count($data),
|
|
791
|
+
];
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
class ProcessorClass
|
|
795
|
+
{
|
|
796
|
+
// Small method - should NOT get closing brace comment
|
|
797
|
+
public function smallMethod(): string
|
|
798
|
+
{
|
|
799
|
+
return 'small';
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
// Large method - should get closing brace comment
|
|
803
|
+
public function largeMethod(array $data): array
|
|
804
|
+
{
|
|
805
|
+
$config = [
|
|
806
|
+
'timeout' => 30,
|
|
807
|
+
'retry_count' => 3,
|
|
808
|
+
'batch_size' => 100,
|
|
809
|
+
];
|
|
810
|
+
|
|
811
|
+
$batches = array_chunk($data, $config['batch_size']);
|
|
812
|
+
$allResults = [];
|
|
813
|
+
|
|
814
|
+
foreach ($batches as $batchIndex => $batch) {
|
|
815
|
+
$batchResults = [];
|
|
816
|
+
$retryCount = 0;
|
|
817
|
+
|
|
818
|
+
while ($retryCount < $config['retry_count']) {
|
|
819
|
+
try {
|
|
820
|
+
foreach ($batch as $item) {
|
|
821
|
+
if ($this->validateItem($item)) {
|
|
822
|
+
$processed = $this->processItem($item);
|
|
823
|
+
if ($processed !== null) {
|
|
824
|
+
$batchResults[] = $processed;
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
break; // Success, exit retry loop
|
|
829
|
+
} catch (Exception $e) {
|
|
830
|
+
$retryCount++;
|
|
831
|
+
if ($retryCount >= $config['retry_count']) {
|
|
832
|
+
error_log("Failed to process batch {$batchIndex}: " . $e->getMessage());
|
|
833
|
+
} else {
|
|
834
|
+
usleep(1000 * $retryCount); // Exponential backoff
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
$allResults = array_merge($allResults, $batchResults);
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
return $allResults;
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
private function validateItem($item): bool
|
|
846
|
+
{
|
|
847
|
+
return !empty($item);
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
private function processItem($item)
|
|
851
|
+
{
|
|
852
|
+
return $item;
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
"#;
|
|
856
|
+
|
|
857
|
+
fs::write(&test_file, content)?;
|
|
858
|
+
|
|
859
|
+
let ctx = TestContext::new();
|
|
860
|
+
let output = ctx.run_probe(&[
|
|
861
|
+
"search",
|
|
862
|
+
"class|trait|interface|function",
|
|
863
|
+
test_file.to_str().unwrap(),
|
|
864
|
+
"--format",
|
|
865
|
+
"outline",
|
|
866
|
+
])?;
|
|
867
|
+
|
|
868
|
+
// Check if we found any functions at all first
|
|
869
|
+
if output.contains("No results found") {
|
|
870
|
+
// Try a different search pattern
|
|
871
|
+
let output2 = ctx.run_probe(&[
|
|
872
|
+
"search",
|
|
873
|
+
"large",
|
|
874
|
+
test_file.to_str().unwrap(),
|
|
875
|
+
"--format",
|
|
876
|
+
"outline",
|
|
877
|
+
"--max-results",
|
|
878
|
+
"20",
|
|
879
|
+
])?;
|
|
880
|
+
|
|
881
|
+
if !output2.contains("No results found") {
|
|
882
|
+
// Use output2 for verification if it has results
|
|
883
|
+
let has_large_functions = output2.contains("largeProcessingFunction")
|
|
884
|
+
|| output2.contains("largeMethod")
|
|
885
|
+
|| output2.contains("function");
|
|
886
|
+
assert!(
|
|
887
|
+
has_large_functions,
|
|
888
|
+
"Should find large functions in search results - output: {}",
|
|
889
|
+
output2
|
|
890
|
+
);
|
|
891
|
+
}
|
|
892
|
+
} else {
|
|
893
|
+
// Original logic for when we have results
|
|
894
|
+
let has_large_functions = output.contains("largeProcessingFunction")
|
|
895
|
+
|| output.contains("largeMethod")
|
|
896
|
+
|| output.contains("function");
|
|
897
|
+
assert!(
|
|
898
|
+
has_large_functions,
|
|
899
|
+
"Should find large functions in search results - output: {}",
|
|
900
|
+
output
|
|
901
|
+
);
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
// Verify small functions do NOT have closing brace comments
|
|
905
|
+
// Look for the section containing smallFunction and ensure no // comment follows
|
|
906
|
+
let small_function_present = output.contains("smallFunction");
|
|
907
|
+
if small_function_present {
|
|
908
|
+
// Get the lines around smallFunction and check no // comment immediately follows
|
|
909
|
+
let lines: Vec<&str> = output.lines().collect();
|
|
910
|
+
let small_func_line = lines.iter().position(|line| line.contains("smallFunction"));
|
|
911
|
+
|
|
912
|
+
if let Some(pos) = small_func_line {
|
|
913
|
+
// Check next few lines don't contain a closing brace comment for small function
|
|
914
|
+
let next_few_lines = lines.get(pos..pos.min(lines.len()).max(pos + 5));
|
|
915
|
+
if let Some(section) = next_few_lines {
|
|
916
|
+
let section_text = section.join("\n");
|
|
917
|
+
assert!(
|
|
918
|
+
!section_text.contains("// function smallFunction")
|
|
919
|
+
&& !section_text.contains("// smallFunction"),
|
|
920
|
+
"Small function should NOT have closing brace comment in section: {}",
|
|
921
|
+
section_text
|
|
922
|
+
);
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
Ok(())
|
|
928
|
+
}
|