UNPKG

@skele/core

Version:

Core package of the Skele framework. Element definitions, registrations and traversal.

385 lines (337 loc) 8.72 kB
'use strict' import I from 'immutable' import * as R from 'ramda' import * as skeleZip from '..' import * as zippa from 'zippa' import { flow } from '../../data' const { elementZipper } = skeleZip const app = { kind: ['test', 'app'], name: 'App', children: { kind: ['test', 'nav', 'tabs'], name: 'Tabs', tabs: [ { kind: 'scene', name: 'First Tab', content: [ { kind: 'header', name: 'Header in First Tab', }, { kind: 'text', name: 'Text One in First Tab', }, { kind: 'text', name: 'Text Two in First Tab', }, { kind: 'image', name: 'Image in First Tab', uri: 'image-uri', }, ], }, { kind: ['scene'], name: 'Second Tab', main: [ { kind: ['header'], name: 'Header in Second Tab Main', }, { kind: ['text'], name: 'Text One in Second Tab Main', }, { kind: ['text'], name: 'Text Two in Second Tab Main', }, { kind: ['image'], name: 'Image in Second Tab Main', uri: 'image-uri', }, ], sidebar: { kind: 'overlay', name: 'Sidebar in Second Tab', content: [ { kind: ['overlay', 'header'], name: 'Header in Second Tab Sidebar', }, { kind: ['overlay', 'text'], name: 'Text One in Second Tab Sidebar', }, { kind: ['overlay', 'text'], name: 'Text Two in Second Tab Sidebar', }, { kind: ['overlay', 'image'], name: 'Image in Second Tab Sidebar', uri: 'image-uri', }, ], }, }, ], }, } const tabs = I.fromJS(app).getIn(['children']) const zipperFor = ({ app, zip }) => elementZipper({ defaultChildPositions: ['children', 'content', 'tabs', 'main', 'sidebar'], makeZipperOverride: zip.makeZipper, })(I.fromJS(app)) const test_down = (zip, zipperName) => { const testName = 'zip.down' // 1. child collection test(`${zipperName}: ${testName}, first .down should get to @@skele/child-collection`, () => { const result = flow( { app, zip }, zipperFor, zip.down, zip.value ) expect(result.get('kind')).toEqual('@@skele/child-collection') }) // 2. tabs test(`${zipperName}: ${testName}, twice .down from root should take us to tabs`, () => { const result = flow( { app, zip }, zipperFor, zip.down, zip.down, zip.value ) expect(result).toEqual(tabs) }) const headerInFirstTab = I.fromJS({ kind: 'header', name: 'Header in First Tab', }) // 3. first header test(`${zipperName}: ${testName}, twice down from firstTab should take us to the Header (remember child-collection) `, () => { const firstTab = I.fromJS(app) .getIn(['children', 'tabs']) .first() const result = flow( { app: firstTab, zip }, zipperFor, zip.down, zip.down, zip.value ) expect(result).toEqual(I.fromJS(headerInFirstTab)) }) // 4. first header 2 test(`${zipperName}: ${testName}, 6x down from root should take us to the Header (remember child-collection) `, () => { const result = flow( { app, zip }, zipperFor, zip.down, zip.down, zip.down, zip.down, zip.down, zip.down, zip.value ) expect(result).toEqual(I.fromJS(headerInFirstTab)) }) // 5. undefined test(`${zipperName}: ${testName}, headerFirstTab (no children) .down should return undefined`, () => { const result = flow( { app: headerInFirstTab, zip }, zipperFor, zip.down ) expect(result == null).toBeTruthy() }) // 6. error test(`${zipperName}: ${testName}, .down of undefined should throw error`, () => { expect(() => { zip.down(undefined) }).toThrow() }) } const test_right = (zip, zipperName) => { const testName = 'zip.right' test(`${zipperName}: ${testName}, .right form the root should be null`, () => { const result = flow( { app, zip }, zipperFor, zip.right ) expect(result).toEqual(null) }) test(`${zipperName}: ${testName}, .right form the first tab should be the second`, () => { const firstTab = flow( { app: tabs, zip }, zipperFor, zip.down, zip.down ) const secondTab = { kind: ['scene'], name: 'Second Tab', main: [ { kind: ['header'], name: 'Header in Second Tab Main', }, { kind: ['text'], name: 'Text One in Second Tab Main', }, { kind: ['text'], name: 'Text Two in Second Tab Main', }, { kind: ['image'], name: 'Image in Second Tab Main', uri: 'image-uri', }, ], sidebar: { kind: 'overlay', name: 'Sidebar in Second Tab', content: [ { kind: ['overlay', 'header'], name: 'Header in Second Tab Sidebar', }, { kind: ['overlay', 'text'], name: 'Text One in Second Tab Sidebar', }, { kind: ['overlay', 'text'], name: 'Text Two in Second Tab Sidebar', }, { kind: ['overlay', 'image'], name: 'Image in Second Tab Sidebar', uri: 'image-uri', }, ], }, } const result = flow( firstTab, zip.right, zip.value ) expect(result).toEqual(I.fromJS(secondTab)) }) test(`${zipperName}: ${testName}, .right form the second tab should be null`, () => { const secondTab = flow( { app: tabs, zip }, zipperFor, zip.down, // childcollection zip.down, // actual children zip.right ) expect(zip.right(secondTab)).toEqual(null) }) } const test_up = (zip, zipperName) => { const testName = 'zip.up' test(`${zipperName}: ${testName}, what goes down must come up`, () => { const down = flow( { app, zip }, zipperFor, zip.down ) const up = flow( down, zip.up, zip.value ) expect(up).toEqual(I.fromJS(app)) }) test(`${zipperName}: ${testName}, what goes down x3 must come up x3`, () => { const down = flow( { app, zip }, zipperFor, zip.down, zip.down, zip.down ) const up = flow( down, zip.up, zip.up, zip.up, zip.value ) expect(up).toEqual(I.fromJS(app)) }) test(`${zipperName}: ${testName}, .up form the root should be null`, () => { const result = flow( { app, zip }, zipperFor, zip.up ) expect(result).toEqual(null) }) } const test_edit = (zip, zipperName) => { const modify = el => el.set('name', 'modified') test(`${zipperName}: zip.up observes and reflects the change that zip.edit does`, () => { // immutable const tabsValue = I.fromJS(app).getIn(['children']) const tabsValueModified = modify(tabsValue) // zipper const tabs = flow( { app, zip }, zipperFor, zip.down, zip.down ) const tabsEdited = zip.edit(modify, tabs) const result = flow( tabsEdited, zip.up, zip.down, zip.value ) // todo: different form zippa check up.path.parentPath // const up = zip.up(tabsModified) // expect(up.path.parentPath).toEqual('') expect(result).toEqual(tabsValueModified) }) test(`${zipperName}: zip.edit, path.changed should be true for edited zipper`, () => { const headerInFirstTab = zipperFor({ app: { kind: 'header', name: 'Header in First Tab', }, zip, }) const result = zip.edit(modify, headerInFirstTab) if (result.path.isChanged != null) { expect(result.path.isChanged).toBeTruthy() } else { expect(result.path.changed).toBeTruthy() } }) } describe('zipper', () => { // we want all the tests to be excersized both zippa and our custom zipper implementation const zippers = [ { name: 'Skele Zip', zip: skeleZip }, { name: 'Zippa Zip', zip: zippa }, ] zippers.forEach(zipper => R.juxt([test_down, test_right, test_up, test_edit])(zipper.zip, zipper.name) ) })