masterrecord 0.3.26 → 0.3.29
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/.claude/settings.local.json +21 -1
- package/Entity/entityModel.js +136 -0
- package/Entity/entityModelBuilder.js +21 -3
- package/Entity/entityTrackerModel.js +251 -1
- package/QueryLanguage/queryMethods.js +330 -4
- package/SQLLiteEngine.js +4 -0
- package/Tools.js +15 -2
- package/context.js +198 -5
- package/mySQLEngine.js +11 -1
- package/package.json +1 -1
- package/postgresEngine.js +6 -1
- package/readme.md +1070 -102
- package/test/bulk-operations-test.js +235 -0
- package/test/cache-toObject-test.js +105 -0
- package/test/debug-id-test.js +63 -0
- package/test/double-where-bug-test.js +71 -0
- package/test/entity-methods-test.js +269 -0
- package/test/id-setting-validation.js +202 -0
- package/test/insert-return-test.js +39 -0
- package/test/lifecycle-hooks-test.js +258 -0
- package/test/query-helpers-test.js +258 -0
- package/test/query-isolation-test.js +59 -0
- package/test/simple-id-test.js +61 -0
- package/test/single-user-id-test.js +70 -0
- package/test/validation-test.js +302 -0
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test: Bulk Operations API
|
|
3
|
+
* Tests: bulkCreate, bulkUpdate, bulkDelete
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const masterrecord = require('../MasterRecord.js');
|
|
7
|
+
const path = require('path');
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
|
|
10
|
+
console.log("╔════════════════════════════════════════════════════════════════╗");
|
|
11
|
+
console.log("║ Bulk Operations API Test ║");
|
|
12
|
+
console.log("╚════════════════════════════════════════════════════════════════╝\n");
|
|
13
|
+
|
|
14
|
+
let passed = 0;
|
|
15
|
+
let failed = 0;
|
|
16
|
+
|
|
17
|
+
class User {
|
|
18
|
+
id(db) {
|
|
19
|
+
db.integer().primary().auto();
|
|
20
|
+
}
|
|
21
|
+
name(db) {
|
|
22
|
+
db.string();
|
|
23
|
+
}
|
|
24
|
+
email(db) {
|
|
25
|
+
db.string();
|
|
26
|
+
}
|
|
27
|
+
status(db) {
|
|
28
|
+
db.string();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
class TestContext extends masterrecord.context {
|
|
33
|
+
constructor() {
|
|
34
|
+
super();
|
|
35
|
+
}
|
|
36
|
+
onConfig(db) {
|
|
37
|
+
this.dbset(User);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const dbPath = path.join(__dirname, '..', 'database', 'bulkOperations.db');
|
|
42
|
+
if (fs.existsSync(dbPath)) {
|
|
43
|
+
fs.unlinkSync(dbPath);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async function runTests() {
|
|
47
|
+
const db = new TestContext();
|
|
48
|
+
|
|
49
|
+
// Initialize SQLite database
|
|
50
|
+
const SQLLiteEngine = require('../SQLLiteEngine');
|
|
51
|
+
const sqlite3 = require('better-sqlite3');
|
|
52
|
+
db.isSQLite = true;
|
|
53
|
+
db.isMySQL = false;
|
|
54
|
+
db.isPostgres = false;
|
|
55
|
+
db._SQLEngine = new SQLLiteEngine();
|
|
56
|
+
db.db = new sqlite3(dbPath);
|
|
57
|
+
db._SQLEngine.setDB(db.db, 'better-sqlite3');
|
|
58
|
+
|
|
59
|
+
db.onConfig();
|
|
60
|
+
|
|
61
|
+
// Create table
|
|
62
|
+
db.db.exec('CREATE TABLE IF NOT EXISTS User (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, email TEXT, status TEXT)');
|
|
63
|
+
|
|
64
|
+
// Test 1: bulkCreate creates multiple entities
|
|
65
|
+
console.log("📝 Test 1: bulkCreate creates multiple entities");
|
|
66
|
+
console.log("──────────────────────────────────────────────────");
|
|
67
|
+
try {
|
|
68
|
+
const users = await db.bulkCreate('User', [
|
|
69
|
+
{ name: 'Alice', email: 'alice@example.com', status: 'active' },
|
|
70
|
+
{ name: 'Bob', email: 'bob@example.com', status: 'active' },
|
|
71
|
+
{ name: 'Charlie', email: 'charlie@example.com', status: 'inactive' },
|
|
72
|
+
{ name: 'Dave', email: 'dave@example.com', status: 'active' },
|
|
73
|
+
{ name: 'Eve', email: 'eve@example.com', status: 'pending' }
|
|
74
|
+
]);
|
|
75
|
+
|
|
76
|
+
if (users.length === 5 && users.every(u => u.id)) {
|
|
77
|
+
console.log(" ✓ Created 5 entities");
|
|
78
|
+
console.log(` ✓ All entities have IDs: ${users.map(u => u.id).join(', ')}`);
|
|
79
|
+
passed++;
|
|
80
|
+
} else {
|
|
81
|
+
console.log(` ✗ bulkCreate failed: ${users.length} entities created`);
|
|
82
|
+
failed++;
|
|
83
|
+
}
|
|
84
|
+
} catch(err) {
|
|
85
|
+
console.log(` ✗ Error: ${err.message}`);
|
|
86
|
+
failed++;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Test 2: bulkCreate returns entities in order
|
|
90
|
+
console.log("\n📝 Test 2: bulkCreate returns entities in order");
|
|
91
|
+
console.log("──────────────────────────────────────────────────");
|
|
92
|
+
try {
|
|
93
|
+
const users = await db.User.toList();
|
|
94
|
+
const names = users.map(u => u.name);
|
|
95
|
+
|
|
96
|
+
if (names[0] === 'Alice' && names[4] === 'Eve') {
|
|
97
|
+
console.log(" ✓ Entities created in correct order");
|
|
98
|
+
passed++;
|
|
99
|
+
} else {
|
|
100
|
+
console.log(` ✗ Order incorrect: ${names.join(', ')}`);
|
|
101
|
+
failed++;
|
|
102
|
+
}
|
|
103
|
+
} catch(err) {
|
|
104
|
+
console.log(` ✗ Error: ${err.message}`);
|
|
105
|
+
failed++;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Test 3: bulkUpdate updates multiple entities
|
|
109
|
+
console.log("\n📝 Test 3: bulkUpdate updates multiple entities");
|
|
110
|
+
console.log("──────────────────────────────────────────────────");
|
|
111
|
+
try {
|
|
112
|
+
await db.bulkUpdate('User', [
|
|
113
|
+
{ id: 1, status: 'inactive' },
|
|
114
|
+
{ id: 2, status: 'inactive' },
|
|
115
|
+
{ id: 4, status: 'inactive' }
|
|
116
|
+
]);
|
|
117
|
+
|
|
118
|
+
const user1 = await db.User.findById(1);
|
|
119
|
+
const user2 = await db.User.findById(2);
|
|
120
|
+
const user4 = await db.User.findById(4);
|
|
121
|
+
|
|
122
|
+
if (user1.status === 'inactive' && user2.status === 'inactive' && user4.status === 'inactive') {
|
|
123
|
+
console.log(" ✓ Updated 3 entities");
|
|
124
|
+
console.log(" ✓ Status changed to: inactive");
|
|
125
|
+
passed++;
|
|
126
|
+
} else {
|
|
127
|
+
console.log(` ✗ Update failed: statuses are ${user1.status}, ${user2.status}, ${user4.status}`);
|
|
128
|
+
failed++;
|
|
129
|
+
}
|
|
130
|
+
} catch(err) {
|
|
131
|
+
console.log(` ✗ Error: ${err.message}`);
|
|
132
|
+
failed++;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Test 4: bulkUpdate leaves other fields unchanged
|
|
136
|
+
console.log("\n📝 Test 4: bulkUpdate leaves other fields unchanged");
|
|
137
|
+
console.log("──────────────────────────────────────────────────");
|
|
138
|
+
try {
|
|
139
|
+
const user1 = await db.User.findById(1);
|
|
140
|
+
|
|
141
|
+
if (user1.name === 'Alice' && user1.email === 'alice@example.com') {
|
|
142
|
+
console.log(" ✓ Other fields unchanged");
|
|
143
|
+
passed++;
|
|
144
|
+
} else {
|
|
145
|
+
console.log(` ✗ Fields changed: name=${user1.name}, email=${user1.email}`);
|
|
146
|
+
failed++;
|
|
147
|
+
}
|
|
148
|
+
} catch(err) {
|
|
149
|
+
console.log(` ✗ Error: ${err.message}`);
|
|
150
|
+
failed++;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Test 5: bulkDelete deletes multiple entities
|
|
154
|
+
console.log("\n📝 Test 5: bulkDelete deletes multiple entities");
|
|
155
|
+
console.log("──────────────────────────────────────────────────");
|
|
156
|
+
try {
|
|
157
|
+
await db.bulkDelete('User', [3, 5]);
|
|
158
|
+
|
|
159
|
+
const user3 = await db.User.findById(3);
|
|
160
|
+
const user5 = await db.User.findById(5);
|
|
161
|
+
const remaining = await db.User.toList();
|
|
162
|
+
|
|
163
|
+
if (user3 === null && user5 === null && remaining.length === 3) {
|
|
164
|
+
console.log(" ✓ Deleted 2 entities");
|
|
165
|
+
console.log(` ✓ Remaining entities: ${remaining.length}`);
|
|
166
|
+
passed++;
|
|
167
|
+
} else {
|
|
168
|
+
console.log(` ✗ Delete failed: user3=${user3}, user5=${user5}, remaining=${remaining.length}`);
|
|
169
|
+
failed++;
|
|
170
|
+
}
|
|
171
|
+
} catch(err) {
|
|
172
|
+
console.log(` ✗ Error: ${err.message}`);
|
|
173
|
+
failed++;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Test 6: bulkCreate with empty array throws error
|
|
177
|
+
console.log("\n📝 Test 6: bulkCreate with empty array throws error");
|
|
178
|
+
console.log("──────────────────────────────────────────────────");
|
|
179
|
+
try {
|
|
180
|
+
await db.bulkCreate('User', []);
|
|
181
|
+
console.log(` ✗ Should have thrown error`);
|
|
182
|
+
failed++;
|
|
183
|
+
} catch(err) {
|
|
184
|
+
if (err.message.includes('non-empty array')) {
|
|
185
|
+
console.log(" ✓ Empty array rejected");
|
|
186
|
+
passed++;
|
|
187
|
+
} else {
|
|
188
|
+
console.log(` ✗ Wrong error: ${err.message}`);
|
|
189
|
+
failed++;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Test 7: bulkUpdate with invalid entity throws error
|
|
194
|
+
console.log("\n📝 Test 7: bulkUpdate with invalid entity throws error");
|
|
195
|
+
console.log("──────────────────────────────────────────────────");
|
|
196
|
+
try {
|
|
197
|
+
await db.bulkUpdate('NonExistentEntity', [{ id: 1, name: 'Test' }]);
|
|
198
|
+
console.log(` ✗ Should have thrown error`);
|
|
199
|
+
failed++;
|
|
200
|
+
} catch(err) {
|
|
201
|
+
if (err.message.includes('not found')) {
|
|
202
|
+
console.log(" ✓ Invalid entity name rejected");
|
|
203
|
+
passed++;
|
|
204
|
+
} else {
|
|
205
|
+
console.log(` ✗ Wrong error: ${err.message}`);
|
|
206
|
+
failed++;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Test 8: bulkDelete with non-existent IDs doesn't throw
|
|
211
|
+
console.log("\n📝 Test 8: bulkDelete with non-existent IDs doesn't throw");
|
|
212
|
+
console.log("──────────────────────────────────────────────────");
|
|
213
|
+
try {
|
|
214
|
+
await db.bulkDelete('User', [999, 1000, 1001]);
|
|
215
|
+
console.log(" ✓ Non-existent IDs handled gracefully");
|
|
216
|
+
passed++;
|
|
217
|
+
} catch(err) {
|
|
218
|
+
console.log(` ✗ Error: ${err.message}`);
|
|
219
|
+
failed++;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// Summary
|
|
223
|
+
console.log("\n" + "=".repeat(64));
|
|
224
|
+
console.log(`Test Results: ${passed} passed, ${failed} failed`);
|
|
225
|
+
console.log("=".repeat(64));
|
|
226
|
+
|
|
227
|
+
if (failed > 0) {
|
|
228
|
+
process.exit(1);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
runTests().catch(err => {
|
|
233
|
+
console.error('Fatal error:', err);
|
|
234
|
+
process.exit(1);
|
|
235
|
+
});
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test to verify caching properly handles entity reconstruction
|
|
3
|
+
*/
|
|
4
|
+
const assert = require('assert');
|
|
5
|
+
const context = require('../context');
|
|
6
|
+
|
|
7
|
+
describe('Cache Entity Reconstruction Test', function() {
|
|
8
|
+
let db;
|
|
9
|
+
|
|
10
|
+
before(async function() {
|
|
11
|
+
// Create in-memory SQLite database
|
|
12
|
+
db = new context({ filename: ":memory:", type: "SQLLite" });
|
|
13
|
+
|
|
14
|
+
// Define a test entity
|
|
15
|
+
db.TestEntity = {
|
|
16
|
+
__name: "TestEntity",
|
|
17
|
+
id: db.EntityModel("id").integer().primary().auto(),
|
|
18
|
+
name: db.EntityModel("name").string(),
|
|
19
|
+
description: db.EntityModel("description").string()
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
await db.initialize();
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
after(async function() {
|
|
26
|
+
if (db && db.close) {
|
|
27
|
+
await db.close();
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('should properly return cached single entity with toObject method', async function() {
|
|
32
|
+
// Insert test data
|
|
33
|
+
const entity = db.TestEntity.create();
|
|
34
|
+
entity.name = "Test Item";
|
|
35
|
+
entity.description = "Test Description";
|
|
36
|
+
await db.saveChanges();
|
|
37
|
+
|
|
38
|
+
// First query (cache miss) - with caching enabled
|
|
39
|
+
const result1 = await db.TestEntity.cache().where(t => t.id === entity.id).single();
|
|
40
|
+
|
|
41
|
+
assert(result1, 'First query should return result');
|
|
42
|
+
assert.strictEqual(result1.name, "Test Item");
|
|
43
|
+
assert(typeof result1.toObject === 'function', 'Result should have toObject method');
|
|
44
|
+
|
|
45
|
+
// Convert to plain object should work
|
|
46
|
+
const plain1 = result1.toObject();
|
|
47
|
+
assert.strictEqual(plain1.name, "Test Item");
|
|
48
|
+
|
|
49
|
+
// Second query (cache hit) - should return entity with methods
|
|
50
|
+
const result2 = await db.TestEntity.cache().where(t => t.id === entity.id).single();
|
|
51
|
+
|
|
52
|
+
assert(result2, 'Cached query should return result');
|
|
53
|
+
assert.strictEqual(result2.name, "Test Item");
|
|
54
|
+
assert(typeof result2.toObject === 'function', 'Cached result should have toObject method');
|
|
55
|
+
|
|
56
|
+
// toObject should work on cached entity
|
|
57
|
+
const plain2 = result2.toObject();
|
|
58
|
+
assert.strictEqual(plain2.name, "Test Item");
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('should properly return cached list with toObject methods', async function() {
|
|
62
|
+
// Clear any existing data
|
|
63
|
+
const existing = await db.TestEntity.toList();
|
|
64
|
+
for (const item of existing) {
|
|
65
|
+
await item.delete();
|
|
66
|
+
}
|
|
67
|
+
await db.saveChanges();
|
|
68
|
+
|
|
69
|
+
// Insert test data
|
|
70
|
+
const entity1 = db.TestEntity.create();
|
|
71
|
+
entity1.name = "Item 1";
|
|
72
|
+
const entity2 = db.TestEntity.create();
|
|
73
|
+
entity2.name = "Item 2";
|
|
74
|
+
await db.saveChanges();
|
|
75
|
+
|
|
76
|
+
// First query (cache miss)
|
|
77
|
+
const list1 = await db.TestEntity.cache().toList();
|
|
78
|
+
|
|
79
|
+
assert(Array.isArray(list1), 'First query should return array');
|
|
80
|
+
assert.strictEqual(list1.length, 2);
|
|
81
|
+
assert(typeof list1[0].toObject === 'function', 'First item should have toObject method');
|
|
82
|
+
assert(typeof list1[1].toObject === 'function', 'Second item should have toObject method');
|
|
83
|
+
|
|
84
|
+
const plain1 = list1[0].toObject();
|
|
85
|
+
assert.strictEqual(plain1.name, "Item 1");
|
|
86
|
+
|
|
87
|
+
// Second query (cache hit)
|
|
88
|
+
const list2 = await db.TestEntity.cache().toList();
|
|
89
|
+
|
|
90
|
+
assert(Array.isArray(list2), 'Cached query should return array');
|
|
91
|
+
assert.strictEqual(list2.length, 2, 'Cached array should have correct length');
|
|
92
|
+
assert(typeof list2[0].toObject === 'function', 'Cached first item should have toObject method');
|
|
93
|
+
assert(typeof list2[1].toObject === 'function', 'Cached second item should have toObject method');
|
|
94
|
+
|
|
95
|
+
const plain2 = list2[0].toObject();
|
|
96
|
+
assert.strictEqual(plain2.name, "Item 1");
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it('should handle null results properly', async function() {
|
|
100
|
+
// Query for non-existent entity
|
|
101
|
+
const result = await db.TestEntity.cache().where(t => t.id === 99999).single();
|
|
102
|
+
|
|
103
|
+
assert.strictEqual(result, null, 'Non-existent entity should return null');
|
|
104
|
+
});
|
|
105
|
+
});
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Debug test to trace ID setting
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const masterrecord = require('../MasterRecord.js');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
|
|
9
|
+
class User {
|
|
10
|
+
id(db) {
|
|
11
|
+
db.integer().primary().auto();
|
|
12
|
+
}
|
|
13
|
+
name(db) {
|
|
14
|
+
db.string();
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
class TestContext extends masterrecord.context {
|
|
19
|
+
constructor() {
|
|
20
|
+
super();
|
|
21
|
+
this.database = path.join(__dirname, '..', 'database', 'debugIdTest.db');
|
|
22
|
+
}
|
|
23
|
+
onConfig(db) {
|
|
24
|
+
this.dbset(User);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Clean
|
|
29
|
+
if (fs.existsSync(path.join(__dirname, '..', 'database', 'debugIdTest.db'))) {
|
|
30
|
+
fs.unlinkSync(path.join(__dirname, '..', 'database', 'debugIdTest.db'));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async function test() {
|
|
34
|
+
const db = new TestContext();
|
|
35
|
+
db.onConfig();
|
|
36
|
+
|
|
37
|
+
const user = db.User.new();
|
|
38
|
+
user.name = 'Test';
|
|
39
|
+
|
|
40
|
+
console.log('\n=== Manual ID set test ===');
|
|
41
|
+
console.log('Before manual set - user.id:', user.id);
|
|
42
|
+
|
|
43
|
+
user.id = 123;
|
|
44
|
+
console.log('After user.id = 123 - user.id:', user.id);
|
|
45
|
+
console.log('After manual set - user.__proto__._id:', user.__proto__._id);
|
|
46
|
+
|
|
47
|
+
user.id = 456;
|
|
48
|
+
console.log('After user.id = 456 - user.id:', user.id);
|
|
49
|
+
|
|
50
|
+
console.log('\n=== Now test with save ===');
|
|
51
|
+
const user2 = db.User.new();
|
|
52
|
+
user2.name = 'Test2';
|
|
53
|
+
|
|
54
|
+
console.log('Before save - tracked entities:', db.__trackedEntities.length);
|
|
55
|
+
console.log('Before save - user2.__state:', user2.__state);
|
|
56
|
+
|
|
57
|
+
await user2.save();
|
|
58
|
+
|
|
59
|
+
console.log('After save - user2.id:', user2.id);
|
|
60
|
+
console.log('After save - user2.__proto__._id:', user2.__proto__._id);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
test().catch(console.error);
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test for double WHERE clause bug fix
|
|
3
|
+
* Verifies that multiple queries don't accumulate parameters
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// Note: This test doesn't actually run queries, just tests query building
|
|
7
|
+
// No database needed
|
|
8
|
+
const queryMethods = require('../QueryLanguage/queryMethods');
|
|
9
|
+
const modelBuilder = require('../Entity/entityModelBuilder');
|
|
10
|
+
|
|
11
|
+
// Mock entity
|
|
12
|
+
const mockEntity = {
|
|
13
|
+
__name: 'TestEntity',
|
|
14
|
+
id: { type: 'number' },
|
|
15
|
+
name: { type: 'string' }
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
// Create test context
|
|
19
|
+
class TestContext extends context {
|
|
20
|
+
constructor() {
|
|
21
|
+
super();
|
|
22
|
+
this.dbset(mockEntity);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
console.log('=== Testing double WHERE clause bug fix ===\n');
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
const ctx = new TestContext();
|
|
30
|
+
|
|
31
|
+
// Access the entity multiple times and build queries
|
|
32
|
+
console.log('Test 1: Multiple separate queries should not share state');
|
|
33
|
+
const query1 = ctx.TestEntity.where(e => e.id == $$, 1);
|
|
34
|
+
const query2 = ctx.TestEntity.where(e => e.id == $$, 2);
|
|
35
|
+
|
|
36
|
+
// Check that they have different queryObject instances
|
|
37
|
+
const haveDifferentInstances = query1.__queryObject !== query2.__queryObject;
|
|
38
|
+
console.log(` ✓ Query instances are separate: ${haveDifferentInstances}`);
|
|
39
|
+
|
|
40
|
+
// Check parameter accumulation
|
|
41
|
+
const params1 = query1.__queryObject.parameters.get();
|
|
42
|
+
const params2 = query2.__queryObject.parameters.get();
|
|
43
|
+
|
|
44
|
+
console.log(` Query 1 parameters: [${params1}]`);
|
|
45
|
+
console.log(` Query 2 parameters: [${params2}]`);
|
|
46
|
+
|
|
47
|
+
if (params1.length === 1 && params1[0] === 1 && params2.length === 1 && params2[0] === 2) {
|
|
48
|
+
console.log(' ✓ Parameters are correctly isolated\n');
|
|
49
|
+
} else {
|
|
50
|
+
console.error(' ✗ FAIL: Parameters are not isolated!\n');
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
console.log('Test 2: Accessing entity property multiple times returns fresh instances');
|
|
55
|
+
const instance1 = ctx.TestEntity;
|
|
56
|
+
const instance2 = ctx.TestEntity;
|
|
57
|
+
const areDifferent = instance1 !== instance2;
|
|
58
|
+
console.log(` ✓ Each access returns a new instance: ${areDifferent}\n`);
|
|
59
|
+
|
|
60
|
+
if (!areDifferent) {
|
|
61
|
+
console.error(' ✗ FAIL: Instances are being reused!\n');
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
console.log('✅ All tests passed! Double WHERE bug is fixed.\n');
|
|
66
|
+
|
|
67
|
+
} catch (error) {
|
|
68
|
+
console.error('❌ Test failed with error:', error.message);
|
|
69
|
+
console.error(error.stack);
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|