UNPKG

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
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([]); } ); } );