class-o-mat
Version:
ALPHA VERSION ONLY: class-o-mats will help to create getter-setter functionality with validations that can be attached to a container class for easier coding. Some basic validations are included. class-o-mats also has the ability to store params as bloc
682 lines (540 loc) • 21.5 kB
JavaScript
import Bunyan from 'bunyan';
const log = Bunyan.createLogger({name: "NestedUsageTest"});
import 'mocha';
import { expect } from 'chai';
import { NONE,
TEST_CLASS,
CLASS_O_MAT,
FIELD,
CHILD_ADDER,
COPY } from '../src/constants';
import ClassOMat from '../src/class-o-mat';
describe(`Test of creating data with nested sets. This targetData
is taken from Aenea Paths factory`,
()=>{
class PathTestClass {
static TYPE = 'PATH'
TYPE = 'PATH'
}
class StoreTestClass {
static TYPE = 'STORE';
TYPE = 'STORE';
}
class FirstClass {
static TYPE = 'FIRST';
TYPE = 'FIRST';
}
class NextClass {
static TYPE = 'NEXT';
TYPE = 'NEXT';
}
var makeBelieveNodeStore = {TYPE: 'NODE_STORE'};
var makeBelieveRelStore = {TYPE: 'REL_STORE'};
var makeBelieveRelChain = {TYPE: 'REL_CHAIN'};
var makeBelieveAddFunction = ':)';
var storeClassOMat;
var toStoreClassOMat;
var fromStoreClassOMat;
var pathClassOMat;
var topClassOMat;
var subTopClassOMat;
var nextClassOMat;
var subNextClassOMat;
var nextSibClassOMat;
it(`Should create the store ClassOMat.
It should have the following fields:
store, field, CollectionType`,
()=>{
storeClassOMat = new ClassOMat('store');
storeClassOMat.BaseClass(StoreTestClass)
.field('store')
.field('type')
.field('getCollection').toggler().default(false)
.field('getItem').toggler().default(true)
const TestClass = storeClassOMat.buildClass(StoreTestClass);
const testInstance = new TestClass();
expect(storeClassOMat.TYPE).to.equal(CLASS_O_MAT);
expect(typeof testInstance._params).to.equal('object')
expect(testInstance.TYPE).to.equal('STORE');
expect(typeof testInstance.store).to.equal('function');
expect(typeof testInstance.type).to.equal('function');
expect(typeof testInstance.getCollection).to.equal('function');
expect(typeof testInstance.getItem).to.equal('function');
}
);
it(`Should create the path ClassOMat. It should have a name field`,
()=>{
pathClassOMat = new ClassOMat('path')
.BaseClass(PathTestClass)
.field('name')
.$();
// pathClassOMat.buildClass();
const TestClass = pathClassOMat.$();
const testInstance = new TestClass();
expect(testInstance.TYPE).to.equal('PATH');
expect(typeof testInstance.name).to.equal('function');
}
);
it(`Should create a ChildAdder class with the addChild command`,
()=>{
const childAdder = pathClassOMat.addChild(storeClassOMat, 'from');
expect(childAdder.TYPE).to.equal(CHILD_ADDER);
expect(typeof childAdder.$).to.equal('function');
expect(typeof childAdder.addChild).to.equal('function');
expect(typeof childAdder.copyField).to.equal('function');
}
);
it(`Should create a Copy class from a ChildAdder
with the copyField command`,
()=>{
const childAdder = pathClassOMat.addChild(storeClassOMat).as('from');
const copy = childAdder.copyField('from');
const sameChildAdder = copy.$();
expect(copy.TYPE).to.equal(COPY);
expect(sameChildAdder.TYPE).to.equal(CHILD_ADDER);
expect(typeof copy.$).to.equal('function');
expect(typeof copy.as).to.equal('function');
}
);
it(`Should attach a storeClassOMat to the pathClassOMat as "from"
The class created by pathClassOMat should contain the one
created by the storeClassOMat. It should be able to access the
store classOMat`,
()=>{
pathClassOMat.addChild(storeClassOMat).as$('from');
const TestClassPath = pathClassOMat.$(PathTestClass);
const thisStoreClassOMat = pathClassOMat.getChild('from');
expect(thisStoreClassOMat.TYPE).to.equal(CLASS_O_MAT);
expect(thisStoreClassOMat.key()).to.equal('store');
expect(thisStoreClassOMat.parent().TYPE).to.equal(CLASS_O_MAT);
}
);
it(`Should create the two classes`,
()=>{
const Path = pathClassOMat.$();
const path = new Path();
expect(path.TYPE).to.equal('PATH');
expect(typeof path.from).to.equal('function');
expect(path.from().TYPE).to.equal('STORE');
}
);
it(`Should complete building out the pathClassOMat with connections`,
()=>{
pathClassOMat.addChild(storeClassOMat).as$('to');
const Path = pathClassOMat.$();
const path = new Path();
expect(typeof path.from).to.equal('function');
const toStore = path.to();
expect(path.TYPE).to.equal('PATH');
expect(path.to().TYPE).to.equal('STORE');
}
);
it(`should be able to create a ClassOMat that instantiates itself`,
()=>{
class TestClass {
TYPE = 'BOO';
}
const classOMat = new ClassOMat('bork')
.BaseClass(TestClass)
.field('success').toggler()
.field('result')
.$();
classOMat.addChild().as$('next');
const Class = classOMat.$();
const test = new Class();
const nextTest = test.next();
expect(test.TYPE).to.equal('BOO')
expect(nextTest.TYPE).to.equal('BOO')
expect(typeof test.next).to.equal('function');
}
);
it(`Start again building the entire set as it might be used in Aenea
path building system`,
()=>{
class FromBaseClass {TYPE='FROM'};
class ToBaseClass {TYPE='TO'};
storeClassOMat = new ClassOMat('from')
.BaseClass(StoreTestClass)
.field('field')
.field('store')
.field('type')
.field('getCollection').toggler().default(true)
.field('getItem').toggler().default(false)
.$();
fromStoreClassOMat = new ClassOMat('from')
.BaseClass(FromBaseClass)
.field('field')
.field('store')
.field('type')
.field('getCollection').toggler().default(true)
.field('getItem').toggler().default(false)
.$();
toStoreClassOMat = new ClassOMat('to')
.BaseClass(ToBaseClass)
.field('field')
.field('store')
.field('type')
.field('getCollection').toggler().default(true)
.field('getItem').toggler().default(false)
.$();
fromStoreClassOMat.addChild(toStoreClassOMat, 'to').$();
toStoreClassOMat.addChild(toStoreClassOMat, 'next').$();
pathClassOMat = new ClassOMat('path')
.BaseClass(PathTestClass)
.field('name').$();
pathClassOMat.addChild(fromStoreClassOMat, 'from')
.addChild(toStoreClassOMat, 'to').$()
expect(pathClassOMat.TYPE).to.equal(CLASS_O_MAT);
expect(fromStoreClassOMat.TYPE).to.equal(CLASS_O_MAT);
expect(toStoreClassOMat.TYPE).to.equal(CLASS_O_MAT);
}
);
it(`Should be able to create a self-referential nest`,
()=>{
class TopClass {
static TYPE = 'TOP';
TYPE = 'TOP';
}
topClassOMat = new ClassOMat('top')
.BaseClass(TopClass)
.field('greet')
.field('author').$()
.addChild().as$('next');
const Top = topClassOMat.$();
const top = new Top();
top.greet('hi').author('there');
const second = top.next();
second.greet('hello from second').author('me');
const secondSecond = second.next();
secondSecond.greet('second second').author('newme');
expect(top.TYPE).to.equal('TOP');
expect(top.greet()).to.equal('hi');
expect(top.author()).to.equal('there');
expect(second.TYPE).to.equal('TOP');
expect(second.greet()).to.equal('hello from second');
expect(second.author()).to.equal('me');
expect(secondSecond.TYPE).to.equal('TOP');
expect(secondSecond.greet()).to.equal('second second');
expect(secondSecond.author()).to.equal('newme');
}
);
it(`Should be able to create a self-referential nest within a
class that is itself nested in another one `,
()=>{
class TopClass {
static TYPE = 'TOP';
TYPE = 'TOP';
}
class NextClass {
static TYPE = 'NEXT';
TYPE = 'NEXT';
}
topClassOMat = new ClassOMat('top')
.BaseClass(TopClass)
.field('greet')
.field('author').$()
nextClassOMat = new ClassOMat('next')
.BaseClass(NextClass)
.field('some').$()
.addChild().as$('next2');
topClassOMat.addChild(nextClassOMat).as$('next');
const Top = topClassOMat.$();
const top = new Top();
top.greet('hi').author('there');
const next = top.next();
next.some('firstNext');
const next2 = next.next2();
next2.some('2');
expect(top.TYPE).to.equal('TOP');
expect(top.greet()).to.equal('hi');
expect(next.TYPE).to.equal('NEXT');
expect(next.some()).to.equal('firstNext');
}
);
it(`Should be able to create a self-referential nest within a
class that is itself nested in another one. In this case,
the nested classOMat is a subOMat of another one.`,
()=>{
class TopClass {
static TYPE = 'TOP';
TYPE = 'TOP';
}
class NextClass {
static TYPE = 'NEXT';
TYPE = 'NEXT';
}
subNextClassOMat = nextClassOMat.subOMat('subNext');
subTopClassOMat = topClassOMat.subOMat('subTop');
subTopClassOMat.addChild(subNextClassOMat).as$('next');
const Top = subTopClassOMat.$();
const top = new Top();
top.greet('hi').author('there');
const next = top.next();
next.some('firstNext');
const next2 = next.next2();
next2.some('2');
expect(top.TYPE).to.equal('TOP');
expect(top.greet()).to.equal('hi');
expect(next.TYPE).to.equal('NEXT');
expect(next.some()).to.equal('firstNext');
}
);
it(`Should be able to create a self-referential nest`,
()=>{
class TopClass {
static TYPE = 'TOP';
TYPE = 'TOP';
}
class NextClass {
static TYPE = 'NEXT';
TYPE = 'NEXT';
}
topClassOMat = new ClassOMat('top')
.BaseClass(TopClass)
.field('greet')
.field('author').$()
nextClassOMat = new ClassOMat('next')
.BaseClass(NextClass)
.field('thing')
.field('some').$()
.addChild().as('next').internalKey('thing')
.addChild().as('next2')
.copyField('some').as$('thing')
.$();
topClassOMat.addChild(nextClassOMat).as$('next');
const Top = topClassOMat.$();
const top = new Top();
top.greet('hi').author('there');
const next = top.next();
next.some('firstNext');
const next2 = next.next2();
next2.some('2');
const next3 = next2.next2();
expect(top.TYPE).to.equal('TOP');
expect(top.greet()).to.equal('hi');
expect(next.TYPE).to.equal('NEXT');
expect(next.some()).to.equal('firstNext');
expect(next2.TYPE).to.equal('NEXT');
expect(next2.some()).to.equal('2');
expect(next3.TYPE).to.equal('NEXT');
expect(next3.thing()).to.equal('2');
}
);
it(`Should be able to safely ignore a parameter passed into a
child class launch function`,
()=>{
const Top = topClassOMat.$();
const top = new Top();
const next = top.next();
const next2 = next.next2(42);
expect(next2.TYPE).to.equal('NEXT');
}
);
it(`Should be able to access a child class from a parent
after the classes are built AND to access the parent from
the child.`,
()=>{
const Top = topClassOMat.$();
const top = new Top();
const nextD = top.next();
const next2D = nextD.next2(42);
const next = top.___child('next');
const next2 = next.___child('next2');
expect(top.TYPE).to.equal('TOP');
expect(nextD.TYPE).to.equal('NEXT');
expect(next2D.TYPE).to.equal('NEXT');
expect(top.___child('next').TYPE).to.equal('NEXT');
expect(nextD.___child('next2').TYPE).to.equal('NEXT');
expect(next2.TYPE).to.equal('NEXT');
expect(nextD.___parent().TYPE).to.equal('TOP');
}
);
it(`Should be able to use a child class launch function and
automatically copy a field as specified by the
addChild.copyField.. function`,
()=>{
const Top = topClassOMat.$();
const top = new Top();
const next = top.next().some(42);
const next2 = next.next2();
expect(next.some()).to.equal(42);
expect(next2.TYPE).to.equal('NEXT');
expect(next2.thing()).to.equal(42);
}
);
it(`should be able to create fields that are auto-copied to the parent`,
()=>{
class TopClass {
TYPE = 'TOP';
}
class NextClass {
TYPE = 'NEXT';
}
class SibNextClass {
TYPE = 'SIB_NEXT';
}
topClassOMat = new ClassOMat('top')
.BaseClass(TopClass)
.field('greeting')
.field('author')
.$();
nextClassOMat = new ClassOMat('next')
.BaseClass(NextClass)
.field('salutation')
.field('writer')
.$();
nextSibClassOMat = new ClassOMat('sibNext')
.BaseClass(SibNextClass)
.field('romper')
.field('room')
.$()
.addChild().as$('sib');
expect(topClassOMat.TYPE).to.equal(CLASS_O_MAT);
expect(nextClassOMat.TYPE).to.equal(CLASS_O_MAT);
expect(nextSibClassOMat.TYPE).to.equal(CLASS_O_MAT);
topClassOMat.addChild(nextClassOMat).as('next')
.copyField('greeting').as$('salutation')
.copyField('author').as$('writer')
.addChild(nextSibClassOMat).as$('sibNext')
.addChild(nextSibClassOMat).as$('room')
.$();
const BuiltTopClass = topClassOMat.$();
const top = new BuiltTopClass();
expect(top.TYPE).to.equal('TOP');
expect(typeof top.next).to.equal('function');
expect(typeof top.sibNext).to.equal('function');
const stillTop = top.greeting('Hello!').author('Robert');
expect(stillTop.greeting()).to.equal('Hello!');
expect(stillTop.author()).to.equal('Robert');
const next = top.next();
expect(next.TYPE).to.equal('NEXT');
expect(typeof next.salutation).to.equal('function');
expect(typeof next.writer).to.equal('function');
const sibFromTopSibNext = top.sibNext();
expect(sibFromTopSibNext.TYPE).to.equal('SIB_NEXT');
const sibFromRoom = top.room();
sibFromRoom.room('Top Room Setting');
expect(sibFromRoom.TYPE).to.equal('SIB_NEXT');
expect(typeof sibFromRoom.room).to.equal('function');
expect(sibFromRoom.room()).to.equal('Top Room Setting');
const sibFromSibFromRoom = sibFromRoom.sib();
expect(sibFromSibFromRoom.TYPE).to.equal('SIB_NEXT');
}
);
it(`should be able to create a nested classOMat with default values
that are objects.`,
()=>{
class TopClass {
TYPE = 'TOP';
}
class NextClass {
TYPE = 'NEXT';
}
const nextClassOMat = new ClassOMat('nextClassOMat');
nextClassOMat.BaseClass(NextClass)
.field('prairie').default([])
.field('dog').default({})
const topClassOMat = new ClassOMat('topClassOMat');
topClassOMat.addChild(nextClassOMat).as$('next');
const top = new (topClassOMat.$());
const next0 = top.next();
next0.prairie(['ralph']);
next0.dog({uboat: true});
const next1 = top.next();
expect(next0.TYPE).to.equal('NEXT');
expect(next0.TYPE).to.equal('NEXT');
expect(next0.prairie()).to.deep.equal(['ralph']);
expect(next1.prairie()).to.deep.equal([]);
expect(next0.dog()).to.deep.equal({uboat: true});
expect(next1.dog()).to.deep.equal({})
}
);
it(`should be able to create a nested classOMat that can be accessed
with an accessAs option.`,
()=>{
class TopClass {
TYPE = 'TOP';
}
class NextClass {
TYPE = 'NEXT';
}
const nextClassOMat = new ClassOMat('nextClassOMat');
nextClassOMat.BaseClass(NextClass);
const topClassOMat = new ClassOMat('topClassOMat').BaseClass(TopClass);
topClassOMat.addChild(nextClassOMat).accessChildAs('nemo').as$('next');
const top = new (topClassOMat.$());
const next = top.next();
const nextFromTop___child = top.___child('next');
const nextFromTopNemo = top.nemo();
expect(top.TYPE).to.equal('TOP');
expect(next.TYPE).to.equal('NEXT');
expect(nextFromTop___child.TYPE).to.equal('NEXT');
expect(nextFromTopNemo.TYPE).to.equal('NEXT');
}
);
it(`should be able to create a nested classOMat that is NOT cached.`,
()=>{
class TopClass {
TYPE = 'TOP';
}
class NextClass {
TYPE = 'NEXT';
}
const nextClassOMat = new ClassOMat('nextClassOMat');
nextClassOMat.BaseClass(NextClass);
const topClassOMat = new ClassOMat('topClassOMat').BaseClass(TopClass);
topClassOMat.addChild(nextClassOMat).cacheChild(false).as$('next');
const top = new (topClassOMat.$());
const next = top.next();
const nextFromTop___child = top.___child('next');
expect(top.TYPE).to.equal('TOP');
expect(next.TYPE).to.equal('NEXT');
expect(nextFromTop___child).to.equal(false);
}
);
it(`should be able to create a nested classOMat minion instance
and then delete in with ___deleteChild function.`,
()=>{
class TopClass {
TYPE = 'TOP';
}
class NextClass {
TYPE = 'NEXT';
}
const nextClassOMat = new ClassOMat('nextClassOMat');
nextClassOMat.BaseClass(NextClass);
const topClassOMat = new ClassOMat('topClassOMat').BaseClass(TopClass);
topClassOMat.addChild(nextClassOMat).accessChildAs('nemo').as$('next');
const top = new (topClassOMat.$());
const next = top.next();
top.___deleteChild('next');
const nextFromTop___child = top.___child('next');
expect(top.TYPE).to.equal('TOP');
expect(next.TYPE).to.equal('NEXT');
expect(nextFromTop___child).to.equal(false)
}
);
it(`should be able to create a nested classOMat minion instance
and then delete in with childAccessAs function.`,
()=>{
class TopClass {
TYPE = 'TOP';
}
class NextClass {
TYPE = 'NEXT';
}
const nextClassOMat = new ClassOMat('nextClassOMat');
nextClassOMat.BaseClass(NextClass);
const topClassOMat = new ClassOMat('topClassOMat').BaseClass(TopClass);
topClassOMat.addChild(nextClassOMat).accessChildAs('nemo').as$('next');
const top = new (topClassOMat.$());
const next = top.next();
top.delete_nemo();
const nextFromTopNemo = top.nemo();
expect(top.TYPE).to.equal('TOP');
expect(next.TYPE).to.equal('NEXT');
expect(nextFromTopNemo).to.deep.equal([]);
}
);
}
);