meadow 2.0.26 → 2.0.27
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,895 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unit tests for the Meadow "SQLite" Provider via meadow-connection-sqlite-browser
|
|
3
|
+
*
|
|
4
|
+
* These tests use an in-memory SQLite database via sql.js (WASM).
|
|
5
|
+
* They mirror the Meadow-Provider-SQLite_tests.js tests but use the
|
|
6
|
+
* browser-compatible connection provider instead of better-sqlite3.
|
|
7
|
+
*
|
|
8
|
+
* @license MIT
|
|
9
|
+
*
|
|
10
|
+
* @author Steven Velozo <steven@velozo.com>
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
var Chai = require("chai");
|
|
14
|
+
var Expect = Chai.expect;
|
|
15
|
+
var Assert = Chai.assert;
|
|
16
|
+
|
|
17
|
+
var libMeadowConnectionSQLiteBrowser = require('meadow-connection-sqlite-browser');
|
|
18
|
+
|
|
19
|
+
var tmpFableSettings = (
|
|
20
|
+
{
|
|
21
|
+
LogStreams:
|
|
22
|
+
[
|
|
23
|
+
{
|
|
24
|
+
level: 'fatal',
|
|
25
|
+
streamtype:'process.stdout',
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
level: 'trace',
|
|
29
|
+
path: __dirname+'/../tests.log'
|
|
30
|
+
}
|
|
31
|
+
]
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
var libFable = new (require('fable'))(tmpFableSettings);
|
|
35
|
+
|
|
36
|
+
// Register the SQLite connection service (browser-compatible provider)
|
|
37
|
+
libFable.serviceManager.addServiceType('MeadowSQLiteProvider', libMeadowConnectionSQLiteBrowser);
|
|
38
|
+
libFable.serviceManager.instantiateServiceProvider('MeadowSQLiteProvider');
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
var _AnimalJsonSchema = (
|
|
42
|
+
{
|
|
43
|
+
title: "Animal",
|
|
44
|
+
description: "A creature that lives in a meadow.",
|
|
45
|
+
type: "object",
|
|
46
|
+
properties: {
|
|
47
|
+
IDAnimal: {
|
|
48
|
+
description: "The unique identifier for an animal",
|
|
49
|
+
type: "integer"
|
|
50
|
+
},
|
|
51
|
+
Name: {
|
|
52
|
+
description: "The animal's name",
|
|
53
|
+
type: "string"
|
|
54
|
+
},
|
|
55
|
+
Type: {
|
|
56
|
+
description: "The type of the animal",
|
|
57
|
+
type: "string"
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
required: ["IDAnimal", "Name", "CreatingIDUser"]
|
|
61
|
+
});
|
|
62
|
+
var _AnimalSchema = (
|
|
63
|
+
[
|
|
64
|
+
{ Column: "IDAnimal", Type:"AutoIdentity" },
|
|
65
|
+
{ Column: "GUIDAnimal", Type:"AutoGUID" },
|
|
66
|
+
{ Column: "CreateDate", Type:"CreateDate" },
|
|
67
|
+
{ Column: "CreatingIDUser", Type:"CreateIDUser" },
|
|
68
|
+
{ Column: "UpdateDate", Type:"UpdateDate" },
|
|
69
|
+
{ Column: "UpdatingIDUser", Type:"UpdateIDUser" },
|
|
70
|
+
{ Column: "Deleted", Type:"Deleted" },
|
|
71
|
+
{ Column: "DeletingIDUser", Type:"DeleteIDUser" },
|
|
72
|
+
{ Column: "DeleteDate", Type:"DeleteDate" }
|
|
73
|
+
]);
|
|
74
|
+
var _AnimalDefault = (
|
|
75
|
+
{
|
|
76
|
+
IDAnimal: null,
|
|
77
|
+
GUIDAnimal: '',
|
|
78
|
+
|
|
79
|
+
CreateDate: false,
|
|
80
|
+
CreatingIDUser: 0,
|
|
81
|
+
UpdateDate: false,
|
|
82
|
+
UpdatingIDUser: 0,
|
|
83
|
+
Deleted: 0,
|
|
84
|
+
DeleteDate: false,
|
|
85
|
+
DeletingIDUser: 0,
|
|
86
|
+
|
|
87
|
+
Name: 'Unknown',
|
|
88
|
+
Type: 'Unclassified'
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
suite
|
|
92
|
+
(
|
|
93
|
+
'Meadow-Provider-SQLiteBrowser',
|
|
94
|
+
function()
|
|
95
|
+
{
|
|
96
|
+
var _SpooledUp = false;
|
|
97
|
+
|
|
98
|
+
var newMeadow = function()
|
|
99
|
+
{
|
|
100
|
+
return require('../source/Meadow.js')
|
|
101
|
+
.new(libFable, 'FableTest')
|
|
102
|
+
.setProvider('SQLite')
|
|
103
|
+
.setSchema(_AnimalSchema)
|
|
104
|
+
.setJsonSchema(_AnimalJsonSchema)
|
|
105
|
+
.setDefaultIdentifier('IDAnimal')
|
|
106
|
+
.setDefault(_AnimalDefault)
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
suiteSetup
|
|
110
|
+
(
|
|
111
|
+
function(fDone)
|
|
112
|
+
{
|
|
113
|
+
// Only do this for the first test.
|
|
114
|
+
if (!_SpooledUp)
|
|
115
|
+
{
|
|
116
|
+
// Connect to SQLite (in-memory via sql.js — no file cleanup needed)
|
|
117
|
+
libFable.MeadowSQLiteProvider.connectAsync(
|
|
118
|
+
function(pError)
|
|
119
|
+
{
|
|
120
|
+
if (pError)
|
|
121
|
+
{
|
|
122
|
+
return fDone(pError);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
var tmpDB = libFable.MeadowSQLiteProvider.db;
|
|
126
|
+
|
|
127
|
+
// Create the FableTest table
|
|
128
|
+
tmpDB.exec(
|
|
129
|
+
"CREATE TABLE IF NOT EXISTS FableTest (" +
|
|
130
|
+
" IDAnimal INTEGER PRIMARY KEY AUTOINCREMENT," +
|
|
131
|
+
" GUIDAnimal TEXT NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000'," +
|
|
132
|
+
" CreateDate TEXT," +
|
|
133
|
+
" CreatingIDUser INTEGER NOT NULL DEFAULT 0," +
|
|
134
|
+
" UpdateDate TEXT," +
|
|
135
|
+
" UpdatingIDUser INTEGER NOT NULL DEFAULT 0," +
|
|
136
|
+
" Deleted INTEGER NOT NULL DEFAULT 0," +
|
|
137
|
+
" DeleteDate TEXT," +
|
|
138
|
+
" DeletingIDUser INTEGER NOT NULL DEFAULT 0," +
|
|
139
|
+
" Name TEXT NOT NULL DEFAULT ''," +
|
|
140
|
+
" Type TEXT NOT NULL DEFAULT ''" +
|
|
141
|
+
");"
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
// Insert test data
|
|
145
|
+
var tmpInsert = tmpDB.prepare(
|
|
146
|
+
"INSERT INTO FableTest (GUIDAnimal, CreateDate, CreatingIDUser, UpdateDate, UpdatingIDUser, Deleted, DeleteDate, DeletingIDUser, Name, Type) " +
|
|
147
|
+
"VALUES ('00000000-0000-0000-0000-000000000000', datetime('now'), 1, datetime('now'), 1, 0, NULL, 0, ?, ?)"
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
tmpInsert.run('Foo Foo', 'Bunny');
|
|
151
|
+
tmpInsert.run('Red Riding Hood', 'Girl');
|
|
152
|
+
tmpInsert.run('Red', 'Dog');
|
|
153
|
+
tmpInsert.run('Spot', 'Dog');
|
|
154
|
+
tmpInsert.run('Gertrude', 'Frog');
|
|
155
|
+
|
|
156
|
+
_SpooledUp = true;
|
|
157
|
+
fDone();
|
|
158
|
+
}
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
else
|
|
162
|
+
{
|
|
163
|
+
fDone();
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
suite
|
|
169
|
+
(
|
|
170
|
+
'Object Sanity',
|
|
171
|
+
function()
|
|
172
|
+
{
|
|
173
|
+
test
|
|
174
|
+
(
|
|
175
|
+
'The SQLite class should initialize itself into a happy little object.',
|
|
176
|
+
function()
|
|
177
|
+
{
|
|
178
|
+
var testMeadow = require('../source/Meadow.js').new(libFable).setProvider('SQLite');
|
|
179
|
+
Expect(testMeadow).to.be.an('object', 'Meadow should initialize as an object directly from the require statement.');
|
|
180
|
+
Expect(testMeadow.providerName).to.equal('SQLite');
|
|
181
|
+
}
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
);
|
|
185
|
+
suite
|
|
186
|
+
(
|
|
187
|
+
'Query Processing',
|
|
188
|
+
function()
|
|
189
|
+
{
|
|
190
|
+
test
|
|
191
|
+
(
|
|
192
|
+
'Create a record in the database',
|
|
193
|
+
function(fDone)
|
|
194
|
+
{
|
|
195
|
+
var testMeadow = newMeadow().setIDUser(90210);
|
|
196
|
+
|
|
197
|
+
// Ensure this query is "slow"...
|
|
198
|
+
testMeadow.fable.settings.QueryThresholdWarnTime = 1;
|
|
199
|
+
|
|
200
|
+
var tmpQuery = testMeadow.query.clone().setLogLevel(5)
|
|
201
|
+
.addRecord({Name:'Blastoise', Type:'Pokemon'});
|
|
202
|
+
|
|
203
|
+
testMeadow.doCreate(tmpQuery,
|
|
204
|
+
function(pError, pQuery, pQueryRead, pRecord)
|
|
205
|
+
{
|
|
206
|
+
// We should have a record ....
|
|
207
|
+
Expect(pRecord.Name)
|
|
208
|
+
.to.equal('Blastoise');
|
|
209
|
+
Expect(pRecord.CreatingIDUser)
|
|
210
|
+
.to.equal(90210);
|
|
211
|
+
testMeadow.fable.settings.QueryThresholdWarnTime = 1000;
|
|
212
|
+
fDone();
|
|
213
|
+
}
|
|
214
|
+
)
|
|
215
|
+
}
|
|
216
|
+
);
|
|
217
|
+
test
|
|
218
|
+
(
|
|
219
|
+
'Create a record in the database with Deleted bit already set',
|
|
220
|
+
function(fDone)
|
|
221
|
+
{
|
|
222
|
+
var testMeadow = newMeadow().setIDUser(90210);
|
|
223
|
+
|
|
224
|
+
var tmpQuery = testMeadow.query.clone().setLogLevel(5)
|
|
225
|
+
.setDisableDeleteTracking(true)
|
|
226
|
+
.addRecord({Name:'Charmander', Type:'Pokemon', Deleted: 1});
|
|
227
|
+
|
|
228
|
+
testMeadow.doCreate(tmpQuery,
|
|
229
|
+
function(pError, pQuery, pQueryRead, pRecord)
|
|
230
|
+
{
|
|
231
|
+
// We should have a record ....
|
|
232
|
+
Expect(pRecord.Name)
|
|
233
|
+
.to.equal('Charmander');
|
|
234
|
+
Expect(pRecord.CreatingIDUser)
|
|
235
|
+
.to.equal(90210);
|
|
236
|
+
fDone();
|
|
237
|
+
}
|
|
238
|
+
)
|
|
239
|
+
}
|
|
240
|
+
);
|
|
241
|
+
test
|
|
242
|
+
(
|
|
243
|
+
'Read a record from the database',
|
|
244
|
+
function(fDone)
|
|
245
|
+
{
|
|
246
|
+
var testMeadow = newMeadow();
|
|
247
|
+
|
|
248
|
+
testMeadow.fable.settings.QueryThresholdWarnTime = 1;
|
|
249
|
+
|
|
250
|
+
var tmpQuery = testMeadow.query
|
|
251
|
+
.addFilter('IDAnimal', 1);
|
|
252
|
+
|
|
253
|
+
testMeadow.doRead(tmpQuery,
|
|
254
|
+
function(pError, pQuery, pRecord)
|
|
255
|
+
{
|
|
256
|
+
// We should have a record ....
|
|
257
|
+
Expect(pRecord.IDAnimal)
|
|
258
|
+
.to.equal(1);
|
|
259
|
+
Expect(pRecord.Name)
|
|
260
|
+
.to.equal('Foo Foo');
|
|
261
|
+
|
|
262
|
+
testMeadow.fable.settings.QueryThresholdWarnTime = 1000;
|
|
263
|
+
|
|
264
|
+
fDone();
|
|
265
|
+
}
|
|
266
|
+
)
|
|
267
|
+
}
|
|
268
|
+
);
|
|
269
|
+
test
|
|
270
|
+
(
|
|
271
|
+
'Read all records from the database',
|
|
272
|
+
function(fDone)
|
|
273
|
+
{
|
|
274
|
+
var testMeadow = newMeadow();
|
|
275
|
+
|
|
276
|
+
testMeadow.doReads(testMeadow.query,
|
|
277
|
+
function(pError, pQuery, pRecords)
|
|
278
|
+
{
|
|
279
|
+
// We should have records ....
|
|
280
|
+
Expect(pRecords[0].IDAnimal)
|
|
281
|
+
.to.equal(1);
|
|
282
|
+
Expect(pRecords[0].Name)
|
|
283
|
+
.to.equal('Foo Foo');
|
|
284
|
+
Expect(pRecords[1].IDAnimal)
|
|
285
|
+
.to.equal(2);
|
|
286
|
+
Expect(pRecords[1].Name)
|
|
287
|
+
.to.equal('Red Riding Hood');
|
|
288
|
+
Expect(pRecords[1].Type)
|
|
289
|
+
.to.equal('Girl');
|
|
290
|
+
fDone();
|
|
291
|
+
}
|
|
292
|
+
)
|
|
293
|
+
}
|
|
294
|
+
);
|
|
295
|
+
test
|
|
296
|
+
(
|
|
297
|
+
'Update a record in the database',
|
|
298
|
+
function(fDone)
|
|
299
|
+
{
|
|
300
|
+
var testMeadow = newMeadow();
|
|
301
|
+
|
|
302
|
+
testMeadow.fable.settings.QueryThresholdWarnTime = 1;
|
|
303
|
+
|
|
304
|
+
var tmpQuery = testMeadow.query
|
|
305
|
+
.addRecord({IDAnimal:2, Type:'Human'});
|
|
306
|
+
|
|
307
|
+
testMeadow.doUpdate(tmpQuery,
|
|
308
|
+
function(pError, pQuery, pQueryRead, pRecord)
|
|
309
|
+
{
|
|
310
|
+
// We should have a record ....
|
|
311
|
+
Expect(pRecord.Type)
|
|
312
|
+
.to.equal('Human');
|
|
313
|
+
|
|
314
|
+
testMeadow.fable.settings.QueryThresholdWarnTime = 1000;
|
|
315
|
+
|
|
316
|
+
fDone();
|
|
317
|
+
}
|
|
318
|
+
)
|
|
319
|
+
}
|
|
320
|
+
);
|
|
321
|
+
test
|
|
322
|
+
(
|
|
323
|
+
'Delete a record in the database',
|
|
324
|
+
function(fDone)
|
|
325
|
+
{
|
|
326
|
+
var testMeadow = newMeadow();
|
|
327
|
+
|
|
328
|
+
testMeadow.fable.settings.QueryThresholdWarnTime = 1;
|
|
329
|
+
var tmpQuery = testMeadow.query.addFilter('IDAnimal',3);
|
|
330
|
+
|
|
331
|
+
testMeadow.doDelete(tmpQuery,
|
|
332
|
+
function(pError, pQuery, pRecord)
|
|
333
|
+
{
|
|
334
|
+
// It returns the number of rows deleted
|
|
335
|
+
Expect(pRecord)
|
|
336
|
+
.to.equal(1);
|
|
337
|
+
|
|
338
|
+
testMeadow.fable.settings.QueryThresholdWarnTime = 1000;
|
|
339
|
+
|
|
340
|
+
fDone();
|
|
341
|
+
}
|
|
342
|
+
)
|
|
343
|
+
}
|
|
344
|
+
);
|
|
345
|
+
test
|
|
346
|
+
(
|
|
347
|
+
'Undelete a record in the database',
|
|
348
|
+
function(fDone)
|
|
349
|
+
{
|
|
350
|
+
var testMeadow = newMeadow();
|
|
351
|
+
|
|
352
|
+
testMeadow.fable.settings.QueryThresholdWarnTime = 1;
|
|
353
|
+
var tmpDeleteQuery = testMeadow.query.addFilter('IDAnimal',5);
|
|
354
|
+
|
|
355
|
+
// Make sure the record is deleted!
|
|
356
|
+
testMeadow.doDelete(tmpDeleteQuery,
|
|
357
|
+
function(pDeleteError, pDeleteQuery, pDeleteRecord)
|
|
358
|
+
{
|
|
359
|
+
var tmpQuery = testMeadow.query.addFilter('IDAnimal',5);
|
|
360
|
+
testMeadow.doUndelete(tmpQuery,
|
|
361
|
+
function(pError, pQuery, pRecord)
|
|
362
|
+
{
|
|
363
|
+
// It returns the number of rows undeleted
|
|
364
|
+
Expect(pRecord)
|
|
365
|
+
.to.equal(1);
|
|
366
|
+
|
|
367
|
+
testMeadow.fable.settings.QueryThresholdWarnTime = 1000;
|
|
368
|
+
|
|
369
|
+
fDone();
|
|
370
|
+
});
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
);
|
|
374
|
+
test
|
|
375
|
+
(
|
|
376
|
+
'Count all records from the database',
|
|
377
|
+
function(fDone)
|
|
378
|
+
{
|
|
379
|
+
var testMeadow = newMeadow();
|
|
380
|
+
testMeadow.fable.settings.QueryThresholdWarnTime = 1;
|
|
381
|
+
|
|
382
|
+
Expect(testMeadow.query.parameters.result.executed)
|
|
383
|
+
.to.equal(false);
|
|
384
|
+
testMeadow.doCount(testMeadow.query,
|
|
385
|
+
function(pError, pQuery, pRecord)
|
|
386
|
+
{
|
|
387
|
+
// There should be 5 non-deleted records (3 not deleted seeded + Blastoise + Gertrude)
|
|
388
|
+
Expect(pRecord)
|
|
389
|
+
.to.equal(5);
|
|
390
|
+
Expect(pQuery.parameters.result.executed)
|
|
391
|
+
.to.equal(true);
|
|
392
|
+
testMeadow.fable.settings.QueryThresholdWarnTime = 1000;
|
|
393
|
+
fDone();
|
|
394
|
+
}
|
|
395
|
+
)
|
|
396
|
+
}
|
|
397
|
+
);
|
|
398
|
+
test
|
|
399
|
+
(
|
|
400
|
+
'Perform operations with a schema-based instantiation',
|
|
401
|
+
function(fDone)
|
|
402
|
+
{
|
|
403
|
+
var testMeadow = require('../source/Meadow.js').new(libFable)
|
|
404
|
+
.loadFromPackage(__dirname+'/Animal.json').setProvider('SQLite');
|
|
405
|
+
|
|
406
|
+
// Make sure the authentication stuff got loaded
|
|
407
|
+
Expect(testMeadow.schemaFull.authorizer.User)
|
|
408
|
+
.to.be.an('object');
|
|
409
|
+
Expect(testMeadow.schemaFull.authorizer.User.Create)
|
|
410
|
+
.to.equal('Allow');
|
|
411
|
+
|
|
412
|
+
var tmpQuery = testMeadow.query
|
|
413
|
+
.addRecord({Name:'Grommet', Type:'Dog'});
|
|
414
|
+
|
|
415
|
+
testMeadow.doCreate(tmpQuery,
|
|
416
|
+
function(pError, pQuery, pQueryRead, pRecord)
|
|
417
|
+
{
|
|
418
|
+
// We should have a record ....
|
|
419
|
+
Expect(pRecord.Name)
|
|
420
|
+
.to.equal('Grommet');
|
|
421
|
+
fDone();
|
|
422
|
+
}
|
|
423
|
+
)
|
|
424
|
+
}
|
|
425
|
+
);
|
|
426
|
+
}
|
|
427
|
+
);
|
|
428
|
+
suite
|
|
429
|
+
(
|
|
430
|
+
'Logged Query Processing',
|
|
431
|
+
function()
|
|
432
|
+
{
|
|
433
|
+
test
|
|
434
|
+
(
|
|
435
|
+
'Create a record in the database',
|
|
436
|
+
function(fDone)
|
|
437
|
+
{
|
|
438
|
+
var testMeadow = newMeadow();
|
|
439
|
+
|
|
440
|
+
var tmpQuery = testMeadow.query
|
|
441
|
+
.setLogLevel(5)
|
|
442
|
+
.addRecord({Name:'MewTwo', Type:'Pokemon'});
|
|
443
|
+
|
|
444
|
+
testMeadow.doCreate(tmpQuery,
|
|
445
|
+
function(pError, pQuery, pQueryRead, pRecord)
|
|
446
|
+
{
|
|
447
|
+
// We should have a record ....
|
|
448
|
+
Expect(pRecord.Name)
|
|
449
|
+
.to.equal('MewTwo');
|
|
450
|
+
fDone();
|
|
451
|
+
}
|
|
452
|
+
)
|
|
453
|
+
}
|
|
454
|
+
);
|
|
455
|
+
test
|
|
456
|
+
(
|
|
457
|
+
'Create a record in the database with a predefined GUID',
|
|
458
|
+
function(fDone)
|
|
459
|
+
{
|
|
460
|
+
var testMeadow = newMeadow();
|
|
461
|
+
|
|
462
|
+
var tmpQuery = testMeadow.query
|
|
463
|
+
.setLogLevel(5)
|
|
464
|
+
.addRecord({Name:'MewThree', GUIDAnimal:'0x12345', Type:'Pokemon'});
|
|
465
|
+
|
|
466
|
+
testMeadow.doCreate(tmpQuery,
|
|
467
|
+
function(pError, pQuery, pQueryRead, pRecord)
|
|
468
|
+
{
|
|
469
|
+
// We should have a record ....
|
|
470
|
+
Expect(pRecord.Name)
|
|
471
|
+
.to.equal('MewThree');
|
|
472
|
+
fDone();
|
|
473
|
+
}
|
|
474
|
+
)
|
|
475
|
+
}
|
|
476
|
+
);
|
|
477
|
+
test
|
|
478
|
+
(
|
|
479
|
+
'Create a record in the database with a previously predefined GUID -- expect failure',
|
|
480
|
+
function(fDone)
|
|
481
|
+
{
|
|
482
|
+
var testMeadow = newMeadow();
|
|
483
|
+
|
|
484
|
+
var tmpQuery = testMeadow.query
|
|
485
|
+
.setLogLevel(5)
|
|
486
|
+
.addRecord({Name:'MewThree', GUIDAnimal:'0x12345', Type:'Pokemon'});
|
|
487
|
+
|
|
488
|
+
testMeadow.doCreate(tmpQuery,
|
|
489
|
+
function(pError, pQuery, pQueryRead, pRecord)
|
|
490
|
+
{
|
|
491
|
+
Expect(pError)
|
|
492
|
+
.to.equal("Record with GUID 0x12345 already exists!");
|
|
493
|
+
fDone();
|
|
494
|
+
}
|
|
495
|
+
)
|
|
496
|
+
}
|
|
497
|
+
);
|
|
498
|
+
test
|
|
499
|
+
(
|
|
500
|
+
'Read a record from the database',
|
|
501
|
+
function(fDone)
|
|
502
|
+
{
|
|
503
|
+
var testMeadow = newMeadow();
|
|
504
|
+
|
|
505
|
+
var tmpQuery = testMeadow.query
|
|
506
|
+
.setLogLevel(5)
|
|
507
|
+
.addFilter('IDAnimal', 1);
|
|
508
|
+
|
|
509
|
+
testMeadow.doRead(tmpQuery,
|
|
510
|
+
function(pError, pQuery, pRecord)
|
|
511
|
+
{
|
|
512
|
+
// We should have a record ....
|
|
513
|
+
Expect(pRecord.IDAnimal)
|
|
514
|
+
.to.equal(1);
|
|
515
|
+
Expect(pRecord.Name)
|
|
516
|
+
.to.equal('Foo Foo');
|
|
517
|
+
fDone();
|
|
518
|
+
}
|
|
519
|
+
)
|
|
520
|
+
}
|
|
521
|
+
);
|
|
522
|
+
test
|
|
523
|
+
(
|
|
524
|
+
'Read all records from the database',
|
|
525
|
+
function(fDone)
|
|
526
|
+
{
|
|
527
|
+
var testMeadow = newMeadow();
|
|
528
|
+
|
|
529
|
+
testMeadow.doReads(testMeadow.query.setLogLevel(5),
|
|
530
|
+
function(pError, pQuery, pRecords)
|
|
531
|
+
{
|
|
532
|
+
// We should have records ....
|
|
533
|
+
Expect(pRecords[0].IDAnimal)
|
|
534
|
+
.to.equal(1);
|
|
535
|
+
Expect(pRecords[0].Name)
|
|
536
|
+
.to.equal('Foo Foo');
|
|
537
|
+
Expect(pRecords[1].IDAnimal)
|
|
538
|
+
.to.equal(2);
|
|
539
|
+
Expect(pRecords[1].Name)
|
|
540
|
+
.to.equal('Red Riding Hood');
|
|
541
|
+
Expect(pRecords[1].Type)
|
|
542
|
+
.to.equal('Human');
|
|
543
|
+
fDone();
|
|
544
|
+
}
|
|
545
|
+
)
|
|
546
|
+
}
|
|
547
|
+
);
|
|
548
|
+
test
|
|
549
|
+
(
|
|
550
|
+
'Update a record in the database',
|
|
551
|
+
function(fDone)
|
|
552
|
+
{
|
|
553
|
+
var testMeadow = newMeadow();
|
|
554
|
+
|
|
555
|
+
var tmpQuery = testMeadow.query
|
|
556
|
+
.setLogLevel(5)
|
|
557
|
+
.addRecord({IDAnimal:2, Type:'HumanGirl'});
|
|
558
|
+
|
|
559
|
+
testMeadow.doUpdate(tmpQuery,
|
|
560
|
+
function(pError, pQuery, pQueryRead, pRecord)
|
|
561
|
+
{
|
|
562
|
+
// We should have a record ....
|
|
563
|
+
Expect(pRecord.Type)
|
|
564
|
+
.to.equal('HumanGirl');
|
|
565
|
+
fDone();
|
|
566
|
+
}
|
|
567
|
+
)
|
|
568
|
+
}
|
|
569
|
+
);
|
|
570
|
+
test
|
|
571
|
+
(
|
|
572
|
+
'Delete a record in the database',
|
|
573
|
+
function(fDone)
|
|
574
|
+
{
|
|
575
|
+
var testMeadow = newMeadow();
|
|
576
|
+
|
|
577
|
+
var tmpQuery = testMeadow.query
|
|
578
|
+
.setLogLevel(5)
|
|
579
|
+
.addFilter('IDAnimal',4);
|
|
580
|
+
|
|
581
|
+
testMeadow.doDelete(tmpQuery,
|
|
582
|
+
function(pError, pQuery, pRecord)
|
|
583
|
+
{
|
|
584
|
+
// It returns the number of rows deleted
|
|
585
|
+
Expect(pRecord)
|
|
586
|
+
.to.equal(1);
|
|
587
|
+
fDone();
|
|
588
|
+
}
|
|
589
|
+
)
|
|
590
|
+
}
|
|
591
|
+
);
|
|
592
|
+
test
|
|
593
|
+
(
|
|
594
|
+
'Count all records from the database',
|
|
595
|
+
function(fDone)
|
|
596
|
+
{
|
|
597
|
+
var testMeadow = newMeadow();
|
|
598
|
+
|
|
599
|
+
testMeadow.doCount(testMeadow.query.setLogLevel(5),
|
|
600
|
+
function(pError, pQuery, pRecord)
|
|
601
|
+
{
|
|
602
|
+
// Count non-deleted records
|
|
603
|
+
Expect(pRecord)
|
|
604
|
+
.to.be.a('number');
|
|
605
|
+
Expect(pRecord).to.be.above(0);
|
|
606
|
+
fDone();
|
|
607
|
+
}
|
|
608
|
+
)
|
|
609
|
+
}
|
|
610
|
+
);
|
|
611
|
+
test
|
|
612
|
+
(
|
|
613
|
+
'Read a record from the database that had a defined GUID',
|
|
614
|
+
function(fDone)
|
|
615
|
+
{
|
|
616
|
+
var testMeadow = newMeadow();
|
|
617
|
+
|
|
618
|
+
var tmpQuery = testMeadow.query
|
|
619
|
+
.addFilter('GUIDAnimal', '0x12345');
|
|
620
|
+
|
|
621
|
+
testMeadow.doRead(tmpQuery,
|
|
622
|
+
function(pError, pQuery, pRecord)
|
|
623
|
+
{
|
|
624
|
+
// We should have a record ....
|
|
625
|
+
Expect(pRecord.Name)
|
|
626
|
+
.to.equal('MewThree');
|
|
627
|
+
fDone();
|
|
628
|
+
}
|
|
629
|
+
)
|
|
630
|
+
}
|
|
631
|
+
);
|
|
632
|
+
test
|
|
633
|
+
(
|
|
634
|
+
'Create a record in the database with a defined creating user',
|
|
635
|
+
function(fDone)
|
|
636
|
+
{
|
|
637
|
+
var testMeadow = newMeadow();
|
|
638
|
+
var tmpQuery = testMeadow.query
|
|
639
|
+
.setIDUser(800)
|
|
640
|
+
.addRecord({Name:'MewSix', GUIDAnimal:'0x123456', Type:'Pokemon'});
|
|
641
|
+
|
|
642
|
+
testMeadow.doCreate(tmpQuery,
|
|
643
|
+
function(pError, pQuery, pQueryRead, pRecord)
|
|
644
|
+
{
|
|
645
|
+
// We should have a record ....
|
|
646
|
+
Expect(pRecord.Name)
|
|
647
|
+
.to.equal('MewSix');
|
|
648
|
+
Expect(pRecord.CreatingIDUser)
|
|
649
|
+
.to.equal(800);
|
|
650
|
+
fDone();
|
|
651
|
+
}
|
|
652
|
+
)
|
|
653
|
+
}
|
|
654
|
+
);
|
|
655
|
+
}
|
|
656
|
+
);
|
|
657
|
+
suite
|
|
658
|
+
(
|
|
659
|
+
'The Bad Kind of Query Processing',
|
|
660
|
+
function()
|
|
661
|
+
{
|
|
662
|
+
test
|
|
663
|
+
(
|
|
664
|
+
'Count all records from a nonexistent table',
|
|
665
|
+
function(fDone)
|
|
666
|
+
{
|
|
667
|
+
var testMeadow = newMeadow();
|
|
668
|
+
|
|
669
|
+
testMeadow.doCount(testMeadow.query.setScope('BadTable'),
|
|
670
|
+
function(pError, pQuery, pRecord)
|
|
671
|
+
{
|
|
672
|
+
// sql.js throws a standard Error instance for missing tables.
|
|
673
|
+
// Chai types Error as 'error' not 'object', so check existence.
|
|
674
|
+
Expect(pError).to.exist;
|
|
675
|
+
fDone();
|
|
676
|
+
}
|
|
677
|
+
)
|
|
678
|
+
}
|
|
679
|
+
);
|
|
680
|
+
test
|
|
681
|
+
(
|
|
682
|
+
'Create a record in the database with no record',
|
|
683
|
+
function(fDone)
|
|
684
|
+
{
|
|
685
|
+
var testMeadow = newMeadow().setDefaultIdentifier('Type');
|
|
686
|
+
|
|
687
|
+
testMeadow.doCreate(testMeadow.query,
|
|
688
|
+
function(pError, pQuery, pQueryRead, pRecord)
|
|
689
|
+
{
|
|
690
|
+
Expect(pError)
|
|
691
|
+
.to.equal('No record submitted');
|
|
692
|
+
fDone();
|
|
693
|
+
}
|
|
694
|
+
)
|
|
695
|
+
}
|
|
696
|
+
);
|
|
697
|
+
test
|
|
698
|
+
(
|
|
699
|
+
'Read a record from the database with no data returned',
|
|
700
|
+
function(fDone)
|
|
701
|
+
{
|
|
702
|
+
var testMeadow = newMeadow();
|
|
703
|
+
|
|
704
|
+
var tmpQuery = testMeadow.query
|
|
705
|
+
.addFilter('IDAnimal', 5000);
|
|
706
|
+
testMeadow.doRead(tmpQuery,
|
|
707
|
+
function(pError, pQuery, pRecord)
|
|
708
|
+
{
|
|
709
|
+
Expect(pRecord)
|
|
710
|
+
.to.equal(false);
|
|
711
|
+
fDone();
|
|
712
|
+
}
|
|
713
|
+
)
|
|
714
|
+
}
|
|
715
|
+
);
|
|
716
|
+
test
|
|
717
|
+
(
|
|
718
|
+
'Read records from the database with no data returned',
|
|
719
|
+
function(fDone)
|
|
720
|
+
{
|
|
721
|
+
var testMeadow = newMeadow();
|
|
722
|
+
|
|
723
|
+
var tmpQuery = testMeadow.query
|
|
724
|
+
.addFilter('IDAnimal', 5000);
|
|
725
|
+
|
|
726
|
+
testMeadow.doReads(tmpQuery,
|
|
727
|
+
function(pError, pQuery, pRecord)
|
|
728
|
+
{
|
|
729
|
+
Expect(pRecord.length)
|
|
730
|
+
.to.equal(0);
|
|
731
|
+
fDone();
|
|
732
|
+
}
|
|
733
|
+
)
|
|
734
|
+
}
|
|
735
|
+
);
|
|
736
|
+
test
|
|
737
|
+
(
|
|
738
|
+
'Update a record in the database with a bad filter',
|
|
739
|
+
function(fDone)
|
|
740
|
+
{
|
|
741
|
+
var testMeadow = newMeadow();
|
|
742
|
+
|
|
743
|
+
var tmpQuery = testMeadow.query
|
|
744
|
+
.setLogLevel(5)
|
|
745
|
+
.addRecord({IDAnimal:undefined, Type:'HumanGirl'});
|
|
746
|
+
|
|
747
|
+
testMeadow.doUpdate(tmpQuery,
|
|
748
|
+
function(pError, pQuery, pQueryRead, pRecord)
|
|
749
|
+
{
|
|
750
|
+
// We should have an error ....
|
|
751
|
+
Expect(pError)
|
|
752
|
+
.to.equal('Automated update missing filters... aborting!');
|
|
753
|
+
fDone();
|
|
754
|
+
}
|
|
755
|
+
)
|
|
756
|
+
}
|
|
757
|
+
);
|
|
758
|
+
test
|
|
759
|
+
(
|
|
760
|
+
'Update a record in the database without passing a record in',
|
|
761
|
+
function(fDone)
|
|
762
|
+
{
|
|
763
|
+
var testMeadow = newMeadow();
|
|
764
|
+
|
|
765
|
+
testMeadow.doUpdate(testMeadow.query,
|
|
766
|
+
function(pError, pQuery, pQueryRead, pRecord)
|
|
767
|
+
{
|
|
768
|
+
Expect(pError)
|
|
769
|
+
.to.equal('No record submitted');
|
|
770
|
+
fDone();
|
|
771
|
+
}
|
|
772
|
+
)
|
|
773
|
+
}
|
|
774
|
+
);
|
|
775
|
+
test
|
|
776
|
+
(
|
|
777
|
+
'Update a record in the database with a bad record passed in (no default identifier)',
|
|
778
|
+
function(fDone)
|
|
779
|
+
{
|
|
780
|
+
var testMeadow = newMeadow();
|
|
781
|
+
|
|
782
|
+
var tmpQuery = testMeadow.query
|
|
783
|
+
.addRecord({Name:'Bill'});
|
|
784
|
+
|
|
785
|
+
testMeadow.doUpdate(tmpQuery,
|
|
786
|
+
function(pError, pQuery, pQueryRead, pRecord)
|
|
787
|
+
{
|
|
788
|
+
Expect(pError)
|
|
789
|
+
.to.equal('Automated update missing default identifier');
|
|
790
|
+
fDone();
|
|
791
|
+
}
|
|
792
|
+
)
|
|
793
|
+
}
|
|
794
|
+
);
|
|
795
|
+
test
|
|
796
|
+
(
|
|
797
|
+
'Update a record in the database that does not exist',
|
|
798
|
+
function(fDone)
|
|
799
|
+
{
|
|
800
|
+
var testMeadow = newMeadow();
|
|
801
|
+
|
|
802
|
+
var tmpQuery = testMeadow.query
|
|
803
|
+
.addRecord({IDAnimal:983924});
|
|
804
|
+
|
|
805
|
+
testMeadow.doUpdate(tmpQuery,
|
|
806
|
+
function(pError, pQuery, pQueryRead, pRecord)
|
|
807
|
+
{
|
|
808
|
+
Expect(pError)
|
|
809
|
+
.to.equal('No record found to update!');
|
|
810
|
+
fDone();
|
|
811
|
+
}
|
|
812
|
+
)
|
|
813
|
+
}
|
|
814
|
+
);
|
|
815
|
+
test
|
|
816
|
+
(
|
|
817
|
+
'Set a raw Query',
|
|
818
|
+
function(fDone)
|
|
819
|
+
{
|
|
820
|
+
var testMeadow = newMeadow();
|
|
821
|
+
testMeadow.rawQueries.setQuery('Read', 'SELECT Something from SomethingElse;');
|
|
822
|
+
|
|
823
|
+
Expect(testMeadow.rawQueries.getQuery('Read'))
|
|
824
|
+
.to.equal('SELECT Something from SomethingElse;');
|
|
825
|
+
fDone();
|
|
826
|
+
}
|
|
827
|
+
);
|
|
828
|
+
test
|
|
829
|
+
(
|
|
830
|
+
'Load a raw Query',
|
|
831
|
+
function(fDone)
|
|
832
|
+
{
|
|
833
|
+
var testMeadow = newMeadow();
|
|
834
|
+
|
|
835
|
+
testMeadow.rawQueries.loadQuery('Read', __dirname+ '/Meadow-Provider-SQLite-AnimalReadQuery.sql',
|
|
836
|
+
function(pSuccess)
|
|
837
|
+
{
|
|
838
|
+
Expect(testMeadow.rawQueries.getQuery('Read'))
|
|
839
|
+
.to.contain('SELECT');
|
|
840
|
+
fDone();
|
|
841
|
+
});
|
|
842
|
+
}
|
|
843
|
+
);
|
|
844
|
+
test
|
|
845
|
+
(
|
|
846
|
+
'Load a bad raw Query',
|
|
847
|
+
function(fDone)
|
|
848
|
+
{
|
|
849
|
+
var testMeadow = newMeadow();
|
|
850
|
+
|
|
851
|
+
testMeadow.rawQueries.loadQuery('Read', __dirname+ '/Meadow-Provider-SQLite-BADAnimalReadQuery.sql',
|
|
852
|
+
function(pSuccess)
|
|
853
|
+
{
|
|
854
|
+
Expect(testMeadow.rawQueries.getQuery('Read'))
|
|
855
|
+
.to.equal('');
|
|
856
|
+
fDone();
|
|
857
|
+
});
|
|
858
|
+
}
|
|
859
|
+
);
|
|
860
|
+
test
|
|
861
|
+
(
|
|
862
|
+
'Check for a query that is not there',
|
|
863
|
+
function()
|
|
864
|
+
{
|
|
865
|
+
var testMeadow = newMeadow();
|
|
866
|
+
Expect(testMeadow.rawQueries.getQuery('Read'))
|
|
867
|
+
.to.equal(false);
|
|
868
|
+
}
|
|
869
|
+
);
|
|
870
|
+
test
|
|
871
|
+
(
|
|
872
|
+
'Read a record from a custom query',
|
|
873
|
+
function(fDone)
|
|
874
|
+
{
|
|
875
|
+
var testMeadow = newMeadow();
|
|
876
|
+
|
|
877
|
+
testMeadow.rawQueries.loadQuery('Read', __dirname+ '/Meadow-Provider-SQLite-AnimalReadQuery.sql',
|
|
878
|
+
function(pSuccess)
|
|
879
|
+
{
|
|
880
|
+
// Now try to read the record
|
|
881
|
+
testMeadow.doRead(testMeadow.query.addFilter('IDAnimal', 2),
|
|
882
|
+
function(pError, pQuery, pRecord)
|
|
883
|
+
{
|
|
884
|
+
Expect(pRecord.AnimalTypeCustom)
|
|
885
|
+
.to.equal('Bunny');
|
|
886
|
+
fDone();
|
|
887
|
+
}
|
|
888
|
+
)
|
|
889
|
+
});
|
|
890
|
+
}
|
|
891
|
+
);
|
|
892
|
+
}
|
|
893
|
+
);
|
|
894
|
+
}
|
|
895
|
+
);
|