UNPKG

@dvo/raven

Version:

A simple store and databinding tool for vanilla applications.

417 lines (376 loc) 11 kB
import raven from '../src/index.js' const evChange = (el, value) => { el.value = value const ev = new Event('change') el.dispatchEvent(ev) } describe('Unit testing functions.', () => { test('Can detect arrays', () => { expect(raven.funcs.isArray([])).toBe(true) expect(raven.funcs.isArray({})).toBe(false) expect(raven.funcs.isArray(undefined)).toBe(false) expect(raven.funcs.isArray(null)).toBe(false) }) test('Can detect objects', () => { expect(raven.funcs.isObject([])).toBe(false) expect(raven.funcs.isObject({})).toBe(true) expect(raven.funcs.isObject(undefined)).toBe(false) expect(raven.funcs.isObject(null)).toBe(false) }) test('Can split path string into an array.', () => { expect(raven.funcs.fromStringToArray('a.b.c')).toEqual(['a', 'b', 'c']) expect(raven.funcs.fromStringToArray('a')).toEqual(['a']) expect(raven.funcs.fromStringToArray('')).toEqual(['']) }) test('Can join path array into string.', () => { expect(raven.funcs.fromArrayToString(['a', 'b', 'c'])).toEqual('a.b.c') expect(raven.funcs.fromArrayToString(['a'])).toEqual('a') expect(raven.funcs.fromArrayToString([''])).toEqual('') }) test('Can reach inside object with a pathArray.', () => { const store = { a: 1, b: [1, 2], c: { d: 2 } } raven.load(store) expect(raven.funcs.reach(store)(['a'])) .toEqual({ parentObject: store, propertyName: 'a', propertyValue: 1 }) expect(raven.funcs.reach(store)(['b'])) .toEqual({ parentObject: store, propertyName: 'b', propertyValue: [1, 2] }) expect(raven.funcs.reach(store)(['c'])) .toEqual({ parentObject: store, propertyName: 'c', propertyValue: { d: 2 } }) expect(raven.funcs.reach(store)(['c', 'd'])) .toEqual({ parentObject: store.c, propertyName: 'd', propertyValue: 2 }) }) test('Can reach inside object with a string path.', () => { const store = { a: 1, b: [1, 2], c: { d: 2 } } raven.load(store) expect(raven.funcs.reach(store)('a')) .toEqual({ parentObject: store, propertyName: 'a', propertyValue: 1 }) expect(raven.funcs.reach(store)('b')) .toEqual({ parentObject: store, propertyName: 'b', propertyValue: [1, 2] }) expect(raven.funcs.reach(store)('c')) .toEqual({ parentObject: store, propertyName: 'c', propertyValue: { d: 2 } }) expect(raven.funcs.reach(store)('c.d')) .toEqual({ parentObject: store.c, propertyName: 'd', propertyValue: 2 }) }) test('Can convert pathString into objects.', () => { expect(raven.funcs.fromStringToObject('a.b.c', 1)) .toEqual({ a: { b: { c: 1 } } }) expect(raven.funcs.fromStringToObject('a', [1, 2])) .toEqual({ a: [1, 2] }) expect(raven.funcs.fromStringToObject('b', 10)) .toEqual({ b: 10 }) expect(raven.funcs.fromStringToObject('a.b.c.d', undefined)) .toEqual({ a: { b: { c: {} } } }) }) test('Can merge two simple objects.', () => { const objA = { a: 1, b: 2 } const objB = { a: 10, c: 20 } expect(raven.funcs.mergeObjects(objA, objB)) .toEqual({ a: 10, b: 2, c: 20 }) }) test('Can merge two simple objects.', () => { const objA = { a: 1, b: 2 } const objB = { a: 10, c: 20 } expect(raven.funcs.mergeObjects(objA, objB)) .toEqual({ a: 10, b: 2, c: 20 }) }) test('Can merge two complex objects.', () => { const objA = { a: { b: { c: 1, d: 2 }, e: { f: 3 } } } const objB = { a: { b: { d: 20, g: 30 }, e: undefined } } expect(raven.funcs.mergeObjects(objA, objB)) .not.toEqual({...objA, ...objB}) expect(raven.funcs.mergeObjects(objA, objB)) .toEqual({ a: { b: { c: 1, d: 20, g: 30 } } }) }) test('Can convert simple objects to array path.', () => { expect(raven.funcs.fromObjectToArrayList({ a: 2 })) .toEqual([['a']]) expect(raven.funcs.fromObjectToArrayList({ a: { b: 1 } })) .toEqual([['a', 'b']]) }) test('Can convert simple objects to string path.', () => { expect(raven.funcs.fromObjectToStringList({ a: 2 })) .toEqual(['a']) expect(raven.funcs.fromObjectToStringList({ a: { b: 1 } })) .toEqual(['a.b']) }) test('Can convert complex objects to array path.', () => { const complexObject = { a: { b: 1, c: { d: 2, e: 3 }, f: 4, g: undefined }, h: 5 } expect(raven.funcs.fromObjectToArrayList(complexObject)) .toEqual([ ['a', 'b'], ['a', 'c', 'd'], ['a', 'c', 'e'], ['a', 'f'], ['a', 'g'], ['h'] ]) }) test('Can convert complex objects to string path.', () => { const complexObject = { a: { b: 1, c: { d: 2, e: 3 }, f: 4, g: undefined }, h: 5 } expect(raven.funcs.fromObjectToStringList(complexObject)) .toEqual([ 'a.b', 'a.c.d', 'a.c.e', 'a.f', 'a.g', 'h' ]) }) test('Can execute callbacks from a request.', () => { let count = 0 const subList = { 'a.b': [() => count += 1], 'a.c': [() => count += 10], 'a.c.d': [() => count += 100], 'a.e': [() => count += 1000] } raven.funcs.executeCallbacks( { a: { b: 1, c: { d: 2 } } }, subList, { a: { b: 1, c: { d: 2 } } } ) expect(count).toBe(111) }) test('Adds partial paths to an array path.', () => { const originalPathArray = [ ['a', 'b'], ['c', 'd', 'e'] ] expect(raven.funcs.addPartialPaths(originalPathArray)) .toEqual([ ['a', 'b'], ['a'], ['c', 'd', 'e'], ['c', 'd'], ['c'] ]) }) test('Set function redirects objects correctly.', () => { let result; const dud = () => {} const callback = (...args) => { result = [...args] } raven.push({}, {}, dud, dud, callback) expect(result).toEqual([{}, {}, dud]) }) test('Set function redirects DOM elements correctly.', () => { let result; document.body.innerHTML = `<div id="dom-element"></div>` const obj = document.querySelector('#dom-element') const dud = () => {} const callback = (...args) => { result = [...args] } raven.push(obj, {}, dud, dud, callback) expect(result).toEqual([obj, {}, dud]) }) test('Data push from an object correctly updates on a target.', () => { raven.clear() raven.load({ target: {} }) const fromObject = { a: 1 } expect(fromObject.a).toBe(1) raven.funcs.pushFromObject({ target: fromObject, prop: 'a' }, { target: 1 }) expect(fromObject.a).toBe(1) fromObject.a = 10 expect(fromObject.a).toBe(10) expect(raven.store.target).toBe(10) }) test('Can read property pushed from an object.', () => { raven.clear() raven.load({ target: {} }) const fromObject = { a: 1 } raven.funcs.pushFromObject({ target: fromObject, prop: 'a' }, { target: 1 }) fromObject.a = 10 expect(raven.store.target).toEqual(10) }) test('Data push from a DOM element correctly updates on a target.', () => { document.body.innerHTML = `<input type="text" id="dom-input">` const input = document.querySelector('#dom-input') raven.clear() raven.load({ target: {} }) raven.funcs.pushFromElement({ target: input }, { target: 1 }) evChange(input, 'changedValue') // input.value = 'changedValue' // const event = new Event('change') // input.dispatchEvent(event) expect(raven.store.target).toBe('changedValue') }) test('Can set a value to a single branch of an object.', () => { const originalObject = { a: { b: { c: false } } } const changedObject = raven.funcs.setValueToObject(originalObject)(true) expect(originalObject).toEqual({ a: { b: { c: false } } }) expect(changedObject).toEqual({ a: { b: { c: true } } }) }) test('Can set a value to multiple branches of an object.', () => { const originalObject = { a: { b: { c: false }, d: false }, e: false } const changedObject = raven.funcs.setValueToObject(originalObject)(true) expect(originalObject).toEqual({ a: { b: { c: false }, d: false }, e: false }) expect(changedObject).toEqual({ a: { b: { c: true }, d: true }, e: true }) }) test('Can create an object from an array of array properties.', () => { const paths = [['a', 'b', 'c', 1], ['a', 'b', 'd', 2], ['e', 3]] const createdObject = raven.funcs.fromArrayListToObject(paths) expect(createdObject).toEqual({ a: { b: { c: 1, d: 2 } }, e: 3 }) }) test('Can immediately copy a value to store.', () => { const store = { a: { b: 'original' } } const externalObject = { a: { b: 'changed' } } raven.clear() raven.load(store) raven.funcs.copyValueToStore({ target: externalObject.a, prop: 'b' }, { a: { b: 1 } }, x => x) expect(raven.store).toEqual({ a: { b: 'changed' } }) }) test('Can immediately copy a value to store through an intermidiate function.', () => { const store = { a: { b: 1 } } const externalObject = { a: { b: 100 } } raven.clear() raven.load(store) raven.funcs.copyValueToStore({ target: externalObject.a, prop: 'b' }, { a: { b: 1 } }, x => x * x) expect(raven.store).toEqual({ a: { b: 10000 } }) }) test('Can pull a value from store into a DOM element with a string.', () => { const store = { a: { b: 'beforeChange' } } document.body.innerHTML = `<div id="dom-element"></div>` const div = document.querySelector('#dom-element') raven.clear() raven.load(store) raven.funcs.pullToElement( 'a.b', { target: div, prop: 'textContent' }, x => x ) expect(div.textContent).toBe('beforeChange') raven.set('a.b', 'afterChange') expect(div.textContent).toBe('afterChange') }) test('Can pull a value from store into a DOM element with an array.', () => { const store = { a: { b: 'beforeChange' } } document.body.innerHTML = `<div id="dom-element"></div>` const div = document.querySelector('#dom-element') raven.clear() raven.load(store) raven.funcs.pullToElement( ['a', 'b'], { target: div, prop: 'textContent' }, x => x ) expect(div.textContent).toBe('beforeChange') raven.set('a.b', 'afterChange') expect(div.textContent).toBe('afterChange') }) })