@jamesaphoenix/tx-test-utils 0.4.2

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.
Files changed (101) hide show
  1. package/dist/database/index.d.ts +8 -0
  2. package/dist/database/index.d.ts.map +1 -0
  3. package/dist/database/index.js +7 -0
  4. package/dist/database/index.js.map +1 -0
  5. package/dist/database/test-database.d.ts +101 -0
  6. package/dist/database/test-database.d.ts.map +1 -0
  7. package/dist/database/test-database.js +130 -0
  8. package/dist/database/test-database.js.map +1 -0
  9. package/dist/factories/anchor.factory.d.ts +117 -0
  10. package/dist/factories/anchor.factory.d.ts.map +1 -0
  11. package/dist/factories/anchor.factory.js +201 -0
  12. package/dist/factories/anchor.factory.js.map +1 -0
  13. package/dist/factories/candidate.factory.d.ts +151 -0
  14. package/dist/factories/candidate.factory.d.ts.map +1 -0
  15. package/dist/factories/candidate.factory.js +194 -0
  16. package/dist/factories/candidate.factory.js.map +1 -0
  17. package/dist/factories/edge.factory.d.ts +119 -0
  18. package/dist/factories/edge.factory.d.ts.map +1 -0
  19. package/dist/factories/edge.factory.js +191 -0
  20. package/dist/factories/edge.factory.js.map +1 -0
  21. package/dist/factories/factories.test.d.ts +8 -0
  22. package/dist/factories/factories.test.d.ts.map +1 -0
  23. package/dist/factories/factories.test.js +419 -0
  24. package/dist/factories/factories.test.js.map +1 -0
  25. package/dist/factories/index.d.ts +15 -0
  26. package/dist/factories/index.d.ts.map +1 -0
  27. package/dist/factories/index.js +21 -0
  28. package/dist/factories/index.js.map +1 -0
  29. package/dist/factories/learning.factory.d.ts +107 -0
  30. package/dist/factories/learning.factory.d.ts.map +1 -0
  31. package/dist/factories/learning.factory.js +150 -0
  32. package/dist/factories/learning.factory.js.map +1 -0
  33. package/dist/factories/task.factory.d.ts +106 -0
  34. package/dist/factories/task.factory.d.ts.map +1 -0
  35. package/dist/factories/task.factory.js +151 -0
  36. package/dist/factories/task.factory.js.map +1 -0
  37. package/dist/fixtures/index.d.ts +36 -0
  38. package/dist/fixtures/index.d.ts.map +1 -0
  39. package/dist/fixtures/index.js +47 -0
  40. package/dist/fixtures/index.js.map +1 -0
  41. package/dist/helpers/effect.d.ts +186 -0
  42. package/dist/helpers/effect.d.ts.map +1 -0
  43. package/dist/helpers/effect.js +298 -0
  44. package/dist/helpers/effect.js.map +1 -0
  45. package/dist/helpers/effect.test.d.ts +7 -0
  46. package/dist/helpers/effect.test.d.ts.map +1 -0
  47. package/dist/helpers/effect.test.js +271 -0
  48. package/dist/helpers/effect.test.js.map +1 -0
  49. package/dist/helpers/index.d.ts +7 -0
  50. package/dist/helpers/index.d.ts.map +1 -0
  51. package/dist/helpers/index.js +11 -0
  52. package/dist/helpers/index.js.map +1 -0
  53. package/dist/index.d.ts +26 -0
  54. package/dist/index.d.ts.map +1 -0
  55. package/dist/index.js +52 -0
  56. package/dist/index.js.map +1 -0
  57. package/dist/llm-cache/cache.d.ts +152 -0
  58. package/dist/llm-cache/cache.d.ts.map +1 -0
  59. package/dist/llm-cache/cache.js +199 -0
  60. package/dist/llm-cache/cache.js.map +1 -0
  61. package/dist/llm-cache/cache.test.d.ts +7 -0
  62. package/dist/llm-cache/cache.test.d.ts.map +1 -0
  63. package/dist/llm-cache/cache.test.js +310 -0
  64. package/dist/llm-cache/cache.test.js.map +1 -0
  65. package/dist/llm-cache/cli.d.ts +113 -0
  66. package/dist/llm-cache/cli.d.ts.map +1 -0
  67. package/dist/llm-cache/cli.js +248 -0
  68. package/dist/llm-cache/cli.js.map +1 -0
  69. package/dist/llm-cache/index.d.ts +31 -0
  70. package/dist/llm-cache/index.d.ts.map +1 -0
  71. package/dist/llm-cache/index.js +31 -0
  72. package/dist/llm-cache/index.js.map +1 -0
  73. package/dist/mocks/anthropic.mock.d.ts +173 -0
  74. package/dist/mocks/anthropic.mock.d.ts.map +1 -0
  75. package/dist/mocks/anthropic.mock.js +125 -0
  76. package/dist/mocks/anthropic.mock.js.map +1 -0
  77. package/dist/mocks/ast-grep.mock.d.ts +216 -0
  78. package/dist/mocks/ast-grep.mock.d.ts.map +1 -0
  79. package/dist/mocks/ast-grep.mock.js +164 -0
  80. package/dist/mocks/ast-grep.mock.js.map +1 -0
  81. package/dist/mocks/file-system.mock.d.ts +181 -0
  82. package/dist/mocks/file-system.mock.d.ts.map +1 -0
  83. package/dist/mocks/file-system.mock.js +280 -0
  84. package/dist/mocks/file-system.mock.js.map +1 -0
  85. package/dist/mocks/index.d.ts +10 -0
  86. package/dist/mocks/index.d.ts.map +1 -0
  87. package/dist/mocks/index.js +16 -0
  88. package/dist/mocks/index.js.map +1 -0
  89. package/dist/mocks/mocks.test.d.ts +10 -0
  90. package/dist/mocks/mocks.test.d.ts.map +1 -0
  91. package/dist/mocks/mocks.test.js +961 -0
  92. package/dist/mocks/mocks.test.js.map +1 -0
  93. package/dist/mocks/openai.mock.d.ts +205 -0
  94. package/dist/mocks/openai.mock.d.ts.map +1 -0
  95. package/dist/mocks/openai.mock.js +178 -0
  96. package/dist/mocks/openai.mock.js.map +1 -0
  97. package/dist/setup/index.d.ts +7 -0
  98. package/dist/setup/index.d.ts.map +1 -0
  99. package/dist/setup/index.js +9 -0
  100. package/dist/setup/index.js.map +1 -0
  101. package/package.json +80 -0
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Test database utilities for in-memory SQLite testing.
3
+ *
4
+ * @module @tx/test-utils/database
5
+ */
6
+ export { createTestDatabase, TestDatabaseService, TestDatabaseLive, createTestDatabaseLayer } from "./test-database.js";
7
+ export type { TestDatabase } from "./test-database.js";
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/database/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,gBAAgB,EAChB,uBAAuB,EACxB,MAAM,oBAAoB,CAAA;AAC3B,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Test database utilities for in-memory SQLite testing.
3
+ *
4
+ * @module @tx/test-utils/database
5
+ */
6
+ export { createTestDatabase, TestDatabaseService, TestDatabaseLive, createTestDatabaseLayer } from "./test-database.js";
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/database/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,gBAAgB,EAChB,uBAAuB,EACxB,MAAM,oBAAoB,CAAA"}
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Test database utilities for in-memory SQLite testing.
3
+ *
4
+ * Provides an in-memory SQLite database with all migrations applied,
5
+ * suitable for integration testing of tx services.
6
+ *
7
+ * @module @tx/test-utils/database
8
+ */
9
+ import Database from "better-sqlite3";
10
+ import { Context, Effect, Layer } from "effect";
11
+ /**
12
+ * Interface for test database operations.
13
+ * Wraps better-sqlite3 with convenience methods for testing.
14
+ */
15
+ export interface TestDatabase {
16
+ /** The underlying better-sqlite3 Database instance */
17
+ readonly db: Database.Database;
18
+ /** Close the database connection */
19
+ readonly close: () => Effect.Effect<void>;
20
+ /** Delete all data from tables (preserves schema and migrations table) */
21
+ readonly reset: () => Effect.Effect<void>;
22
+ /** Execute a SELECT query and return results */
23
+ readonly query: <T = unknown>(sql: string, params?: unknown[]) => T[];
24
+ /** Execute raw SQL (DDL or DML) */
25
+ readonly exec: (sql: string) => void;
26
+ /** Execute a parameterized INSERT/UPDATE/DELETE and return run result */
27
+ readonly run: (sql: string, params?: unknown[]) => Database.RunResult;
28
+ /** Execute a function within a transaction */
29
+ readonly transaction: <T>(fn: () => T) => T;
30
+ }
31
+ declare const TestDatabaseService_base: Context.TagClass<TestDatabaseService, "TestDatabaseService", TestDatabase>;
32
+ /**
33
+ * Service tag for test database dependency injection.
34
+ *
35
+ * @example
36
+ * ```typescript
37
+ * const program = Effect.gen(function* () {
38
+ * const testDb = yield* TestDatabaseService
39
+ * testDb.exec("INSERT INTO tasks ...")
40
+ * })
41
+ *
42
+ * Effect.runSync(Effect.provide(program, TestDatabaseLive))
43
+ * ```
44
+ */
45
+ export declare class TestDatabaseService extends TestDatabaseService_base {
46
+ }
47
+ /**
48
+ * Create an in-memory test database with all migrations applied.
49
+ *
50
+ * @returns Effect that resolves to a TestDatabase instance
51
+ *
52
+ * @example
53
+ * ```typescript
54
+ * const testDb = await Effect.runPromise(createTestDatabase())
55
+ * testDb.exec("INSERT INTO tasks (id, title, status, score) VALUES ('tx-abc123', 'Test', 'backlog', 500)")
56
+ * const tasks = testDb.query("SELECT * FROM tasks")
57
+ * await Effect.runPromise(testDb.close())
58
+ * ```
59
+ */
60
+ export declare const createTestDatabase: () => Effect.Effect<TestDatabase, Error>;
61
+ /**
62
+ * Layer that provides a scoped test database.
63
+ * The database is automatically closed when the scope ends.
64
+ *
65
+ * @example
66
+ * ```typescript
67
+ * import { Effect } from 'effect'
68
+ * import { TestDatabaseService, TestDatabaseLive } from '@tx/test-utils'
69
+ *
70
+ * const program = Effect.gen(function* () {
71
+ * const testDb = yield* TestDatabaseService
72
+ * testDb.exec("INSERT INTO tasks ...")
73
+ * return testDb.query("SELECT * FROM tasks")
74
+ * })
75
+ *
76
+ * const result = await Effect.runPromise(
77
+ * Effect.provide(program, TestDatabaseLive)
78
+ * )
79
+ * ```
80
+ */
81
+ export declare const TestDatabaseLive: Layer.Layer<TestDatabaseService, Error, never>;
82
+ /**
83
+ * Create a test database Layer that can be used with SqliteClient.
84
+ * This allows using the test database with existing services that depend on SqliteClient.
85
+ *
86
+ * @example
87
+ * ```typescript
88
+ * import { SqliteClient } from '@tx/core'
89
+ * import { createTestDatabaseLayer } from '@tx/test-utils'
90
+ *
91
+ * const testLayer = createTestDatabaseLayer()
92
+ *
93
+ * // Use with services that depend on SqliteClient
94
+ * const result = await Effect.runPromise(
95
+ * Effect.provide(myServiceMethod(), testLayer)
96
+ * )
97
+ * ```
98
+ */
99
+ export declare const createTestDatabaseLayer: () => Layer.Layer<TestDatabaseService, Error>;
100
+ export {};
101
+ //# sourceMappingURL=test-database.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-database.d.ts","sourceRoot":"","sources":["../../src/database/test-database.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,QAAQ,MAAM,gBAAgB,CAAA;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAG/C;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,sDAAsD;IACtD,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,CAAA;IAC9B,oCAAoC;IACpC,QAAQ,CAAC,KAAK,EAAE,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IACzC,0EAA0E;IAC1E,QAAQ,CAAC,KAAK,EAAE,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IACzC,gDAAgD;IAChD,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,CAAA;IACrE,mCAAmC;IACnC,QAAQ,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;IACpC,yEAAyE;IACzE,QAAQ,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,KAAK,QAAQ,CAAC,SAAS,CAAA;IACrE,8CAA8C;IAC9C,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,KAAK,CAAC,CAAA;CAC5C;;AAED;;;;;;;;;;;;GAYG;AACH,qBAAa,mBAAoB,SAAQ,wBAGtC;CAAG;AAEN;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,kBAAkB,QAAO,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,KAAK,CAmEnE,CAAA;AAEJ;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,gBAAgB,gDAG5B,CAAA;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,uBAAuB,QAAO,KAAK,CAAC,KAAK,CAAC,mBAAmB,EAAE,KAAK,CAI9E,CAAA"}
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Test database utilities for in-memory SQLite testing.
3
+ *
4
+ * Provides an in-memory SQLite database with all migrations applied,
5
+ * suitable for integration testing of tx services.
6
+ *
7
+ * @module @tx/test-utils/database
8
+ */
9
+ import Database from "better-sqlite3";
10
+ import { Context, Effect, Layer } from "effect";
11
+ import { applyMigrations } from "@jamesaphoenix/tx-core";
12
+ /**
13
+ * Service tag for test database dependency injection.
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const program = Effect.gen(function* () {
18
+ * const testDb = yield* TestDatabaseService
19
+ * testDb.exec("INSERT INTO tasks ...")
20
+ * })
21
+ *
22
+ * Effect.runSync(Effect.provide(program, TestDatabaseLive))
23
+ * ```
24
+ */
25
+ export class TestDatabaseService extends Context.Tag("TestDatabaseService")() {
26
+ }
27
+ /**
28
+ * Create an in-memory test database with all migrations applied.
29
+ *
30
+ * @returns Effect that resolves to a TestDatabase instance
31
+ *
32
+ * @example
33
+ * ```typescript
34
+ * const testDb = await Effect.runPromise(createTestDatabase())
35
+ * testDb.exec("INSERT INTO tasks (id, title, status, score) VALUES ('tx-abc123', 'Test', 'backlog', 500)")
36
+ * const tasks = testDb.query("SELECT * FROM tasks")
37
+ * await Effect.runPromise(testDb.close())
38
+ * ```
39
+ */
40
+ export const createTestDatabase = () => Effect.try({
41
+ try: () => {
42
+ const db = new Database(":memory:");
43
+ // Enable WAL mode for better concurrent access (matches production settings)
44
+ db.pragma("journal_mode = WAL");
45
+ db.pragma("foreign_keys = ON");
46
+ // Run all migrations
47
+ applyMigrations(db);
48
+ const testDb = {
49
+ db,
50
+ close: () => Effect.sync(() => {
51
+ db.close();
52
+ }),
53
+ reset: () => Effect.sync(() => {
54
+ // Get all user tables (exclude sqlite internals, migrations tracking, and FTS tables)
55
+ // FTS5 shadow tables (*_fts, *_fts_data, *_fts_idx, etc.) cannot be modified directly
56
+ const tables = db
57
+ .prepare(`
58
+ SELECT name FROM sqlite_master
59
+ WHERE type='table'
60
+ AND name NOT LIKE 'sqlite_%'
61
+ AND name != 'schema_version'
62
+ AND name NOT LIKE '%_fts'
63
+ AND name NOT LIKE '%_fts_%'
64
+ AND name NOT LIKE '%_config'
65
+ `)
66
+ .all();
67
+ // Disable foreign keys temporarily to allow deletion in any order
68
+ db.exec("PRAGMA foreign_keys = OFF");
69
+ for (const { name } of tables) {
70
+ db.exec(`DELETE FROM "${name}"`);
71
+ }
72
+ db.exec("PRAGMA foreign_keys = ON");
73
+ }),
74
+ query: (sql, params = []) => {
75
+ return db.prepare(sql).all(...params);
76
+ },
77
+ exec: (sql) => {
78
+ db.exec(sql);
79
+ },
80
+ run: (sql, params = []) => {
81
+ return db.prepare(sql).run(...params);
82
+ },
83
+ transaction: (fn) => {
84
+ return db.transaction(fn)();
85
+ }
86
+ };
87
+ return testDb;
88
+ },
89
+ catch: (error) => new Error(`Failed to create test database: ${error instanceof Error ? error.message : String(error)}`)
90
+ });
91
+ /**
92
+ * Layer that provides a scoped test database.
93
+ * The database is automatically closed when the scope ends.
94
+ *
95
+ * @example
96
+ * ```typescript
97
+ * import { Effect } from 'effect'
98
+ * import { TestDatabaseService, TestDatabaseLive } from '@tx/test-utils'
99
+ *
100
+ * const program = Effect.gen(function* () {
101
+ * const testDb = yield* TestDatabaseService
102
+ * testDb.exec("INSERT INTO tasks ...")
103
+ * return testDb.query("SELECT * FROM tasks")
104
+ * })
105
+ *
106
+ * const result = await Effect.runPromise(
107
+ * Effect.provide(program, TestDatabaseLive)
108
+ * )
109
+ * ```
110
+ */
111
+ export const TestDatabaseLive = Layer.scoped(TestDatabaseService, Effect.acquireRelease(createTestDatabase(), (db) => db.close()));
112
+ /**
113
+ * Create a test database Layer that can be used with SqliteClient.
114
+ * This allows using the test database with existing services that depend on SqliteClient.
115
+ *
116
+ * @example
117
+ * ```typescript
118
+ * import { SqliteClient } from '@tx/core'
119
+ * import { createTestDatabaseLayer } from '@tx/test-utils'
120
+ *
121
+ * const testLayer = createTestDatabaseLayer()
122
+ *
123
+ * // Use with services that depend on SqliteClient
124
+ * const result = await Effect.runPromise(
125
+ * Effect.provide(myServiceMethod(), testLayer)
126
+ * )
127
+ * ```
128
+ */
129
+ export const createTestDatabaseLayer = () => Layer.scoped(TestDatabaseService, Effect.acquireRelease(createTestDatabase(), (db) => db.close()));
130
+ //# sourceMappingURL=test-database.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-database.js","sourceRoot":"","sources":["../../src/database/test-database.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,117 @@
1
+ /**
2
+ * Anchor factory for creating test anchor data.
3
+ *
4
+ * Anchors link learnings to specific file locations, symbols, or code regions.
5
+ *
6
+ * @module @tx/test-utils/factories/anchor
7
+ */
8
+ import type { Anchor, AnchorType, AnchorStatus } from "@jamesaphoenix/tx-types";
9
+ import type { TestDatabase } from "../database/index.js";
10
+ /**
11
+ * Options for creating a test anchor.
12
+ */
13
+ export interface CreateAnchorOptions {
14
+ /** Anchor ID (auto-generated if not provided) */
15
+ id?: number;
16
+ /** ID of the learning this anchor belongs to */
17
+ learningId: number;
18
+ /** Type of anchor (glob, hash, symbol, line_range) */
19
+ anchorType?: AnchorType;
20
+ /** The anchor value (pattern, hash, symbol name, etc.) */
21
+ anchorValue?: string;
22
+ /** File path the anchor points to */
23
+ filePath?: string;
24
+ /** Fully qualified symbol name (for symbol anchors) */
25
+ symbolFqname?: string | null;
26
+ /** Start line (for line_range anchors) */
27
+ lineStart?: number | null;
28
+ /** End line (for line_range anchors) */
29
+ lineEnd?: number | null;
30
+ /** Content hash (for hash anchors) */
31
+ contentHash?: string | null;
32
+ /** Content preview for self-healing comparison */
33
+ contentPreview?: string | null;
34
+ /** Anchor status (valid, drifted, invalid) */
35
+ status?: AnchorStatus;
36
+ /** Whether anchor is pinned (prevents auto-invalidation) */
37
+ pinned?: boolean;
38
+ /** Last verification timestamp */
39
+ verifiedAt?: Date | null;
40
+ /** Creation timestamp */
41
+ createdAt?: Date;
42
+ }
43
+ /**
44
+ * Factory class for creating test anchors.
45
+ *
46
+ * @example
47
+ * ```typescript
48
+ * const db = await Effect.runPromise(createTestDatabase())
49
+ * const factory = new AnchorFactory(db)
50
+ *
51
+ * // Create symbol anchor
52
+ * const anchor = factory.symbolAnchor(1, 'src/service.ts', 'handleRequest')
53
+ *
54
+ * // Create glob anchor
55
+ * const glob = factory.globAnchor(1, 'src/repo/*.ts')
56
+ *
57
+ * // Create line range anchor
58
+ * const lines = factory.lineRangeAnchor(1, 'src/service.ts', 10, 25)
59
+ * ```
60
+ */
61
+ export declare class AnchorFactory {
62
+ private counter;
63
+ private readonly db;
64
+ constructor(db: TestDatabase);
65
+ /**
66
+ * Create a single test anchor.
67
+ */
68
+ create(options: CreateAnchorOptions): Anchor;
69
+ /**
70
+ * Create multiple test anchors.
71
+ */
72
+ createMany(count: number, baseOptions: CreateAnchorOptions): Anchor[];
73
+ /**
74
+ * Create a symbol anchor pointing to a function/class/method.
75
+ */
76
+ symbolAnchor(learningId: number, filePath: string, symbolName: string, options?: Partial<CreateAnchorOptions>): Anchor;
77
+ /**
78
+ * Create a glob pattern anchor.
79
+ */
80
+ globAnchor(learningId: number, pattern: string, options?: Partial<CreateAnchorOptions>): Anchor;
81
+ /**
82
+ * Create a line range anchor.
83
+ */
84
+ lineRangeAnchor(learningId: number, filePath: string, lineStart: number, lineEnd: number, options?: Partial<CreateAnchorOptions>): Anchor;
85
+ /**
86
+ * Create a content hash anchor.
87
+ */
88
+ hashAnchor(learningId: number, filePath: string, contentHash: string, options?: Partial<CreateAnchorOptions>): Anchor;
89
+ /**
90
+ * Create an anchor with drifted status (code changed).
91
+ */
92
+ driftedAnchor(learningId: number, filePath: string, options?: Partial<CreateAnchorOptions>): Anchor;
93
+ /**
94
+ * Create an anchor with invalid status (no longer exists).
95
+ */
96
+ invalidAnchor(learningId: number, filePath: string, options?: Partial<CreateAnchorOptions>): Anchor;
97
+ /**
98
+ * Reset the internal counter.
99
+ */
100
+ reset(): void;
101
+ }
102
+ /**
103
+ * Create a single test anchor (convenience function).
104
+ *
105
+ * @example
106
+ * ```typescript
107
+ * const db = await Effect.runPromise(createTestDatabase())
108
+ * const anchor = createTestAnchor(db, {
109
+ * learningId: 1,
110
+ * anchorType: 'symbol',
111
+ * anchorValue: 'handleRequest',
112
+ * filePath: 'src/service.ts'
113
+ * })
114
+ * ```
115
+ */
116
+ export declare const createTestAnchor: (db: TestDatabase, options: CreateAnchorOptions) => Anchor;
117
+ //# sourceMappingURL=anchor.factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anchor.factory.d.ts","sourceRoot":"","sources":["../../src/factories/anchor.factory.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACV,MAAM,EAEN,UAAU,EACV,YAAY,EACb,MAAM,yBAAyB,CAAA;AAChC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAExD;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,iDAAiD;IACjD,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,gDAAgD;IAChD,UAAU,EAAE,MAAM,CAAA;IAClB,sDAAsD;IACtD,UAAU,CAAC,EAAE,UAAU,CAAA;IACvB,0DAA0D;IAC1D,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,qCAAqC;IACrC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,uDAAuD;IACvD,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,wCAAwC;IACxC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,sCAAsC;IACtC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,kDAAkD;IAClD,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,8CAA8C;IAC9C,MAAM,CAAC,EAAE,YAAY,CAAA;IACrB,4DAA4D;IAC5D,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,kCAAkC;IAClC,UAAU,CAAC,EAAE,IAAI,GAAG,IAAI,CAAA;IACxB,yBAAyB;IACzB,SAAS,CAAC,EAAE,IAAI,CAAA;CACjB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAAI;IACnB,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAc;gBAErB,EAAE,EAAE,YAAY;IAI5B;;OAEG;IACH,MAAM,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM;IA0D5C;;OAEG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,mBAAmB,GAAG,MAAM,EAAE;IAarE;;OAEG;IACH,YAAY,CACV,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,OAAO,CAAC,mBAAmB,CAAM,GACzC,MAAM;IAYT;;OAEG;IACH,UAAU,CACR,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,OAAO,CAAC,mBAAmB,CAAM,GACzC,MAAM;IAUT;;OAEG;IACH,eAAe,CACb,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,OAAO,CAAC,mBAAmB,CAAM,GACzC,MAAM;IAYT;;OAEG;IACH,UAAU,CACR,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,OAAO,CAAC,mBAAmB,CAAM,GACzC,MAAM;IAWT;;OAEG;IACH,aAAa,CACX,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,OAAO,CAAC,mBAAmB,CAAM,GACzC,MAAM;IAST;;OAEG;IACH,aAAa,CACX,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,OAAO,CAAC,mBAAmB,CAAM,GACzC,MAAM;IAST;;OAEG;IACH,KAAK,IAAI,IAAI;CAGd;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,gBAAgB,GAC3B,IAAI,YAAY,EAChB,SAAS,mBAAmB,KAC3B,MAGF,CAAA"}
@@ -0,0 +1,201 @@
1
+ /**
2
+ * Anchor factory for creating test anchor data.
3
+ *
4
+ * Anchors link learnings to specific file locations, symbols, or code regions.
5
+ *
6
+ * @module @tx/test-utils/factories/anchor
7
+ */
8
+ /**
9
+ * Factory class for creating test anchors.
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * const db = await Effect.runPromise(createTestDatabase())
14
+ * const factory = new AnchorFactory(db)
15
+ *
16
+ * // Create symbol anchor
17
+ * const anchor = factory.symbolAnchor(1, 'src/service.ts', 'handleRequest')
18
+ *
19
+ * // Create glob anchor
20
+ * const glob = factory.globAnchor(1, 'src/repo/*.ts')
21
+ *
22
+ * // Create line range anchor
23
+ * const lines = factory.lineRangeAnchor(1, 'src/service.ts', 10, 25)
24
+ * ```
25
+ */
26
+ export class AnchorFactory {
27
+ counter = 0;
28
+ db;
29
+ constructor(db) {
30
+ this.db = db;
31
+ }
32
+ /**
33
+ * Create a single test anchor.
34
+ */
35
+ create(options) {
36
+ this.counter++;
37
+ const now = new Date();
38
+ const id = options.id ?? this.counter;
39
+ const learningId = options.learningId;
40
+ const anchorType = options.anchorType ?? "symbol";
41
+ const anchorValue = options.anchorValue ?? `anchor-${this.counter}`;
42
+ const filePath = options.filePath ?? "src/test.ts";
43
+ const symbolFqname = options.symbolFqname ?? null;
44
+ const lineStart = options.lineStart ?? null;
45
+ const lineEnd = options.lineEnd ?? null;
46
+ const contentHash = options.contentHash ?? null;
47
+ const contentPreview = options.contentPreview ?? null;
48
+ const status = options.status ?? "valid";
49
+ const pinned = options.pinned ?? false;
50
+ const verifiedAt = options.verifiedAt ?? null;
51
+ const createdAt = options.createdAt ?? now;
52
+ this.db.run(`INSERT INTO learning_anchors (id, learning_id, anchor_type, anchor_value, file_path, symbol_fqname, line_start, line_end, content_hash, content_preview, status, pinned, verified_at, created_at)
53
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
54
+ id,
55
+ learningId,
56
+ anchorType,
57
+ anchorValue,
58
+ filePath,
59
+ symbolFqname,
60
+ lineStart,
61
+ lineEnd,
62
+ contentHash,
63
+ contentPreview,
64
+ status,
65
+ pinned ? 1 : 0,
66
+ verifiedAt ? verifiedAt.toISOString() : null,
67
+ createdAt.toISOString()
68
+ ]);
69
+ return {
70
+ id: id,
71
+ learningId,
72
+ anchorType,
73
+ anchorValue,
74
+ filePath,
75
+ symbolFqname,
76
+ lineStart,
77
+ lineEnd,
78
+ contentHash,
79
+ contentPreview,
80
+ status,
81
+ pinned,
82
+ verifiedAt,
83
+ createdAt
84
+ };
85
+ }
86
+ /**
87
+ * Create multiple test anchors.
88
+ */
89
+ createMany(count, baseOptions) {
90
+ const anchors = [];
91
+ for (let i = 0; i < count; i++) {
92
+ anchors.push(this.create({
93
+ ...baseOptions,
94
+ anchorValue: baseOptions.anchorValue
95
+ ? `${baseOptions.anchorValue}-${i + 1}`
96
+ : undefined
97
+ }));
98
+ }
99
+ return anchors;
100
+ }
101
+ /**
102
+ * Create a symbol anchor pointing to a function/class/method.
103
+ */
104
+ symbolAnchor(learningId, filePath, symbolName, options = {}) {
105
+ const fqname = `${filePath}::${symbolName}`;
106
+ return this.create({
107
+ ...options,
108
+ learningId,
109
+ anchorType: "symbol",
110
+ anchorValue: symbolName,
111
+ filePath,
112
+ symbolFqname: fqname
113
+ });
114
+ }
115
+ /**
116
+ * Create a glob pattern anchor.
117
+ */
118
+ globAnchor(learningId, pattern, options = {}) {
119
+ return this.create({
120
+ ...options,
121
+ learningId,
122
+ anchorType: "glob",
123
+ anchorValue: pattern,
124
+ filePath: pattern
125
+ });
126
+ }
127
+ /**
128
+ * Create a line range anchor.
129
+ */
130
+ lineRangeAnchor(learningId, filePath, lineStart, lineEnd, options = {}) {
131
+ return this.create({
132
+ ...options,
133
+ learningId,
134
+ anchorType: "line_range",
135
+ anchorValue: `${lineStart}-${lineEnd}`,
136
+ filePath,
137
+ lineStart,
138
+ lineEnd
139
+ });
140
+ }
141
+ /**
142
+ * Create a content hash anchor.
143
+ */
144
+ hashAnchor(learningId, filePath, contentHash, options = {}) {
145
+ return this.create({
146
+ ...options,
147
+ learningId,
148
+ anchorType: "hash",
149
+ anchorValue: contentHash,
150
+ filePath,
151
+ contentHash
152
+ });
153
+ }
154
+ /**
155
+ * Create an anchor with drifted status (code changed).
156
+ */
157
+ driftedAnchor(learningId, filePath, options = {}) {
158
+ return this.create({
159
+ ...options,
160
+ learningId,
161
+ filePath,
162
+ status: "drifted"
163
+ });
164
+ }
165
+ /**
166
+ * Create an anchor with invalid status (no longer exists).
167
+ */
168
+ invalidAnchor(learningId, filePath, options = {}) {
169
+ return this.create({
170
+ ...options,
171
+ learningId,
172
+ filePath,
173
+ status: "invalid"
174
+ });
175
+ }
176
+ /**
177
+ * Reset the internal counter.
178
+ */
179
+ reset() {
180
+ this.counter = 0;
181
+ }
182
+ }
183
+ /**
184
+ * Create a single test anchor (convenience function).
185
+ *
186
+ * @example
187
+ * ```typescript
188
+ * const db = await Effect.runPromise(createTestDatabase())
189
+ * const anchor = createTestAnchor(db, {
190
+ * learningId: 1,
191
+ * anchorType: 'symbol',
192
+ * anchorValue: 'handleRequest',
193
+ * filePath: 'src/service.ts'
194
+ * })
195
+ * ```
196
+ */
197
+ export const createTestAnchor = (db, options) => {
198
+ const factory = new AnchorFactory(db);
199
+ return factory.create(options);
200
+ };
201
+ //# sourceMappingURL=anchor.factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anchor.factory.js","sourceRoot":"","sources":["../../src/factories/anchor.factory.ts"],"names":[],"mappings":"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"}