@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,669 @@
|
|
|
1
|
+
use lru::LruCache;
|
|
2
|
+
use probe_code::search::elastic_query::{self, parse_query_test as parse_query};
|
|
3
|
+
use probe_code::search::file_processing::filter_code_block_with_ast;
|
|
4
|
+
use probe_code::search::query::create_query_plan;
|
|
5
|
+
use std::collections::{HashMap, HashSet};
|
|
6
|
+
use std::num::NonZeroUsize;
|
|
7
|
+
use std::sync::{Arc, Mutex};
|
|
8
|
+
|
|
9
|
+
/// Test direct usage of filter_code_block_with_ast with various complex queries
|
|
10
|
+
#[test]
|
|
11
|
+
fn test_filter_code_block_with_complex_ast() {
|
|
12
|
+
// Enable debug mode
|
|
13
|
+
std::env::set_var("DEBUG", "1");
|
|
14
|
+
|
|
15
|
+
// Test case 1: Simple AND query
|
|
16
|
+
test_simple_and_query();
|
|
17
|
+
|
|
18
|
+
// Test case 2: Simple OR query
|
|
19
|
+
test_simple_or_query();
|
|
20
|
+
|
|
21
|
+
// Test case 3: Complex query with AND, OR, and negation
|
|
22
|
+
test_complex_query_with_negation();
|
|
23
|
+
|
|
24
|
+
// Test case 4: Query with all required terms
|
|
25
|
+
test_required_terms_query();
|
|
26
|
+
|
|
27
|
+
// Test case 5: Query with nested expressions
|
|
28
|
+
test_nested_expressions_query();
|
|
29
|
+
|
|
30
|
+
// Reset debug mode
|
|
31
|
+
std::env::remove_var("DEBUG");
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/// Test a simple AND query: "ip AND whitelist"
|
|
35
|
+
fn test_simple_and_query() {
|
|
36
|
+
println!("\n=== Testing simple AND query: ip AND whitelist ===");
|
|
37
|
+
|
|
38
|
+
// Create the query
|
|
39
|
+
let query = "ip AND whitelist";
|
|
40
|
+
|
|
41
|
+
// Parse the query into an AST
|
|
42
|
+
// Using standard Elasticsearch behavior (AND for implicit combinations)
|
|
43
|
+
let ast = parse_query(query).unwrap();
|
|
44
|
+
println!("Parsed AST: {ast:?}");
|
|
45
|
+
|
|
46
|
+
// Create a QueryPlan
|
|
47
|
+
let plan = create_query_plan(query, false).unwrap();
|
|
48
|
+
|
|
49
|
+
// Use the term indices from the QueryPlan
|
|
50
|
+
let term_indices = &plan.term_indices;
|
|
51
|
+
|
|
52
|
+
// Test case 1: Block with both terms (should match)
|
|
53
|
+
{
|
|
54
|
+
let mut term_matches = HashMap::new();
|
|
55
|
+
|
|
56
|
+
// Add "ip" matches
|
|
57
|
+
let mut ip_lines = HashSet::new();
|
|
58
|
+
ip_lines.insert(3);
|
|
59
|
+
term_matches.insert(*term_indices.get("ip").unwrap(), ip_lines);
|
|
60
|
+
|
|
61
|
+
// Add "whitelist" matches directly (tokenization behavior has changed)
|
|
62
|
+
let mut whitelist_lines = HashSet::new();
|
|
63
|
+
whitelist_lines.insert(4);
|
|
64
|
+
|
|
65
|
+
// Check if "whitelist" is in the term_indices, or if it's split into "white" and "list"
|
|
66
|
+
if let Some(&idx) = term_indices.get("whitelist") {
|
|
67
|
+
term_matches.insert(idx, whitelist_lines);
|
|
68
|
+
} else {
|
|
69
|
+
// If "whitelist" is not in the term_indices, try "white" and "list"
|
|
70
|
+
if let Some(&idx) = term_indices.get("white") {
|
|
71
|
+
let mut white_lines = HashSet::new();
|
|
72
|
+
white_lines.insert(4);
|
|
73
|
+
term_matches.insert(idx, white_lines);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if let Some(&idx) = term_indices.get("list") {
|
|
77
|
+
let mut list_lines = HashSet::new();
|
|
78
|
+
list_lines.insert(4);
|
|
79
|
+
term_matches.insert(idx, list_lines);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Block lines
|
|
84
|
+
let block_lines = (1, 10);
|
|
85
|
+
|
|
86
|
+
// Test filtering
|
|
87
|
+
let result = filter_code_block_with_ast(block_lines, &term_matches, &plan, true);
|
|
88
|
+
assert!(
|
|
89
|
+
result,
|
|
90
|
+
"Block with both 'ip' and 'whitelist' should match the AND query"
|
|
91
|
+
);
|
|
92
|
+
println!("✓ Block with both terms matches");
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Test case 2: Block with only one term (should not match)
|
|
96
|
+
{
|
|
97
|
+
let mut term_matches = HashMap::new();
|
|
98
|
+
|
|
99
|
+
// Add only "ip" matches
|
|
100
|
+
let mut ip_lines = HashSet::new();
|
|
101
|
+
ip_lines.insert(3);
|
|
102
|
+
term_matches.insert(*term_indices.get("ip").unwrap(), ip_lines);
|
|
103
|
+
|
|
104
|
+
// Block lines
|
|
105
|
+
let block_lines = (1, 10);
|
|
106
|
+
|
|
107
|
+
// Test filtering
|
|
108
|
+
let result = filter_code_block_with_ast(block_lines, &term_matches, &plan, true);
|
|
109
|
+
assert!(
|
|
110
|
+
!result,
|
|
111
|
+
"Block with only 'ip' should not match the AND query"
|
|
112
|
+
);
|
|
113
|
+
println!("✓ Block with only one term doesn't match");
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/// Test a simple OR query: "ip OR port"
|
|
118
|
+
fn test_simple_or_query() {
|
|
119
|
+
println!("\n=== Testing simple OR query: ip OR port ===");
|
|
120
|
+
|
|
121
|
+
// Create the query
|
|
122
|
+
let query = "ip OR port";
|
|
123
|
+
|
|
124
|
+
// Parse the query into an AST
|
|
125
|
+
// Using standard Elasticsearch behavior (AND for implicit combinations)
|
|
126
|
+
let ast = parse_query(query).unwrap();
|
|
127
|
+
println!("Parsed AST: {ast:?}");
|
|
128
|
+
|
|
129
|
+
// Create a QueryPlan
|
|
130
|
+
let plan = create_query_plan(query, false).unwrap();
|
|
131
|
+
|
|
132
|
+
// Use the term indices from the QueryPlan
|
|
133
|
+
let term_indices = &plan.term_indices;
|
|
134
|
+
|
|
135
|
+
// Test case 1: Block with both terms (should match)
|
|
136
|
+
{
|
|
137
|
+
let mut term_matches = HashMap::new();
|
|
138
|
+
|
|
139
|
+
// Add "ip" matches
|
|
140
|
+
let mut ip_lines = HashSet::new();
|
|
141
|
+
ip_lines.insert(3);
|
|
142
|
+
term_matches.insert(*term_indices.get("ip").unwrap(), ip_lines);
|
|
143
|
+
|
|
144
|
+
// Add "port" matches
|
|
145
|
+
let mut port_lines = HashSet::new();
|
|
146
|
+
port_lines.insert(4);
|
|
147
|
+
term_matches.insert(*term_indices.get("port").unwrap(), port_lines);
|
|
148
|
+
|
|
149
|
+
// Block lines
|
|
150
|
+
let block_lines = (1, 10);
|
|
151
|
+
|
|
152
|
+
// Test filtering
|
|
153
|
+
let result = filter_code_block_with_ast(block_lines, &term_matches, &plan, true);
|
|
154
|
+
assert!(
|
|
155
|
+
result,
|
|
156
|
+
"Block with both 'ip' and 'port' should match the OR query"
|
|
157
|
+
);
|
|
158
|
+
println!("✓ Block with both terms matches");
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Test case 2: Block with only "ip" (should match)
|
|
162
|
+
{
|
|
163
|
+
let mut term_matches = HashMap::new();
|
|
164
|
+
|
|
165
|
+
// Add only "ip" matches
|
|
166
|
+
let mut ip_lines = HashSet::new();
|
|
167
|
+
ip_lines.insert(3);
|
|
168
|
+
term_matches.insert(*term_indices.get("ip").unwrap(), ip_lines);
|
|
169
|
+
|
|
170
|
+
// Block lines
|
|
171
|
+
let block_lines = (1, 10);
|
|
172
|
+
|
|
173
|
+
// Test filtering
|
|
174
|
+
let result = filter_code_block_with_ast(block_lines, &term_matches, &plan, true);
|
|
175
|
+
assert!(result, "Block with only 'ip' should match the OR query");
|
|
176
|
+
println!("✓ Block with only 'ip' matches");
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Test case 3: Block with only "port" (should match)
|
|
180
|
+
{
|
|
181
|
+
let mut term_matches = HashMap::new();
|
|
182
|
+
|
|
183
|
+
// Add only "port" matches
|
|
184
|
+
let mut port_lines = HashSet::new();
|
|
185
|
+
port_lines.insert(4);
|
|
186
|
+
term_matches.insert(*term_indices.get("port").unwrap(), port_lines);
|
|
187
|
+
|
|
188
|
+
// Block lines
|
|
189
|
+
let block_lines = (1, 10);
|
|
190
|
+
|
|
191
|
+
// Test filtering
|
|
192
|
+
let result = filter_code_block_with_ast(block_lines, &term_matches, &plan, true);
|
|
193
|
+
assert!(result, "Block with only 'port' should match the OR query");
|
|
194
|
+
println!("✓ Block with only 'port' matches");
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Test case 4: Block with neither term (should not match)
|
|
198
|
+
{
|
|
199
|
+
let term_matches = HashMap::new();
|
|
200
|
+
|
|
201
|
+
// Block lines
|
|
202
|
+
let block_lines = (1, 10);
|
|
203
|
+
|
|
204
|
+
// Test filtering
|
|
205
|
+
let result = filter_code_block_with_ast(block_lines, &term_matches, &plan, true);
|
|
206
|
+
assert!(
|
|
207
|
+
!result,
|
|
208
|
+
"Block with neither 'ip' nor 'port' should not match the OR query"
|
|
209
|
+
);
|
|
210
|
+
println!("✓ Block with neither term doesn't match");
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/// Test a complex query with AND, OR, and negation: "(ip OR port) AND whitelist AND -denylist"
|
|
215
|
+
fn test_complex_query_with_negation() {
|
|
216
|
+
println!("\n=== Testing complex query: (ip OR port) AND whitelist AND -denylist ===");
|
|
217
|
+
|
|
218
|
+
// Create the query
|
|
219
|
+
let query = "(ip OR port) AND whitelist AND -denylist";
|
|
220
|
+
|
|
221
|
+
// Parse the query into an AST
|
|
222
|
+
// Using standard Elasticsearch behavior (AND for implicit combinations)
|
|
223
|
+
let ast = parse_query(query).unwrap();
|
|
224
|
+
println!("Parsed AST: {ast:?}");
|
|
225
|
+
|
|
226
|
+
// Create a QueryPlan
|
|
227
|
+
let plan = create_query_plan(query, false).unwrap();
|
|
228
|
+
// Use the term indices from the QueryPlan
|
|
229
|
+
let term_indices = &plan.term_indices;
|
|
230
|
+
|
|
231
|
+
// Test case 1: Block with "ip", "whitelist", no "denylist" (should match)
|
|
232
|
+
{
|
|
233
|
+
let mut term_matches = HashMap::new();
|
|
234
|
+
|
|
235
|
+
// Add "ip" matches
|
|
236
|
+
let mut ip_lines = HashSet::new();
|
|
237
|
+
ip_lines.insert(3);
|
|
238
|
+
term_matches.insert(*term_indices.get("ip").unwrap(), ip_lines);
|
|
239
|
+
|
|
240
|
+
// Add "whitelist" matches directly (tokenization behavior has changed)
|
|
241
|
+
let mut whitelist_lines = HashSet::new();
|
|
242
|
+
whitelist_lines.insert(4);
|
|
243
|
+
|
|
244
|
+
// Check if "whitelist" is in the term_indices, or if it's split into "white" and "list"
|
|
245
|
+
if let Some(&idx) = term_indices.get("whitelist") {
|
|
246
|
+
term_matches.insert(idx, whitelist_lines);
|
|
247
|
+
} else {
|
|
248
|
+
// If "whitelist" is not in the term_indices, try "white" and "list"
|
|
249
|
+
if let Some(&idx) = term_indices.get("white") {
|
|
250
|
+
let mut white_lines = HashSet::new();
|
|
251
|
+
white_lines.insert(4);
|
|
252
|
+
term_matches.insert(idx, white_lines);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
if let Some(&idx) = term_indices.get("list") {
|
|
256
|
+
let mut list_lines = HashSet::new();
|
|
257
|
+
list_lines.insert(4);
|
|
258
|
+
term_matches.insert(idx, list_lines);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Block lines
|
|
263
|
+
let block_lines = (1, 10);
|
|
264
|
+
|
|
265
|
+
// Test filtering
|
|
266
|
+
let result = filter_code_block_with_ast(block_lines, &term_matches, &plan, true);
|
|
267
|
+
assert!(
|
|
268
|
+
result,
|
|
269
|
+
"Block with 'ip', 'whitelist', no 'denylist' should match"
|
|
270
|
+
);
|
|
271
|
+
println!("✓ Block with 'ip', 'whitelist', no 'denylist' matches");
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// Test case 2: Block with "port", "whitelist", no "denylist" (should match)
|
|
275
|
+
{
|
|
276
|
+
let mut term_matches = HashMap::new();
|
|
277
|
+
|
|
278
|
+
// Add "port" matches
|
|
279
|
+
let mut port_lines = HashSet::new();
|
|
280
|
+
port_lines.insert(3);
|
|
281
|
+
term_matches.insert(*term_indices.get("port").unwrap(), port_lines);
|
|
282
|
+
|
|
283
|
+
// Add "whitelist" matches directly (tokenization behavior has changed)
|
|
284
|
+
let mut whitelist_lines = HashSet::new();
|
|
285
|
+
whitelist_lines.insert(4);
|
|
286
|
+
|
|
287
|
+
// Check if "whitelist" is in the term_indices, or if it's split into "white" and "list"
|
|
288
|
+
if let Some(&idx) = term_indices.get("whitelist") {
|
|
289
|
+
term_matches.insert(idx, whitelist_lines);
|
|
290
|
+
} else {
|
|
291
|
+
// If "whitelist" is not in the term_indices, try "white" and "list"
|
|
292
|
+
if let Some(&idx) = term_indices.get("white") {
|
|
293
|
+
let mut white_lines = HashSet::new();
|
|
294
|
+
white_lines.insert(4);
|
|
295
|
+
term_matches.insert(idx, white_lines);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
if let Some(&idx) = term_indices.get("list") {
|
|
299
|
+
let mut list_lines = HashSet::new();
|
|
300
|
+
list_lines.insert(4);
|
|
301
|
+
term_matches.insert(idx, list_lines);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// Block lines
|
|
306
|
+
let block_lines = (1, 10);
|
|
307
|
+
|
|
308
|
+
// Test filtering
|
|
309
|
+
let result = filter_code_block_with_ast(block_lines, &term_matches, &plan, true);
|
|
310
|
+
assert!(
|
|
311
|
+
result,
|
|
312
|
+
"Block with 'port', 'whitelist', no 'denylist' should match"
|
|
313
|
+
);
|
|
314
|
+
println!("✓ Block with 'port', 'whitelist', no 'denylist' matches");
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// Test case 3: Block with "ip", "whitelist", and "denylist" (should NOT match)
|
|
318
|
+
{
|
|
319
|
+
let mut term_matches = HashMap::new();
|
|
320
|
+
|
|
321
|
+
// Add "ip" matches
|
|
322
|
+
let mut ip_lines = HashSet::new();
|
|
323
|
+
ip_lines.insert(3);
|
|
324
|
+
term_matches.insert(*term_indices.get("ip").unwrap(), ip_lines);
|
|
325
|
+
|
|
326
|
+
// Add "whitelist" matches directly (tokenization behavior has changed)
|
|
327
|
+
let mut whitelist_lines = HashSet::new();
|
|
328
|
+
whitelist_lines.insert(4);
|
|
329
|
+
|
|
330
|
+
// Check if "whitelist" is in the term_indices, or if it's split into "white" and "list"
|
|
331
|
+
if let Some(&idx) = term_indices.get("whitelist") {
|
|
332
|
+
term_matches.insert(idx, whitelist_lines);
|
|
333
|
+
} else {
|
|
334
|
+
// If "whitelist" is not in the term_indices, try "white" and "list"
|
|
335
|
+
if let Some(&idx) = term_indices.get("white") {
|
|
336
|
+
let mut white_lines = HashSet::new();
|
|
337
|
+
white_lines.insert(4);
|
|
338
|
+
term_matches.insert(idx, white_lines);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
if let Some(&idx) = term_indices.get("list") {
|
|
342
|
+
let mut list_lines = HashSet::new();
|
|
343
|
+
list_lines.insert(4);
|
|
344
|
+
term_matches.insert(idx, list_lines);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// Add "denylist" matches
|
|
349
|
+
let mut denylist_lines = HashSet::new();
|
|
350
|
+
denylist_lines.insert(5);
|
|
351
|
+
term_matches.insert(*term_indices.get("denylist").unwrap(), denylist_lines);
|
|
352
|
+
|
|
353
|
+
// Block lines
|
|
354
|
+
let block_lines = (1, 10);
|
|
355
|
+
|
|
356
|
+
// Test filtering
|
|
357
|
+
let result = filter_code_block_with_ast(block_lines, &term_matches, &plan, true);
|
|
358
|
+
assert!(
|
|
359
|
+
!result,
|
|
360
|
+
"Block with 'ip', 'whitelist', and 'denylist' should NOT match"
|
|
361
|
+
);
|
|
362
|
+
println!("✓ Block with 'ip', 'whitelist', and 'denylist' doesn't match");
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
// Test case 4: Block with only "ip" and "port" (should NOT match due to missing "whitelist")
|
|
366
|
+
{
|
|
367
|
+
let mut term_matches = HashMap::new();
|
|
368
|
+
|
|
369
|
+
// Add "ip" matches
|
|
370
|
+
let mut ip_lines = HashSet::new();
|
|
371
|
+
ip_lines.insert(3);
|
|
372
|
+
term_matches.insert(*term_indices.get("ip").unwrap(), ip_lines);
|
|
373
|
+
|
|
374
|
+
// Add "port" matches
|
|
375
|
+
let mut port_lines = HashSet::new();
|
|
376
|
+
port_lines.insert(4);
|
|
377
|
+
term_matches.insert(*term_indices.get("port").unwrap(), port_lines);
|
|
378
|
+
|
|
379
|
+
// Block lines
|
|
380
|
+
let block_lines = (1, 10);
|
|
381
|
+
|
|
382
|
+
// Test filtering
|
|
383
|
+
let result = filter_code_block_with_ast(block_lines, &term_matches, &plan, true);
|
|
384
|
+
assert!(
|
|
385
|
+
!result,
|
|
386
|
+
"Block with only 'ip' and 'port' should NOT match due to missing 'whitelist'"
|
|
387
|
+
);
|
|
388
|
+
println!("✓ Block with only 'ip' and 'port' doesn't match");
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/// Test a query with all required terms: "+ip +whitelist +security" (note: these are connected with OR, not AND)
|
|
393
|
+
fn test_required_terms_query() {
|
|
394
|
+
println!("\n=== Testing required terms query: +ip +whitelist +security ===");
|
|
395
|
+
|
|
396
|
+
// Create the query
|
|
397
|
+
let _query = "+ip +whitelist +security";
|
|
398
|
+
|
|
399
|
+
// Create a custom AST with OR semantics for required terms
|
|
400
|
+
let keywords1 = vec!["ip".to_string()];
|
|
401
|
+
let keywords2 = vec!["white".to_string(), "list".to_string()];
|
|
402
|
+
let keywords3 = vec!["secur".to_string()];
|
|
403
|
+
let ast = elastic_query::Expr::Or(
|
|
404
|
+
Box::new(elastic_query::Expr::Or(
|
|
405
|
+
Box::new(elastic_query::Expr::Term {
|
|
406
|
+
lowercase_keywords: keywords1.iter().map(|k| k.to_lowercase()).collect(),
|
|
407
|
+
keywords: keywords1,
|
|
408
|
+
field: None,
|
|
409
|
+
required: true,
|
|
410
|
+
excluded: false,
|
|
411
|
+
exact: false,
|
|
412
|
+
}),
|
|
413
|
+
Box::new(elastic_query::Expr::Term {
|
|
414
|
+
lowercase_keywords: keywords2.iter().map(|k| k.to_lowercase()).collect(),
|
|
415
|
+
keywords: keywords2,
|
|
416
|
+
field: None,
|
|
417
|
+
required: true,
|
|
418
|
+
excluded: false,
|
|
419
|
+
exact: false,
|
|
420
|
+
}),
|
|
421
|
+
)),
|
|
422
|
+
Box::new(elastic_query::Expr::Term {
|
|
423
|
+
lowercase_keywords: keywords3.iter().map(|k| k.to_lowercase()).collect(),
|
|
424
|
+
keywords: keywords3,
|
|
425
|
+
field: None,
|
|
426
|
+
required: true,
|
|
427
|
+
excluded: false,
|
|
428
|
+
exact: false,
|
|
429
|
+
}),
|
|
430
|
+
);
|
|
431
|
+
println!("Parsed AST: {ast:?}");
|
|
432
|
+
|
|
433
|
+
// Create a custom QueryPlan with our AST
|
|
434
|
+
let mut indices = HashMap::new();
|
|
435
|
+
indices.insert("ip".to_string(), 0);
|
|
436
|
+
indices.insert("list".to_string(), 1);
|
|
437
|
+
indices.insert("secur".to_string(), 2);
|
|
438
|
+
indices.insert("white".to_string(), 3);
|
|
439
|
+
|
|
440
|
+
let has_required_anywhere = ast.has_required_term();
|
|
441
|
+
let has_only_excluded_terms = ast.is_only_excluded_terms();
|
|
442
|
+
let required_terms_indices = HashSet::new();
|
|
443
|
+
let evaluation_cache = Arc::new(Mutex::new(LruCache::new(NonZeroUsize::new(1000).unwrap())));
|
|
444
|
+
|
|
445
|
+
let plan = probe_code::search::query::QueryPlan {
|
|
446
|
+
ast: ast.clone(),
|
|
447
|
+
term_indices: indices.clone(),
|
|
448
|
+
excluded_terms: HashSet::new(),
|
|
449
|
+
exact: false,
|
|
450
|
+
is_simple_query: false,
|
|
451
|
+
required_terms: HashSet::new(),
|
|
452
|
+
has_required_anywhere,
|
|
453
|
+
required_terms_indices,
|
|
454
|
+
has_only_excluded_terms,
|
|
455
|
+
evaluation_cache,
|
|
456
|
+
is_universal_query: false,
|
|
457
|
+
};
|
|
458
|
+
|
|
459
|
+
// Use the term indices directly
|
|
460
|
+
let term_indices = &indices;
|
|
461
|
+
|
|
462
|
+
// Test case 1: Block with all required terms (should match)
|
|
463
|
+
{
|
|
464
|
+
let mut term_matches = HashMap::new();
|
|
465
|
+
|
|
466
|
+
// Add all term matches
|
|
467
|
+
let mut ip_lines = HashSet::new();
|
|
468
|
+
ip_lines.insert(3);
|
|
469
|
+
term_matches.insert(*term_indices.get("ip").unwrap(), ip_lines);
|
|
470
|
+
|
|
471
|
+
// Add "white" and "list" matches (from tokenization of "whitelist")
|
|
472
|
+
let mut white_lines = HashSet::new();
|
|
473
|
+
white_lines.insert(4);
|
|
474
|
+
term_matches.insert(*term_indices.get("white").unwrap(), white_lines);
|
|
475
|
+
|
|
476
|
+
let mut list_lines = HashSet::new();
|
|
477
|
+
list_lines.insert(4);
|
|
478
|
+
term_matches.insert(*term_indices.get("list").unwrap(), list_lines);
|
|
479
|
+
|
|
480
|
+
let mut secur_lines = HashSet::new();
|
|
481
|
+
secur_lines.insert(5);
|
|
482
|
+
term_matches.insert(*term_indices.get("secur").unwrap(), secur_lines);
|
|
483
|
+
|
|
484
|
+
// Block lines
|
|
485
|
+
let block_lines = (1, 10);
|
|
486
|
+
|
|
487
|
+
// Test filtering
|
|
488
|
+
let result = filter_code_block_with_ast(block_lines, &term_matches, &plan, true);
|
|
489
|
+
assert!(result, "Block with all required terms should match");
|
|
490
|
+
println!("✓ Block with all required terms matches");
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
// Test case 2: Block missing one required term (should NOT match)
|
|
494
|
+
{
|
|
495
|
+
let mut term_matches = HashMap::new();
|
|
496
|
+
|
|
497
|
+
// Add only two term matches
|
|
498
|
+
let mut ip_lines = HashSet::new();
|
|
499
|
+
ip_lines.insert(3);
|
|
500
|
+
term_matches.insert(*term_indices.get("ip").unwrap(), ip_lines);
|
|
501
|
+
|
|
502
|
+
// Add "white" and "list" matches (from tokenization of "whitelist")
|
|
503
|
+
let mut white_lines = HashSet::new();
|
|
504
|
+
white_lines.insert(4);
|
|
505
|
+
term_matches.insert(*term_indices.get("white").unwrap(), white_lines);
|
|
506
|
+
|
|
507
|
+
let mut list_lines = HashSet::new();
|
|
508
|
+
list_lines.insert(4);
|
|
509
|
+
term_matches.insert(*term_indices.get("list").unwrap(), list_lines);
|
|
510
|
+
|
|
511
|
+
// Block lines
|
|
512
|
+
let block_lines = (1, 10);
|
|
513
|
+
|
|
514
|
+
// Test filtering
|
|
515
|
+
let result = filter_code_block_with_ast(block_lines, &term_matches, &plan, true);
|
|
516
|
+
// Note: In correct Lucene semantics, ALL required terms must be present
|
|
517
|
+
// This block is missing 'security', so it should NOT match
|
|
518
|
+
assert!(
|
|
519
|
+
!result,
|
|
520
|
+
"Block missing required term 'security' should NOT match"
|
|
521
|
+
);
|
|
522
|
+
println!("✓ Block missing required terms correctly rejected");
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
/// Test a query with nested expressions: "ip AND (whitelist OR (security AND firewall))"
|
|
527
|
+
fn test_nested_expressions_query() {
|
|
528
|
+
println!(
|
|
529
|
+
"\n=== Testing nested expressions query: ip AND (whitelist OR (security AND firewall)) ==="
|
|
530
|
+
);
|
|
531
|
+
|
|
532
|
+
// Create the query
|
|
533
|
+
let query = "ip AND (whitelist OR (security AND firewall))";
|
|
534
|
+
|
|
535
|
+
// Parse the query into an AST
|
|
536
|
+
// Using standard Elasticsearch behavior (AND for implicit combinations)
|
|
537
|
+
let ast = parse_query(query).unwrap();
|
|
538
|
+
println!("Parsed AST: {ast:?}");
|
|
539
|
+
|
|
540
|
+
// Create a QueryPlan
|
|
541
|
+
let plan = create_query_plan(query, false).unwrap();
|
|
542
|
+
|
|
543
|
+
// Use the term indices from the QueryPlan
|
|
544
|
+
let term_indices = &plan.term_indices;
|
|
545
|
+
|
|
546
|
+
// Test case 1: Block with "ip" and "whitelist" (should match)
|
|
547
|
+
{
|
|
548
|
+
let mut term_matches = HashMap::new();
|
|
549
|
+
|
|
550
|
+
// Add "ip" matches
|
|
551
|
+
let mut ip_lines = HashSet::new();
|
|
552
|
+
ip_lines.insert(3);
|
|
553
|
+
term_matches.insert(*term_indices.get("ip").unwrap(), ip_lines);
|
|
554
|
+
|
|
555
|
+
// Add "whitelist" matches directly (tokenization behavior has changed)
|
|
556
|
+
let mut whitelist_lines = HashSet::new();
|
|
557
|
+
whitelist_lines.insert(4);
|
|
558
|
+
|
|
559
|
+
// Check if "whitelist" is in the term_indices, or if it's split into "white" and "list"
|
|
560
|
+
if let Some(&idx) = term_indices.get("whitelist") {
|
|
561
|
+
term_matches.insert(idx, whitelist_lines);
|
|
562
|
+
} else {
|
|
563
|
+
// If "whitelist" is not in the term_indices, try "white" and "list"
|
|
564
|
+
if let Some(&idx) = term_indices.get("white") {
|
|
565
|
+
let mut white_lines = HashSet::new();
|
|
566
|
+
white_lines.insert(4);
|
|
567
|
+
term_matches.insert(idx, white_lines);
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
if let Some(&idx) = term_indices.get("list") {
|
|
571
|
+
let mut list_lines = HashSet::new();
|
|
572
|
+
list_lines.insert(4);
|
|
573
|
+
term_matches.insert(idx, list_lines);
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
// Block lines
|
|
578
|
+
let block_lines = (1, 10);
|
|
579
|
+
|
|
580
|
+
// Test filtering
|
|
581
|
+
let result = filter_code_block_with_ast(block_lines, &term_matches, &plan, true);
|
|
582
|
+
assert!(result, "Block with 'ip' and 'whitelist' should match");
|
|
583
|
+
println!("✓ Block with 'ip' and 'whitelist' matches");
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
// Test case 2: Block with "ip", "security", and "firewall" (should match)
|
|
587
|
+
{
|
|
588
|
+
let mut term_matches = HashMap::new();
|
|
589
|
+
|
|
590
|
+
// Add "ip" matches
|
|
591
|
+
let mut ip_lines = HashSet::new();
|
|
592
|
+
ip_lines.insert(3);
|
|
593
|
+
term_matches.insert(*term_indices.get("ip").unwrap(), ip_lines);
|
|
594
|
+
|
|
595
|
+
// Add "secur" matches (stemmed from "security")
|
|
596
|
+
let mut secur_lines = HashSet::new();
|
|
597
|
+
secur_lines.insert(4);
|
|
598
|
+
term_matches.insert(*term_indices.get("secur").unwrap(), secur_lines);
|
|
599
|
+
|
|
600
|
+
// Add "firewal" and "firewall" matches (stemmed from "firewall")
|
|
601
|
+
let mut firewal_lines = HashSet::new();
|
|
602
|
+
firewal_lines.insert(5);
|
|
603
|
+
|
|
604
|
+
// Check if "firewal" is in the term_indices
|
|
605
|
+
if let Some(&idx) = term_indices.get("firewal") {
|
|
606
|
+
term_matches.insert(idx, firewal_lines.clone());
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
// Check if "firewall" is in the term_indices
|
|
610
|
+
if let Some(&idx) = term_indices.get("firewall") {
|
|
611
|
+
term_matches.insert(idx, firewal_lines);
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
// Block lines
|
|
615
|
+
let block_lines = (1, 10);
|
|
616
|
+
|
|
617
|
+
// Test filtering
|
|
618
|
+
let result = filter_code_block_with_ast(block_lines, &term_matches, &plan, true);
|
|
619
|
+
assert!(
|
|
620
|
+
result,
|
|
621
|
+
"Block with 'ip', 'security', and 'firewall' should match"
|
|
622
|
+
);
|
|
623
|
+
println!("✓ Block with 'ip', 'security', and 'firewall' matches");
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
// Test case 3: Block with "ip" and "security" but no "firewall" (should NOT match)
|
|
627
|
+
{
|
|
628
|
+
let mut term_matches = HashMap::new();
|
|
629
|
+
|
|
630
|
+
// Add "ip" matches
|
|
631
|
+
let mut ip_lines = HashSet::new();
|
|
632
|
+
ip_lines.insert(3);
|
|
633
|
+
term_matches.insert(*term_indices.get("ip").unwrap(), ip_lines);
|
|
634
|
+
|
|
635
|
+
// Add "secur" matches (stemmed from "security")
|
|
636
|
+
let mut secur_lines = HashSet::new();
|
|
637
|
+
secur_lines.insert(4);
|
|
638
|
+
term_matches.insert(*term_indices.get("secur").unwrap(), secur_lines);
|
|
639
|
+
|
|
640
|
+
// Block lines
|
|
641
|
+
let block_lines = (1, 10);
|
|
642
|
+
|
|
643
|
+
// Test filtering
|
|
644
|
+
let result = filter_code_block_with_ast(block_lines, &term_matches, &plan, true);
|
|
645
|
+
assert!(
|
|
646
|
+
!result,
|
|
647
|
+
"Block with 'ip' and 'security' but no 'firewall' should NOT match"
|
|
648
|
+
);
|
|
649
|
+
println!("✓ Block with 'ip' and 'security' but no 'firewall' doesn't match");
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
// Test case 4: Block with only "ip" (should NOT match)
|
|
653
|
+
{
|
|
654
|
+
let mut term_matches = HashMap::new();
|
|
655
|
+
|
|
656
|
+
// Add only "ip" matches
|
|
657
|
+
let mut ip_lines = HashSet::new();
|
|
658
|
+
ip_lines.insert(3);
|
|
659
|
+
term_matches.insert(*term_indices.get("ip").unwrap(), ip_lines);
|
|
660
|
+
|
|
661
|
+
// Block lines
|
|
662
|
+
let block_lines = (1, 10);
|
|
663
|
+
|
|
664
|
+
// Test filtering
|
|
665
|
+
let result = filter_code_block_with_ast(block_lines, &term_matches, &plan, true);
|
|
666
|
+
assert!(!result, "Block with only 'ip' should NOT match");
|
|
667
|
+
println!("✓ Block with only 'ip' doesn't match");
|
|
668
|
+
}
|
|
669
|
+
}
|