UNPKG

catberry

Version:

Catberry is an isomorphic framework for building universal front-end apps using components, Flux architecture and progressive rendering.

173 lines (148 loc) 5.5 kB
'use strict'; const assert = require('assert'); const events = require('events'); const testCases = require('../../cases/lib/loaders/ComponentLoader/test-cases.json'); const ServiceLocator = require('catberry-locator'); const ComponentLoader = require('../../../lib/loaders/ComponentLoader'); const ContextFactory = require('../../../lib/ContextFactory'); const ModuleApiProvider = require('../../../lib/providers/ModuleApiProvider'); const CookieWrapper = require('../../../lib/CookieWrapper'); const ComponentFinder = require('../../mocks/finders/ComponentFinder'); /* eslint prefer-arrow-callback:0 */ /* eslint max-nested-callbacks:0 */ /* eslint require-jsdoc:0 */ describe('lib/loaders/ComponentLoader', function() { testCases.load.forEach(testCase => { it(testCase.name, function(done) { const locator = createLocator(testCase.components); const loader = locator.resolve('componentLoader'); loader .load() .then(loadedComponents => { // loader should cache the components assert.strictEqual(loadedComponents, loader.getComponentsByNames()); const componentNames = Object.keys(loadedComponents); assert.strictEqual(componentNames.length, testCase.expectedCount); componentNames.forEach(componentName => { const component = loadedComponents[componentName]; const expected = testCase.components[componentName]; assert.strictEqual(component.name, expected.name); assert.strictEqual(component.path, expected.path); assert.deepEqual(component.properties, expected.properties); assert.strictEqual(typeof (component.constructor), 'function'); }); if (componentNames.length === 0) { return null; } return Promise .all(componentNames.map(componentName => loadedComponents[componentName].template.render())) .then(rendered => assert.deepEqual(rendered, testCase.expectedTemplates)) .then(() => { const promises = componentNames.map(componentName => { const component = loadedComponents[componentName]; if (!component.errorTemplate) { return null; } return component.errorTemplate.render(); }); return Promise.all(promises); }) .then(rendered => assert.deepEqual(rendered, testCase.expectedErrorTemplates)); }) .then(done) .catch(done); }); if (testCase.expectedCount === 0) { return; } it(`${testCase.name} (with transformation)`, function(done) { const locator = createLocator(testCase.components); locator.registerInstance('componentTransform', { transform: component => { component.name += '!'; return component; } }); locator.registerInstance('componentTransform', { transform: component => { component.name += '?'; return Promise.resolve(component); } }); const loader = locator.resolve('componentLoader'); loader .load() .then(loadedComponents => { const componentNames = Object.keys(loadedComponents); assert.strictEqual(componentNames.length, testCase.expectedCount); Object.keys(testCase.components) .forEach(componentName => { const expected = testCase.components[componentName]; const newName = `${expected.name}!?`; const component = loadedComponents[newName]; assert.strictEqual(component.name, newName); }); }) .then(done) .catch(done); }); }); it('should throw error if transform returns a bad result', function(done) { const components = { 'first-cool': { name: 'first-cool', path: 'test/cases/lib/loaders/ComponentLoader/first/first.json', properties: { logic: './logic.js', template: './templates/template.html' } } }; const locator = createLocator(components); locator.registerInstance('componentTransform', { transform: component => null }); const eventBus = locator.resolve('eventBus'); const loader = locator.resolve('componentLoader'); eventBus.once('error', () => done()); loader .load() .catch(done); }); }); function createLocator(components) { const locator = new ServiceLocator(); locator.registerInstance('serviceLocator', locator); locator.registerInstance('config', {isRelease: true}); const eventBus = new events.EventEmitter(); eventBus.on('error', function() {}); const HTMLTemplates = {}; const HTMLTemplateProvider = { getName: () => 'html', isTemplateSupported: filename => /html$/.test(filename), compile: str => Promise.resolve(str), render: name => Promise.resolve(`HTML: ${HTMLTemplates[name]}`), registerCompiled: (name, source) => { HTMLTemplates[name] = source; } }; const HTMTemplates = {}; const HTMTemplateProvider = { getName: () => 'htm', isTemplateSupported: filename => /htm$/.test(filename), compile: str => Promise.resolve(str), render: name => Promise.resolve(`HTM: ${HTMTemplates[name]}`), registerCompiled: (name, source) => { HTMTemplates[name] = source; } }; locator.registerInstance('eventBus', eventBus); locator.registerInstance('componentFinder', new ComponentFinder(components)); locator.registerInstance('templateProvider', HTMLTemplateProvider); locator.registerInstance('templateProvider', HTMTemplateProvider); locator.register('contextFactory', ContextFactory); locator.register('moduleApiProvider', ModuleApiProvider); locator.register('cookieWrapper', CookieWrapper); locator.register('componentLoader', ComponentLoader); return locator; }