@nymphjs/nymph
Version:
Nymph.js - Nymph ORM
1,155 lines • 91.4 kB
JavaScript
import { dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
import fs from 'node:fs';
import strtotime from 'locutus/php/datetime/strtotime.js';
import { guid } from '@nymphjs/guid';
import { EntityUniqueConstraintError } from '../errors/index.js';
import { TestBModel as TestBModelClass, TestModel as TestModelClass, TestEmptyModel as TestEmptyModelClass, } from '../testArtifacts.js';
const __dirname = dirname(fileURLToPath(import.meta.url));
export function EntitiesTest(nymph, it) {
const TestModel = nymph.addEntityClass(TestModelClass);
const TestBModel = nymph.addEntityClass(TestBModelClass);
const TestEmptyModel = nymph.addEntityClass(TestEmptyModelClass);
let testEntity;
let testGuid;
let refGuid;
let createdMultiple = false;
// The entities created by this function are required by many of the tests.
async function createTestEntities() {
if (testGuid != null) {
return;
}
// Creating entity...
testEntity = await TestModel.factory();
// Saving entity...
testEntity.name = 'Entity Test ' + new Date().toLocaleString();
testEntity.null = null;
testEntity.string = 'test';
testEntity.array = [
'full',
'of',
'values',
500,
{ test: true },
{ nullbyte: '\\\x00\u0000 \x00' },
];
testEntity.match = matchValue;
testEntity.number = 30;
testEntity.numberString = '30';
testEntity.timestamp = Date.now();
expect(await testEntity.$save()).toEqual(true);
expect(testEntity.guid).not.toBeNull();
testGuid = testEntity.guid;
const entityReferenceTest = new TestModel();
entityReferenceTest.string = 'wrong';
entityReferenceTest.timestamp = strtotime('-2 days') * 1000;
expect(await entityReferenceTest.$save()).toEqual(true);
refGuid = entityReferenceTest.guid;
testEntity.reference = entityReferenceTest;
testEntity.refArray = [entityReferenceTest];
expect(await testEntity.$save()).toEqual(true);
entityReferenceTest.test = 'good';
expect(await entityReferenceTest.$save()).toEqual(true);
// Test asynchronous getEntity.
testEntity = (await nymph.getEntity({ class: TestModel }, testGuid));
expect(testEntity).toBeInstanceOf(TestModel);
expect(testEntity.guid).toEqual(testGuid);
}
// The entities created by this function are required by many of the tests.
async function createMultipleTestEntities() {
if (!createdMultiple) {
createdMultiple = true;
// Creating 100 entities...
for (let i = 0; i < 100; i++) {
const testEntity = await TestModel.factory();
testEntity.name = `Multi Test ${i}`;
// Reverse the number for sort testing.
testEntity.number = 100 - i;
testEntity.$removeTag('test');
testEntity.$addTag('multiTest');
expect(await testEntity.$save()).toEqual(true);
// Pause for a few milliseconds so the cdate and mdate can be sorted.
await new Promise((res) => setTimeout(() => res(1), 5));
}
}
}
it('delete old test data', async () => {
let amodels = await nymph.getEntities({ class: TestModel });
expect(Array.isArray(amodels)).toEqual(true);
for (const cur of amodels) {
expect(await cur.$delete()).toEqual(true);
}
amodels = await nymph.getEntities({ class: TestModel });
expect(amodels.length).toEqual(0);
let bmodels = await nymph.getEntities({ class: TestBModel });
expect(Array.isArray(bmodels)).toEqual(true);
for (const cur of bmodels) {
expect(await cur.$delete()).toEqual(true);
}
bmodels = await nymph.getEntities({ class: TestBModel });
expect(bmodels.length).toEqual(0);
});
it('create entity', async () => {
await createTestEntities();
});
it("doesn't create empty entity", async () => {
const testEntity = await TestEmptyModel.factory();
expect(await testEntity.$save()).toBeFalsy();
expect(testEntity.guid).toBeNull();
});
it('update mdate on save', async () => {
await createTestEntities();
const oldMdate = testEntity.mdate ?? Infinity;
await new Promise((resolve) => setTimeout(() => resolve(true), 100));
await testEntity.$save();
expect(testEntity.mdate).toBeGreaterThan(oldMdate);
});
it('create multiple entities', async () => {
return createMultipleTestEntities();
});
it('by guid', async () => {
await createTestEntities();
// Retrieving entity by GUID...
let resultEntity = await nymph.getEntity({ class: TestModel }, testGuid);
expect(testEntity.$is(resultEntity)).toEqual(true);
// Using class constructor...
resultEntity = await TestModel.factory(testGuid);
expect(testEntity.$is(resultEntity)).toEqual(true);
// Testing wrong GUID...
resultEntity = await nymph.getEntity({ class: TestModel }, guid());
expect(testEntity.$is(resultEntity)).toEqual(false);
});
it('guaranteed guid', async () => {
// Creating entity...
const testEntity = await TestModel.factory();
// Saving entity...
testEntity.name = 'Entity Test ' + new Date().toLocaleString();
testEntity.null = null;
testEntity.string = 'test';
testEntity.array = [];
testEntity.match = matchValue;
testEntity.number = 30;
testEntity.numberString = '30';
testEntity.timestamp = Date.now();
// Get the guaranteed GUID.
const testGuid = testEntity.$getGuaranteedGUID();
expect(await testEntity.$save()).toEqual(true);
expect(testEntity.guid).not.toBeNull();
expect(testEntity.guid).toEqual(testGuid);
// Retrieving entity by GUID...
let resultEntity = await nymph.getEntity({ class: TestModel }, testGuid);
expect(testEntity.$is(resultEntity)).toEqual(true);
// Delete the entity.
expect(await testEntity.$delete()).toEqual(true);
});
it('transactions', async () => {
await createTestEntities();
// Verify not in a transaction.
expect(await nymph.inTransaction()).toEqual(false);
let transaction = await nymph.startTransaction('test');
testEntity.$nymph = transaction;
if (!(await transaction.inTransaction())) {
console.log('This Nymph driver or database seems to not support transactions. Skipping transaction tests.');
await transaction.rollback('test');
return;
}
// Change a value in the test entity.
testEntity.string = 'bad value';
expect(await testEntity.$save()).toEqual(true);
// Rollback the transaction.
await transaction.rollback('test');
// Verify not in a transaction.
expect(await transaction.inTransaction()).toEqual(false);
// Verify the value is correct.
await testEntity.$refresh();
expect(testEntity.string).toEqual('test');
// Start a new transaction.
transaction = await nymph.startTransaction('test');
testEntity.$nymph = transaction;
// Verify in a transaction.
expect(await transaction.inTransaction()).toEqual(true);
// Delete the entity.
expect(await testEntity.$delete()).toEqual(true);
const resultEntity = await transaction.getEntity({ class: TestModel }, testGuid);
expect(resultEntity).toBeNull();
// Rollback the transaction.
await transaction.rollback('test');
// Verify not in a transaction.
expect(await transaction.inTransaction()).toEqual(false);
// Verify it's back.
testEntity = (await transaction.getEntity({ class: TestModel }, testGuid));
expect(testEntity.guid).toEqual(testGuid);
// Start a new transaction with a dot in the name.
transaction = await nymph.startTransaction('test.1');
testEntity.$nymph = transaction;
// Verify in a transaction.
expect(await transaction.inTransaction()).toEqual(true);
// Make a change.
testEntity.string = 'fish';
expect(await testEntity.$save()).toEqual(true);
// Commit the transaction.
await transaction.commit('test.1');
testEntity.$nymph = nymph;
// Verify not in a transaction.
expect(await transaction.inTransaction()).toEqual(false);
// Verify the value is correct.
await testEntity.$refresh();
expect(testEntity.string).toEqual('fish');
// Finally, change it back.
testEntity.string = 'test';
expect(await testEntity.$save()).toEqual(true);
// TODO: nested transactions
});
it('options', async () => {
await createTestEntities();
// Testing entity order, offset, limit...
const resultEntities = await nymph.getEntities({
class: TestModel,
reverse: true,
offset: 1,
limit: 1,
sort: 'cdate',
}, { type: '&', tag: 'test' });
expect(resultEntities.length).toEqual(1);
expect(testEntity.$is(resultEntities[0])).toEqual(true);
});
it('guid and tags', async () => {
await createTestEntities();
// Retrieving entity by GUID and tags...
const resultEntity = await nymph.getEntity({ class: TestModel }, { type: '&', guid: testGuid, tag: 'test' });
expect(testEntity.$is(resultEntity)).toEqual(true);
});
it('or selector', async () => {
await createTestEntities();
// Retrieving entity by GUID and tags...
const resultEntity = await nymph.getEntity({ class: TestModel }, { type: '|', guid: [testGuid, guid()] });
expect(testEntity.$is(resultEntity)).toEqual(true);
});
it('wrong or selector', async () => {
await createTestEntities();
// Retrieving entity by GUID and tags...
const resultEntity = await nymph.getEntity({ class: TestModel }, { type: '|', guid: [guid(), guid()] });
expect(testEntity.$is(resultEntity)).toEqual(false);
});
it('not guid', async () => {
await createTestEntities();
// Retrieving entity by !GUID...
const resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', '!guid': guid(), tag: 'test' });
expect(testEntity.$inArray(resultEntity)).toEqual(true);
});
it('not tags', async () => {
await createTestEntities();
// Retrieving entity by !tags...
const resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', guid: testGuid, '!tag': ['barbecue', 'pickles'] });
expect(testEntity.$inArray(resultEntity)).toEqual(true);
});
it('guid and wrong tags', async () => {
await createTestEntities();
// Testing GUID and wrong tags...
const resultEntity = await nymph.getEntity({ class: TestModel }, { type: '&', guid: testGuid, tag: ['pickles'] });
expect(resultEntity).toBeNull();
});
it('tags', async () => {
await createTestEntities();
// Retrieving entity by tags...
const resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', tag: 'test' });
expect(testEntity.$inArray(resultEntity)).toEqual(true);
});
it('wrong tags', async () => {
await createTestEntities();
// Testing wrong tags...
const resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', tag: 'pickles' });
expect(testEntity.$inArray(resultEntity)).toEqual(false);
});
it('inclusive tags', async () => {
await createTestEntities();
// Retrieving entity by tags inclusively...
const resultEntity = await nymph.getEntities({ class: TestModel }, { type: '|', tag: ['pickles', 'test', 'barbecue'] });
expect(testEntity.$inArray(resultEntity)).toEqual(true);
});
it('wrong inclusive tags', async () => {
await createTestEntities();
// Testing wrong inclusive tags...
const resultEntity = await nymph.getEntities({ class: TestModel }, { type: '|', tag: ['pickles', 'barbecue'] });
expect(testEntity.$inArray(resultEntity)).toEqual(false);
});
it('mixed tags', async () => {
await createTestEntities();
// Retrieving entity by mixed tags...
const resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', tag: 'test' }, { type: '|', tag: ['pickles', 'test', 'barbecue'] });
expect(testEntity.$inArray(resultEntity)).toEqual(true);
});
it('wrong inclusive mixed tags', async () => {
await createTestEntities();
// Testing wrong inclusive mixed tags...
const resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', tag: 'test' }, { type: '|', tag: ['pickles', 'barbecue'] });
expect(testEntity.$inArray(resultEntity)).toEqual(false);
});
it('wrong exclusive mixed tags', async () => {
await createTestEntities();
// Testing wrong exclusive mixed tags...
const resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', tag: 'pickles' }, { type: '|', tag: ['test', 'barbecue'] });
expect(testEntity.$inArray(resultEntity)).toEqual(false);
});
it('defined', async () => {
await createTestEntities();
// Retrieving entity by defined...
const resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', defined: 'string' });
expect(testEntity.$inArray(resultEntity)).toEqual(true);
});
it('not defined', async () => {
await createTestEntities();
// Retrieving entity by !defined...
const resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', tag: 'test', '!defined': 'pickles' });
expect(testEntity.$inArray(resultEntity)).toEqual(true);
});
it('defined in a not and clause', async () => {
await createTestEntities();
// Retrieving entity by defined in not and clause...
const resultEntity = await nymph.getEntities({ class: TestModel }, { type: '!&', defined: 'pickles' }, { type: '&', tag: 'test' });
expect(testEntity.$inArray(resultEntity)).toEqual(true);
});
it('equal', async () => {
await createTestEntities();
// Retrieving entity by equal...
let resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', equal: ['string', 'test'] });
expect(testEntity.$inArray(resultEntity)).toEqual(true);
// Retrieving entity by equal...
resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', equal: ['null', null] });
expect(testEntity.$inArray(resultEntity)).toEqual(true);
// Retrieving entity by equal...
resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', equal: ['boolean', true] });
expect(testEntity.$inArray(resultEntity)).toEqual(true);
// Retrieving entity by equal...
resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', equal: ['number', 30] });
expect(testEntity.$inArray(resultEntity)).toEqual(true);
// Retrieving entity by equal...
resultEntity = await nymph.getEntities({ class: TestModel }, {
type: '&',
equal: [
'array',
[
'full',
'of',
'values',
500,
{ test: true },
{ nullbyte: '\\\x00\u0000 \x00' },
],
],
});
expect(testEntity.$inArray(resultEntity)).toEqual(true);
// Retrieving entity by equal...
resultEntity = await nymph.getEntities({ class: TestModel }, {
type: '&',
equal: ['match', matchValue],
});
expect(testEntity.$inArray(resultEntity)).toEqual(true);
});
it('not equal', async () => {
await createTestEntities();
const referenceEntity = await TestModel.factory(refGuid);
expect(referenceEntity.guid).toEqual(refGuid);
// Retrieving entity by !equal...
const resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', tag: 'test', '!equal': ['string', 'wrong'] });
expect(testEntity.$inArray(resultEntity)).toEqual(true);
expect(referenceEntity.$inArray(resultEntity)).toEqual(false);
});
it('like', async () => {
await createTestEntities();
// Retrieving entity by like...
const resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', like: ['string', 't_s%'] });
expect(testEntity.$inArray(resultEntity)).toEqual(true);
});
it('not like', async () => {
await createTestEntities();
const referenceEntity = await TestModel.factory(refGuid);
expect(referenceEntity.guid).toEqual(refGuid);
// Retrieving entity by !like...
const resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', tag: 'test', '!like': ['string', 'wr_n%'] });
expect(testEntity.$inArray(resultEntity)).toEqual(true);
expect(referenceEntity.$inArray(resultEntity)).toEqual(false);
});
it('ilike', async () => {
await createTestEntities();
// Retrieving entity by ilike...
const resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', ilike: ['string', 'T_s%'] });
expect(testEntity.$inArray(resultEntity)).toEqual(true);
});
it('not ilike', async () => {
await createTestEntities();
const referenceEntity = await TestModel.factory(refGuid);
expect(referenceEntity.guid).toEqual(refGuid);
// Retrieving entity by !ilike...
const resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', tag: 'test', '!ilike': ['string', 'wr_n%'] });
expect(testEntity.$inArray(resultEntity)).toEqual(true);
expect(referenceEntity.$inArray(resultEntity)).toEqual(false);
});
it('like with wrong case', async () => {
await createTestEntities();
// Retrieving entity by like...
const resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', like: ['string', 'T_s%'] });
expect(testEntity.$inArray(resultEntity)).toEqual(false);
});
it('tags and equal', async () => {
await createTestEntities();
// Retrieving entity by tags and equal...
const resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', tag: 'test', equal: ['string', 'test'] });
expect(testEntity.$inArray(resultEntity)).toEqual(true);
});
it('wrong tags right equal', async () => {
await createTestEntities();
// Testing wrong tags and right equal...
const resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', tag: 'pickles', equal: ['string', 'test'] });
expect(testEntity.$inArray(resultEntity)).toEqual(false);
});
it('right tags wrong equal', async () => {
await createTestEntities();
// Testing right tags and wrong equal...
const resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', tag: 'test', equal: ['string', 'pickles'] });
expect(testEntity.$inArray(resultEntity)).toEqual(false);
});
it('wrong tags wrong equal', async () => {
await createTestEntities();
// Testing wrong tags and wrong equal...
const resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', tag: 'pickles', equal: ['string', 'pickles'] });
expect(testEntity.$inArray(resultEntity)).toEqual(false);
});
it('contain', async () => {
await createTestEntities();
// Retrieving entity by contain...
let resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', contain: ['array', 'values'] });
expect(testEntity.$inArray(resultEntity)).toEqual(true);
// Retrieving entity by contain...
resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', contain: ['array', 500] });
expect(testEntity.$inArray(resultEntity)).toEqual(true);
// Retrieving entity by contain...
resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', contain: ['array', { test: true }] });
expect(testEntity.$inArray(resultEntity)).toEqual(true);
});
it('not contain', async () => {
await createTestEntities();
// Retrieving entity by !contain...
const resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', tag: 'test' }, { type: '!&', contain: ['array', 'pickles'] });
expect(testEntity.$inArray(resultEntity)).toEqual(true);
});
it('wrong contain', async () => {
await createTestEntities();
// Testing wrong contain...
let resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', contain: ['array', 'pickles'] });
expect(testEntity.$inArray(resultEntity)).toEqual(false);
// Testing wrong contain...
resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', contain: ['string', 'pickles'] });
expect(testEntity.$inArray(resultEntity)).toEqual(false);
});
it('match', async () => {
await createTestEntities();
// Retrieving entity by regex match...
let resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', match: ['match', '.*'] });
expect(testEntity.$inArray(resultEntity)).toEqual(true);
resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', tag: 'test', match: ['match', 'Edward McCheese'] });
expect(testEntity.$inArray(resultEntity)).toEqual(true);
resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', tag: 'test' }, {
type: '|',
match: [
['string', '[0-9]'],
['match', 'Edward McCheese'],
],
});
expect(testEntity.$inArray(resultEntity)).toEqual(true);
resultEntity = await nymph.getEntities({ class: TestModel }, {
type: '&',
tag: 'test',
match: ['match', '[-a-zA-Z0-9+_]+@[-a-zA-Z0-9_]+.[-a-zA-Z0-9_]{2,4}'],
});
expect(testEntity.$inArray(resultEntity)).toEqual(true);
resultEntity = await nymph.getEntities({ class: TestModel }, {
type: '&',
tag: 'test',
match: ['match', '\\([0-9]{3}\\) [0-9]{3}-[0-9]{4}'],
});
expect(testEntity.$inArray(resultEntity)).toEqual(true);
});
it('imatch', async () => {
await createTestEntities();
// Retrieving entity by regex match...
const resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', tag: 'test', imatch: ['match', 'edward mccheese'] });
expect(testEntity.$inArray(resultEntity)).toEqual(true);
});
it('wrong match', async () => {
await createTestEntities();
// Testing wrong regex match...
let resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', match: ['match', '='] });
expect(testEntity.$inArray(resultEntity)).toEqual(false);
resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', tag: 'pickle', match: ['match', '.*'] });
expect(testEntity.$inArray(resultEntity)).toEqual(false);
resultEntity = await nymph.getEntities({ class: TestModel }, {
type: '|',
match: [
['string', '[0-9]'],
['match', ',,'],
],
});
expect(testEntity.$inArray(resultEntity)).toEqual(false);
});
it('match wrong case', async () => {
await createTestEntities();
// Retrieving entity by regex match...
const resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', tag: 'test', match: ['match', 'edward mccheese'] });
expect(testEntity.$inArray(resultEntity)).toEqual(false);
});
it('match and equal inclusive', async () => {
await createTestEntities();
// Retrieving entity by regex + equal inclusively...
const resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', tag: 'test' }, { type: '|', equal: ['string', 'pickles'], match: ['string', 'test'] });
expect(testEntity.$inArray(resultEntity)).toEqual(true);
});
it('greater than', async () => {
await createTestEntities();
// Retrieving entity by inequality...
let resultEntity = await nymph.getEntities({ class: TestModel }, {
type: '|',
gt: [
['number', 30],
['pickles', 100],
],
});
expect(testEntity.$inArray(resultEntity)).toEqual(false);
// Retrieving entity by inequality...
resultEntity = await nymph.getEntities({ class: TestModel }, {
type: '|',
gt: [
['number', 31],
['pickles', 100],
],
});
expect(testEntity.$inArray(resultEntity)).toEqual(false);
// Retrieving entity by inequality...
resultEntity = await nymph.getEntities({ class: TestModel }, {
type: '|',
gt: [
['number', 29],
['pickles', 100],
],
});
expect(testEntity.$inArray(resultEntity)).toEqual(true);
// Retrieving entity by inequality...
resultEntity = await nymph.getEntities({ class: TestModel }, {
type: '|',
gt: [
['numberString', 30],
['pickles', 100],
],
});
expect(testEntity.$inArray(resultEntity)).toEqual(false);
// Retrieving entity by inequality...
resultEntity = await nymph.getEntities({ class: TestModel }, {
type: '|',
gt: [
['numberString', 31],
['pickles', 100],
],
});
expect(testEntity.$inArray(resultEntity)).toEqual(false);
// Retrieving entity by inequality...
resultEntity = await nymph.getEntities({ class: TestModel }, {
type: '|',
gt: [
['numberString', 29],
['pickles', 100],
],
});
expect(testEntity.$inArray(resultEntity)).toEqual(true);
});
it('greater than or equal', async () => {
await createTestEntities();
// Retrieving entity by inequality...
let resultEntity = await nymph.getEntities({ class: TestModel }, {
type: '|',
gte: [
['number', 30],
['pickles', 100],
],
});
expect(testEntity.$inArray(resultEntity)).toEqual(true);
// Retrieving entity by inequality...
resultEntity = await nymph.getEntities({ class: TestModel }, {
type: '|',
gte: [
['number', 31],
['pickles', 100],
],
});
expect(testEntity.$inArray(resultEntity)).toEqual(false);
// Retrieving entity by inequality...
resultEntity = await nymph.getEntities({ class: TestModel }, {
type: '|',
gte: [
['number', 29],
['pickles', 100],
],
});
expect(testEntity.$inArray(resultEntity)).toEqual(true);
// Retrieving entity by inequality...
resultEntity = await nymph.getEntities({ class: TestModel }, {
type: '|',
gte: [
['numberString', 30],
['pickles', 100],
],
});
expect(testEntity.$inArray(resultEntity)).toEqual(true);
// Retrieving entity by inequality...
resultEntity = await nymph.getEntities({ class: TestModel }, {
type: '|',
gte: [
['numberString', 31],
['pickles', 100],
],
});
expect(testEntity.$inArray(resultEntity)).toEqual(false);
// Retrieving entity by inequality...
resultEntity = await nymph.getEntities({ class: TestModel }, {
type: '|',
gte: [
['numberString', 29],
['pickles', 100],
],
});
expect(testEntity.$inArray(resultEntity)).toEqual(true);
});
it('less than', async () => {
await createTestEntities();
// Retrieving entity by inequality...
let resultEntity = await nymph.getEntities({ class: TestModel }, {
type: '|',
lt: [
['number', 30],
['pickles', 100],
],
});
expect(testEntity.$inArray(resultEntity)).toEqual(false);
// Retrieving entity by inequality...
resultEntity = await nymph.getEntities({ class: TestModel }, {
type: '|',
lt: [
['number', 31],
['pickles', 100],
],
});
expect(testEntity.$inArray(resultEntity)).toEqual(true);
// Retrieving entity by inequality...
resultEntity = await nymph.getEntities({ class: TestModel }, {
type: '|',
lt: [
['number', 29],
['pickles', 100],
],
});
expect(testEntity.$inArray(resultEntity)).toEqual(false);
// Retrieving entity by inequality...
resultEntity = await nymph.getEntities({ class: TestModel }, {
type: '|',
lt: [
['numberString', 30],
['pickles', 100],
],
});
expect(testEntity.$inArray(resultEntity)).toEqual(false);
// Retrieving entity by inequality...
resultEntity = await nymph.getEntities({ class: TestModel }, {
type: '|',
lt: [
['numberString', 31],
['pickles', 100],
],
});
expect(testEntity.$inArray(resultEntity)).toEqual(true);
// Retrieving entity by inequality...
resultEntity = await nymph.getEntities({ class: TestModel }, {
type: '|',
lt: [
['numberString', 29],
['pickles', 100],
],
});
expect(testEntity.$inArray(resultEntity)).toEqual(false);
});
it('less than or equal', async () => {
await createTestEntities();
// Retrieving entity by inequality...
let resultEntity = await nymph.getEntities({ class: TestModel }, {
type: '|',
lte: [
['number', 30],
['pickles', 100],
],
});
expect(testEntity.$inArray(resultEntity)).toEqual(true);
// Retrieving entity by inequality...
resultEntity = await nymph.getEntities({ class: TestModel }, {
type: '|',
lte: [
['number', 31],
['pickles', 100],
],
});
expect(testEntity.$inArray(resultEntity)).toEqual(true);
// Retrieving entity by inequality...
resultEntity = await nymph.getEntities({ class: TestModel }, {
type: '|',
lte: [
['number', 29],
['pickles', 100],
],
});
expect(testEntity.$inArray(resultEntity)).toEqual(false);
// Retrieving entity by inequality...
resultEntity = await nymph.getEntities({ class: TestModel }, {
type: '|',
lte: [
['numberString', 30],
['pickles', 100],
],
});
expect(testEntity.$inArray(resultEntity)).toEqual(true);
// Retrieving entity by inequality...
resultEntity = await nymph.getEntities({ class: TestModel }, {
type: '|',
lte: [
['numberString', 31],
['pickles', 100],
],
});
expect(testEntity.$inArray(resultEntity)).toEqual(true);
// Retrieving entity by inequality...
resultEntity = await nymph.getEntities({ class: TestModel }, {
type: '|',
lte: [
['numberString', 29],
['pickles', 100],
],
});
expect(testEntity.$inArray(resultEntity)).toEqual(false);
});
it('not inequality', async () => {
await createTestEntities();
// Retrieving entity by !inequality...
const resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', tag: 'test' }, { type: '!&', gte: ['number', 60] });
expect(testEntity.$inArray(resultEntity)).toEqual(true);
});
it('wrong inequality', async () => {
await createTestEntities();
// Testing wrong inequality...
const resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', lte: ['number', 29.99] });
expect(testEntity.$inArray(resultEntity)).toEqual(false);
});
it('greater than cdate', async () => {
await createTestEntities();
// Retrieving entity by time...
const resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', tag: 'test', gt: ['cdate', (testEntity.cdate ?? 0) - 120] });
expect(testEntity.$inArray(resultEntity)).toEqual(true);
});
it('wrong cdate', async () => {
await createTestEntities();
// Testing wrong time...
const resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', tag: 'test', gte: ['cdate', (testEntity.cdate ?? 0) + 1] });
expect(testEntity.$inArray(resultEntity)).toEqual(false);
});
it('time selector', async () => {
await createTestEntities();
const referenceEntity = await TestModel.factory(refGuid);
// Retrieving entity by relative time...
let resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', gt: ['timestamp', null, '-1 day'] });
expect(testEntity.$inArray(resultEntity)).toEqual(true);
expect(referenceEntity.$inArray(resultEntity)).toEqual(false);
// Retrieving entity by relative time inclusively...
resultEntity = await nymph.getEntities({ class: TestModel }, {
type: '|',
gt: [
['timestamp', null, '-1 day'],
['timestamp', null, '+5 days'],
],
});
expect(testEntity.$inArray(resultEntity)).toEqual(true);
expect(referenceEntity.$inArray(resultEntity)).toEqual(false);
// Retrieving entity by relative time...
resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', gt: ['timestamp', null, '-3 days'] });
expect(testEntity.$inArray(resultEntity)).toEqual(true);
expect(referenceEntity.$inArray(resultEntity)).toEqual(true);
// Retrieving entity by relative time...
resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', gt: ['cdate', null, '-1 day'] });
expect(testEntity.$inArray(resultEntity)).toEqual(true);
expect(referenceEntity.$inArray(resultEntity)).toEqual(true);
});
it('wrong time selector', async () => {
await createTestEntities();
const referenceEntity = await TestModel.factory(refGuid);
// Retrieving entity by relative time...
let resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', tag: 'test', gt: ['timestamp', null, '+1 day'] });
expect(testEntity.$inArray(resultEntity)).toEqual(false);
expect(referenceEntity.$inArray(resultEntity)).toEqual(false);
// Retrieving entity by relative time...
resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', tag: 'test', lt: ['timestamp', null, '-3 days'] });
expect(testEntity.$inArray(resultEntity)).toEqual(false);
expect(referenceEntity.$inArray(resultEntity)).toEqual(false);
// Retrieving entity by relative time...
resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', tag: 'test', gt: ['cdate', null, '+1 day'] });
expect(testEntity.$inArray(resultEntity)).toEqual(false);
expect(referenceEntity.$inArray(resultEntity)).toEqual(false);
});
it('references', async () => {
await createTestEntities();
// Testing referenced entities...
await testEntity.reference?.$wake();
expect(testEntity.reference?.test).toEqual('good');
// Testing referenced entity arrays...
await Promise.all(testEntity.refArray?.map((e) => e.$wake()) || []);
expect(testEntity.refArray?.[0].test).toEqual('good');
});
it('ref', async () => {
await createTestEntities();
// Retrieving entity by reference...
const resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', ref: ['reference', refGuid] });
expect(testEntity.$inArray(resultEntity)).toEqual(true);
});
it('not ref', async () => {
await createTestEntities();
// Retrieving entity by !reference...
const resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', tag: 'test' }, { type: '!&', ref: ['reference', guid()] });
expect(testEntity.$inArray(resultEntity)).toEqual(true);
});
it('wrong ref', async () => {
await createTestEntities();
// Testing wrong reference...
const resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', ref: ['reference', guid()] });
expect(testEntity.$inArray(resultEntity)).toEqual(false);
});
it('nonexistent ref', async () => {
await createTestEntities();
// Testing non-existent reference...
const resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', ref: ['pickle', refGuid] });
expect(testEntity.$inArray(resultEntity)).toEqual(false);
});
it('inclusive ref', async () => {
await createTestEntities();
// Retrieving entity by inclusive reference...
const resultEntity = await nymph.getEntities({ class: TestModel }, {
type: '|',
ref: [
['reference', refGuid],
['reference', guid()],
],
});
expect(testEntity.$inArray(resultEntity)).toEqual(true);
});
it('wrong inclusive ref', async () => {
await createTestEntities();
// Testing wrong inclusive reference...
const resultEntity = await nymph.getEntities({ class: TestModel }, {
type: '|',
ref: [
['reference', guid()],
['reference', guid()],
],
});
expect(testEntity.$inArray(resultEntity)).toEqual(false);
});
it('ref in an array', async () => {
await createTestEntities();
// Retrieving entity by array reference...
const resultEntity = await nymph.getEntities({ class: TestModel }, { type: '&', ref: ['refArray', refGuid] });
expect(testEntity.$inArray(resultEntity)).toEqual(true);
});
it('wrong ref in an array', async () => {
await createTestEntities();
// Testing wrong array reference...
const resultEntity = await nymph.getEntities({ class: TestModel }, {
type: '&',
ref: [
['refArray', refGuid],
['refArray', guid()],
],
});
expect(testEntity.$inArray(resultEntity)).toEqual(false);
});
it('logic operations', async () => {
await createTestEntities();
// Testing logic operations...
const resultEntity = await nymph.getEntities({ class: TestModel }, {
type: '&',
'!ref': [
['refArray', guid()],
['refArray', guid()],
],
'!lte': ['number', 29.99],
}, {
type: '|',
'!lte': [
['number', 29.99],
['number', 30],
],
}, {
type: '!&',
'!equal': ['string', 'test'],
'!contain': [
['array', 'full'],
['array', 'of'],
['array', 'values'],
['array', 500],
['array', { test: true }],
['array', { nullbyte: '\\\x00\u0000 \x00' }],
],
}, {
type: '!|',
'!equal': ['string', 'test'],
contain: [
['array', 'full'],
['array', 'of'],
['array', 'values'],
['array', 500],
],
});
expect(testEntity.$inArray(resultEntity)).toEqual(true);
});
it('count return', async () => {
await createTestEntities();
const result = await nymph.getEntities({ class: TestModel });
// Testing count return...
const resultCount = await nymph.getEntities({
class: TestModel,
return: 'count',
});
expect(resultCount).toBeGreaterThanOrEqual(1);
expect(resultCount).toEqual(result.length);
const resultSelectors = await nymph.getEntities({ class: TestModel }, { type: '&', ref: ['reference', refGuid] });
// Testing count return with selectors...
const resultSelectorsCount = await nymph.getEntities({ class: TestModel, return: 'count' }, { type: '&', ref: ['reference', refGuid] });
expect(resultSelectorsCount).toBeGreaterThanOrEqual(1);
expect(resultSelectorsCount).toEqual(resultSelectors.length);
// Testing count return with limit...
const resultSelectorsLimit = await nymph.getEntities({
class: TestModel,
limit: 1,
return: 'count',
});
expect(resultSelectorsLimit).toEqual(1);
// Testing count return with limit...
const resultSelectorsSingle = await nymph.getEntity({
class: TestModel,
return: 'count',
});
expect(resultSelectorsSingle).toEqual(1);
// Testing empty count...
const resultSelectorsEmpty = await nymph.getEntities({ class: TestModel, return: 'count' }, { type: '&', ref: ['reference', guid()] });
expect(resultSelectorsEmpty).toEqual(0);
});
it('guid return', async () => {
await createTestEntities();
// Testing guid return using logic operations...
const resultGuid = await nymph.getEntities({ class: TestModel, return: 'guid' }, {
type: '&',
'!ref': [
['refArray', guid()],
['refArray', guid()],
],
'!lte': ['number', 29.99],
}, {
type: '|',
'!lte': [
['number', 29.99],
['number', 30],
],
}, {
type: '!&',
'!equal': ['string', 'test'],
'!contain': [
['array', 'full'],
['array', 'of'],
['array', 'values'],
['array', 500],
['array', { test: true }],
['array', { nullbyte: '\\\x00\u0000 \x00' }],
],
}, {
type: '!|',
'!equal': ['string', 'test'],
contain: [
['array', 'full'],
['array', 'of'],
['array', 'values'],
['array', 500],
],
});
expect(resultGuid.indexOf(testEntity.guid ?? '')).toBeGreaterThan(-1);
});
it('object return', async () => {
await createTestEntities();
// Testing object return using logic operations...
const resultObjects = await nymph.getEntities({ class: TestModel, return: 'object' }, {
type: '&',
'!ref': [
['refArray', guid()],
['refArray', guid()],
],
'!lte': ['number', 29.99],
}, {
type: '|',
'!lte': [
['number', 29.99],
['number', 30],
],
}, {
type: '!&',
'!equal': ['string', 'test'],
'!contain': [
['array', 'full'],
['array', 'of'],
['array', 'values'],
['array', 500],
['array', { test: true }],
['array', { nullbyte: '\\\x00\u0000 \x00' }],
],
}, {
type: '!|',
'!equal': ['string', 'test'],
contain: [
['array', 'full'],
['array', 'of'],
['array', 'values'],
['array', 500],
],
});
const resultObject = resultObjects.find((entity) => entity.guid === testEntity.guid);
expect(resultObject).toBeInstanceOf(Object);
expect(resultObject).not.toBeInstanceOf(TestModel);
expect(Array.isArray(resultObject?.tags)).toBeTruthy();
expect(resultObject?.string).toEqual('test');
});
it('deep selector', async () => {
await createTestEntities();
// Testing deep selectors...
const resultEntity = await nymph.getEntities({ class: TestModel }, {
type: '&',
'!ref': [
['refArray', guid()],
['refArray', guid()],
],
'!lte': ['number', 29.99],
}, {
type: '&',
selector: [
{
type: '|',
'!lte': [
['number', 29.99],
['number', 30],
],
},
{
type: '!&',
'!equal': ['string', 'test'],
'!contain': [
['array', 'full'],
['array', 'of'],
['array', 'values'],
['array', 500],
['array', { test: true }],
['array', { nullbyte: '\\\x00\u0000 \x00' }],
],
},
{
type: '!|',
'!equal': ['string', 'test'],
contain: [
['array', 'full'],
['array', 'of'],
['array', 'values'],
['array', 500],
],
},
],
});
expect(testEntity.$inArray(resultEntity)).toEqual(true);
const resultEntity2 = await nymph.getEntities({ class: TestModel }, {
type: '&',
'!ref': [
['refArray', guid()],
['refArray', guid()],
],
'!lte': ['number', 29.99],
}, {
type: '|',
selector: [
{
type: '&',
'!lte': [
['number', 29.99],
['number', 30],
],
},
{
type: '!&',
'!equal': ['string', 'test'],
'!contain': [
['array', 'full'],
['array', 'of'],
['array', 'values'],
['array', 500],
['array', { test: true }],
['array', { nullbyte: '\\\x00\u0000 \x00' }],
],
},
{
type: '&',
'!equal': ['string', 'test'],
contain: [
['array', 'full'],
['array', 'of'],
['array', 'values'],
['array', 500],
],
},
],
});
expect(testEntity.$inArray(resultEntity2)).toEqual(true);
const resultEntity3 = await nymph.getEntities({ class: TestModel }, {
type: '|',
selector: [
{
type: '&',
'!ref': ['refArray', guid()],
'!lte': ['number', 29.99],
},
{ type: '&', gte: ['number', 16000] },
],
});
expect(testEntity.$inArray(resultEntity3)).toEqual(true);
const resultEntity4 = await nymph.getEntities({ class: TestModel }, {
type: '|',
selector: [
{
type: '&',
'!ref': ['refArray', guid()],
'!lte': ['number', 29.99],
},
{
type: '&',
selector: {
type: '&',
selector: { type: '&', gte: ['number', 16000] },
},
},
],
});
expect(testEntity.$inArray(resultEntity4)).toEqual(true);
});
it('wrong deep selector', async () => {
// Testing wrong deep selectors...
const resultEntity = await nymph.getEntities({ class: TestModel }, {
type: '&',
selector: [
{
type: '&',
'!ref': ['refArray', guid()],
'!lte'