@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,166 @@
|
|
|
1
|
+
use probe_code::search::{perform_probe, SearchOptions};
|
|
2
|
+
use std::fs;
|
|
3
|
+
use tempfile::tempdir;
|
|
4
|
+
|
|
5
|
+
#[test]
|
|
6
|
+
fn test_symbols_flag_with_rust_code() {
|
|
7
|
+
// Create a temporary directory and file
|
|
8
|
+
let temp_dir = tempdir().expect("Failed to create temp dir");
|
|
9
|
+
let test_file = temp_dir.path().join("test.rs");
|
|
10
|
+
|
|
11
|
+
// Write Rust code with various symbols
|
|
12
|
+
let rust_code = r#"
|
|
13
|
+
pub struct User {
|
|
14
|
+
pub name: String,
|
|
15
|
+
pub age: u32,
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
impl User {
|
|
19
|
+
pub fn new(name: String, age: u32) -> Self {
|
|
20
|
+
Self { name, age }
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
pub fn greet(&self) -> String {
|
|
24
|
+
format!("Hello, I'm {}", self.name)
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
pub fn main() {
|
|
29
|
+
let user = User::new("Alice".to_string(), 30);
|
|
30
|
+
println!("{}", user.greet());
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
pub const MAX_USERS: usize = 1000;
|
|
34
|
+
"#;
|
|
35
|
+
|
|
36
|
+
fs::write(&test_file, rust_code).expect("Failed to write test file");
|
|
37
|
+
|
|
38
|
+
// Test search with symbols flag enabled
|
|
39
|
+
let options = SearchOptions {
|
|
40
|
+
path: temp_dir.path(),
|
|
41
|
+
queries: &["pub fn".to_string()],
|
|
42
|
+
files_only: false,
|
|
43
|
+
custom_ignores: &[],
|
|
44
|
+
exclude_filenames: false,
|
|
45
|
+
reranker: "bm25",
|
|
46
|
+
frequency_search: true,
|
|
47
|
+
exact: false,
|
|
48
|
+
language: None,
|
|
49
|
+
max_results: Some(10),
|
|
50
|
+
max_bytes: None,
|
|
51
|
+
max_tokens: None,
|
|
52
|
+
allow_tests: false,
|
|
53
|
+
no_merge: false,
|
|
54
|
+
merge_threshold: None,
|
|
55
|
+
dry_run: false,
|
|
56
|
+
session: None,
|
|
57
|
+
timeout: 30,
|
|
58
|
+
question: None,
|
|
59
|
+
no_gitignore: true,
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
let results = perform_probe(&options).expect("Search should succeed");
|
|
63
|
+
|
|
64
|
+
// Verify we got results
|
|
65
|
+
assert!(!results.results.is_empty(), "Should find symbol matches");
|
|
66
|
+
|
|
67
|
+
// Verify that symbol signatures are populated
|
|
68
|
+
let has_symbol_signatures = results.results.iter().any(|r| r.symbol_signature.is_some());
|
|
69
|
+
assert!(
|
|
70
|
+
has_symbol_signatures,
|
|
71
|
+
"At least one result should have a symbol signature"
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
// Test with symbols flag disabled
|
|
75
|
+
let options_no_symbols = SearchOptions { ..options };
|
|
76
|
+
|
|
77
|
+
let results_no_symbols = perform_probe(&options_no_symbols).expect("Search should succeed");
|
|
78
|
+
|
|
79
|
+
// Verify that symbol signatures are not populated when flag is disabled
|
|
80
|
+
let has_symbol_signatures = results_no_symbols
|
|
81
|
+
.results
|
|
82
|
+
.iter()
|
|
83
|
+
.any(|r| r.symbol_signature.is_some());
|
|
84
|
+
assert!(
|
|
85
|
+
!has_symbol_signatures,
|
|
86
|
+
"No results should have symbol signatures when flag is disabled"
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
#[test]
|
|
91
|
+
fn test_symbols_flag_with_python_code() {
|
|
92
|
+
// Create a temporary directory and file
|
|
93
|
+
let temp_dir = tempdir().expect("Failed to create temp dir");
|
|
94
|
+
let test_file = temp_dir.path().join("test.py");
|
|
95
|
+
|
|
96
|
+
// Write Python code with various symbols
|
|
97
|
+
let python_code = r#"
|
|
98
|
+
class User:
|
|
99
|
+
def __init__(self, name: str, age: int):
|
|
100
|
+
self.name = name
|
|
101
|
+
self.age = age
|
|
102
|
+
|
|
103
|
+
def greet(self) -> str:
|
|
104
|
+
return f"Hello, I'm {self.name}"
|
|
105
|
+
|
|
106
|
+
def create_user(name: str, age: int) -> User:
|
|
107
|
+
return User(name, age)
|
|
108
|
+
|
|
109
|
+
async def async_function(data: list) -> dict:
|
|
110
|
+
return {"length": len(data)}
|
|
111
|
+
|
|
112
|
+
MAX_USERS = 1000
|
|
113
|
+
"#;
|
|
114
|
+
|
|
115
|
+
fs::write(&test_file, python_code).expect("Failed to write test file");
|
|
116
|
+
|
|
117
|
+
// Test search with symbols flag enabled
|
|
118
|
+
let options = SearchOptions {
|
|
119
|
+
path: temp_dir.path(),
|
|
120
|
+
queries: &["def ".to_string()],
|
|
121
|
+
files_only: false,
|
|
122
|
+
custom_ignores: &[],
|
|
123
|
+
exclude_filenames: false,
|
|
124
|
+
reranker: "bm25",
|
|
125
|
+
frequency_search: true,
|
|
126
|
+
exact: false,
|
|
127
|
+
language: None,
|
|
128
|
+
max_results: Some(10),
|
|
129
|
+
max_bytes: None,
|
|
130
|
+
max_tokens: None,
|
|
131
|
+
allow_tests: false,
|
|
132
|
+
no_merge: false,
|
|
133
|
+
merge_threshold: None,
|
|
134
|
+
dry_run: false,
|
|
135
|
+
session: None,
|
|
136
|
+
timeout: 30,
|
|
137
|
+
question: None,
|
|
138
|
+
no_gitignore: true,
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
let results = perform_probe(&options).expect("Search should succeed");
|
|
142
|
+
|
|
143
|
+
// Verify we got results
|
|
144
|
+
assert!(!results.results.is_empty(), "Should find symbol matches");
|
|
145
|
+
|
|
146
|
+
// Verify that symbol signatures are populated and contain Python syntax
|
|
147
|
+
let python_symbols: Vec<_> = results
|
|
148
|
+
.results
|
|
149
|
+
.iter()
|
|
150
|
+
.filter_map(|r| r.symbol_signature.as_ref())
|
|
151
|
+
.collect();
|
|
152
|
+
|
|
153
|
+
assert!(
|
|
154
|
+
!python_symbols.is_empty(),
|
|
155
|
+
"Should have Python symbol signatures"
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
// Check that we have recognizable Python function signatures
|
|
159
|
+
let has_python_function = python_symbols
|
|
160
|
+
.iter()
|
|
161
|
+
.any(|sig| sig.contains("def ") && sig.contains("(") && sig.contains(")"));
|
|
162
|
+
assert!(
|
|
163
|
+
has_python_function,
|
|
164
|
+
"Should have Python function signatures"
|
|
165
|
+
);
|
|
166
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// This is a test file for probe
|
|
2
|
+
|
|
3
|
+
#[allow(dead_code)]
|
|
4
|
+
fn function1() {
|
|
5
|
+
println!("This is function 1");
|
|
6
|
+
// Some code here
|
|
7
|
+
let x = 10;
|
|
8
|
+
let y = 20;
|
|
9
|
+
println!("Sum: {}", x + y);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// This comment is between function1 and function2
|
|
13
|
+
// Only a few lines of separation
|
|
14
|
+
|
|
15
|
+
#[allow(dead_code)]
|
|
16
|
+
fn function2() {
|
|
17
|
+
println!("This is function 2");
|
|
18
|
+
// Some code here
|
|
19
|
+
let a = 30;
|
|
20
|
+
let b = 40;
|
|
21
|
+
println!("Product: {}", a * b);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// This is a larger gap between functions
|
|
25
|
+
|
|
26
|
+
// More comments
|
|
27
|
+
// More comments
|
|
28
|
+
// More comments
|
|
29
|
+
// More comments
|
|
30
|
+
// More comments
|
|
31
|
+
// More comments
|
|
32
|
+
// More comments
|
|
33
|
+
// More comments
|
|
34
|
+
// More comments
|
|
35
|
+
// More comments
|
|
36
|
+
// More comments
|
|
37
|
+
|
|
38
|
+
#[allow(dead_code)]
|
|
39
|
+
fn function3() {
|
|
40
|
+
println!("This is function 3");
|
|
41
|
+
// Some code here
|
|
42
|
+
let c = 50;
|
|
43
|
+
let d = 60;
|
|
44
|
+
println!("Difference: {}", d - c);
|
|
45
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
fn main() {
|
|
2
|
+
// Import the tokenize function from our probe crate
|
|
3
|
+
use probe_code::ranking::tokenize;
|
|
4
|
+
|
|
5
|
+
// Test strings
|
|
6
|
+
let test_strings = ["The quick brown fox jumps over the lazy dog",
|
|
7
|
+
"function calculateTotal(items) { return items.reduce((sum, item) => sum + item.price, 0); }",
|
|
8
|
+
"class UserController extends BaseController implements UserInterface",
|
|
9
|
+
"Searching for files containing important information",
|
|
10
|
+
"Fruitlessly searching for the missing variable in the codebase"];
|
|
11
|
+
|
|
12
|
+
println!("Testing tokenization with stop word removal and stemming:\n");
|
|
13
|
+
|
|
14
|
+
for (i, test_str) in test_strings.iter().enumerate() {
|
|
15
|
+
println!("Original text {}:\n{}", i + 1, test_str);
|
|
16
|
+
|
|
17
|
+
// Tokenize with stop word removal and stemming
|
|
18
|
+
let tokens = tokenize(test_str);
|
|
19
|
+
|
|
20
|
+
println!("Tokens after stop word removal and stemming:");
|
|
21
|
+
println!("{tokens:?}");
|
|
22
|
+
println!("Number of tokens: {}\n", tokens.len());
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Specific test for stemming
|
|
26
|
+
println!("Specific stemming test:");
|
|
27
|
+
println!("'fruitlessly' stems to: {}", tokenize("fruitlessly")[0]);
|
|
28
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
use std::path::Path;
|
|
2
|
+
use std::process::Command;
|
|
3
|
+
use std::time::Instant;
|
|
4
|
+
use tempfile::TempDir;
|
|
5
|
+
|
|
6
|
+
/// Create a large test file that will take time to process
|
|
7
|
+
fn create_large_test_file(temp_dir: &Path) {
|
|
8
|
+
let file_path = temp_dir.join("large_file.rs");
|
|
9
|
+
|
|
10
|
+
// Create a very large file with many lines to ensure the search takes longer than the timeout
|
|
11
|
+
let mut content = String::new();
|
|
12
|
+
for i in 0..500000 {
|
|
13
|
+
// Increased to 500,000 lines
|
|
14
|
+
content.push_str(&format!("// Line {i} with searchable content\n"));
|
|
15
|
+
content.push_str(&format!("fn function_{i}() {{\n"));
|
|
16
|
+
content.push_str(&format!(" let search_term = {i};\n"));
|
|
17
|
+
content.push_str(" println!(\"Found: {}\", search_term);\n");
|
|
18
|
+
content.push_str("}\n\n");
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Write the file
|
|
22
|
+
std::fs::write(file_path, content).expect("Failed to write large test file");
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/// Test that the search operation times out after the specified timeout
|
|
26
|
+
/// This test runs the search command in a separate process since our timeout
|
|
27
|
+
/// implementation calls std::process::exit(1)
|
|
28
|
+
#[test]
|
|
29
|
+
fn test_search_timeout() {
|
|
30
|
+
// Create a temporary directory
|
|
31
|
+
let temp_dir = TempDir::new().expect("Failed to create temp dir");
|
|
32
|
+
|
|
33
|
+
// Create a large test file
|
|
34
|
+
create_large_test_file(temp_dir.path());
|
|
35
|
+
|
|
36
|
+
// Measure the time it takes to run the search
|
|
37
|
+
let start_time = Instant::now();
|
|
38
|
+
|
|
39
|
+
// Run the search command with a very short timeout using cargo run
|
|
40
|
+
let output = Command::new("cargo")
|
|
41
|
+
.arg("run")
|
|
42
|
+
.arg("--")
|
|
43
|
+
.arg("search")
|
|
44
|
+
.arg("search_term") // This term appears in every function
|
|
45
|
+
.arg("/")
|
|
46
|
+
.arg("--timeout")
|
|
47
|
+
.arg("1") // 1 second timeout should be short enough to trigger
|
|
48
|
+
.output()
|
|
49
|
+
.expect("Failed to execute command");
|
|
50
|
+
|
|
51
|
+
// Check how long it took
|
|
52
|
+
let elapsed = start_time.elapsed();
|
|
53
|
+
|
|
54
|
+
// Print the output for debugging
|
|
55
|
+
println!(
|
|
56
|
+
"Command output: {}",
|
|
57
|
+
String::from_utf8_lossy(&output.stdout)
|
|
58
|
+
);
|
|
59
|
+
println!("Command error: {}", String::from_utf8_lossy(&output.stderr));
|
|
60
|
+
|
|
61
|
+
// The command should have failed (non-zero exit code)
|
|
62
|
+
assert_ne!(
|
|
63
|
+
output.status.code().unwrap_or(-1),
|
|
64
|
+
0,
|
|
65
|
+
"Command should have failed with a non-zero exit code"
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
// The error output should mention timeout
|
|
69
|
+
let stderr = String::from_utf8_lossy(&output.stderr);
|
|
70
|
+
assert!(
|
|
71
|
+
stderr.contains("timeout") || stderr.contains("timed out"),
|
|
72
|
+
"Error output should mention timeout: {stderr}"
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
// The elapsed time should be close to the timeout value
|
|
76
|
+
assert!(
|
|
77
|
+
elapsed.as_secs() >= 1 && elapsed.as_secs() <= 5,
|
|
78
|
+
"Search should have timed out after about 1 second, but took {elapsed:?}"
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
println!("✓ Search timed out correctly after {elapsed:?}");
|
|
82
|
+
}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
use probe_code::search::elastic_query::parse_query_test as parse_query;
|
|
2
|
+
|
|
3
|
+
use probe_code::search::query::{create_query_plan, create_structured_patterns};
|
|
4
|
+
use probe_code::search::tokenization::{load_vocabulary, split_camel_case, split_compound_word};
|
|
5
|
+
|
|
6
|
+
#[test]
|
|
7
|
+
fn test_camel_case_splitting() {
|
|
8
|
+
// Test camelCase splitting with "RPCStorageHandler"
|
|
9
|
+
let input = "RPCStorageHandler";
|
|
10
|
+
let camel_parts = split_camel_case(input);
|
|
11
|
+
|
|
12
|
+
println!("Direct camelCase split of '{input}': {camel_parts:?}");
|
|
13
|
+
|
|
14
|
+
// We expect "RPCStorageHandler" to be split into ["rpc", "storage", "handler"]
|
|
15
|
+
assert!(camel_parts.contains(&"rpc".to_string()));
|
|
16
|
+
assert!(camel_parts.contains(&"storage".to_string()));
|
|
17
|
+
assert!(camel_parts.contains(&"handler".to_string()));
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
#[test]
|
|
21
|
+
fn test_compound_word_splitting() {
|
|
22
|
+
// Test compound word splitting with "whitelist"
|
|
23
|
+
let vocab = load_vocabulary();
|
|
24
|
+
let mut enhanced_vocab = vocab.clone();
|
|
25
|
+
|
|
26
|
+
// Add specific programming terms to the vocabulary
|
|
27
|
+
for term in [
|
|
28
|
+
"rpc", "storage", "handler", "client", "server", "api", "service", "http", "handler",
|
|
29
|
+
] {
|
|
30
|
+
enhanced_vocab.insert(term.to_string());
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
let input = "httpHandler";
|
|
34
|
+
let compound_parts = split_compound_word(input, &enhanced_vocab);
|
|
35
|
+
|
|
36
|
+
println!("Compound split of '{input}': {compound_parts:?}");
|
|
37
|
+
|
|
38
|
+
assert!(compound_parts.contains(&"http".to_string()));
|
|
39
|
+
assert!(compound_parts.contains(&"Handler".to_string()));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
#[test]
|
|
43
|
+
fn test_query_preprocessing() {
|
|
44
|
+
// Test query preprocessing with "RPCStorageHandler"
|
|
45
|
+
let query = "RPCStorageHandler";
|
|
46
|
+
let plan = create_query_plan(query, false).expect("Failed to create query plan");
|
|
47
|
+
|
|
48
|
+
println!("Query plan for '{query}': {plan:?}");
|
|
49
|
+
|
|
50
|
+
// Check if the term_indices include the expected parts
|
|
51
|
+
let term_strings: Vec<String> = plan.term_indices.keys().cloned().collect();
|
|
52
|
+
|
|
53
|
+
// We expect to see "rpc", "storage", "handler" in the terms
|
|
54
|
+
assert!(
|
|
55
|
+
term_strings.contains(&"rpc".to_string())
|
|
56
|
+
|| term_strings.contains(&"storage".to_string())
|
|
57
|
+
|| term_strings.contains(&"handler".to_string()),
|
|
58
|
+
"Expected at least one of 'rpc', 'storage', or 'handler' in {term_strings:?}"
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
#[test]
|
|
63
|
+
fn test_pattern_generation() {
|
|
64
|
+
// Test pattern generation with "RPCStorageHandler"
|
|
65
|
+
let query = "RPCStorageHandler";
|
|
66
|
+
let plan = create_query_plan(query, false).expect("Failed to create query plan");
|
|
67
|
+
let patterns = create_structured_patterns(&plan);
|
|
68
|
+
|
|
69
|
+
println!("Generated patterns:");
|
|
70
|
+
for (i, (pattern, indices)) in patterns.iter().enumerate() {
|
|
71
|
+
println!("Pattern {i}: {pattern} - Indices: {indices:?}");
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Check that we have patterns for the expected terms
|
|
75
|
+
let term_indices = &plan.term_indices;
|
|
76
|
+
|
|
77
|
+
// Verify that each term in the plan has at least one pattern
|
|
78
|
+
for (term, &idx) in term_indices {
|
|
79
|
+
if !plan.excluded_terms.contains(term) {
|
|
80
|
+
let has_pattern = patterns.iter().any(|(_, indices)| indices.contains(&idx));
|
|
81
|
+
assert!(
|
|
82
|
+
has_pattern,
|
|
83
|
+
"No pattern found for term '{term}' at index {idx}"
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Check that all patterns are valid regexes
|
|
89
|
+
for (pattern, _) in &patterns {
|
|
90
|
+
assert!(
|
|
91
|
+
regex::Regex::new(pattern).is_ok(),
|
|
92
|
+
"Invalid regex pattern: {pattern}"
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
#[test]
|
|
98
|
+
fn test_multiple_word_query() {
|
|
99
|
+
// Test multiple words with "ip whitelist"
|
|
100
|
+
let query = "ip whitelist";
|
|
101
|
+
let plan = create_query_plan(query, false).expect("Failed to create query plan");
|
|
102
|
+
|
|
103
|
+
println!("Query plan for '{query}': {plan:?}");
|
|
104
|
+
|
|
105
|
+
// Check if the terms include the expected parts
|
|
106
|
+
let term_strings: Vec<String> = plan.term_indices.keys().cloned().collect();
|
|
107
|
+
|
|
108
|
+
// We expect to see "ip", "white", "list" in the terms
|
|
109
|
+
assert!(term_strings.contains(&"ip".to_string()));
|
|
110
|
+
|
|
111
|
+
// Either "white" and "list" separately, or "whitelist" as a whole
|
|
112
|
+
let has_white_and_list =
|
|
113
|
+
term_strings.contains(&"white".to_string()) && term_strings.contains(&"list".to_string());
|
|
114
|
+
let has_whitelist = term_strings.contains(&"whitelist".to_string());
|
|
115
|
+
|
|
116
|
+
assert!(
|
|
117
|
+
has_white_and_list || has_whitelist,
|
|
118
|
+
"Expected either both 'white' and 'list', or 'whitelist' in {term_strings:?}"
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
#[test]
|
|
123
|
+
fn test_underscore_handling() {
|
|
124
|
+
use probe_code::search::elastic_query;
|
|
125
|
+
|
|
126
|
+
// Test tokenization with underscores
|
|
127
|
+
let query = "keyword_underscore";
|
|
128
|
+
let plan = create_query_plan(query, false).expect("Failed to create query plan");
|
|
129
|
+
|
|
130
|
+
println!("Query plan for '{query}': {plan:?}");
|
|
131
|
+
|
|
132
|
+
// Check if the term is preserved with the underscore in the term_indices
|
|
133
|
+
let term_strings: Vec<String> = plan.term_indices.keys().cloned().collect();
|
|
134
|
+
|
|
135
|
+
// We expect to see "keyword_underscore" or its tokenized parts
|
|
136
|
+
let has_tokenized_parts = term_strings.contains(&"key".to_string())
|
|
137
|
+
|| term_strings.contains(&"word".to_string())
|
|
138
|
+
|| term_strings.contains(&"score".to_string());
|
|
139
|
+
|
|
140
|
+
assert!(
|
|
141
|
+
has_tokenized_parts,
|
|
142
|
+
"Expected tokenized parts of 'keyword_underscore' in {term_strings:?}"
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
// Check if the term is properly tokenized in the elastic query parser
|
|
146
|
+
// This is already done in the create_query_plan function, but we'll verify the AST
|
|
147
|
+
if let elastic_query::Expr::Term { keywords, .. } = &plan.ast {
|
|
148
|
+
// The term should be tokenized into ["key", "word", "under", "score"]
|
|
149
|
+
// Note: "under" might be filtered out as a stop word
|
|
150
|
+
assert!(
|
|
151
|
+
keywords.contains(&"key".to_string()),
|
|
152
|
+
"Expected 'key' in keywords: {keywords:?}"
|
|
153
|
+
);
|
|
154
|
+
assert!(
|
|
155
|
+
keywords.contains(&"word".to_string()),
|
|
156
|
+
"Expected 'word' in keywords: {keywords:?}"
|
|
157
|
+
);
|
|
158
|
+
assert!(
|
|
159
|
+
keywords.contains(&"score".to_string()),
|
|
160
|
+
"Expected 'score' in keywords: {keywords:?}"
|
|
161
|
+
);
|
|
162
|
+
} else {
|
|
163
|
+
panic!("Expected Term expression");
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
#[test]
|
|
168
|
+
fn test_underscore_in_elastic_query() {
|
|
169
|
+
use probe_code::search::elastic_query;
|
|
170
|
+
|
|
171
|
+
// Test that the elastic query parser preserves underscores
|
|
172
|
+
let query = "keyword_underscore";
|
|
173
|
+
// Use parse_query with standard Elasticsearch behavior (AND for implicit combinations)
|
|
174
|
+
let ast = parse_query(query).unwrap();
|
|
175
|
+
|
|
176
|
+
// Check that the AST contains the tokenized terms from "keyword_underscore"
|
|
177
|
+
if let elastic_query::Expr::Term { keywords, .. } = ast {
|
|
178
|
+
// The term should be tokenized into ["key", "word", "under", "score"]
|
|
179
|
+
// Note: "under" might be filtered out as a stop word
|
|
180
|
+
assert!(
|
|
181
|
+
keywords.contains(&"key".to_string()),
|
|
182
|
+
"Expected 'key' in keywords: {keywords:?}"
|
|
183
|
+
);
|
|
184
|
+
assert!(
|
|
185
|
+
keywords.contains(&"word".to_string()),
|
|
186
|
+
"Expected 'word' in keywords: {keywords:?}"
|
|
187
|
+
);
|
|
188
|
+
assert!(
|
|
189
|
+
keywords.contains(&"score".to_string()),
|
|
190
|
+
"Expected 'score' in keywords: {keywords:?}"
|
|
191
|
+
);
|
|
192
|
+
} else {
|
|
193
|
+
panic!("Expected Term expression");
|
|
194
|
+
}
|
|
195
|
+
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
use probe_code::search::file_processing::filter_tokenized_block;
|
|
2
|
+
use probe_code::search::query::create_query_plan;
|
|
3
|
+
use std::collections::{HashMap, HashSet};
|
|
4
|
+
|
|
5
|
+
/// Test direct usage of filter_tokenized_block with various complex queries
|
|
6
|
+
#[test]
|
|
7
|
+
fn test_filter_tokenized_block_basic() {
|
|
8
|
+
// Create a simple tokenized content
|
|
9
|
+
let tokenized_content = vec![
|
|
10
|
+
"ip".to_string(),
|
|
11
|
+
"whitelist".to_string(),
|
|
12
|
+
"config".to_string(),
|
|
13
|
+
];
|
|
14
|
+
|
|
15
|
+
// Test with a simple AND query
|
|
16
|
+
let query = "ip AND whitelist";
|
|
17
|
+
let plan = create_query_plan(query, false).unwrap();
|
|
18
|
+
|
|
19
|
+
// Test filtering
|
|
20
|
+
let result = filter_tokenized_block(&tokenized_content, &plan.term_indices, &plan, true);
|
|
21
|
+
assert!(
|
|
22
|
+
result,
|
|
23
|
+
"Block with 'ip' and 'whitelist' should match the AND query"
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
// Test with a simple OR query
|
|
27
|
+
let query = "ip OR port";
|
|
28
|
+
let plan = create_query_plan(query, false).unwrap();
|
|
29
|
+
|
|
30
|
+
// Test filtering
|
|
31
|
+
let result = filter_tokenized_block(&tokenized_content, &plan.term_indices, &plan, true);
|
|
32
|
+
assert!(
|
|
33
|
+
result,
|
|
34
|
+
"Block with 'ip' should match the OR query even without 'port'"
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
// Test with a more complex query
|
|
38
|
+
let query = "(ip OR port) AND config";
|
|
39
|
+
let plan = create_query_plan(query, false).unwrap();
|
|
40
|
+
|
|
41
|
+
// Test filtering
|
|
42
|
+
let result = filter_tokenized_block(&tokenized_content, &plan.term_indices, &plan, true);
|
|
43
|
+
assert!(
|
|
44
|
+
result,
|
|
45
|
+
"Block with 'ip' and 'config' should match the complex query"
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
#[test]
|
|
50
|
+
fn test_filter_tokenized_block_with_excluded_terms() {
|
|
51
|
+
// Create a tokenized content with some terms
|
|
52
|
+
let tokenized_content = vec![
|
|
53
|
+
"ip".to_string(),
|
|
54
|
+
"whitelist".to_string(),
|
|
55
|
+
"config".to_string(),
|
|
56
|
+
];
|
|
57
|
+
|
|
58
|
+
// Test with a query that has excluded terms
|
|
59
|
+
let query = "ip -test";
|
|
60
|
+
let plan = create_query_plan(query, false).unwrap();
|
|
61
|
+
|
|
62
|
+
// Test filtering
|
|
63
|
+
let result = filter_tokenized_block(&tokenized_content, &plan.term_indices, &plan, true);
|
|
64
|
+
assert!(result, "Block with 'ip' but without 'test' should match");
|
|
65
|
+
|
|
66
|
+
// Create a tokenized content with the excluded term
|
|
67
|
+
let tokenized_content_with_excluded = vec![
|
|
68
|
+
"ip".to_string(),
|
|
69
|
+
"whitelist".to_string(),
|
|
70
|
+
"test".to_string(),
|
|
71
|
+
];
|
|
72
|
+
|
|
73
|
+
// Test filtering with the excluded term present
|
|
74
|
+
let result = filter_tokenized_block(
|
|
75
|
+
&tokenized_content_with_excluded,
|
|
76
|
+
&plan.term_indices,
|
|
77
|
+
&plan,
|
|
78
|
+
true,
|
|
79
|
+
);
|
|
80
|
+
assert!(
|
|
81
|
+
!result,
|
|
82
|
+
"Block with 'ip' and 'test' should NOT match because 'test' is excluded"
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
#[test]
|
|
87
|
+
fn test_filter_tokenized_block_with_complex_queries() {
|
|
88
|
+
// Create a tokenized content
|
|
89
|
+
let tokenized_content = vec![
|
|
90
|
+
"ip".to_string(),
|
|
91
|
+
"whitelist".to_string(),
|
|
92
|
+
"config".to_string(),
|
|
93
|
+
"server".to_string(),
|
|
94
|
+
];
|
|
95
|
+
|
|
96
|
+
// Test with a complex query with AND, OR, and excluded terms
|
|
97
|
+
let query = "(ip OR port) AND (whitelist OR config) -test";
|
|
98
|
+
let plan = create_query_plan(query, false).unwrap();
|
|
99
|
+
|
|
100
|
+
// Test filtering
|
|
101
|
+
let result = filter_tokenized_block(&tokenized_content, &plan.term_indices, &plan, true);
|
|
102
|
+
assert!(
|
|
103
|
+
result,
|
|
104
|
+
"Block with 'ip', 'whitelist', and 'config' but without 'test' should match"
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
// Test with a different tokenized content that doesn't match
|
|
108
|
+
let tokenized_content_missing_required = vec!["port".to_string(), "server".to_string()];
|
|
109
|
+
|
|
110
|
+
// Test filtering
|
|
111
|
+
let result = filter_tokenized_block(
|
|
112
|
+
&tokenized_content_missing_required,
|
|
113
|
+
&plan.term_indices,
|
|
114
|
+
&plan,
|
|
115
|
+
true,
|
|
116
|
+
);
|
|
117
|
+
assert!(
|
|
118
|
+
!result,
|
|
119
|
+
"Block with only 'port' and 'server' should NOT match because it's missing 'whitelist' or 'config'"
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
#[test]
|
|
124
|
+
fn test_filter_tokenized_block_empty_content() {
|
|
125
|
+
// Create an empty tokenized content
|
|
126
|
+
let tokenized_content: Vec<String> = vec![];
|
|
127
|
+
|
|
128
|
+
// Test with a simple query
|
|
129
|
+
let query = "ip AND whitelist";
|
|
130
|
+
let plan = create_query_plan(query, false).unwrap();
|
|
131
|
+
|
|
132
|
+
// Test filtering
|
|
133
|
+
let result = filter_tokenized_block(&tokenized_content, &plan.term_indices, &plan, true);
|
|
134
|
+
assert!(!result, "Empty block should not match any query");
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
#[test]
|
|
138
|
+
fn test_filter_tokenized_block_comparison_with_line_based() {
|
|
139
|
+
// This test compares the behavior of filter_tokenized_block with filter_code_block_with_ast
|
|
140
|
+
// to ensure they produce the same results for equivalent inputs
|
|
141
|
+
|
|
142
|
+
// Create a tokenized content
|
|
143
|
+
let tokenized_content = vec![
|
|
144
|
+
"ip".to_string(),
|
|
145
|
+
"whitelist".to_string(),
|
|
146
|
+
"config".to_string(),
|
|
147
|
+
];
|
|
148
|
+
|
|
149
|
+
// Create a query
|
|
150
|
+
let query = "ip AND whitelist";
|
|
151
|
+
let plan = create_query_plan(query, false).unwrap();
|
|
152
|
+
|
|
153
|
+
// Test tokenized filtering
|
|
154
|
+
let tokenized_result =
|
|
155
|
+
filter_tokenized_block(&tokenized_content, &plan.term_indices, &plan, true);
|
|
156
|
+
|
|
157
|
+
// Import the line-based filtering function for comparison
|
|
158
|
+
use probe_code::search::file_processing::filter_code_block_with_ast;
|
|
159
|
+
|
|
160
|
+
// Create equivalent line-based term matches
|
|
161
|
+
let mut term_matches = HashMap::new();
|
|
162
|
+
term_matches.insert(0, HashSet::from([1])); // ip on line 1
|
|
163
|
+
term_matches.insert(1, HashSet::from([1])); // whitelist on line 1
|
|
164
|
+
term_matches.insert(2, HashSet::from([1])); // config on line 1
|
|
165
|
+
|
|
166
|
+
// Test line-based filtering
|
|
167
|
+
let line_based_result = filter_code_block_with_ast((1, 1), &term_matches, &plan, true);
|
|
168
|
+
|
|
169
|
+
// Compare results
|
|
170
|
+
assert_eq!(
|
|
171
|
+
tokenized_result, line_based_result,
|
|
172
|
+
"Tokenized filtering and line-based filtering should produce the same result"
|
|
173
|
+
);
|
|
174
|
+
}
|