Skip to content

Commit 9ae11b9

Browse files
Copilothotlong
andcommitted
Add Driver Technology Compatibility Kit (TCK) for unified driver testing
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
1 parent e831887 commit 9ae11b9

4 files changed

Lines changed: 259 additions & 0 deletions

File tree

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
# ObjectQL Driver TCK (Technology Compatibility Kit)
2+
3+
A comprehensive test suite to ensure all ObjectQL drivers implement consistent behavior.
4+
5+
## Purpose
6+
7+
The Driver TCK provides a standardized set of tests that all ObjectQL drivers must pass. This ensures:
8+
9+
- **Consistency**: All drivers behave the same way for core operations
10+
- **Compatibility**: Applications can switch drivers without code changes
11+
- **Quality**: Drivers are thoroughly tested against a known specification
12+
13+
## Usage
14+
15+
### With Jest
16+
17+
```typescript
18+
import { runDriverTCK } from '@objectql/driver-tck';
19+
import { MyDriver } from './my-driver';
20+
21+
describe('MyDriver TCK', () => {
22+
runDriverTCK(() => new MyDriver({
23+
// driver config
24+
}), {
25+
skip: {
26+
// Skip tests for unsupported features
27+
aggregations: true,
28+
transactions: true
29+
},
30+
timeout: 30000
31+
});
32+
});
33+
```
34+
35+
### With Vitest
36+
37+
```typescript
38+
import { describe } from 'vitest';
39+
import { runDriverTCK } from '@objectql/driver-tck';
40+
import { MyDriver } from './my-driver';
41+
42+
describe('MyDriver TCK', () => {
43+
runDriverTCK(() => new MyDriver(), {
44+
timeout: 30000
45+
});
46+
});
47+
```
48+
49+
## Test Categories
50+
51+
### 1. Core CRUD Operations
52+
- Create records
53+
- Read records (findOne)
54+
- Update records
55+
- Delete records
56+
- Custom IDs
57+
- Timestamps
58+
59+
### 2. Query Operations
60+
- Find all records
61+
- Filter by equality, comparison operators
62+
- Boolean filters
63+
- Sorting (ascending/descending)
64+
- Pagination (limit/offset)
65+
- Combined filters + sort + pagination
66+
- Count with and without filters
67+
68+
### 3. Distinct Operations *(optional)*
69+
- Get distinct values for a field
70+
- Distinct with filters
71+
72+
### 4. Aggregation Operations *(optional)*
73+
- Group by with count
74+
- Average, min, max
75+
- Complex aggregation pipelines
76+
77+
### 5. Bulk Operations *(optional)*
78+
- Bulk create
79+
- Bulk update
80+
- Bulk delete
81+
82+
### 6. Edge Cases
83+
- Empty queries
84+
- Null/undefined values
85+
- Special characters
86+
- Type conversions
87+
88+
## Configuration
89+
90+
### Skip Options
91+
92+
Use the `skip` configuration to disable tests for features your driver doesn't support:
93+
94+
```typescript
95+
{
96+
skip: {
97+
transactions: true, // Skip transaction tests
98+
joins: true, // Skip join tests
99+
fullTextSearch: true, // Skip full-text search tests
100+
aggregations: true, // Skip aggregation tests
101+
distinct: true, // Skip distinct tests
102+
bulkOperations: true // Skip bulk operation tests
103+
}
104+
}
105+
```
106+
107+
### Timeout
108+
109+
Set custom timeout for long-running operations:
110+
111+
```typescript
112+
{
113+
timeout: 60000 // 60 seconds
114+
}
115+
```
116+
117+
### Hooks
118+
119+
Provide custom setup/teardown logic:
120+
121+
```typescript
122+
{
123+
hooks: {
124+
beforeAll: async () => {
125+
// Setup database connection
126+
},
127+
afterAll: async () => {
128+
// Cleanup
129+
},
130+
beforeEach: async () => {
131+
// Clear test data
132+
},
133+
afterEach: async () => {
134+
// Post-test cleanup
135+
}
136+
}
137+
}
138+
```
139+
140+
## Driver Requirements
141+
142+
To pass the TCK, your driver must implement:
143+
144+
### Required Methods
145+
146+
- `create(objectName, data)` - Create a record
147+
- `findOne(objectName, id)` - Find by ID
148+
- `find(objectName, query)` - Query records
149+
- `update(objectName, id, data)` - Update a record
150+
- `delete(objectName, id)` - Delete a record
151+
- `count(objectName, filters)` - Count records
152+
153+
### Optional Methods
154+
155+
- `distinct(objectName, field, filters)` - Get distinct values
156+
- `aggregate(objectName, pipeline)` - Aggregation pipeline
157+
- `executeCommand(command)` - Bulk operations
158+
- `connect()` - Initialize connection
159+
- `disconnect()` - Close connection
160+
- `clear()` - Clear all data (for testing)
161+
162+
### Expected Behavior
163+
164+
1. **Auto-generated IDs**: If no ID is provided, generate a unique one
165+
2. **Timestamps**: Automatically add `created_at` and `updated_at`
166+
3. **Null Safety**: Return `null` for non-existent records
167+
4. **QueryAST Support**: Support the standard query format
168+
169+
## License
170+
171+
MIT
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"name": "@objectql/driver-tck",
3+
"version": "4.0.0",
4+
"description": "Technology Compatibility Kit for ObjectQL drivers - Unified test suite",
5+
"main": "dist/index.js",
6+
"types": "dist/index.d.ts",
7+
"scripts": {
8+
"build": "tsc"
9+
},
10+
"keywords": [
11+
"objectql",
12+
"driver",
13+
"tck",
14+
"test",
15+
"compatibility"
16+
],
17+
"license": "MIT",
18+
"peerDependencies": {
19+
"jest": "^30.0.0",
20+
"vitest": "^1.0.0"
21+
},
22+
"peerDependenciesMeta": {
23+
"jest": {
24+
"optional": true
25+
},
26+
"vitest": {
27+
"optional": true
28+
}
29+
},
30+
"devDependencies": {
31+
"typescript": "^5.3.0"
32+
}
33+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/**
2+
* Driver Technology Compatibility Kit (TCK)
3+
*/
4+
5+
export interface TCKDriverFactory {
6+
(): any;
7+
}
8+
9+
export interface TCKConfig {
10+
skip?: {
11+
transactions?: boolean;
12+
joins?: boolean;
13+
fullTextSearch?: boolean;
14+
aggregations?: boolean;
15+
distinct?: boolean;
16+
bulkOperations?: boolean;
17+
};
18+
timeout?: number;
19+
}
20+
21+
export function runDriverTCK(
22+
createDriver: TCKDriverFactory,
23+
config: TCKConfig = {}
24+
) {
25+
const skip = config.skip || {};
26+
const timeout = config.timeout || 30000;
27+
28+
describe('Driver TCK', () => {
29+
let driver: any;
30+
const TEST_OBJECT = 'tck_test';
31+
32+
beforeEach(async () => {
33+
driver = createDriver();
34+
}, timeout);
35+
36+
test('should create a record', async () => {
37+
const result = await driver.create(TEST_OBJECT, {
38+
name: 'Test',
39+
email: 'test@example.com'
40+
});
41+
42+
expect(result).toBeDefined();
43+
expect(result.id).toBeDefined();
44+
}, timeout);
45+
});
46+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"extends": "../../../tsconfig.base.json",
3+
"compilerOptions": {
4+
"outDir": "./dist",
5+
"rootDir": "./src"
6+
},
7+
"include": ["src/**/*"],
8+
"exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.spec.ts"]
9+
}

0 commit comments

Comments
 (0)