UNPKG

forerunnerdb

Version:

A NoSQL document store database for browsers and Node.js.

556 lines (469 loc) 13.5 kB
"use strict"; var TB = require('testbear'), ForerunnerDB = require('../../builds/nodecore'); //TB.config.noCatch = true; TB.timeout = 10000; TB.test('Core', 'Instantiate ForerunnerDB', function (callback) { var fdb = new ForerunnerDB(); TB.strictEqual(fdb instanceof ForerunnerDB, true, 'ForerunnerDB instance is instantiated'); callback(); }); TB.test('Core', 'Instantiate a Database Instance', function (callback) { var fdb = new ForerunnerDB(), db = fdb.db('temp'); TB.strictEqual(db instanceof ForerunnerDB.shared.modules.Db, true, 'ForerunnerDB database instance is instantiated'); callback(); }); TB.test('Collection', 'Instantiate a Collection Instance', function (callback) { var fdb = new ForerunnerDB(), db = fdb.db('temp'), coll = db.collection('test'); TB.strictEqual(coll instanceof ForerunnerDB.shared.modules.Collection, true, 'ForerunnerDB instance is instantiated'); callback(); }); TB.test('Collection', 'Upsert with array in update correctly removes maintain references', function (callback) { var fdb = new ForerunnerDB(), db = fdb.db('temp'), coll = db.collection('test'), newArr = [{ _id: 0, attended: 0 }, { _id: 1, attended: 0 }], data; coll.insert({_id: 1, arr: []}, {_id: 2, arr: []}); coll.upsert({ _id: 1, arr: newArr }); coll.upsert({ _id: 2, arr: newArr }); coll.update({ _id: 1, 'arr.$': { _id: 0 } }, { arr: { attended:1 } }); // Check if upsert worked data = coll.find(); TB.strictEqual(data.length, 2, 'Data length is correct'); TB.strictEqual(data[0]._id, 1, 'Data id 1 is correct'); TB.strictEqual(data[1]._id, 2, 'Data id 2 is correct'); TB.strictEqual(data[0].arr[0].attended, 1, 'Data id 1 arr 1 is correct'); TB.strictEqual(data[1].arr[0].attended, 0, 'Data id 2 arr 1 is correct'); TB.strictEqual(data[0].arr.length, 2, 'Data 1 length is correct'); TB.strictEqual(data[1].arr.length, 2, 'Data 1 length is correct'); // Check if the arrays are non-referenced in find TB.strictEqual(data[0].arr === data[1].arr, false, 'Data arrays in find result have been decoupled'); // Check if the arrays are non-referenced in underlying data objects TB.strictEqual(coll._data[0].arr === coll._data[1].arr, false, 'Data arrays in underlying data have been decoupled'); callback(); }); TB.test('Persist', 'Save Collection Data and Load it Back From File-Based Persistent Storage', function (callback) { var fdb = new ForerunnerDB(), self = this, db = fdb.db('temp'), coll = db.collection('test', { changeTimestamp: true }), result, lastChange; db.persist.dataDir('./configData'); coll.insert({ name: 'Test' }); lastChange = coll.metaData().lastChange; coll.save(function (err) { if (err) { console.log(err); TB.ok(false, err); } else { TB.equal(err, false, 'Save did not produce an error'); } db.drop(false); db = fdb.db('temp'); db.persist.dataDir('./configData'); coll = db.collection('test'); // Make sure the item does not currently exist result = coll.find(); TB.strictEqual(result.length, 0, 'Check that there are currently no items in the collection'); coll.load(function (err) { if (err) { console.log(err); TB.ok(false, err); } else { TB.ok(!err, 'Load did not produce an error'); } result = coll.find(); TB.strictEqual(result.length, 1, 'Check that items were loaded correctly'); TB.strictEqual(result[0] && result[0].name, 'Test', 'Check that the data loaded holds correct information'); TB.strictEqual(coll.metaData().lastChange.toISOString(), lastChange.toISOString(), 'Collection lastChange flag in metadata is the same as when saved'); db.drop(); callback(); }); }); }); TB.test('Persist', 'Timed save, 50,000 records', function (callback) { var fdb = new ForerunnerDB(), self = this, db = fdb.db('temp'), coll = db.collection('test', { changeTimestamp: true }), result, lastChange, dataArr = [], dataCount = 50000, testString, i = 0; db.persist.dataDir('./configData'); testString = JSON.stringify({ "_id": String(i), "data": [{ "moo": db.objectId(), "foo": db.objectId() }, { "moo": db.objectId(), "foo": db.objectId() }, { "moo": db.objectId(), "foo": db.objectId() }, { "moo": db.objectId(), "foo": db.objectId() }, { "moo": db.objectId(), "foo": db.objectId() }, { "moo": db.objectId(), "foo": db.objectId() }, { "moo": db.objectId(), "foo": db.objectId() }, { "moo": db.objectId(), "foo": db.objectId() }, { "moo": db.objectId(), "foo": db.objectId() }, { "moo": db.objectId(), "foo": db.objectId() }] }); TB.ok(testString.length === 519 || testString.length === 520, 'Check that each entry is 519 or 520 bytes'); TB.time('Generating ' + dataCount + ' records'); for (i = 0; i < dataCount; i++) { dataArr.push({ "_id": String(i), "data": [{ "moo": db.objectId(), "foo": db.objectId() }, { "moo": db.objectId(), "foo": db.objectId() }, { "moo": db.objectId(), "foo": db.objectId() }, { "moo": db.objectId(), "foo": db.objectId() }, { "moo": db.objectId(), "foo": db.objectId() }] }); } TB.time('Generating ' + dataCount + ' records'); TB.time('Inserting ' + dataCount + ' records'); coll.insert(dataArr, function () { TB.time('Inserting ' + dataCount + ' records'); lastChange = coll.metaData().lastChange; //console.log('Test', lastChange.toString()); TB.time('Saving data'); coll.save(function (err) { TB.time('Saving data'); if (err) { console.log(err); TB.ok(false, err); } else { TB.equal(err, false, 'Save did not produce an error'); } db.drop(false); db = fdb.db('temp'); db.persist.dataDir('./configData'); coll = db.collection('test'); // Make sure the item does not currently exist result = coll.find(); TB.strictEqual(result.length, 0, 'Check that there are currently no items in the collection'); TB.time('Loading data'); coll.load(function (err) { TB.time('Loading data'); if (err) { console.log(err); TB.ok(false, err); } else { TB.ok(!err, 'Load did not produce an error'); } TB.time('Running find on collection'); result = coll.find({}, {$decouple: false}); TB.time('Running find on collection'); TB.strictEqual(dataCount, result.length, 'Check that items were loaded correctly'); if (coll.metaData() && coll.metaData().lastChange && coll.metaData().lastChange.toISOString && lastChange) { TB.strictEqual(coll.metaData().lastChange.toISOString(), lastChange.toISOString(), 'Collection lastChange flag in metadata is the same as when saved'); } db.drop(); callback(); }); }); }); }); TB.test('Collection', 'index() :: Test 2d index search on large data set', function (callback) { var fdb = new ForerunnerDB(), db = fdb.db('temp'), coll = db.collection('cities').truncate(), result1, result2, cityData; cityData = require('./cities.json'); coll.ensureIndex({ lngLat: 1 }, { name: 'cityLatLngIndex', type: '2d' }); TB.ok(cityData.length, 499, 'Correct number of geospatial records loaded from data file'); coll.insert(cityData, function () { TB.ok(cityData.length, coll.count(), 'Correct number of geospatial records inserted'); console.log('Collection record count: ' + coll.count()); var index = coll.index('cityLatLngIndex'); TB.ok(index !== undefined, "Check index is available: " + index.name()); TB.ok(index.name() === 'cityLatLngIndex', "Check index is correct name: " + index.name()); // Query index by distance // $near queries are sorted by distance from center point by default result1 = coll.find({ lngLat: { $near: { $point: [51.50722, -0.12750], $maxDistance: 50, $distanceUnits: 'miles', $distanceField: 'dist', $geoHashField: 'geoHash' } } }); result2 = coll.find({ lngLat: { $near: { $point: [51.50722, -0.12750], $maxDistance: 100, $distanceUnits: 'miles', $distanceField: 'dist', $geoHashField: 'geoHash' } } }); TB.strictEqual(result1.length < result2.length, true, 'Number of doc in 100 miles is more than docs in 50 miles'); TB.strictEqual(result1.length, 9, 'Result1 count correct'); TB.strictEqual(result2.length, 22, 'Result2 count correct'); TB.strictEqual(result1[0].name, 'London, UK', 'Result 1 correct'); TB.strictEqual(result1[1].name, 'Wycombe, Swanley, Greater London BR8, UK', 'Result 2 correct'); TB.strictEqual(result1[2].name, 'Basildon, Essex, UK', 'Result 3 correct'); TB.strictEqual(result1[3].name, 'Luton, UK', 'Result 4 correct'); TB.strictEqual(result1[4].name, 'Chelmsford, Essex, UK', 'Result 5 correct'); TB.strictEqual(result1[5].name, 'Southend-on-Sea, UK', 'Result 6 correct'); TB.strictEqual(result1[6].name, 'Aylesbury, Buckinghamshire, UK', 'Result 7 correct'); TB.strictEqual(result1[7].name, 'Milton Keynes, UK', 'Result 8 correct'); TB.strictEqual(result1[8].name, 'Brighton, Brighton and Hove, UK', 'Result 9 correct'); TB.strictEqual(result2[0].name, 'London, UK', 'Result 1 correct'); TB.strictEqual(result2[1].name, 'Wycombe, Swanley, Greater London BR8, UK', 'Result 2 correct'); TB.strictEqual(result2[2].name, 'Basildon, Essex, UK', 'Result 3 correct'); TB.strictEqual(result2[3].name, 'Luton, UK', 'Result 4 correct'); TB.strictEqual(result2[4].name, 'Chelmsford, Essex, UK', 'Result 5 correct'); TB.strictEqual(result2[5].name, 'Southend-on-Sea, UK', 'Result 6 correct'); TB.strictEqual(result2[6].name, 'Aylesbury, Buckinghamshire, UK', 'Result 7 correct'); TB.strictEqual(result2[7].name, 'Milton Keynes, UK', 'Result 8 correct'); TB.strictEqual(result2[8].name, 'Brighton, Brighton and Hove, UK', 'Result 9 correct'); callback(); }); }); TB.test('Condition', 'Test IFTTT condition functionality', function (finishTest) { var fdb = new ForerunnerDB(), db = fdb.db('test'), coll = db.collection('stocksIOwn'), condition; condition = coll.when({ _id: 'TSLA', val: { $gt: 210 } }) .and({ _id: 'SCTY', val: { $gt: 23 } }) .then(function () { var tsla = coll.findById('TSLA'), scty = coll.findById('SCTY'); TB.strictEqual(tsla.val, 214, 'TSLA value is 214'); TB.strictEqual(scty.val, 25, 'TSLA value is 25'); TB.expect(4); finishTest(); }) .else(function () { var tsla = coll.findById('TSLA'), scty = coll.findById('SCTY'); TB.strictEqual(tsla.val, 214, 'TSLA value is 214'); TB.strictEqual(scty.val, 20, 'TSLA value is 20'); }); coll.insert([{ _id: 'TSLA', val: 214 }, { _id: 'SCTY', val: 20 }]); condition.start(undefined); coll.update({_id: 'SCTY'}, {val: 25}); }); TB.test('Persist', 'Check persist.auto()', function (finishTest) { var fdb = new ForerunnerDB(), db = fdb.db('testPersistDb'), coll; db.persist.dataDir('./testData'); db.persist.auto(true); coll = db.collection('testPersist'); coll.on('load', function () { TB.ok(true, 'Collection load event fired'); finishTest(); }); }); TB.test('Collection', 'Check aggregation', function (finishTest) { var fdb = new ForerunnerDB(), db = fdb.db('testPersistDb'), coll = db.collection("res"); coll.primaryKey("resId"); coll.insert({ resId: 1, TypeId: "Person", UID: "Bob", Data: {Age: 20, Name:"Bob"} }); coll.insert({ resId: 2, TypeId: "Person", UID: "Bob", Data: {Age: 25, Name:"Bob"} }); coll.insert({ resId: 3, TypeId: "Car", UID: "TeslaModelX", Data: {Manufacturer: "Tesla", Owner:"Bob"} }); coll.insert({ resId: 4, TypeId: "Person", UID: "Bill", Data: {Age: 22, Name:"Bill"} }); var tmpObj = {}, val; val = coll.sort({resId: -1}, coll.find({ "TypeId": "Person" })).filter(function (doc) { return coll._match(doc, { $distinct: { UID: 1 } }, {}, 'and', tmpObj); }); TB.ok(val.length === 2, 'The return data length is correct'); finishTest(); }); // This works but haven't written any test (strictEquals) stuff for it /*TB.test('Joins', 'Join multiple levels', function (callback) { var fdb = new ForerunnerDB(), db = fdb.db('temp'), customers = db.collection('customers'), orders = db.collection('orders'), addresses = db.collection('addresses'); customers.insert([{ "_id": 1, "name": 'Customer 1' }, { "_id": 2, "name": 'Customer 2' }, { "_id": 3, "name": 'Customer 3' }, { "_id": 4, "name": 'Customer 4' }]); addresses.insert([{ "customerId": 1, "address": "Customer 1 Address" }, { "customerId": 2, "address": "Customer 2 Address" }, { "customerId": 3, "address": "Customer 3 Address" }, { "customerId": 4, "address": "Customer 4 Address" }]); orders.insert([{ "_id": 1, "customers": [ 1, 2 ] }, { "_id": 2, "customers": [ 3, 4 ] }]); var result = orders.find({}, { "$join": [{ "customers": { "$where": { "$query": { "_id": "$$.customers" }, $options: { "$join": [{ "addresses": { "$where": { "$query": { "customerId": "$$._id" } }, "$as": "customerAddress", "$require": false, "$multi": false } }] } }, "$as": "customerDetails", "$require": false, "$multi": true } }] }); TB.strictEqual(result.length, 2, 'Customer data joined'); callback(); });*/ TB.start();