Skip to content

Commit

Permalink
introduce a buildComponent test helper
Browse files Browse the repository at this point in the history
  • Loading branch information
anton-107 committed Oct 9, 2015
1 parent 82196c5 commit 7b1c8bb
Show file tree
Hide file tree
Showing 11 changed files with 96 additions and 56 deletions.
2 changes: 1 addition & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@
"indent": [2, 2, {"SwitchCase": 1}],
"jsx-quotes": 2,
"key-spacing": 2,
"lines-around-comment": 2,
"lines-around-comment": 0,
"linebreak-style": 2,
"max-nested-callbacks": 2,
"new-cap": 2,
Expand Down
4 changes: 3 additions & 1 deletion Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ module.exports = function(grunt) {
src: 'coverage/lcov.json',
options: {
reports: {
lcovonly: 'coverage/lcov-remapped.info'
'lcovonly': 'coverage/lcov-remapped.info',
'text-summary': null,
'html': 'coverage/html'
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion dist/amd/anglue.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions dist/amd/utils.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/amd/utils.js.map

Large diffs are not rendered by default.

2 changes: 0 additions & 2 deletions karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,6 @@ module.exports = function(config) {
dir: 'coverage/',
subdir: '.',
file: 'lcov.json'
}, {
type: 'text-summary'
}]
},

Expand Down
1 change: 1 addition & 0 deletions src/anglue.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ export * from './actions';
export * from './component';
export * from './store';
export * from './behaviors';
export * from './test-helpers';
63 changes: 13 additions & 50 deletions src/behaviors/paginatable-component.spec.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/*eslint-env node, jasmine*//*global module, inject*/
/*eslint-env node, jasmine*//*global module*/
/*eslint-disable max-statements, max-params*/
import angular from 'angular';
import 'angular-mocks';
import {buildComponent} from 'anglue/anglue';

import {
Annotations,
Expand Down Expand Up @@ -144,8 +143,7 @@ describe('PaginatableComponent', () => {
};

@Component()
@PaginatableComponent()
class PaginatableTestComponent {
@PaginatableComponent() class PaginatableTestComponent {
paginatableActions = mockActions;
paginatableStore = mockStore;
}
Expand All @@ -155,8 +153,7 @@ describe('PaginatableComponent', () => {
entity: 'foo',
initialPage: 3,
initialLimit: 100
})
class PaginatableEntityConfiguredComponent {
}) class PaginatableEntityConfiguredComponent {
fooActions = mockActions;
fooStore = mockStore;
}
Expand All @@ -165,91 +162,57 @@ describe('PaginatableComponent', () => {
@PaginatableComponent({
actions: 'customActions',
store: 'customStore'
})
class PaginatableCustomConfiguredComponent {
}) class PaginatableCustomConfiguredComponent {
customActions = mockActions;
customStore = mockStore;
}

@Component()
@PaginatableComponent('foo')
class PaginatableStringConfiguredComponent {
@PaginatableComponent('foo') class PaginatableStringConfiguredComponent {
fooActions = mockActions;
fooStore = mockStore;
}

angular.module('paginatableComponents', [
PaginatableTestComponent.annotation.module.name,
PaginatableEntityConfiguredComponent.annotation.module.name,
PaginatableCustomConfiguredComponent.annotation.module.name,
PaginatableStringConfiguredComponent.annotation.module.name
]);

let $compile, $rootScope;
let autoConfiguredComponent;
let entityConfiguredComponent;
let customConfiguredComponent;
let stringConfiguredComponent;

beforeEach(module('paginatableComponents'));
beforeEach(inject((_$compile_, _$rootScope_) => {
$compile = _$compile_;
$rootScope = _$rootScope_;

autoConfiguredComponent = compileTemplate(
'<paginatable-test></paginatable-test>', $compile, $rootScope)
.controller('paginatableTest');
entityConfiguredComponent = compileTemplate(
'<paginatable-entity-configured></paginatable-entity-configured>', $compile, $rootScope)
.controller('paginatableEntityConfigured');
customConfiguredComponent = compileTemplate(
'<paginatable-custom-configured></paginatable-custom-configured>', $compile, $rootScope)
.controller('paginatableCustomConfigured');
stringConfiguredComponent = compileTemplate(
'<paginatable-string-configured></paginatable-string-configured>', $compile, $rootScope)
.controller('paginatableStringConfigured');
}));

it('should define the PaginatableComponent API on the component', () => {
const autoConfiguredComponent = buildComponent(PaginatableTestComponent);
[
'pagination'
].forEach(api => expect(autoConfiguredComponent[api]).toBeDefined());
});

it('should have an instance of PaginatableComponentBehavior as the behavior property', () => {
const autoConfiguredComponent = buildComponent(PaginatableTestComponent);
expect(autoConfiguredComponent.pagination).toEqual(jasmine.any(PaginatableComponentBehavior));
});

it('should use the first uppercased part of class name to determine the actions and store', () => {
const autoConfiguredComponent = buildComponent(PaginatableTestComponent);
expect(autoConfiguredComponent.pagination.actions).toEqual('paginatableActions');
expect(autoConfiguredComponent.pagination.store).toEqual('paginatableStore');
});

it('should be possible to pass the entity property as a string to determine actions and store', () => {
const stringConfiguredComponent = buildComponent(PaginatableStringConfiguredComponent);
expect(stringConfiguredComponent.pagination.actions).toEqual('fooActions');
expect(stringConfiguredComponent.pagination.store).toEqual('fooStore');
});

it('should be possible to configure an entity to determine the actions and store', () => {
const entityConfiguredComponent = buildComponent(PaginatableEntityConfiguredComponent);
expect(entityConfiguredComponent.pagination.actions).toEqual('fooActions');
expect(entityConfiguredComponent.pagination.store).toEqual('fooStore');
});

it('should be possible to pass the actions and store in the configuration', () => {
const customConfiguredComponent = buildComponent(PaginatableCustomConfiguredComponent);
expect(customConfiguredComponent.pagination.actions).toEqual('customActions');
expect(customConfiguredComponent.pagination.store).toEqual('customStore');
});

it('should be possible to configure initial page and limit', () => {
const entityConfiguredComponent = buildComponent(PaginatableEntityConfiguredComponent);
expect(entityConfiguredComponent.pagination.config.initialPage).toEqual(3);
expect(entityConfiguredComponent.pagination.config.initialLimit).toEqual(100);
});
});
});

function compileTemplate(template, $compile, $rootScope) {
const el = angular.element(template.trim());
$compile(el)($rootScope.$new());
$rootScope.$digest();
return el;
}
38 changes: 38 additions & 0 deletions src/test-helpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import angular from 'angular';
import 'angular-mocks';
import {camelCaseToDashes, dashesToCamelCase} from './utils';

let counter = 0;

export function buildComponent(ComponentClass) {
if (!ComponentClass.annotation || !ComponentClass.annotation.module || !ComponentClass.annotation.module.name) {
throw new Error(`ComponentClass is not annotated: ${ComponentClass.name}`);
}

const tagName = camelCaseToDashes(ComponentClass.annotation.name).toLowerCase();
const template = `<${tagName}></${tagName}>`;
const elProperty = dashesToCamelCase(tagName);

counter += 1;
const componentName = `TestedComponents${counter}`;

angular.module(componentName, [ComponentClass.annotation.module.name]);

let controller = null;

angular.mock.module(componentName);
angular.mock.inject((_$compile_, _$rootScope_) => {
const compiledTemplate = compileTemplate(template, _$compile_, _$rootScope_);
controller = compiledTemplate.controller(elProperty);
controller._element = compiledTemplate;
});

return controller;
}

function compileTemplate(template, $compile, $rootScope) {
const el = angular.element(template.trim());
$compile(el)($rootScope.$new());
$rootScope.$digest();
return el;
}
16 changes: 16 additions & 0 deletions src/test-helpers.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*eslint-env node, jasmine*/
import {buildComponent} from 'anglue/anglue';

describe('Test helpers', () => {
describe('buildComponent', () => {

class Generic {}

it('should throw an error when called with a class without annotation', () => {
expect(() => {
buildComponent(Generic);
}).toThrow(new Error('ComponentClass is not annotated: Generic'));
});

});
});
8 changes: 8 additions & 0 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,3 +144,11 @@ export function getCurrentDescriptorValue(propertyDescriptor) {
export function camelcase(name) {
return `${name[0].toUpperCase()}${name.slice(1)}`;
}

export function camelCaseToDashes (name) {
return name.replace(/([a-z])([A-Z])/g, '$1-$2');
}

export function dashesToCamelCase (name) {
return String(name).replace(/-([a-z])/g, part => part[1].toUpperCase());
}

0 comments on commit 7b1c8bb

Please sign in to comment.