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.
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Single user ID test
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
+ }
22
+ onConfig(db) {
23
+ this.dbset(User);
24
+ }
25
+ }
26
+
27
+ // Clean
28
+ const dbPath = path.join(__dirname, '..', 'database', 'singleUserTest.db');
29
+ if (fs.existsSync(dbPath)) {
30
+ fs.unlinkSync(dbPath);
31
+ }
32
+
33
+ async function test() {
34
+ const db = new TestContext();
35
+
36
+ // Manually initialize SQLite for testing
37
+ const SQLLiteEngine = require('../SQLLiteEngine');
38
+ const sqlite3 = require('better-sqlite3');
39
+
40
+ db.isSQLite = true;
41
+ db.isMySQL = false;
42
+ db.isPostgres = false;
43
+ db._SQLEngine = new SQLLiteEngine();
44
+ db.db = new sqlite3(dbPath);
45
+ db._SQLEngine.setDB(db.db, 'better-sqlite3');
46
+
47
+ db.onConfig();
48
+
49
+ // Create table
50
+ db.db.exec('CREATE TABLE IF NOT EXISTS User (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT)');
51
+
52
+ const user = db.User.new();
53
+ user.name = 'Test';
54
+
55
+ console.log('Before save - user.id:', user.id);
56
+ console.log('Before save - tracked:', db.__trackedEntities.length);
57
+
58
+ await user.save();
59
+
60
+ console.log('After save - user.id:', user.id);
61
+ console.log('After save - user.__proto__._id:', user.__proto__._id);
62
+
63
+ if (user.id) {
64
+ console.log('✓ SUCCESS - ID was set to:', user.id);
65
+ } else {
66
+ console.log('✗ FAIL - ID is still undefined');
67
+ }
68
+ }
69
+
70
+ test().catch(console.error);
@@ -0,0 +1,302 @@
1
+ /**
2
+ * Test: Business Logic Validation
3
+ * Tests: required, email, minLength, maxLength, pattern, min, max, custom
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("║ Business Logic Validation 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().required('Name is required').minLength(3, 'Name must be at least 3 characters');
23
+ }
24
+ email(db) {
25
+ db.string().required().email('Invalid email format');
26
+ }
27
+ password(db) {
28
+ db.string().minLength(8, 'Password must be at least 8 characters').maxLength(100);
29
+ }
30
+ username(db) {
31
+ db.string().pattern(/^[a-zA-Z0-9_]+$/, 'Username can only contain letters, numbers, and underscores');
32
+ }
33
+ age(db) {
34
+ db.integer().min(18, 'Must be at least 18 years old').max(120, 'Age cannot exceed 120');
35
+ }
36
+ status(db) {
37
+ db.string().custom((value) => {
38
+ return ['active', 'inactive', 'pending'].includes(value);
39
+ }, 'Status must be active, inactive, or pending');
40
+ }
41
+ }
42
+
43
+ class TestContext extends masterrecord.context {
44
+ constructor() {
45
+ super();
46
+ }
47
+ onConfig(db) {
48
+ this.dbset(User);
49
+ }
50
+ }
51
+
52
+ const dbPath = path.join(__dirname, '..', 'database', 'validation.db');
53
+ if (fs.existsSync(dbPath)) {
54
+ fs.unlinkSync(dbPath);
55
+ }
56
+
57
+ async function runTests() {
58
+ const db = new TestContext();
59
+
60
+ // Initialize SQLite database
61
+ const SQLLiteEngine = require('../SQLLiteEngine');
62
+ const sqlite3 = require('better-sqlite3');
63
+ db.isSQLite = true;
64
+ db.isMySQL = false;
65
+ db.isPostgres = false;
66
+ db._SQLEngine = new SQLLiteEngine();
67
+ db.db = new sqlite3(dbPath);
68
+ db._SQLEngine.setDB(db.db, 'better-sqlite3');
69
+
70
+ db.onConfig();
71
+
72
+ // Create table
73
+ db.db.exec('CREATE TABLE IF NOT EXISTS User (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, email TEXT, password TEXT, username TEXT, age INTEGER, status TEXT)');
74
+
75
+ // Test 1: required() validation
76
+ console.log("📝 Test 1: required() validation");
77
+ console.log("──────────────────────────────────────────────────");
78
+ try {
79
+ const user = db.User.new();
80
+ try {
81
+ user.name = '';
82
+ console.log(` ✗ Should have thrown validation error`);
83
+ failed++;
84
+ } catch (validationError) {
85
+ if (validationError.message.includes('Name is required')) {
86
+ console.log(" ✓ required() prevents empty values");
87
+ passed++;
88
+ } else {
89
+ console.log(` ✗ Wrong error: ${validationError.message}`);
90
+ failed++;
91
+ }
92
+ }
93
+ } catch(err) {
94
+ console.log(` ✗ Error: ${err.message}`);
95
+ failed++;
96
+ }
97
+
98
+ // Test 2: email() validation
99
+ console.log("\n📝 Test 2: email() validation");
100
+ console.log("──────────────────────────────────────────────────");
101
+ try {
102
+ const user = db.User.new();
103
+ try {
104
+ user.email = 'not-an-email';
105
+ console.log(` ✗ Should have thrown validation error`);
106
+ failed++;
107
+ } catch (validationError) {
108
+ if (validationError.message.includes('Invalid email format')) {
109
+ console.log(" ✓ email() rejects invalid format");
110
+ passed++;
111
+ } else {
112
+ console.log(` ✗ Wrong error: ${validationError.message}`);
113
+ failed++;
114
+ }
115
+ }
116
+ } catch(err) {
117
+ console.log(` ✗ Error: ${err.message}`);
118
+ failed++;
119
+ }
120
+
121
+ // Test 3: minLength() validation
122
+ console.log("\n📝 Test 3: minLength() validation");
123
+ console.log("──────────────────────────────────────────────────");
124
+ try {
125
+ const user = db.User.new();
126
+ try {
127
+ user.name = 'AB'; // Too short
128
+ console.log(` ✗ Should have thrown validation error`);
129
+ failed++;
130
+ } catch (validationError) {
131
+ if (validationError.message.includes('at least 3 characters')) {
132
+ console.log(" ✓ minLength() enforces minimum length");
133
+ passed++;
134
+ } else {
135
+ console.log(` ✗ Wrong error: ${validationError.message}`);
136
+ failed++;
137
+ }
138
+ }
139
+ } catch(err) {
140
+ console.log(` ✗ Error: ${err.message}`);
141
+ failed++;
142
+ }
143
+
144
+ // Test 4: maxLength() validation
145
+ console.log("\n📝 Test 4: maxLength() validation");
146
+ console.log("──────────────────────────────────────────────────");
147
+ try {
148
+ const user = db.User.new();
149
+ try {
150
+ user.password = 'a'.repeat(101); // Too long
151
+ console.log(` ✗ Should have thrown validation error`);
152
+ failed++;
153
+ } catch (validationError) {
154
+ if (validationError.message.includes('at most 100 characters')) {
155
+ console.log(" ✓ maxLength() enforces maximum length");
156
+ passed++;
157
+ } else {
158
+ console.log(` ✗ Wrong error: ${validationError.message}`);
159
+ failed++;
160
+ }
161
+ }
162
+ } catch(err) {
163
+ console.log(` ✗ Error: ${err.message}`);
164
+ failed++;
165
+ }
166
+
167
+ // Test 5: pattern() validation
168
+ console.log("\n📝 Test 5: pattern() validation");
169
+ console.log("──────────────────────────────────────────────────");
170
+ try {
171
+ const user = db.User.new();
172
+ try {
173
+ user.username = 'user@name'; // Invalid character @
174
+ console.log(` ✗ Should have thrown validation error`);
175
+ failed++;
176
+ } catch (validationError) {
177
+ if (validationError.message.includes('letters, numbers, and underscores')) {
178
+ console.log(" ✓ pattern() enforces regex pattern");
179
+ passed++;
180
+ } else {
181
+ console.log(` ✗ Wrong error: ${validationError.message}`);
182
+ failed++;
183
+ }
184
+ }
185
+ } catch(err) {
186
+ console.log(` ✗ Error: ${err.message}`);
187
+ failed++;
188
+ }
189
+
190
+ // Test 6: min() validation for numbers
191
+ console.log("\n📝 Test 6: min() validation for numbers");
192
+ console.log("──────────────────────────────────────────────────");
193
+ try {
194
+ const user = db.User.new();
195
+ try {
196
+ user.age = 17; // Too young
197
+ console.log(` ✗ Should have thrown validation error`);
198
+ failed++;
199
+ } catch (validationError) {
200
+ if (validationError.message.includes('at least 18')) {
201
+ console.log(" ✓ min() enforces minimum value");
202
+ passed++;
203
+ } else {
204
+ console.log(` ✗ Wrong error: ${validationError.message}`);
205
+ failed++;
206
+ }
207
+ }
208
+ } catch(err) {
209
+ console.log(` ✗ Error: ${err.message}`);
210
+ failed++;
211
+ }
212
+
213
+ // Test 7: max() validation for numbers
214
+ console.log("\n📝 Test 7: max() validation for numbers");
215
+ console.log("──────────────────────────────────────────────────");
216
+ try {
217
+ const user = db.User.new();
218
+ try {
219
+ user.age = 121; // Too old
220
+ console.log(` ✗ Should have thrown validation error`);
221
+ failed++;
222
+ } catch (validationError) {
223
+ if (validationError.message.includes('cannot exceed 120')) {
224
+ console.log(" ✓ max() enforces maximum value");
225
+ passed++;
226
+ } else {
227
+ console.log(` ✗ Wrong error: ${validationError.message}`);
228
+ failed++;
229
+ }
230
+ }
231
+ } catch(err) {
232
+ console.log(` ✗ Error: ${err.message}`);
233
+ failed++;
234
+ }
235
+
236
+ // Test 8: custom() validation
237
+ console.log("\n📝 Test 8: custom() validation");
238
+ console.log("──────────────────────────────────────────────────");
239
+ try {
240
+ const user = db.User.new();
241
+ try {
242
+ user.status = 'invalid-status';
243
+ console.log(` ✗ Should have thrown validation error`);
244
+ failed++;
245
+ } catch (validationError) {
246
+ if (validationError.message.includes('active, inactive, or pending')) {
247
+ console.log(" ✓ custom() executes custom validation function");
248
+ passed++;
249
+ } else {
250
+ console.log(` ✗ Wrong error: ${validationError.message}`);
251
+ failed++;
252
+ }
253
+ }
254
+ } catch(err) {
255
+ console.log(` ✗ Error: ${err.message}`);
256
+ failed++;
257
+ }
258
+
259
+ // Test 9: Valid data passes all validations
260
+ console.log("\n📝 Test 9: Valid data passes all validations");
261
+ console.log("──────────────────────────────────────────────────");
262
+ try {
263
+ // Clear tracked entities from previous tests (they have invalid/missing values)
264
+ db.__trackedEntities = [];
265
+ db.__trackedEntitiesMap = new Map();
266
+
267
+ const user = db.User.new();
268
+ user.name = 'John Doe';
269
+ user.email = 'john@example.com';
270
+ user.password = 'secure-password-123';
271
+ user.username = 'john_doe_123';
272
+ user.age = 25;
273
+ user.status = 'active';
274
+ await user.save();
275
+
276
+ if (user.id) {
277
+ console.log(" ✓ Valid data passes all validations");
278
+ console.log(` ✓ Entity saved with ID: ${user.id}`);
279
+ passed++;
280
+ } else {
281
+ console.log(` ✗ Entity not saved`);
282
+ failed++;
283
+ }
284
+ } catch(err) {
285
+ console.log(` ✗ Error: ${err.message}`);
286
+ failed++;
287
+ }
288
+
289
+ // Summary
290
+ console.log("\n" + "=".repeat(64));
291
+ console.log(`Test Results: ${passed} passed, ${failed} failed`);
292
+ console.log("=".repeat(64));
293
+
294
+ if (failed > 0) {
295
+ process.exit(1);
296
+ }
297
+ }
298
+
299
+ runTests().catch(err => {
300
+ console.error('Fatal error:', err);
301
+ process.exit(1);
302
+ });