seer-mcp 0.1.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/.vscode/settings.json +3 -0
- package/LICENSE +176 -0
- package/README.md +272 -0
- package/README_dev.md +199 -0
- package/dist/bundle/ci.d.ts +47 -0
- package/dist/bundle/ci.d.ts.map +1 -0
- package/dist/bundle/ci.js +113 -0
- package/dist/bundle/ci.js.map +1 -0
- package/dist/bundle/contract.d.ts +111 -0
- package/dist/bundle/contract.d.ts.map +1 -0
- package/dist/bundle/contract.js +352 -0
- package/dist/bundle/contract.js.map +1 -0
- package/dist/bundle/export.d.ts +36 -0
- package/dist/bundle/export.d.ts.map +1 -0
- package/dist/bundle/export.js +152 -0
- package/dist/bundle/export.js.map +1 -0
- package/dist/bundle/external.d.ts +66 -0
- package/dist/bundle/external.d.ts.map +1 -0
- package/dist/bundle/external.js +238 -0
- package/dist/bundle/external.js.map +1 -0
- package/dist/bundle/format.d.ts +94 -0
- package/dist/bundle/format.d.ts.map +1 -0
- package/dist/bundle/format.js +42 -0
- package/dist/bundle/format.js.map +1 -0
- package/dist/bundle/import.d.ts +49 -0
- package/dist/bundle/import.d.ts.map +1 -0
- package/dist/bundle/import.js +116 -0
- package/dist/bundle/import.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +1402 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init.d.ts +48 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +284 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/db/schema.d.ts +3 -0
- package/dist/db/schema.d.ts.map +1 -0
- package/dist/db/schema.js +616 -0
- package/dist/db/schema.js.map +1 -0
- package/dist/db/store.d.ts +1011 -0
- package/dist/db/store.d.ts.map +1 -0
- package/dist/db/store.js +3888 -0
- package/dist/db/store.js.map +1 -0
- package/dist/graph/pagerank.d.ts +9 -0
- package/dist/graph/pagerank.d.ts.map +1 -0
- package/dist/graph/pagerank.js +47 -0
- package/dist/graph/pagerank.js.map +1 -0
- package/dist/indexer/architecture.d.ts +72 -0
- package/dist/indexer/architecture.d.ts.map +1 -0
- package/dist/indexer/architecture.js +112 -0
- package/dist/indexer/architecture.js.map +1 -0
- package/dist/indexer/behavior.d.ts +75 -0
- package/dist/indexer/behavior.d.ts.map +1 -0
- package/dist/indexer/behavior.js +395 -0
- package/dist/indexer/behavior.js.map +1 -0
- package/dist/indexer/boundaries.d.ts +60 -0
- package/dist/indexer/boundaries.d.ts.map +1 -0
- package/dist/indexer/boundaries.js +366 -0
- package/dist/indexer/boundaries.js.map +1 -0
- package/dist/indexer/churn.d.ts +15 -0
- package/dist/indexer/churn.d.ts.map +1 -0
- package/dist/indexer/churn.js +49 -0
- package/dist/indexer/churn.js.map +1 -0
- package/dist/indexer/classify.d.ts +9 -0
- package/dist/indexer/classify.d.ts.map +1 -0
- package/dist/indexer/classify.js +90 -0
- package/dist/indexer/classify.js.map +1 -0
- package/dist/indexer/context.d.ts +176 -0
- package/dist/indexer/context.d.ts.map +1 -0
- package/dist/indexer/context.js +193 -0
- package/dist/indexer/context.js.map +1 -0
- package/dist/indexer/continuity.d.ts +67 -0
- package/dist/indexer/continuity.d.ts.map +1 -0
- package/dist/indexer/continuity.js +288 -0
- package/dist/indexer/continuity.js.map +1 -0
- package/dist/indexer/detectchanges.d.ts +32 -0
- package/dist/indexer/detectchanges.d.ts.map +1 -0
- package/dist/indexer/detectchanges.js +74 -0
- package/dist/indexer/detectchanges.js.map +1 -0
- package/dist/indexer/discovery.d.ts +37 -0
- package/dist/indexer/discovery.d.ts.map +1 -0
- package/dist/indexer/discovery.js +136 -0
- package/dist/indexer/discovery.js.map +1 -0
- package/dist/indexer/externaldeps.d.ts +18 -0
- package/dist/indexer/externaldeps.d.ts.map +1 -0
- package/dist/indexer/externaldeps.js +288 -0
- package/dist/indexer/externaldeps.js.map +1 -0
- package/dist/indexer/freshness.d.ts +48 -0
- package/dist/indexer/freshness.d.ts.map +1 -0
- package/dist/indexer/freshness.js +128 -0
- package/dist/indexer/freshness.js.map +1 -0
- package/dist/indexer/git.d.ts +144 -0
- package/dist/indexer/git.d.ts.map +1 -0
- package/dist/indexer/git.js +444 -0
- package/dist/indexer/git.js.map +1 -0
- package/dist/indexer/index.d.ts +145 -0
- package/dist/indexer/index.d.ts.map +1 -0
- package/dist/indexer/index.js +930 -0
- package/dist/indexer/index.js.map +1 -0
- package/dist/indexer/modules.d.ts +62 -0
- package/dist/indexer/modules.d.ts.map +1 -0
- package/dist/indexer/modules.js +293 -0
- package/dist/indexer/modules.js.map +1 -0
- package/dist/indexer/preflight.d.ts +154 -0
- package/dist/indexer/preflight.d.ts.map +1 -0
- package/dist/indexer/preflight.js +399 -0
- package/dist/indexer/preflight.js.map +1 -0
- package/dist/indexer/protoScanner.d.ts +34 -0
- package/dist/indexer/protoScanner.d.ts.map +1 -0
- package/dist/indexer/protoScanner.js +133 -0
- package/dist/indexer/protoScanner.js.map +1 -0
- package/dist/indexer/risk.d.ts +115 -0
- package/dist/indexer/risk.d.ts.map +1 -0
- package/dist/indexer/risk.js +194 -0
- package/dist/indexer/risk.js.map +1 -0
- package/dist/indexer/serviceHostScanner.d.ts +25 -0
- package/dist/indexer/serviceHostScanner.d.ts.map +1 -0
- package/dist/indexer/serviceHostScanner.js +95 -0
- package/dist/indexer/serviceHostScanner.js.map +1 -0
- package/dist/indexer/serviceLinks.d.ts +105 -0
- package/dist/indexer/serviceLinks.d.ts.map +1 -0
- package/dist/indexer/serviceLinks.js +509 -0
- package/dist/indexer/serviceLinks.js.map +1 -0
- package/dist/indexer/shapehash.d.ts +98 -0
- package/dist/indexer/shapehash.d.ts.map +1 -0
- package/dist/indexer/shapehash.js +354 -0
- package/dist/indexer/shapehash.js.map +1 -0
- package/dist/indexer/skeleton.d.ts +15 -0
- package/dist/indexer/skeleton.d.ts.map +1 -0
- package/dist/indexer/skeleton.js +136 -0
- package/dist/indexer/skeleton.js.map +1 -0
- package/dist/indexer/symbolhistory.d.ts +41 -0
- package/dist/indexer/symbolhistory.d.ts.map +1 -0
- package/dist/indexer/symbolhistory.js +124 -0
- package/dist/indexer/symbolhistory.js.map +1 -0
- package/dist/indexer/watcher.d.ts +68 -0
- package/dist/indexer/watcher.d.ts.map +1 -0
- package/dist/indexer/watcher.js +179 -0
- package/dist/indexer/watcher.js.map +1 -0
- package/dist/mcp/server.d.ts +80 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +1610 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/parser/index.d.ts +8 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +33 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/parser/languages/cpp.d.ts +3 -0
- package/dist/parser/languages/cpp.d.ts.map +1 -0
- package/dist/parser/languages/cpp.js +350 -0
- package/dist/parser/languages/cpp.js.map +1 -0
- package/dist/parser/languages/csharp.d.ts +3 -0
- package/dist/parser/languages/csharp.d.ts.map +1 -0
- package/dist/parser/languages/csharp.js +239 -0
- package/dist/parser/languages/csharp.js.map +1 -0
- package/dist/parser/languages/go.d.ts +3 -0
- package/dist/parser/languages/go.d.ts.map +1 -0
- package/dist/parser/languages/go.js +259 -0
- package/dist/parser/languages/go.js.map +1 -0
- package/dist/parser/languages/java.d.ts +3 -0
- package/dist/parser/languages/java.d.ts.map +1 -0
- package/dist/parser/languages/java.js +391 -0
- package/dist/parser/languages/java.js.map +1 -0
- package/dist/parser/languages/python.d.ts +3 -0
- package/dist/parser/languages/python.d.ts.map +1 -0
- package/dist/parser/languages/python.js +396 -0
- package/dist/parser/languages/python.js.map +1 -0
- package/dist/parser/languages/rust.d.ts +3 -0
- package/dist/parser/languages/rust.d.ts.map +1 -0
- package/dist/parser/languages/rust.js +159 -0
- package/dist/parser/languages/rust.js.map +1 -0
- package/dist/parser/languages/typescript.d.ts +3 -0
- package/dist/parser/languages/typescript.d.ts.map +1 -0
- package/dist/parser/languages/typescript.js +1442 -0
- package/dist/parser/languages/typescript.js.map +1 -0
- package/dist/parser/parserContext.d.ts +77 -0
- package/dist/parser/parserContext.d.ts.map +1 -0
- package/dist/parser/parserContext.js +354 -0
- package/dist/parser/parserContext.js.map +1 -0
- package/dist/parser/walker.d.ts +81 -0
- package/dist/parser/walker.d.ts.map +1 -0
- package/dist/parser/walker.js +217 -0
- package/dist/parser/walker.js.map +1 -0
- package/dist/parser/worker.d.ts +66 -0
- package/dist/parser/worker.d.ts.map +1 -0
- package/dist/parser/worker.js +129 -0
- package/dist/parser/worker.js.map +1 -0
- package/dist/parser/workerpool.d.ts +107 -0
- package/dist/parser/workerpool.d.ts.map +1 -0
- package/dist/parser/workerpool.js +383 -0
- package/dist/parser/workerpool.js.map +1 -0
- package/dist/scip/format.d.ts +87 -0
- package/dist/scip/format.d.ts.map +1 -0
- package/dist/scip/format.js +31 -0
- package/dist/scip/format.js.map +1 -0
- package/dist/scip/import.d.ts +37 -0
- package/dist/scip/import.d.ts.map +1 -0
- package/dist/scip/import.js +180 -0
- package/dist/scip/import.js.map +1 -0
- package/dist/types.d.ts +392 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +4 -0
- package/dist/types.js.map +1 -0
- package/docs/architecture.md +105 -0
- package/docs/benchmarks/methodology.md +134 -0
- package/docs/benchmarks/raw-results.md +71 -0
- package/docs/benchmarks.md +74 -0
- package/docs/cli.md +148 -0
- package/docs/examples/behavior-tests.md +70 -0
- package/docs/examples/change-history.md +85 -0
- package/docs/examples/pre-edit-context.md +81 -0
- package/docs/examples/service-links.md +88 -0
- package/docs/examples.md +80 -0
- package/docs/faq.md +70 -0
- package/docs/internals.md +104 -0
- package/docs/languages.md +70 -0
- package/docs/limits.md +52 -0
- package/docs/mcp.md +199 -0
- package/docs/quickstart.md +119 -0
- package/docs/testing.md +123 -0
- package/docs/tools.md +115 -0
- package/package.json +52 -0
- package/research-codebase.md +578 -0
- package/seer-cli-docs.md +326 -0
- package/seer-master-guide.md +246 -0
- package/src/bundle/ci.ts +141 -0
- package/src/bundle/contract.ts +387 -0
- package/src/bundle/export.ts +175 -0
- package/src/bundle/external.ts +285 -0
- package/src/bundle/format.ts +92 -0
- package/src/bundle/import.ts +157 -0
- package/src/cli/index.ts +1249 -0
- package/src/cli/init.ts +389 -0
- package/src/db/schema.ts +614 -0
- package/src/db/store.ts +4306 -0
- package/src/graph/pagerank.ts +53 -0
- package/src/indexer/architecture.ts +148 -0
- package/src/indexer/behavior.ts +466 -0
- package/src/indexer/boundaries.ts +374 -0
- package/src/indexer/churn.ts +58 -0
- package/src/indexer/classify.ts +96 -0
- package/src/indexer/context.ts +340 -0
- package/src/indexer/continuity.ts +322 -0
- package/src/indexer/detectchanges.ts +94 -0
- package/src/indexer/discovery.ts +176 -0
- package/src/indexer/externaldeps.ts +243 -0
- package/src/indexer/freshness.ts +166 -0
- package/src/indexer/git.ts +453 -0
- package/src/indexer/index.ts +1092 -0
- package/src/indexer/modules.ts +358 -0
- package/src/indexer/preflight.ts +548 -0
- package/src/indexer/protoScanner.ts +147 -0
- package/src/indexer/risk.ts +304 -0
- package/src/indexer/serviceHostScanner.ts +92 -0
- package/src/indexer/serviceLinks.ts +543 -0
- package/src/indexer/shapehash.ts +370 -0
- package/src/indexer/skeleton.ts +169 -0
- package/src/indexer/symbolhistory.ts +172 -0
- package/src/indexer/watcher.ts +206 -0
- package/src/mcp/server.ts +1659 -0
- package/src/parser/index.ts +37 -0
- package/src/parser/languages/cpp.ts +361 -0
- package/src/parser/languages/csharp.ts +235 -0
- package/src/parser/languages/go.ts +259 -0
- package/src/parser/languages/java.ts +382 -0
- package/src/parser/languages/python.ts +370 -0
- package/src/parser/languages/rust.ts +164 -0
- package/src/parser/languages/typescript.ts +1435 -0
- package/src/parser/parserContext.ts +392 -0
- package/src/parser/walker.ts +306 -0
- package/src/parser/worker.ts +181 -0
- package/src/parser/workerpool.ts +448 -0
- package/src/scip/format.ts +83 -0
- package/src/scip/import.ts +216 -0
- package/src/types.ts +457 -0
- package/tests/benchmark-service-links.ts +244 -0
- package/tests/bug-regressions.ts +626 -0
- package/tests/filters.ts +264 -0
- package/tests/fixtures/Counter.tsx +38 -0
- package/tests/fixtures/caller.ts +7 -0
- package/tests/fixtures/collisions.ts +23 -0
- package/tests/fixtures/local_helper.ts +5 -0
- package/tests/fixtures/overloads.java +17 -0
- package/tests/fixtures/remote_helper.ts +4 -0
- package/tests/fixtures/sample.c +15 -0
- package/tests/fixtures/sample.cpp +47 -0
- package/tests/fixtures/sample.cs +62 -0
- package/tests/fixtures/sample.go +68 -0
- package/tests/fixtures/sample.h +30 -0
- package/tests/fixtures/sample.java +85 -0
- package/tests/fixtures/sample.py +46 -0
- package/tests/fixtures/sample.rs +78 -0
- package/tests/fixtures/sample.ts +76 -0
- package/tests/fixtures-service/HttpClients.cs +30 -0
- package/tests/fixtures-service/HttpClients.java +24 -0
- package/tests/fixtures-service/billing.ts +15 -0
- package/tests/fixtures-service/docker-compose.yml +15 -0
- package/tests/fixtures-service/gateway.ts +10 -0
- package/tests/fixtures-service/get_user.ts +11 -0
- package/tests/fixtures-service/graphql_client.ts +63 -0
- package/tests/fixtures-service/graphql_server.ts +30 -0
- package/tests/fixtures-service/grpc_client.go +30 -0
- package/tests/fixtures-service/http_clients.go +23 -0
- package/tests/fixtures-service/http_clients.py +38 -0
- package/tests/fixtures-service/http_clients.ts +49 -0
- package/tests/fixtures-service/k8s/payment-service.yaml +22 -0
- package/tests/fixtures-service/k8s_calls.ts +20 -0
- package/tests/fixtures-service/messaging.ts +87 -0
- package/tests/fixtures-service/trpc_client.ts +39 -0
- package/tests/fixtures-service/trpc_server.ts +39 -0
- package/tests/fixtures-service/user_service.proto +33 -0
- package/tests/fixtures-trackcd/Cargo.toml +11 -0
- package/tests/fixtures-trackcd/SpringController.java +36 -0
- package/tests/fixtures-trackcd/auth_service.ts +19 -0
- package/tests/fixtures-trackcd/complex_module.py +50 -0
- package/tests/fixtures-trackcd/express_app.js +30 -0
- package/tests/fixtures-trackcd/fastapi_app.py +49 -0
- package/tests/fixtures-trackcd/fastify_object_routes.js +32 -0
- package/tests/fixtures-trackcd/go.mod +8 -0
- package/tests/fixtures-trackcd/package.json +15 -0
- package/tests/fixtures-trackcd/requirements.txt +4 -0
- package/tests/fixtures-trackcd/tests/auth_service.test.ts +13 -0
- package/tests/fixtures-tracke/auth/AuthService.ts +23 -0
- package/tests/fixtures-tracke/auth/crypto.ts +7 -0
- package/tests/fixtures-tracke/billing/Billing.ts +20 -0
- package/tests/fixtures-tracke/billing/Invoice.ts +10 -0
- package/tests/fixtures-tracke/billing/server.ts +17 -0
- package/tests/fixtures-tracke/package.json +7 -0
- package/tests/fixtures-tracke/tests/auth.test.ts +23 -0
- package/tests/fixtures-tracke/tests/billing.test.ts +14 -0
- package/tests/fixtures-trackf/package.json +5 -0
- package/tests/fixtures-trackf/src/auth.ts +26 -0
- package/tests/fixtures-trackf/src/handlers.ts +35 -0
- package/tests/fixtures-tracki/billing/routes.ts +12 -0
- package/tests/fixtures-tracki/gateway/client.ts +13 -0
- package/tests/git-features.ts +267 -0
- package/tests/init.ts +141 -0
- package/tests/mcp-jit.ts +130 -0
- package/tests/mcp-smoke.ts +191 -0
- package/tests/mcp-trackcd.ts +169 -0
- package/tests/mcp-tracke.ts +229 -0
- package/tests/mcp-trackf.ts +330 -0
- package/tests/mcp-trackg.ts +219 -0
- package/tests/mcp-tracki.ts +174 -0
- package/tests/mcp-watcher.ts +126 -0
- package/tests/optspec.ts +194 -0
- package/tests/parallel-index.ts +333 -0
- package/tests/parallel-read.ts +125 -0
- package/tests/parallel-recovery.ts +241 -0
- package/tests/perf-callers.ts +145 -0
- package/tests/query-parity.ts +184 -0
- package/tests/query-perf.ts +55 -0
- package/tests/scale-parallel-parity.ts +225 -0
- package/tests/scale-test.ts +523 -0
- package/tests/smoke.ts +396 -0
- package/tests/trackcd.ts +325 -0
- package/tests/tracke-collisions.ts +255 -0
- package/tests/tracke.ts +314 -0
- package/tests/trackf-bugs.ts +406 -0
- package/tests/trackf.ts +390 -0
- package/tests/trackg.ts +1372 -0
- package/tests/tracki-boundaries.ts +202 -0
- package/tests/tracki-continuity.ts +253 -0
- package/tests/tracki-contract-diff.ts +249 -0
- package/tests/tracki-external-bundles.ts +341 -0
- package/tests/tracki-preflight.ts +251 -0
- package/tests/verify-roles.ts +51 -0
- package/tests/worker-parity.ts +286 -0
- package/tests/worker-pool.ts +262 -0
- package/tsconfig.json +20 -0
package/tests/filters.ts
ADDED
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filter-default tests for Task 2.
|
|
3
|
+
*
|
|
4
|
+
* Verifies that:
|
|
5
|
+
* - Default search/ranking excludes test-file symbols, declarations, and
|
|
6
|
+
* (vacuously) type_refs.
|
|
7
|
+
* - Explicit includeTests=true / includeDeclarations=true / includeTypeRefs=true
|
|
8
|
+
* re-include them.
|
|
9
|
+
* - C/C++ class-body method declarations and free-function prototypes are
|
|
10
|
+
* stored with symbol_role='declaration', distinct from the body-bearing
|
|
11
|
+
* out-of-line definitions.
|
|
12
|
+
* - seer_behavior (test-edges) still works regardless of the test-file
|
|
13
|
+
* filter — the relationship table doesn't go through the file-role gate.
|
|
14
|
+
*
|
|
15
|
+
* Run with: npx tsx tests/filters.ts
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import path from 'path';
|
|
19
|
+
import os from 'os';
|
|
20
|
+
import fs from 'fs';
|
|
21
|
+
import { Indexer } from '../src/indexer/index';
|
|
22
|
+
import { Store } from '../src/db/store';
|
|
23
|
+
|
|
24
|
+
const FIXTURES = path.join(__dirname, 'fixtures');
|
|
25
|
+
const FIXTURES_TRACKCD = path.join(__dirname, 'fixtures-trackcd');
|
|
26
|
+
|
|
27
|
+
let passed = 0;
|
|
28
|
+
let failed = 0;
|
|
29
|
+
|
|
30
|
+
function assert(condition: boolean, message: string): void {
|
|
31
|
+
if (condition) {
|
|
32
|
+
console.log(` ✓ ${message}`);
|
|
33
|
+
passed++;
|
|
34
|
+
} else {
|
|
35
|
+
console.error(` ✗ ${message}`);
|
|
36
|
+
failed++;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Build a temp fixture dir that combines the C/C++ sample (for declaration
|
|
42
|
+
* tests) and the trackcd auth_service + tests/ subdir (for test-file filter
|
|
43
|
+
* tests). `indexDirectory` prunes files not seen this run, so we need ONE
|
|
44
|
+
* indexer pass over a single tree.
|
|
45
|
+
*/
|
|
46
|
+
function buildCombinedFixtures(): string {
|
|
47
|
+
const root = path.join(os.tmpdir(), `seer-filters-fixtures-${Date.now()}`);
|
|
48
|
+
fs.mkdirSync(root, { recursive: true });
|
|
49
|
+
// C/C++ smoke samples — preserves the .h vs .cpp split that produces the
|
|
50
|
+
// declaration / definition pair we want to test.
|
|
51
|
+
for (const f of ['sample.h', 'sample.cpp']) {
|
|
52
|
+
fs.copyFileSync(path.join(FIXTURES, f), path.join(root, f));
|
|
53
|
+
}
|
|
54
|
+
// Auth service from track-C/D fixtures + its test file. The test file MUST
|
|
55
|
+
// live under a tests/ subdir for classifyFile to tag it 'test'.
|
|
56
|
+
fs.copyFileSync(
|
|
57
|
+
path.join(FIXTURES_TRACKCD, 'auth_service.ts'),
|
|
58
|
+
path.join(root, 'auth_service.ts'),
|
|
59
|
+
);
|
|
60
|
+
fs.mkdirSync(path.join(root, 'tests'), { recursive: true });
|
|
61
|
+
fs.copyFileSync(
|
|
62
|
+
path.join(FIXTURES_TRACKCD, 'tests', 'auth_service.test.ts'),
|
|
63
|
+
path.join(root, 'tests', 'auth_service.test.ts'),
|
|
64
|
+
);
|
|
65
|
+
return root;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async function run(): Promise<void> {
|
|
69
|
+
console.log('\nSeer Filter Tests (Task 2)');
|
|
70
|
+
console.log('============================\n');
|
|
71
|
+
|
|
72
|
+
const root = buildCombinedFixtures();
|
|
73
|
+
const tmpDb = path.join(os.tmpdir(), `seer-filters-${Date.now()}.db`);
|
|
74
|
+
|
|
75
|
+
const store = new Store(tmpDb);
|
|
76
|
+
const indexer = new Indexer(store);
|
|
77
|
+
console.log(`Indexing ${root}...`);
|
|
78
|
+
await indexer.indexDirectory(root, { quiet: true });
|
|
79
|
+
|
|
80
|
+
// ── C/C++ declarations vs definitions ──────────────────────────────────────
|
|
81
|
+
console.log('\n── C/C++ class-body declarations ──');
|
|
82
|
+
|
|
83
|
+
// sample.h has APickupItem class-body method declarations (field_declaration
|
|
84
|
+
// with function_declarator). sample.cpp has the out-of-line definitions
|
|
85
|
+
// (function_definition). Both should be indexed; their symbol_role should
|
|
86
|
+
// differ.
|
|
87
|
+
const onPickedUpAll = store.getDefinition('OnPickedUp', { includeDeclarations: true });
|
|
88
|
+
console.log(` getDefinition('OnPickedUp', includeDeclarations=true) → ${onPickedUpAll.length} row(s):`);
|
|
89
|
+
for (const r of onPickedUpAll) {
|
|
90
|
+
console.log(` ${r.symbolRole ?? 'definition'} ${path.basename(r.filePath)}:${r.lineStart + 1} kind=${r.kind}`);
|
|
91
|
+
}
|
|
92
|
+
assert(onPickedUpAll.length >= 2, 'OnPickedUp has both declaration (.h) AND definition (.cpp)');
|
|
93
|
+
assert(
|
|
94
|
+
onPickedUpAll.some(r => r.symbolRole === 'declaration' && r.filePath.endsWith('sample.h')),
|
|
95
|
+
`sample.h's OnPickedUp tagged as 'declaration'`,
|
|
96
|
+
);
|
|
97
|
+
assert(
|
|
98
|
+
onPickedUpAll.some(r => (r.symbolRole === 'definition' || r.symbolRole == null) && r.filePath.endsWith('sample.cpp')),
|
|
99
|
+
`sample.cpp's OnPickedUp tagged as 'definition'`,
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
const onPickedUpDefault = store.getDefinition('OnPickedUp');
|
|
103
|
+
console.log(` getDefinition('OnPickedUp') default → ${onPickedUpDefault.length} row(s):`);
|
|
104
|
+
for (const r of onPickedUpDefault) {
|
|
105
|
+
console.log(` ${r.symbolRole ?? 'definition'} ${path.basename(r.filePath)}:${r.lineStart + 1}`);
|
|
106
|
+
}
|
|
107
|
+
assert(
|
|
108
|
+
onPickedUpDefault.every(r => r.symbolRole !== 'declaration'),
|
|
109
|
+
`default getDefinition hides declarations (got ${onPickedUpDefault.map(r => r.symbolRole ?? 'definition').join(', ')})`,
|
|
110
|
+
);
|
|
111
|
+
assert(
|
|
112
|
+
onPickedUpDefault.some(r => r.filePath.endsWith('sample.cpp')),
|
|
113
|
+
'default getDefinition still returns the .cpp definition',
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
const onPickedUpFindDefault = store.findSymbols('OnPickedUp');
|
|
117
|
+
assert(
|
|
118
|
+
onPickedUpFindDefault.every(r => r.symbolRole !== 'declaration'),
|
|
119
|
+
'default findSymbols hides declarations',
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
const onPickedUpFindAll = store.findSymbols('OnPickedUp', { includeDeclarations: true });
|
|
123
|
+
assert(
|
|
124
|
+
onPickedUpFindAll.some(r => r.symbolRole === 'declaration'),
|
|
125
|
+
'findSymbols(includeDeclarations=true) returns declarations',
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
// ── Test-file symbols default filter ───────────────────────────────────────
|
|
129
|
+
console.log('\n── Test-file symbols (file role: test) ──');
|
|
130
|
+
|
|
131
|
+
const testFnDefault = store.findSymbols('testAuthServiceLogin');
|
|
132
|
+
console.log(` findSymbols('testAuthServiceLogin') default → ${testFnDefault.length}`);
|
|
133
|
+
assert(
|
|
134
|
+
testFnDefault.length === 0,
|
|
135
|
+
'default findSymbols hides test-file symbols',
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
const testFnIncl = store.findSymbols('testAuthServiceLogin', { includeTests: true });
|
|
139
|
+
console.log(` findSymbols('testAuthServiceLogin', includeTests=true) → ${testFnIncl.length}`);
|
|
140
|
+
assert(
|
|
141
|
+
testFnIncl.length >= 1,
|
|
142
|
+
'findSymbols(includeTests=true) returns test-file symbols',
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
const topDefault = store.getTopSymbols(50);
|
|
146
|
+
const testInTop = topDefault.filter(s => s.filePath.includes(path.sep + 'tests' + path.sep) || s.filePath.includes('/tests/'));
|
|
147
|
+
assert(
|
|
148
|
+
testInTop.length === 0,
|
|
149
|
+
`default getTopSymbols hides test-file symbols (got ${testInTop.length})`,
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
const topWithTests = store.getTopSymbols(50, { includeTests: true });
|
|
153
|
+
assert(
|
|
154
|
+
topWithTests.length >= topDefault.length,
|
|
155
|
+
'getTopSymbols(includeTests=true) returns ≥ default count',
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
// countSymbols must respect both filters too — otherwise the MCP "total"
|
|
159
|
+
// header would lie about visible result count.
|
|
160
|
+
const cntDefault = store.countSymbols('testAuthServiceLogin');
|
|
161
|
+
const cntWithTests = store.countSymbols('testAuthServiceLogin', { includeTests: true });
|
|
162
|
+
assert(
|
|
163
|
+
cntDefault === 0 && cntWithTests >= 1,
|
|
164
|
+
`countSymbols respects includeTests (default=${cntDefault}, withTests=${cntWithTests})`,
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
// ── seer_behavior still works regardless of test-file filter ──────────────
|
|
168
|
+
console.log('\n── seer_behavior (tests edges) bypasses test filter ──');
|
|
169
|
+
|
|
170
|
+
const testsEdges = (store.rawDb().prepare(`
|
|
171
|
+
SELECT s.name AS callerName, e.to_name AS calleeName, f.role AS callerRole
|
|
172
|
+
FROM edges e
|
|
173
|
+
JOIN symbols s ON s.id = e.from_id
|
|
174
|
+
JOIN files f ON f.id = s.file_id
|
|
175
|
+
WHERE e.kind = 'tests'
|
|
176
|
+
`).all()) as Array<{ callerName: string; calleeName: string; callerRole: string }>;
|
|
177
|
+
console.log(` synthesized 'tests' edges:`);
|
|
178
|
+
for (const e of testsEdges) console.log(` ${e.callerName} → ${e.calleeName} (callerRole=${e.callerRole})`);
|
|
179
|
+
assert(
|
|
180
|
+
testsEdges.length >= 1 && testsEdges.every(e => e.callerRole === 'test'),
|
|
181
|
+
'tests edges originate from test-file symbols (intentional; seer_behavior queries them directly)',
|
|
182
|
+
);
|
|
183
|
+
|
|
184
|
+
// ── includeTypeRefs is forward-looking (no type_ref rows emitted yet) ────
|
|
185
|
+
console.log('\n── includeTypeRefs (forward-looking) ──');
|
|
186
|
+
|
|
187
|
+
const typeRefRows = (store.rawDb().prepare(`SELECT COUNT(*) AS c FROM symbols WHERE symbol_role = 'type_ref'`).get()) as { c: number };
|
|
188
|
+
console.log(` symbols with role='type_ref' in DB: ${typeRefRows.c}`);
|
|
189
|
+
assert(
|
|
190
|
+
typeRefRows.c === 0,
|
|
191
|
+
'no extractor emits type_ref rows yet (filter slot is reserved for future use)',
|
|
192
|
+
);
|
|
193
|
+
|
|
194
|
+
const empty = store.findSymbols('OnPickedUp', { includeTypeRefs: true });
|
|
195
|
+
assert(
|
|
196
|
+
Array.isArray(empty),
|
|
197
|
+
'findSymbols accepts includeTypeRefs without crashing',
|
|
198
|
+
);
|
|
199
|
+
|
|
200
|
+
// ── Vendor / generated defaults still respected ────────────────────────────
|
|
201
|
+
console.log('\n── Vendor + generated filter still in place ──');
|
|
202
|
+
|
|
203
|
+
const roles = store.getRoleCounts();
|
|
204
|
+
console.log(` role counts: project=${roles.project}, test=${roles.test}, vendor=${roles.vendor}, generated=${roles.generated}`);
|
|
205
|
+
assert(roles.test >= 1, 'at least one test file classified as test');
|
|
206
|
+
assert(roles.project >= 1, 'at least one project file');
|
|
207
|
+
|
|
208
|
+
// ── symbol_role column populated for new rows ─────────────────────────────
|
|
209
|
+
console.log('\n── symbol_role column populated ──');
|
|
210
|
+
|
|
211
|
+
const sampleDef = (store.rawDb().prepare(
|
|
212
|
+
`SELECT symbol_role FROM symbols WHERE name = 'OnPickedUp' AND file_id IN (SELECT id FROM files WHERE rel_path LIKE '%sample.cpp')`,
|
|
213
|
+
).get()) as { symbol_role: string } | undefined;
|
|
214
|
+
assert(
|
|
215
|
+
sampleDef !== undefined && sampleDef.symbol_role === 'definition',
|
|
216
|
+
`sample.cpp OnPickedUp persisted as symbol_role='definition' (got ${sampleDef?.symbol_role ?? 'missing'})`,
|
|
217
|
+
);
|
|
218
|
+
|
|
219
|
+
const sampleDecl = (store.rawDb().prepare(
|
|
220
|
+
`SELECT symbol_role FROM symbols WHERE name = 'OnPickedUp' AND file_id IN (SELECT id FROM files WHERE rel_path LIKE '%sample.h')`,
|
|
221
|
+
).get()) as { symbol_role: string } | undefined;
|
|
222
|
+
assert(
|
|
223
|
+
sampleDecl !== undefined && sampleDecl.symbol_role === 'declaration',
|
|
224
|
+
`sample.h OnPickedUp persisted as symbol_role='declaration' (got ${sampleDecl?.symbol_role ?? 'missing'})`,
|
|
225
|
+
);
|
|
226
|
+
|
|
227
|
+
// ── PageRank discipline: declarations should be non-rankable ──────────────
|
|
228
|
+
console.log('\n── Declarations are non-rankable (pinned to pr=0) ──');
|
|
229
|
+
|
|
230
|
+
const declPagerank = (store.rawDb().prepare(
|
|
231
|
+
`SELECT pagerank, is_rankable FROM symbols
|
|
232
|
+
WHERE symbol_role = 'declaration' AND kind IN ('function','method','constructor','class')`,
|
|
233
|
+
).all()) as Array<{ pagerank: number; is_rankable: number }>;
|
|
234
|
+
console.log(` declaration rows with rankable kind: ${declPagerank.length}`);
|
|
235
|
+
assert(
|
|
236
|
+
declPagerank.every(r => r.is_rankable === 0 && r.pagerank === 0),
|
|
237
|
+
'declarations are excluded from PageRank (is_rankable=0, pagerank=0)',
|
|
238
|
+
);
|
|
239
|
+
|
|
240
|
+
const defPagerank = (store.rawDb().prepare(
|
|
241
|
+
`SELECT COUNT(*) AS c FROM symbols WHERE symbol_role = 'definition' AND kind IN ('function','method','constructor','class') AND is_rankable = 1`,
|
|
242
|
+
).get()) as { c: number };
|
|
243
|
+
assert(defPagerank.c > 0, 'body-bearing definitions remain rankable');
|
|
244
|
+
|
|
245
|
+
// ── Cleanup ──────────────────────────────────────────────────────────────
|
|
246
|
+
store.close();
|
|
247
|
+
if (fs.existsSync(tmpDb)) fs.unlinkSync(tmpDb);
|
|
248
|
+
fs.rmSync(root, { recursive: true, force: true });
|
|
249
|
+
|
|
250
|
+
console.log('\n══════════════════════════════════════════════════════════════');
|
|
251
|
+
console.log(` Filter test results: ${passed} passed, ${failed} failed`);
|
|
252
|
+
|
|
253
|
+
if (failed > 0) {
|
|
254
|
+
console.error('\n FILTER TESTS FAILED\n');
|
|
255
|
+
process.exit(1);
|
|
256
|
+
} else {
|
|
257
|
+
console.log('\n All filter tests passed! ✓\n');
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
run().catch(err => {
|
|
262
|
+
console.error('Filter test threw:', err);
|
|
263
|
+
process.exit(1);
|
|
264
|
+
});
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// React + JSX fixture for Seer smoke tests.
|
|
2
|
+
// Critically this file contains JSX, which the plain `typescript` grammar
|
|
3
|
+
// cannot parse — it must be routed to the `tsx` grammar.
|
|
4
|
+
|
|
5
|
+
import React, { useState } from 'react';
|
|
6
|
+
|
|
7
|
+
interface CounterProps {
|
|
8
|
+
initial: number;
|
|
9
|
+
label?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function formatLabel(label: string | undefined, value: number): string {
|
|
13
|
+
return label ? `${label}: ${value}` : String(value);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function Counter({ initial, label }: CounterProps) {
|
|
17
|
+
const [count, setCount] = useState(initial);
|
|
18
|
+
|
|
19
|
+
const handleIncrement = () => {
|
|
20
|
+
setCount(count + 1);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<div className="counter">
|
|
25
|
+
<span>{formatLabel(label, count)}</span>
|
|
26
|
+
<button onClick={handleIncrement}>+</button>
|
|
27
|
+
</div>
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function Dashboard() {
|
|
32
|
+
return (
|
|
33
|
+
<main>
|
|
34
|
+
<Counter initial={0} label="Apples" />
|
|
35
|
+
<Counter initial={5} label="Oranges" />
|
|
36
|
+
</main>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// Two classes with a colliding short method name `run`. The walker must
|
|
2
|
+
// produce qualified names `Alpha.run` and `Beta.run` so they're
|
|
3
|
+
// distinguishable even though both have short name `run`.
|
|
4
|
+
//
|
|
5
|
+
// alphaOnly / betaOnly are unique names used to verify that call edges inside
|
|
6
|
+
// each method are attributed to the *correct* symbol, not the first `run`.
|
|
7
|
+
|
|
8
|
+
function alphaOnly(): number { return 1; }
|
|
9
|
+
function betaOnly(): number { return 2; }
|
|
10
|
+
|
|
11
|
+
export class Alpha {
|
|
12
|
+
run(): string {
|
|
13
|
+
alphaOnly();
|
|
14
|
+
return 'alpha';
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export class Beta {
|
|
19
|
+
run(): string {
|
|
20
|
+
betaOnly();
|
|
21
|
+
return 'beta';
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Overload fixture: two methods with the same name inside the same class.
|
|
2
|
+
// javaOnly1 / javaOnly2 are unique names used to verify call-edge attribution.
|
|
3
|
+
|
|
4
|
+
class OverloadHelper {
|
|
5
|
+
static int javaOnly1() { return 1; }
|
|
6
|
+
static int javaOnly2() { return 2; }
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
class Overload {
|
|
10
|
+
void run(int value) {
|
|
11
|
+
OverloadHelper.javaOnly1();
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
void run(String value) {
|
|
15
|
+
OverloadHelper.javaOnly2();
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#include <stdio.h>
|
|
2
|
+
|
|
3
|
+
static int c_helper(int value) {
|
|
4
|
+
return value + 1;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
static void c_emit(const char *message) {
|
|
8
|
+
puts(message);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
int c_entrypoint(int seed) {
|
|
12
|
+
int value = c_helper(seed);
|
|
13
|
+
c_emit("indexed from C");
|
|
14
|
+
return value;
|
|
15
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// Unreal-Engine-style implementation fixture.
|
|
2
|
+
// Exercises:
|
|
3
|
+
// - out-of-line method definitions (`APickupItem::OnPickedUp`)
|
|
4
|
+
// - field_expression call (`MeshComponent->SetVisibility`)
|
|
5
|
+
// - qualified_identifier call (`UGameplayStatics::SpawnEmitterAtLocation`)
|
|
6
|
+
// - #include resolution as "imports"
|
|
7
|
+
|
|
8
|
+
#include "sample.h"
|
|
9
|
+
#include "Kismet/GameplayStatics.h"
|
|
10
|
+
|
|
11
|
+
APickupItem::APickupItem()
|
|
12
|
+
: MeshComponent(nullptr)
|
|
13
|
+
, ItemValue(10.0f)
|
|
14
|
+
{
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
void APickupItem::BeginPlay()
|
|
18
|
+
{
|
|
19
|
+
PlayPickupSound();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
void APickupItem::Tick(float DeltaSeconds)
|
|
23
|
+
{
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
void APickupItem::OnPickedUp(APlayerCharacter* PickerUpper)
|
|
27
|
+
{
|
|
28
|
+
PlayPickupSound();
|
|
29
|
+
DestroyPickup();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
float APickupItem::GetValue() const
|
|
33
|
+
{
|
|
34
|
+
return ItemValue;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
void APickupItem::PlayPickupSound()
|
|
38
|
+
{
|
|
39
|
+
// Simulated call to an engine subsystem
|
|
40
|
+
UGameplayStatics::PlaySound2D(this, nullptr);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
void APickupItem::DestroyPickup()
|
|
44
|
+
{
|
|
45
|
+
// Another engine subsystem call via qualified identifier
|
|
46
|
+
UGameplayStatics::SpawnEmitterAtLocation(this, nullptr);
|
|
47
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// Godot-style C# fixture for Seer smoke tests.
|
|
2
|
+
// Models a Player CharacterBody2D the way Godot 4's C# bindings expose it.
|
|
3
|
+
// Exercises:
|
|
4
|
+
// - method_declaration with overrides
|
|
5
|
+
// - object_creation_expression (`new Vector2(...)`)
|
|
6
|
+
// - invocation_expression via member_access (`Input.GetVector(...)`)
|
|
7
|
+
// - using_directive imports
|
|
8
|
+
|
|
9
|
+
using System;
|
|
10
|
+
using Godot;
|
|
11
|
+
|
|
12
|
+
public partial class Player : CharacterBody2D
|
|
13
|
+
{
|
|
14
|
+
[Export]
|
|
15
|
+
public float Speed = 300.0f;
|
|
16
|
+
|
|
17
|
+
private InventoryService inventory;
|
|
18
|
+
|
|
19
|
+
public override void _Ready()
|
|
20
|
+
{
|
|
21
|
+
inventory = new InventoryService();
|
|
22
|
+
ResetState();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
public override void _PhysicsProcess(double delta)
|
|
26
|
+
{
|
|
27
|
+
Vector2 direction = Input.GetVector("left", "right", "up", "down");
|
|
28
|
+
ApplyMovement(direction, (float)delta);
|
|
29
|
+
MoveAndSlide();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
private void ApplyMovement(Vector2 direction, float delta)
|
|
33
|
+
{
|
|
34
|
+
Velocity = direction * Speed;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
private void ResetState()
|
|
38
|
+
{
|
|
39
|
+
inventory.Clear();
|
|
40
|
+
Velocity = new Vector2(0, 0);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
public class InventoryService
|
|
45
|
+
{
|
|
46
|
+
private int itemCount;
|
|
47
|
+
|
|
48
|
+
public InventoryService()
|
|
49
|
+
{
|
|
50
|
+
itemCount = 0;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
public void Clear()
|
|
54
|
+
{
|
|
55
|
+
itemCount = 0;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
public int GetItemCount()
|
|
59
|
+
{
|
|
60
|
+
return itemCount;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// Sample Go fixture for Seer smoke tests
|
|
2
|
+
package main
|
|
3
|
+
|
|
4
|
+
import "fmt"
|
|
5
|
+
|
|
6
|
+
// UserRepository handles user persistence
|
|
7
|
+
type UserRepository struct {
|
|
8
|
+
db Database
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// Database interface for storage abstraction
|
|
12
|
+
type Database interface {
|
|
13
|
+
Query(sql string, args ...interface{}) ([]Row, error)
|
|
14
|
+
Exec(sql string, args ...interface{}) error
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// Row represents a database row
|
|
18
|
+
type Row struct {
|
|
19
|
+
Values map[string]interface{}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
func NewUserRepository(db Database) *UserRepository {
|
|
23
|
+
return &UserRepository{db: db}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
func (r *UserRepository) FindByID(id string) (*User, error) {
|
|
27
|
+
rows, err := r.db.Query("SELECT * FROM users WHERE id = ?", id)
|
|
28
|
+
if err != nil {
|
|
29
|
+
return nil, err
|
|
30
|
+
}
|
|
31
|
+
return parseUser(rows)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
func (r *UserRepository) Save(user *User) error {
|
|
35
|
+
return r.db.Exec("INSERT INTO users VALUES (?, ?, ?)", user.ID, user.Email, user.Name)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// User represents a system user
|
|
39
|
+
type User struct {
|
|
40
|
+
ID string
|
|
41
|
+
Email string
|
|
42
|
+
Name string
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
func parseUser(rows []Row) (*User, error) {
|
|
46
|
+
if len(rows) == 0 {
|
|
47
|
+
return nil, fmt.Errorf("user not found")
|
|
48
|
+
}
|
|
49
|
+
row := rows[0]
|
|
50
|
+
return &User{
|
|
51
|
+
ID: fmt.Sprintf("%v", row.Values["id"]),
|
|
52
|
+
Email: fmt.Sprintf("%v", row.Values["email"]),
|
|
53
|
+
Name: fmt.Sprintf("%v", row.Values["name"]),
|
|
54
|
+
}, nil
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
func validateEmail(email string) bool {
|
|
58
|
+
return len(email) > 3 && containsAt(email)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
func containsAt(s string) bool {
|
|
62
|
+
for _, c := range s {
|
|
63
|
+
if c == '@' {
|
|
64
|
+
return true
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return false
|
|
68
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// Unreal-Engine-style header fixture for Seer smoke tests.
|
|
2
|
+
// Mimics the shape of an AActor subclass with UCLASS/UPROPERTY/UFUNCTION
|
|
3
|
+
// macros (which tree-sitter-cpp tolerates as preprocessor noise).
|
|
4
|
+
|
|
5
|
+
#pragma once
|
|
6
|
+
|
|
7
|
+
#include "CoreMinimal.h"
|
|
8
|
+
#include "GameFramework/Actor.h"
|
|
9
|
+
|
|
10
|
+
class UStaticMeshComponent;
|
|
11
|
+
|
|
12
|
+
class APickupItem : public AActor
|
|
13
|
+
{
|
|
14
|
+
public:
|
|
15
|
+
APickupItem();
|
|
16
|
+
|
|
17
|
+
void OnPickedUp(class APlayerCharacter* PickerUpper);
|
|
18
|
+
float GetValue() const;
|
|
19
|
+
|
|
20
|
+
protected:
|
|
21
|
+
virtual void BeginPlay() override;
|
|
22
|
+
virtual void Tick(float DeltaSeconds) override;
|
|
23
|
+
|
|
24
|
+
private:
|
|
25
|
+
void PlayPickupSound();
|
|
26
|
+
void DestroyPickup();
|
|
27
|
+
|
|
28
|
+
UStaticMeshComponent* MeshComponent;
|
|
29
|
+
float ItemValue;
|
|
30
|
+
};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
// Sample Java fixture for Seer smoke tests
|
|
2
|
+
import java.util.List;
|
|
3
|
+
import java.util.Optional;
|
|
4
|
+
|
|
5
|
+
public class OrderProcessor {
|
|
6
|
+
|
|
7
|
+
private final InventoryService inventory;
|
|
8
|
+
private final PaymentGateway payment;
|
|
9
|
+
|
|
10
|
+
public OrderProcessor(InventoryService inventory, PaymentGateway payment) {
|
|
11
|
+
this.inventory = inventory;
|
|
12
|
+
this.payment = payment;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
public OrderResult processOrder(Order order) {
|
|
16
|
+
if (!validateOrder(order)) {
|
|
17
|
+
return OrderResult.failure("Invalid order");
|
|
18
|
+
}
|
|
19
|
+
boolean reserved = inventory.reserve(order.getItems());
|
|
20
|
+
if (!reserved) {
|
|
21
|
+
return OrderResult.failure("Out of stock");
|
|
22
|
+
}
|
|
23
|
+
boolean charged = payment.charge(order.getTotal(), order.getCurrency());
|
|
24
|
+
if (!charged) {
|
|
25
|
+
inventory.release(order.getItems());
|
|
26
|
+
return OrderResult.failure("Payment failed");
|
|
27
|
+
}
|
|
28
|
+
return OrderResult.success(order.getId());
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
private boolean validateOrder(Order order) {
|
|
32
|
+
return order != null
|
|
33
|
+
&& order.getItems() != null
|
|
34
|
+
&& !order.getItems().isEmpty()
|
|
35
|
+
&& order.getTotal() > 0;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
interface InventoryService {
|
|
40
|
+
boolean reserve(List<OrderItem> items);
|
|
41
|
+
void release(List<OrderItem> items);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
interface PaymentGateway {
|
|
45
|
+
boolean charge(double amount, String currency);
|
|
46
|
+
boolean refund(String transactionId);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
class Order {
|
|
50
|
+
private String id;
|
|
51
|
+
private List<OrderItem> items;
|
|
52
|
+
private double total;
|
|
53
|
+
private String currency;
|
|
54
|
+
|
|
55
|
+
public String getId() { return id; }
|
|
56
|
+
public List<OrderItem> getItems() { return items; }
|
|
57
|
+
public double getTotal() { return total; }
|
|
58
|
+
public String getCurrency() { return currency; }
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
class OrderItem {
|
|
62
|
+
private String productId;
|
|
63
|
+
private int quantity;
|
|
64
|
+
|
|
65
|
+
public String getProductId() { return productId; }
|
|
66
|
+
public int getQuantity() { return quantity; }
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
class OrderResult {
|
|
70
|
+
private final boolean success;
|
|
71
|
+
private final String message;
|
|
72
|
+
|
|
73
|
+
private OrderResult(boolean success, String message) {
|
|
74
|
+
this.success = success;
|
|
75
|
+
this.message = message;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
public static OrderResult success(String orderId) {
|
|
79
|
+
return new OrderResult(true, orderId);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
public static OrderResult failure(String reason) {
|
|
83
|
+
return new OrderResult(false, reason);
|
|
84
|
+
}
|
|
85
|
+
}
|