@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,682 @@
|
|
|
1
|
+
//! Comprehensive tests demonstrating cache invalidation issues in probe
|
|
2
|
+
//!
|
|
3
|
+
//! These tests expose critical flaws in the current caching architecture:
|
|
4
|
+
//! 1. Stale cache entries returning incorrect results
|
|
5
|
+
//! 2. Lack of cache invalidation causing memory leaks
|
|
6
|
+
//! 3. Inconsistent behavior across different cache layers
|
|
7
|
+
//! 4. Race conditions and concurrent access issues
|
|
8
|
+
|
|
9
|
+
use std::collections::HashMap;
|
|
10
|
+
use std::fs::{self, File, OpenOptions};
|
|
11
|
+
use std::io::{Read, Write};
|
|
12
|
+
use std::path::{Path, PathBuf};
|
|
13
|
+
use std::sync::{
|
|
14
|
+
atomic::{AtomicUsize, Ordering},
|
|
15
|
+
Arc, Mutex,
|
|
16
|
+
};
|
|
17
|
+
use std::thread;
|
|
18
|
+
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
|
19
|
+
use tempfile::{NamedTempFile, TempDir};
|
|
20
|
+
|
|
21
|
+
use probe_code::language::factory::get_language_impl_by_extension;
|
|
22
|
+
use probe_code::language::tree_cache::{
|
|
23
|
+
self, clear_tree_cache, get_cache_size, get_or_parse_tree, invalidate_cache_entry, is_in_cache,
|
|
24
|
+
};
|
|
25
|
+
use probe_code::search::cache::{calculate_file_md5, hash_query, SessionCache};
|
|
26
|
+
use probe_code::search::search_tokens::{count_block_tokens, count_tokens, get_tokenizer};
|
|
27
|
+
use probe_code::search::tokenization::{is_filtering_vocabulary_term, tokenize_query};
|
|
28
|
+
|
|
29
|
+
/// Test demonstrating stale tree cache returning incorrect parsing results
|
|
30
|
+
/// ISSUE: Tree cache doesn't invalidate when file content changes
|
|
31
|
+
#[test]
|
|
32
|
+
#[ignore] // This test is expected to FAIL - it demonstrates the bug
|
|
33
|
+
fn test_tree_cache_stale_entry_bug() {
|
|
34
|
+
clear_tree_cache();
|
|
35
|
+
|
|
36
|
+
let temp_dir = TempDir::new().unwrap();
|
|
37
|
+
let file_path = temp_dir.path().join("test.rs");
|
|
38
|
+
|
|
39
|
+
// Create initial file content
|
|
40
|
+
let initial_content = r#"
|
|
41
|
+
fn original_function() {
|
|
42
|
+
println!("This is the original function");
|
|
43
|
+
let x = 42;
|
|
44
|
+
return x;
|
|
45
|
+
}
|
|
46
|
+
"#;
|
|
47
|
+
fs::write(&file_path, initial_content).unwrap();
|
|
48
|
+
|
|
49
|
+
// Get language implementation and parser
|
|
50
|
+
let language_impl = get_language_impl_by_extension("rs").unwrap();
|
|
51
|
+
let mut parser = tree_sitter::Parser::new();
|
|
52
|
+
parser
|
|
53
|
+
.set_language(language_impl.get_tree_sitter_language())
|
|
54
|
+
.unwrap();
|
|
55
|
+
|
|
56
|
+
// Parse the initial content - this will cache the tree
|
|
57
|
+
let initial_tree =
|
|
58
|
+
get_or_parse_tree(file_path.to_str().unwrap(), initial_content, &mut parser).unwrap();
|
|
59
|
+
let initial_node_count = initial_tree.root_node().child_count();
|
|
60
|
+
|
|
61
|
+
// Verify the file is cached
|
|
62
|
+
assert!(is_in_cache(file_path.to_str().unwrap()));
|
|
63
|
+
|
|
64
|
+
// CRITICAL BUG: Modify file content without updating cache
|
|
65
|
+
let modified_content = r#"
|
|
66
|
+
fn completely_different_function() {
|
|
67
|
+
println!("This is completely different");
|
|
68
|
+
let y = 100;
|
|
69
|
+
let z = 200;
|
|
70
|
+
return y + z;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
fn another_function() {
|
|
74
|
+
println!("Additional function");
|
|
75
|
+
}
|
|
76
|
+
"#;
|
|
77
|
+
fs::write(&file_path, modified_content).unwrap();
|
|
78
|
+
|
|
79
|
+
// BUG: get_or_parse_tree should detect content change and reparse
|
|
80
|
+
// but it uses file path as key, not content hash!
|
|
81
|
+
let cached_tree =
|
|
82
|
+
get_or_parse_tree(file_path.to_str().unwrap(), modified_content, &mut parser).unwrap();
|
|
83
|
+
let cached_node_count = cached_tree.root_node().child_count();
|
|
84
|
+
|
|
85
|
+
// Parse directly for comparison
|
|
86
|
+
let fresh_tree = parser.parse(modified_content, None).unwrap();
|
|
87
|
+
let fresh_node_count = fresh_tree.root_node().child_count();
|
|
88
|
+
|
|
89
|
+
// FAILING ASSERTION: The cached tree should match the fresh parse
|
|
90
|
+
// This will FAIL because cache returns stale tree structure
|
|
91
|
+
assert_eq!(
|
|
92
|
+
cached_node_count, fresh_node_count,
|
|
93
|
+
"BUG: Tree cache returned stale AST! Cached: {}, Fresh: {}",
|
|
94
|
+
cached_node_count, fresh_node_count
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
// Additional verification: Function names should match
|
|
98
|
+
let cached_root = cached_tree.root_node();
|
|
99
|
+
let fresh_root = fresh_tree.root_node();
|
|
100
|
+
|
|
101
|
+
let cached_functions = extract_function_names(&cached_root, modified_content.as_bytes());
|
|
102
|
+
let fresh_functions = extract_function_names(&fresh_root, modified_content.as_bytes());
|
|
103
|
+
|
|
104
|
+
assert_eq!(
|
|
105
|
+
cached_functions, fresh_functions,
|
|
106
|
+
"BUG: Cached functions {:?} != Fresh functions {:?}",
|
|
107
|
+
cached_functions, fresh_functions
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/// Test demonstrating token cache returning stale counts
|
|
112
|
+
/// ISSUE: Token cache uses content hash but doesn't handle hash collisions properly
|
|
113
|
+
#[test]
|
|
114
|
+
#[ignore] // This test is expected to FAIL - it demonstrates the bug
|
|
115
|
+
fn test_token_cache_stale_count_bug() {
|
|
116
|
+
// Create two different strings that may have same hash (artificial collision)
|
|
117
|
+
let content1 = "function calculateTotal(items) {\n return items.reduce((sum, item) => sum + item.price, 0);\n}";
|
|
118
|
+
let content2 = "class PaymentProcessor {\n processPayment(amount) {\n return amount * 1.1;\n }\n}";
|
|
119
|
+
|
|
120
|
+
// Count tokens for first content
|
|
121
|
+
let count1_first = count_tokens(content1);
|
|
122
|
+
let count2_first = count_tokens(content2);
|
|
123
|
+
|
|
124
|
+
// Verify different content has different token counts
|
|
125
|
+
assert_ne!(
|
|
126
|
+
count1_first, count2_first,
|
|
127
|
+
"Test setup: contents should have different token counts"
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
// Now test potential hash collision scenario
|
|
131
|
+
// In a real scenario, hash collisions could cause wrong token counts
|
|
132
|
+
|
|
133
|
+
// Force cache the first content by calling multiple times
|
|
134
|
+
for _ in 0..10 {
|
|
135
|
+
let _ = count_tokens(content1);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Now if there's a hash collision, content2 might get content1's count
|
|
139
|
+
let count2_second = count_tokens(content2);
|
|
140
|
+
|
|
141
|
+
// This should always be equal, but hash collisions could break this
|
|
142
|
+
assert_eq!(
|
|
143
|
+
count2_first, count2_second,
|
|
144
|
+
"BUG: Token cache corruption! First count: {}, Second count: {}",
|
|
145
|
+
count2_first, count2_second
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/// Test demonstrating unbounded cache growth
|
|
150
|
+
/// ISSUE: Caches grow without bounds leading to memory exhaustion
|
|
151
|
+
#[test]
|
|
152
|
+
#[ignore] // This test will cause OOM if run to completion
|
|
153
|
+
fn test_unbounded_cache_growth_bug() {
|
|
154
|
+
clear_tree_cache();
|
|
155
|
+
|
|
156
|
+
let temp_dir = TempDir::new().unwrap();
|
|
157
|
+
let initial_cache_size = get_cache_size();
|
|
158
|
+
|
|
159
|
+
// Generate thousands of unique files to fill cache
|
|
160
|
+
let num_files = 10000; // This will cause OOM in practice
|
|
161
|
+
let mut file_paths = Vec::new();
|
|
162
|
+
|
|
163
|
+
for i in 0..num_files {
|
|
164
|
+
let file_path = temp_dir.path().join(format!("file_{}.rs", i));
|
|
165
|
+
let content = format!(
|
|
166
|
+
r#"
|
|
167
|
+
fn function_{}() {{
|
|
168
|
+
println!("Function number {}", {});
|
|
169
|
+
let result = {} * 2;
|
|
170
|
+
return result;
|
|
171
|
+
}}
|
|
172
|
+
"#,
|
|
173
|
+
i, i, i
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
fs::write(&file_path, &content).unwrap();
|
|
177
|
+
file_paths.push((file_path, content));
|
|
178
|
+
|
|
179
|
+
// Parse each file to fill the cache
|
|
180
|
+
let language_impl = get_language_impl_by_extension("rs").unwrap();
|
|
181
|
+
let mut parser = tree_sitter::Parser::new();
|
|
182
|
+
parser
|
|
183
|
+
.set_language(language_impl.get_tree_sitter_language())
|
|
184
|
+
.unwrap();
|
|
185
|
+
|
|
186
|
+
let _ = get_or_parse_tree(file_path.to_str().unwrap(), &content, &mut parser);
|
|
187
|
+
|
|
188
|
+
// Print cache growth (will grow without bounds)
|
|
189
|
+
if i % 1000 == 0 {
|
|
190
|
+
println!("Cache size after {} files: {}", i, get_cache_size());
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
let final_cache_size = get_cache_size();
|
|
195
|
+
|
|
196
|
+
// BUG: Cache should have size limits, but it grows without bounds
|
|
197
|
+
assert!(
|
|
198
|
+
final_cache_size < 1000,
|
|
199
|
+
"BUG: Cache grew unbounded to {} entries! This will cause OOM.",
|
|
200
|
+
final_cache_size
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/// Test demonstrating session cache invalidation failures
|
|
205
|
+
/// ISSUE: Session cache doesn't properly detect file changes
|
|
206
|
+
#[test]
|
|
207
|
+
#[ignore] // This test is expected to FAIL - it demonstrates the bug
|
|
208
|
+
fn test_session_cache_invalidation_bug() {
|
|
209
|
+
let temp_dir = TempDir::new().unwrap();
|
|
210
|
+
let file_path = temp_dir.path().join("session_test.rs");
|
|
211
|
+
|
|
212
|
+
// Create initial file
|
|
213
|
+
let initial_content = r#"
|
|
214
|
+
fn initial_function() {
|
|
215
|
+
let value = 42;
|
|
216
|
+
return value;
|
|
217
|
+
}
|
|
218
|
+
"#;
|
|
219
|
+
fs::write(&file_path, initial_content).unwrap();
|
|
220
|
+
|
|
221
|
+
// Create session cache
|
|
222
|
+
let query = "function value";
|
|
223
|
+
let query_hash = hash_query(query);
|
|
224
|
+
let mut cache = SessionCache::new("test_session".to_string(), query_hash.clone());
|
|
225
|
+
|
|
226
|
+
// Add block to cache with initial file hash
|
|
227
|
+
let initial_md5 = calculate_file_md5(&file_path).unwrap();
|
|
228
|
+
cache
|
|
229
|
+
.file_md5_hashes
|
|
230
|
+
.insert(file_path.to_string_lossy().to_string(), initial_md5.clone());
|
|
231
|
+
cache.add_to_cache(format!("{}:1-5", file_path.to_string_lossy()));
|
|
232
|
+
|
|
233
|
+
// Verify block is cached
|
|
234
|
+
assert!(cache.is_cached(&format!("{}:1-5", file_path.to_string_lossy())));
|
|
235
|
+
|
|
236
|
+
// Modify file content
|
|
237
|
+
let modified_content = r#"
|
|
238
|
+
fn completely_different_function() {
|
|
239
|
+
let different_value = 999;
|
|
240
|
+
let another_value = 888;
|
|
241
|
+
return different_value + another_value;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
fn second_function() {
|
|
245
|
+
println!("This is a second function");
|
|
246
|
+
}
|
|
247
|
+
"#;
|
|
248
|
+
fs::write(&file_path, modified_content).unwrap();
|
|
249
|
+
|
|
250
|
+
// BUG: Cache validation should detect file change and invalidate
|
|
251
|
+
cache.validate_and_invalidate_cache(true).unwrap();
|
|
252
|
+
|
|
253
|
+
// FAILING ASSERTION: Block should be invalidated after file change
|
|
254
|
+
assert!(
|
|
255
|
+
!cache.is_cached(&format!("{}:1-5", file_path.to_string_lossy())),
|
|
256
|
+
"BUG: Session cache failed to invalidate stale entry after file modification!"
|
|
257
|
+
);
|
|
258
|
+
|
|
259
|
+
// Additional check: File hash should be removed from cache
|
|
260
|
+
assert!(
|
|
261
|
+
!cache
|
|
262
|
+
.file_md5_hashes
|
|
263
|
+
.contains_key(&file_path.to_string_lossy().to_string()),
|
|
264
|
+
"BUG: Session cache still contains stale file hash!"
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/// Test demonstrating concurrent cache corruption
|
|
269
|
+
/// ISSUE: Multiple threads can corrupt cache state
|
|
270
|
+
#[test]
|
|
271
|
+
#[ignore] // This test is expected to FAIL - it demonstrates race conditions
|
|
272
|
+
fn test_concurrent_cache_corruption_bug() {
|
|
273
|
+
clear_tree_cache();
|
|
274
|
+
|
|
275
|
+
let temp_dir = TempDir::new().unwrap();
|
|
276
|
+
let corruption_count = Arc::new(AtomicUsize::new(0));
|
|
277
|
+
let num_threads = 10;
|
|
278
|
+
let files_per_thread = 100;
|
|
279
|
+
|
|
280
|
+
// Create shared file for concurrent access
|
|
281
|
+
let shared_file = temp_dir.path().join("shared.rs");
|
|
282
|
+
let initial_content = r#"
|
|
283
|
+
fn shared_function() {
|
|
284
|
+
let value = 42;
|
|
285
|
+
return value;
|
|
286
|
+
}
|
|
287
|
+
"#;
|
|
288
|
+
fs::write(&shared_file, initial_content).unwrap();
|
|
289
|
+
|
|
290
|
+
let handles: Vec<_> = (0..num_threads)
|
|
291
|
+
.map(|thread_id| {
|
|
292
|
+
let temp_dir = temp_dir.path().to_path_buf();
|
|
293
|
+
let corruption_count = Arc::clone(&corruption_count);
|
|
294
|
+
let shared_file = shared_file.clone();
|
|
295
|
+
|
|
296
|
+
thread::spawn(move || {
|
|
297
|
+
let language_impl = get_language_impl_by_extension("rs").unwrap();
|
|
298
|
+
let mut parser = tree_sitter::Parser::new();
|
|
299
|
+
parser
|
|
300
|
+
.set_language(language_impl.get_tree_sitter_language())
|
|
301
|
+
.unwrap();
|
|
302
|
+
|
|
303
|
+
for i in 0..files_per_thread {
|
|
304
|
+
// Each thread modifies the shared file concurrently
|
|
305
|
+
let content = format!(
|
|
306
|
+
r#"
|
|
307
|
+
fn shared_function_thread_{}_iteration_{}() {{
|
|
308
|
+
let value = {};
|
|
309
|
+
return value * {};
|
|
310
|
+
}}
|
|
311
|
+
"#,
|
|
312
|
+
thread_id, i, thread_id, i
|
|
313
|
+
);
|
|
314
|
+
|
|
315
|
+
// Write and immediately try to parse (race condition)
|
|
316
|
+
if let Err(_) = fs::write(&shared_file, &content) {
|
|
317
|
+
corruption_count.fetch_add(1, Ordering::SeqCst);
|
|
318
|
+
continue;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// Parse with potential race conditions in cache
|
|
322
|
+
match get_or_parse_tree(shared_file.to_str().unwrap(), &content, &mut parser) {
|
|
323
|
+
Ok(tree) => {
|
|
324
|
+
// Verify the tree matches expected content
|
|
325
|
+
let root = tree.root_node();
|
|
326
|
+
let function_names = extract_function_names(&root, content.as_bytes());
|
|
327
|
+
|
|
328
|
+
let expected_function =
|
|
329
|
+
format!("shared_function_thread_{}_iteration_{}", thread_id, i);
|
|
330
|
+
if !function_names.contains(&expected_function) {
|
|
331
|
+
corruption_count.fetch_add(1, Ordering::SeqCst);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
Err(_) => {
|
|
335
|
+
corruption_count.fetch_add(1, Ordering::SeqCst);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
// Small delay to increase chance of race conditions
|
|
340
|
+
thread::sleep(Duration::from_millis(1));
|
|
341
|
+
}
|
|
342
|
+
})
|
|
343
|
+
})
|
|
344
|
+
.collect();
|
|
345
|
+
|
|
346
|
+
// Wait for all threads
|
|
347
|
+
for handle in handles {
|
|
348
|
+
handle.join().unwrap();
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
let total_corruptions = corruption_count.load(Ordering::SeqCst);
|
|
352
|
+
|
|
353
|
+
// BUG: There should be no corruptions in a properly synchronized cache
|
|
354
|
+
assert_eq!(
|
|
355
|
+
total_corruptions,
|
|
356
|
+
0,
|
|
357
|
+
"BUG: Cache corruption detected! {} corruptions out of {} operations",
|
|
358
|
+
total_corruptions,
|
|
359
|
+
num_threads * files_per_thread
|
|
360
|
+
);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/// Test demonstrating tokenization cache memory leak
|
|
364
|
+
/// ISSUE: Tokenization caches never clean up old entries
|
|
365
|
+
#[test]
|
|
366
|
+
#[ignore] // This test will consume excessive memory
|
|
367
|
+
fn test_tokenization_cache_memory_leak_bug() {
|
|
368
|
+
let mut memory_usage = Vec::new();
|
|
369
|
+
let num_unique_strings = 50000; // Large number to trigger memory issues
|
|
370
|
+
|
|
371
|
+
for i in 0..num_unique_strings {
|
|
372
|
+
// Generate unique content to fill tokenization cache
|
|
373
|
+
let content = format!(
|
|
374
|
+
r#"
|
|
375
|
+
function processData_{}(input) {{
|
|
376
|
+
const result = input.map(item => {{
|
|
377
|
+
return {{
|
|
378
|
+
id: item.id + {},
|
|
379
|
+
value: item.value * {},
|
|
380
|
+
processed: true,
|
|
381
|
+
timestamp: Date.now(),
|
|
382
|
+
metadata: {{
|
|
383
|
+
iteration: {},
|
|
384
|
+
batch: Math.floor({} / 1000)
|
|
385
|
+
}}
|
|
386
|
+
}};
|
|
387
|
+
}});
|
|
388
|
+
return result.filter(item => item.value > {});
|
|
389
|
+
}}
|
|
390
|
+
"#,
|
|
391
|
+
i,
|
|
392
|
+
i,
|
|
393
|
+
i,
|
|
394
|
+
i,
|
|
395
|
+
i,
|
|
396
|
+
i % 100
|
|
397
|
+
);
|
|
398
|
+
|
|
399
|
+
// Count tokens to fill cache
|
|
400
|
+
let _token_count = count_tokens(&content);
|
|
401
|
+
|
|
402
|
+
// Track memory usage (approximate)
|
|
403
|
+
if i % 5000 == 0 {
|
|
404
|
+
memory_usage.push(i);
|
|
405
|
+
println!("Processed {} strings", i);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
// Generate more content with different pattern to test cache behavior
|
|
410
|
+
for i in 0..10000 {
|
|
411
|
+
let content = format!("Very short string number {}", i);
|
|
412
|
+
let _token_count = count_tokens(&content);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
// BUG: Memory should be bounded, but tokenization cache never cleans up
|
|
416
|
+
// This test will consume excessive memory if cache has no limits
|
|
417
|
+
|
|
418
|
+
println!("Tokenization cache memory test completed");
|
|
419
|
+
// In practice, this test would reveal unbounded memory growth
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/// Test demonstrating compound word cache inconsistencies
|
|
423
|
+
/// ISSUE: Compound word cache can return inconsistent results
|
|
424
|
+
#[test]
|
|
425
|
+
#[ignore] // This test is expected to FAIL - it demonstrates inconsistencies
|
|
426
|
+
fn test_compound_word_cache_inconsistency_bug() {
|
|
427
|
+
// Test compound words that might be cached differently
|
|
428
|
+
let test_cases = vec![
|
|
429
|
+
"processPaymentData",
|
|
430
|
+
"calculateTotalAmount",
|
|
431
|
+
"getUserInformation",
|
|
432
|
+
"validateInputParameters",
|
|
433
|
+
"generateReportSummary",
|
|
434
|
+
];
|
|
435
|
+
|
|
436
|
+
let mut inconsistencies = 0;
|
|
437
|
+
|
|
438
|
+
for word in &test_cases {
|
|
439
|
+
// Tokenize the word multiple times
|
|
440
|
+
let mut results = Vec::new();
|
|
441
|
+
|
|
442
|
+
for _ in 0..10 {
|
|
443
|
+
let tokens = tokenize_query(word);
|
|
444
|
+
results.push(tokens);
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
// Check if all results are identical
|
|
448
|
+
let first_result = &results[0];
|
|
449
|
+
for (i, result) in results.iter().enumerate().skip(1) {
|
|
450
|
+
if result != first_result {
|
|
451
|
+
inconsistencies += 1;
|
|
452
|
+
println!(
|
|
453
|
+
"Inconsistency in '{}': attempt 0: {:?}, attempt {}: {:?}",
|
|
454
|
+
word, first_result, i, result
|
|
455
|
+
);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
// BUG: Compound word tokenization should be deterministic
|
|
461
|
+
assert_eq!(
|
|
462
|
+
inconsistencies, 0,
|
|
463
|
+
"BUG: Found {} inconsistencies in compound word tokenization!",
|
|
464
|
+
inconsistencies
|
|
465
|
+
);
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
/// Test demonstrating filtering vocabulary cache staleness
|
|
469
|
+
/// ISSUE: Filtering vocabulary cache can become stale with vocabulary updates
|
|
470
|
+
#[test]
|
|
471
|
+
#[ignore] // This test is expected to FAIL - it demonstrates staleness
|
|
472
|
+
fn test_filtering_vocabulary_cache_staleness_bug() {
|
|
473
|
+
// Test with terms that should be in vocabulary
|
|
474
|
+
let test_terms = vec![
|
|
475
|
+
"function",
|
|
476
|
+
"class",
|
|
477
|
+
"variable",
|
|
478
|
+
"method",
|
|
479
|
+
"property",
|
|
480
|
+
"interface",
|
|
481
|
+
"struct",
|
|
482
|
+
"enum",
|
|
483
|
+
"trait",
|
|
484
|
+
"module",
|
|
485
|
+
];
|
|
486
|
+
|
|
487
|
+
let mut initial_results = HashMap::new();
|
|
488
|
+
let mut final_results = HashMap::new();
|
|
489
|
+
|
|
490
|
+
// Check initial vocabulary state
|
|
491
|
+
for term in &test_terms {
|
|
492
|
+
initial_results.insert(term.to_string(), is_filtering_vocabulary_term(term));
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
// Simulate vocabulary update (this doesn't actually exist in current code)
|
|
496
|
+
// In a proper implementation, vocabulary could be updated dynamically
|
|
497
|
+
|
|
498
|
+
// Force some cache operations that might affect vocabulary cache
|
|
499
|
+
for i in 0..1000 {
|
|
500
|
+
let fake_term = format!("fake_term_{}", i);
|
|
501
|
+
let _ = is_filtering_vocabulary_term(&fake_term);
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
// Check vocabulary state after operations
|
|
505
|
+
for term in &test_terms {
|
|
506
|
+
final_results.insert(term.to_string(), is_filtering_vocabulary_term(term));
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
// Compare results
|
|
510
|
+
let mut mismatches = 0;
|
|
511
|
+
for term in &test_terms {
|
|
512
|
+
let initial = initial_results.get(term).unwrap();
|
|
513
|
+
let final_result = final_results.get(term).unwrap();
|
|
514
|
+
|
|
515
|
+
if initial != final_result {
|
|
516
|
+
mismatches += 1;
|
|
517
|
+
println!(
|
|
518
|
+
"Vocabulary staleness in '{}': initial: {}, final: {}",
|
|
519
|
+
term, initial, final_result
|
|
520
|
+
);
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
// BUG: Vocabulary cache should be consistent
|
|
525
|
+
assert_eq!(
|
|
526
|
+
mismatches, 0,
|
|
527
|
+
"BUG: Found {} vocabulary cache inconsistencies!",
|
|
528
|
+
mismatches
|
|
529
|
+
);
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
/// Helper function to extract function names from AST
|
|
533
|
+
fn extract_function_names(node: &tree_sitter::Node, source: &[u8]) -> Vec<String> {
|
|
534
|
+
let mut function_names = Vec::new();
|
|
535
|
+
|
|
536
|
+
if node.kind() == "function_item" {
|
|
537
|
+
// Look for the function name
|
|
538
|
+
for child in node.children(&mut node.walk()) {
|
|
539
|
+
if child.kind() == "identifier" {
|
|
540
|
+
if let Ok(name) = std::str::from_utf8(&source[child.start_byte()..child.end_byte()])
|
|
541
|
+
{
|
|
542
|
+
function_names.push(name.to_string());
|
|
543
|
+
break;
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
// Recursively check children
|
|
550
|
+
for child in node.children(&mut node.walk()) {
|
|
551
|
+
function_names.extend(extract_function_names(&child, source));
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
function_names
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
/// Performance test demonstrating cache effectiveness vs correctness trade-off
|
|
558
|
+
#[test]
|
|
559
|
+
fn test_cache_performance_vs_correctness_trade_off() {
|
|
560
|
+
clear_tree_cache();
|
|
561
|
+
|
|
562
|
+
let temp_dir = TempDir::new().unwrap();
|
|
563
|
+
let file_path = temp_dir.path().join("perf_test.rs");
|
|
564
|
+
|
|
565
|
+
// Create test content
|
|
566
|
+
let content = r#"
|
|
567
|
+
fn performance_test_function() {
|
|
568
|
+
let data = vec![1, 2, 3, 4, 5];
|
|
569
|
+
let result: Vec<i32> = data.iter().map(|x| x * 2).collect();
|
|
570
|
+
println!("Result: {:?}", result);
|
|
571
|
+
return result.len();
|
|
572
|
+
}
|
|
573
|
+
"#;
|
|
574
|
+
fs::write(&file_path, content).unwrap();
|
|
575
|
+
|
|
576
|
+
let language_impl = get_language_impl_by_extension("rs").unwrap();
|
|
577
|
+
let mut parser = tree_sitter::Parser::new();
|
|
578
|
+
parser
|
|
579
|
+
.set_language(language_impl.get_tree_sitter_language())
|
|
580
|
+
.unwrap();
|
|
581
|
+
|
|
582
|
+
// Measure performance with cache
|
|
583
|
+
let start_time = SystemTime::now();
|
|
584
|
+
for _ in 0..1000 {
|
|
585
|
+
let _ = get_or_parse_tree(file_path.to_str().unwrap(), content, &mut parser);
|
|
586
|
+
}
|
|
587
|
+
let cached_duration = start_time.elapsed().unwrap();
|
|
588
|
+
|
|
589
|
+
// Clear cache and measure without cache
|
|
590
|
+
clear_tree_cache();
|
|
591
|
+
let start_time = SystemTime::now();
|
|
592
|
+
for _ in 0..1000 {
|
|
593
|
+
let _ = parser.parse(content, None);
|
|
594
|
+
}
|
|
595
|
+
let uncached_duration = start_time.elapsed().unwrap();
|
|
596
|
+
|
|
597
|
+
println!("Cached parsing: {:?}", cached_duration);
|
|
598
|
+
println!("Uncached parsing: {:?}", uncached_duration);
|
|
599
|
+
println!(
|
|
600
|
+
"Speedup: {:.2}x",
|
|
601
|
+
uncached_duration.as_secs_f64() / cached_duration.as_secs_f64()
|
|
602
|
+
);
|
|
603
|
+
|
|
604
|
+
// The cache provides significant performance improvement
|
|
605
|
+
// But at the cost of potential correctness issues demonstrated in other tests
|
|
606
|
+
assert!(
|
|
607
|
+
cached_duration < uncached_duration,
|
|
608
|
+
"Cache should provide performance improvement"
|
|
609
|
+
);
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
#[cfg(test)]
|
|
613
|
+
mod integration_tests {
|
|
614
|
+
use super::*;
|
|
615
|
+
|
|
616
|
+
/// Integration test showing cascade invalidation failure
|
|
617
|
+
/// ISSUE: Changes in one cache layer don't propagate to dependent layers
|
|
618
|
+
#[test]
|
|
619
|
+
#[ignore] // This test is expected to FAIL - demonstrates cascade issues
|
|
620
|
+
fn test_cascade_invalidation_failure() {
|
|
621
|
+
clear_tree_cache();
|
|
622
|
+
|
|
623
|
+
let temp_dir = TempDir::new().unwrap();
|
|
624
|
+
let file_path = temp_dir.path().join("cascade_test.rs");
|
|
625
|
+
|
|
626
|
+
// Create initial content
|
|
627
|
+
let initial_content = "fn test() { let x = 1; }";
|
|
628
|
+
fs::write(&file_path, initial_content).unwrap();
|
|
629
|
+
|
|
630
|
+
// Fill multiple cache layers
|
|
631
|
+
let language_impl = get_language_impl_by_extension("rs").unwrap();
|
|
632
|
+
let mut parser = tree_sitter::Parser::new();
|
|
633
|
+
parser
|
|
634
|
+
.set_language(language_impl.get_tree_sitter_language())
|
|
635
|
+
.unwrap();
|
|
636
|
+
|
|
637
|
+
// Tree cache
|
|
638
|
+
let _ = get_or_parse_tree(file_path.to_str().unwrap(), initial_content, &mut parser);
|
|
639
|
+
|
|
640
|
+
// Token cache
|
|
641
|
+
let initial_tokens = count_tokens(initial_content);
|
|
642
|
+
|
|
643
|
+
// Session cache
|
|
644
|
+
let query = "test function";
|
|
645
|
+
let query_hash = hash_query(query);
|
|
646
|
+
let mut session_cache = SessionCache::new("test".to_string(), query_hash);
|
|
647
|
+
let initial_md5 = calculate_file_md5(&file_path).unwrap();
|
|
648
|
+
session_cache
|
|
649
|
+
.file_md5_hashes
|
|
650
|
+
.insert(file_path.to_string_lossy().to_string(), initial_md5);
|
|
651
|
+
session_cache.add_to_cache(format!("{}:1-1", file_path.to_string_lossy()));
|
|
652
|
+
|
|
653
|
+
// Modify file
|
|
654
|
+
let modified_content = "fn completely_different_test() { let y = 999; let z = 888; }";
|
|
655
|
+
fs::write(&file_path, modified_content).unwrap();
|
|
656
|
+
|
|
657
|
+
// BUG: Tree cache invalidation should cascade to token cache
|
|
658
|
+
invalidate_cache_entry(file_path.to_str().unwrap());
|
|
659
|
+
|
|
660
|
+
// Get new tree (should be fresh)
|
|
661
|
+
let new_tree =
|
|
662
|
+
get_or_parse_tree(file_path.to_str().unwrap(), modified_content, &mut parser).unwrap();
|
|
663
|
+
|
|
664
|
+
// Get token count (might still be cached with old value)
|
|
665
|
+
let new_tokens = count_tokens(modified_content);
|
|
666
|
+
|
|
667
|
+
// Session cache validation
|
|
668
|
+
session_cache.validate_and_invalidate_cache(true).unwrap();
|
|
669
|
+
|
|
670
|
+
// FAILING ASSERTIONS: All caches should be consistent
|
|
671
|
+
let expected_tokens = count_tokens(modified_content);
|
|
672
|
+
assert_eq!(
|
|
673
|
+
new_tokens, expected_tokens,
|
|
674
|
+
"BUG: Token cache not invalidated when tree cache was cleared!"
|
|
675
|
+
);
|
|
676
|
+
|
|
677
|
+
assert!(
|
|
678
|
+
!session_cache.is_cached(&format!("{}:1-1", file_path.to_string_lossy())),
|
|
679
|
+
"BUG: Session cache not invalidated despite file change!"
|
|
680
|
+
);
|
|
681
|
+
}
|
|
682
|
+
}
|