Skip to content

Commit f566ebe

Browse files
authored
Merge pull request #357 from hoijnet/rdf-list-operator-library
Rdf list operator library
2 parents a352701 + 8882b66 commit f566ebe

22 files changed

Lines changed: 3228 additions & 197 deletions

.eslintrc.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,6 @@ module.exports = {
1313
},
1414
rules: {
1515
'func-names': ['error', 'never'],
16+
'no-unused-vars': ['error', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }],
1617
},
1718
};

integration_tests/create_database.test.ts

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,24 @@
11
//@ts-check
2-
import {describe, expect, test, beforeAll} from '@jest/globals';
3-
//import WOQLClient from '../lib/woqlClient';
4-
import {WOQLClient} from '../index.js';
2+
import {describe, expect, test, beforeAll, afterAll} from '@jest/globals';
53
import { DbDetails, DocParamsGet } from '../dist/typescript/lib/typedef';
6-
//import {ParamsObj,DbDetails} from '../lib/typedef';
74
import schemaJson from './persons_schema'
8-
//console.log(typeof schemaJson)
5+
import { createTestClient, cleanupDatabase } from "./test_utils";
96

10-
let client : WOQLClient //= new WOQLClient('http://127.0.0.1:6363');
7+
const db01 = 'db__test_create_database';
8+
let client = createTestClient();
119

12-
beforeAll(() => {
13-
client = new WOQLClient("http://127.0.0.1:6363",{ user: 'admin', organization: 'admin', key: process.env.TDB_ADMIN_PASS ?? 'root' })
10+
beforeAll(async () => {
11+
await cleanupDatabase(client, db01);
1412
});
1513

16-
const db01 = 'db__test';
17-
1814
describe('Create a database, schema and insert data', () => {
1915
test('Create a database', async () => {
2016
const dbObj : DbDetails = { label: db01, comment: 'add db', schema: true }
2117
const result = await client.createDatabase(db01,dbObj);
2218
//woqlClient return only the data no status
2319
expect(result["@type"]).toEqual("api:DbCreateResponse");
2420
expect(result["api:status"]).toEqual("api:success");
25-
});
21+
}, 15000);
2622

2723
test('Create a schema', async () => {
2824
const result = await client.addDocument(schemaJson,{graph_type:"schema",full_replace:true});
@@ -124,8 +120,8 @@ describe('Create a database, schema and insert data', () => {
124120
expect(result).toStrictEqual({ '@type': 'api:BranchResponse', 'api:status': 'api:success' });
125121
});
126122

127-
test('Delete a database', async () => {
128-
const result = await client.deleteDatabase(db01);
129-
expect(result).toStrictEqual({ '@type': 'api:DbDeleteResponse', 'api:status': 'api:success' });
130-
});
123+
});
124+
125+
afterAll(async () => {
126+
await cleanupDatabase(client, db01);
131127
});

integration_tests/remote_operations.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ describe('Remote Operations', () => {
3838
schema: true
3939
});
4040
client.db(testDbName);
41-
});
41+
}, 15000);
4242

4343
describe('createRemote', () => {
4444
test('should create a new remote successfully', async () => {

integration_tests/test_utils.ts

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
/**
2+
* Shared test utilities for integration tests
3+
*
4+
* This module provides common setup and teardown functions to avoid
5+
* code duplication across integration test files.
6+
*
7+
* Uses a shared database with per-test-suite branches for faster test isolation.
8+
*/
9+
10+
import { WOQLClient } from "../index.js";
11+
import { DbDetails } from "../dist/typescript/lib/typedef.js";
12+
13+
/**
14+
* Default server configuration for tests
15+
*/
16+
export const TEST_SERVER_URL = "http://127.0.0.1:6363";
17+
export const TEST_USER = "admin";
18+
export const TEST_ORG = "admin";
19+
export const SHARED_TEST_DB = "db__integration_tests";
20+
21+
/**
22+
* Creates a WOQLClient configured for testing
23+
*/
24+
export function createTestClient(): WOQLClient {
25+
return new WOQLClient(TEST_SERVER_URL, {
26+
user: TEST_USER,
27+
organization: TEST_ORG,
28+
key: process.env.TDB_ADMIN_PASS ?? "root"
29+
});
30+
}
31+
32+
/**
33+
* Ensures the shared test database exists
34+
* Creates it if it doesn't exist, does nothing if it already exists
35+
*/
36+
export async function ensureSharedDatabase(client: WOQLClient): Promise<void> {
37+
try {
38+
// Try to list databases and check if shared db exists
39+
const dbs = await client.getDatabases();
40+
const dbExists = dbs.some((db: any) => db.name === SHARED_TEST_DB || db.path === `${TEST_ORG}/${SHARED_TEST_DB}`);
41+
if (!dbExists) {
42+
throw new Error("Database not found");
43+
}
44+
client.db(SHARED_TEST_DB);
45+
} catch (_e) {
46+
// Database doesn't exist, create it
47+
const dbObj: DbDetails = {
48+
label: SHARED_TEST_DB,
49+
comment: "Shared database for integration tests",
50+
schema: true
51+
};
52+
await client.createDatabase(SHARED_TEST_DB, dbObj);
53+
client.db(SHARED_TEST_DB);
54+
}
55+
}
56+
57+
/**
58+
* Cleans up a branch if it exists (safe to call if it doesn't exist)
59+
*/
60+
export async function cleanupBranch(client: WOQLClient, branchName: string): Promise<void> {
61+
try {
62+
await client.deleteBranch(branchName);
63+
} catch (_e) {
64+
// Branch doesn't exist, which is fine
65+
}
66+
}
67+
68+
/**
69+
* Sets up a test branch in the shared database
70+
* Cleans up any existing branch first, then creates a fresh one
71+
*
72+
* @param client - The WOQLClient instance
73+
* @param branchName - The name of the branch to create
74+
* @returns The result of branch()
75+
*/
76+
export async function setupTestBranch(
77+
client: WOQLClient,
78+
branchName: string
79+
): Promise<any> {
80+
// Ensure shared database exists
81+
await ensureSharedDatabase(client);
82+
83+
// Clean up any existing branch from previous failed runs
84+
await cleanupBranch(client, branchName);
85+
86+
// Create a new branch from empty (not from main, to get clean state)
87+
const result = await client.branch(branchName, true);
88+
89+
// Switch to the new branch
90+
client.checkout(branchName);
91+
92+
return result;
93+
}
94+
95+
/**
96+
* Tears down a test branch
97+
* Safe to call even if the branch doesn't exist
98+
*/
99+
export async function teardownTestBranch(client: WOQLClient, branchName: string): Promise<void> {
100+
// Switch back to main before deleting
101+
client.checkout("main");
102+
await cleanupBranch(client, branchName);
103+
}
104+
105+
/**
106+
* Cleans up a database if it exists (safe to call if it doesn't exist)
107+
* This is useful for cleaning up leftover databases from failed test runs
108+
*
109+
* @param client - The WOQLClient instance
110+
* @param dbName - The name of the database to clean up
111+
*/
112+
export async function cleanupDatabase(client: WOQLClient, dbName: string): Promise<void> {
113+
try {
114+
await client.deleteDatabase(dbName);
115+
} catch (_e) {
116+
// Database doesn't exist, which is fine
117+
}
118+
}
119+
120+
/**
121+
* Sets up a test database with optional schema
122+
* Cleans up any existing database first, then creates a fresh one
123+
*
124+
* @param client - The WOQLClient instance
125+
* @param dbName - The name of the database to create
126+
* @param options - Optional configuration for the database
127+
* @returns The result of createDatabase
128+
*/
129+
export async function setupTestDatabase(
130+
client: WOQLClient,
131+
dbName: string,
132+
options: Partial<DbDetails> = {}
133+
): Promise<any> {
134+
// Clean up any existing database from previous failed runs
135+
await cleanupDatabase(client, dbName);
136+
137+
// Set up the client to use this database
138+
client.db(dbName);
139+
140+
// Create the database with default options merged with provided options
141+
const dbObj: DbDetails = {
142+
label: dbName,
143+
comment: options.comment || `Test database: ${dbName}`,
144+
schema: options.schema ?? true,
145+
...options
146+
};
147+
148+
return client.createDatabase(dbName, dbObj);
149+
}
150+
151+
/**
152+
* Tears down a test database
153+
* Safe to call even if the database doesn't exist
154+
*
155+
* @param client - The WOQLClient instance
156+
* @param dbName - The name of the database to delete
157+
*/
158+
export async function teardownTestDatabase(client: WOQLClient, dbName: string): Promise<void> {
159+
await cleanupDatabase(client, dbName);
160+
}
161+
162+
/**
163+
* Helper to run beforeAll setup for a standard integration test
164+
* Creates the client and cleans up any existing database
165+
*
166+
* @param dbName - The database name for this test suite
167+
* @returns Object with client that will be initialized
168+
*/
169+
export function createTestSetup(dbName: string): {
170+
client: WOQLClient;
171+
beforeAllFn: () => Promise<void>;
172+
afterAllFn: () => Promise<void>;
173+
} {
174+
let client: WOQLClient;
175+
176+
return {
177+
get client() {
178+
return client;
179+
},
180+
beforeAllFn: async () => {
181+
client = createTestClient();
182+
client.db(dbName);
183+
await cleanupDatabase(client, dbName);
184+
},
185+
afterAllFn: async () => {
186+
await cleanupDatabase(client, dbName);
187+
}
188+
};
189+
}

integration_tests/woql_arithmetic.test.ts

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,18 @@
11
//@ts-check
2-
import { describe, expect, test, beforeAll } from '@jest/globals';
3-
import { WOQLClient, WOQL } from '../index.js';
4-
import { DbDetails } from '../dist/typescript/lib/typedef.js';
2+
import { describe, expect, test, beforeAll, afterAll } from '@jest/globals';
3+
import { WOQL } from '../index.js';
54
import { vars, vars_unique, Vars, VarsUnique } from '../lib/woql.js';
5+
import { createTestClient, setupTestBranch, teardownTestBranch } from "./test_utils";
66

7-
let client: WOQLClient //= new WOQLClient('http://127.0.0.1:6363');
8-
const db01 = 'db__test_woql_arithmetic';
7+
const branchName = 'test_woql_arithmetic';
8+
let client = createTestClient();
99

10-
beforeAll(() => {
10+
beforeAll(async () => {
1111
WOQL.vars_unique_reset_start(20);
12-
client = new WOQLClient("http://127.0.0.1:6363", { user: 'admin', organization: 'admin', key: process.env.TDB_ADMIN_PASS ?? 'root' })
13-
client.db(db01);
14-
});
15-
12+
await setupTestBranch(client, branchName);
13+
}, 30000);
1614

1715
describe('Tests for woql arithmetic', () => {
18-
test('Create a database', async () => {
19-
const dbObj: DbDetails = { label: db01, comment: 'add db', schema: true }
20-
const result = await client.createDatabase(db01, dbObj);
21-
//woqlClient return only the data no status
22-
expect(result["@type"]).toEqual("api:DbCreateResponse");
23-
expect(result["api:status"]).toEqual("api:success");
24-
});
25-
2616
test('Test simple arithmetic with Vars variables handling', async () => {
2717
let v = Vars("result1", "result2");
2818
const query = WOQL.limit(100).eval(WOQL.times(2, 3), v.result1);
@@ -74,8 +64,8 @@ describe('Tests for woql arithmetic', () => {
7464
expect(result?.bindings).toStrictEqual(expectedJson);
7565
});
7666

77-
test('Delete a database', async () => {
78-
const result = await client.deleteDatabase(db01);
79-
expect(result).toStrictEqual({ '@type': 'api:DbDeleteResponse', 'api:status': 'api:success' });
80-
});
67+
});
68+
69+
afterAll(async () => {
70+
await teardownTestBranch(client, branchName);
8171
});

integration_tests/woql_client.test.ts

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,21 @@
11
//@ts-check
2-
import { describe, expect, test, beforeAll } from '@jest/globals';
3-
import { WOQLClient, WOQL } from '../index.js';
4-
import { DbDetails, DocParamsGet } from '../dist/typescript/lib/typedef.js';
2+
import { describe, expect, test, beforeAll, afterAll } from '@jest/globals';
3+
import { WOQL } from '../index.js';
4+
import { DocParamsGet } from '../dist/typescript/lib/typedef.js';
55
import schemaJson from './persons_schema'
66
import { mock_employees_limit_1 } from './data/employees_limit1';
77
import fs from 'fs';
8+
import { createTestClient, cleanupDatabase, setupTestDatabase } from "./test_utils";
89

9-
let client: WOQLClient //= new WOQLClient('http://127.0.0.1:6363');
10+
const db01 = 'db__test_woql_client';
11+
let client = createTestClient();
1012

11-
beforeAll(() => {
12-
client = new WOQLClient("http://127.0.0.1:6363", { user: 'admin', organization: 'admin', key: process.env.TDB_ADMIN_PASS ?? 'root' })
13-
});
14-
15-
const db01 = 'db__test_woql';
13+
beforeAll(async () => {
14+
client.db(db01);
15+
await setupTestDatabase(client, db01, { comment: 'add db' });
16+
}, 30000);
1617

1718
describe('Create a database, schema and insert data', () => {
18-
test('Create a database', async () => {
19-
const dbObj: DbDetails = { label: db01, comment: 'add db', schema: true }
20-
const result = await client.createDatabase(db01, dbObj);
21-
//woqlClient return only the data no status
22-
expect(result["@type"]).toEqual("api:DbCreateResponse");
23-
expect(result["api:status"]).toEqual("api:success");
24-
});
25-
2619
test('Create a schema', async () => {
2720
const result = await client.addDocument(schemaJson, { graph_type: "schema", full_replace: true });
2821
expect(result).toStrictEqual(["Child", "Person", "Parent"]);
@@ -80,8 +73,8 @@ describe('Create a database, schema and insert data', () => {
8073
expect(result[0]["@id"]).toStrictEqual("Organization/admin");
8174
});
8275

83-
test('Delete a database', async () => {
84-
const result = await client.deleteDatabase(db01);
85-
expect(result).toStrictEqual({ '@type': 'api:DbDeleteResponse', 'api:status': 'api:success' });
86-
});
76+
});
77+
78+
afterAll(async () => {
79+
await cleanupDatabase(client, db01);
8780
});

0 commit comments

Comments
 (0)