Skip to content

Commit

Permalink
feat/test framework (ShuyunFF2E#93)
Browse files Browse the repository at this point in the history
* test framework

* GridCtrl 测试用例

* test package.json update

* GridHelper单元测试

* GridHelper单元测试

* 添加GridCtrl $onInit单元测试

* 补充测试覆盖率配置

* ci配置更新

* ci npm test

* ci npm test

* add coverage to readme

* add download badge

* readme update
  • Loading branch information
kuitos authored and arzyu committed Jul 27, 2016
1 parent 7f373ae commit 6afecc9
Show file tree
Hide file tree
Showing 17 changed files with 394 additions and 118 deletions.
3 changes: 2 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
"env": {
"browser": true,
"es6": true,
"node": true
"node": true,
"mocha": true
},

"plugins": [
Expand Down
7 changes: 6 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
---
language: node_js
node_js:
- 6.2.0 # lastest
cache:
directories:
- node_modules
script:
- npm test
- cat ./test/coverage/lcov.info | ./node_modules/.bin/codecov
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
# CCMS Components [![Build Status](https://img.shields.io/travis/ShuyunFF2E/ccms-components/master.svg?style=flat)](https://travis-ci.org/ShuyunFF2E/ccms-components) [![npm version](https://img.shields.io/npm/v/ccms-components.svg?style=flat)](https://www.npmjs.com/package/ccms-components)
# CCMS Components
[![Build Status](https://img.shields.io/travis/ShuyunFF2E/ccms-components/master.svg?style=flat)](https://travis-ci.org/ShuyunFF2E/ccms-components)
[![npm version](https://img.shields.io/npm/v/ccms-components.svg?style=flat)](https://www.npmjs.com/package/ccms-components)
[![npm downloads](https://img.shields.io/npm/dt/ccms-components.svg?style=flat)](https://www.npmjs.com/package/ccms-components)
[![coverage](https://img.shields.io/codecov/c/github/ShuyunFF2E/ccms-components.svg?style=flat)](https://www.npmjs.com/package/ccms-components)

[组件 API 文档](http://shuyunff2e.github.io/ccms-components/)

Expand Down
31 changes: 23 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,31 +9,36 @@
],
"main": "./index.js",
"scripts": {
"build:dist": "NODE_ENV=production webpack --config webpack-build.config.js",
"build": "npm run build:dist",
"codecheck": "NODE_EVN=test eslint src/components",
"build": "NODE_ENV=production webpack --config webpack-build.config.js",
"docs": "jekyll serve --source docs",
"start": "node server.js",
"lint": "npm run codecheck",
"prepush": "npm run codecheck",
"release:major": "./scripts/release.sh --major",
"release:minor": "./scripts/release.sh --minor",
"release:patch": "./scripts/release.sh --patch",
"update-dev-server": "./scripts/update-dev-server.sh",
"test": "npm run lint"
"copy-dist": "./scripts/copy-dist-to-server.sh",
"start": "node server.js",
"prepush": "npm run codecheck",
"codecheck": "NODE_EVN=test eslint src/components",
"start:test": "karma start test/karma.unit.conf.js",
"test": "npm run codecheck & npm run test:cover",
"test:unit": "karma start test/karma.unit.conf.js --single-run",
"test:cover": "karma start test/karma.cover.conf.js --single-run"
},
"author": "shuyun FE2E",
"devDependencies": {
"assets-webpack-plugin": "^3.1.0",
"angular-mocks": "^1.5.7",
"autoprefixer": "^6.3.6",
"babel-cli": "^6.9.0",
"babel-core": "^6.9.0",
"babel-eslint": "^6.0.4",
"babel-loader": "^6.2.4",
"babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-polyfill": "^6.9.1",
"babel-preset-es2015": "^6.9.0",
"babel-preset-stage-0": "^6.5.0",
"chai": "^3.5.0",
"clean-webpack-plugin": "^0.1.9",
"codecov": "^1.0.1",
"css-loader": "^0.21.0",
"cssnano": "^3.7.1",
"eslint": "^2.10.2",
Expand All @@ -47,13 +52,23 @@
"html-loader": "^0.4.0",
"husky": "^0.10.1",
"image-webpack-loader": "^1.6.3",
"istanbul-instrumenter-loader": "^0.2.0",
"json-mock-kuitos": "^1.0.3",
"karma": "^1.1.1",
"karma-chrome-launcher": "^1.0.1",
"karma-coverage": "^1.1.0",
"karma-mocha": "^1.1.1",
"karma-mocha-reporter": "^2.0.4",
"karma-phantomjs-launcher": "^1.0.1",
"karma-webpack": "^1.7.0",
"mocha": "^2.5.3",
"node-dir": "^0.1.11",
"node-sass": "^3.7.0",
"optimize-css-assets-webpack-plugin": "^1.3.0",
"postcss-loader": "^0.7.0",
"resolve-url-loader": "^1.4.3",
"sass-loader": "^3.1.1",
"sinon": "^2.0.0-pre",
"style-loader": "^0.13.0",
"url-loader": "^0.5.7",
"webpack": "^1.12.2",
Expand Down
8 changes: 4 additions & 4 deletions src/components/grid/GridCtrl.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ function contains(container, collection) {
* 从集合中获取entity的index,找不到返回-1
*/
function findEntity(collection, entity) {
return collection.findIndex(item => entity === item || angular.equals(item, entity));
return collection.findIndex(item => angular.equals(item, entity));
}

const PLACEHOLDER = '{::cell-placeholder}';
Expand Down Expand Up @@ -66,9 +66,9 @@ export default class GridCtrl {
.then(() => this.onRefresh && this.onRefresh({opts}));
}

selectAll(allSelected, collection) {
switchSelectAll(allSelected, selectedCollection) {

collection.forEach(entity => {
selectedCollection.forEach(entity => {

const index = findEntity(this.selectedItems, entity);

Expand All @@ -84,7 +84,7 @@ export default class GridCtrl {
});
}

selectItem(entity, $selected) {
switchSelectItem($selected, entity) {

if ($selected) {
this.selectedItems.push(entity);
Expand Down
8 changes: 1 addition & 7 deletions src/components/grid/GridHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,7 @@ export default {
headerTpl: null, // 表头模板,允许 字符串 or 模板url
cellTpl: null, // 表格元素模板,允许 字符串 or 模板url
emptyTipTpl: null, // 表格为空时的提示 允许 字符串 or 模板url
pager: {
totals: 0, // 总条数
totalPages: 1, // 总页数
pageNum: 1, // 当前页码
pageSize: 20, // 每页大小
pageSizeList: [10, 15, 20, 30, 50]
}
pager: null // 分页配置 @see pagination component
};

return Object.assign(gridOptions, Object.assign(DEFAULT_CONFIGS, gridOptions));
Expand Down
93 changes: 93 additions & 0 deletions src/components/grid/__tests__/test-GridCtrl.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/**
* @author Kuitos
* @homepage https://github.com/kuitos/
* @since 2016-07-14
*/

import GridCtrl from '../GridCtrl';
import GRID_TEMPLATES from '../Constant';
import rowCellTemplate from '../tpls/row-cell.tpl.html';

import {assert} from 'chai';

describe('GridCtrl', () => {

let gridCtrl;

before(() => {

gridCtrl = new GridCtrl();
gridCtrl.opts = {
response: null,
queryParams: {
pageNum: 2
},
columnsDef: [
{
cellTemplate: '<span style="color:blue" ng-bind="entity.name" ng-click="app.click()" tooltip="entity.name" tooltip-append-to-body="true"></span>',
displayName: '姓名',
align: 'center',
width: '100px'
},
{field: 'age', displayName: '年龄', align: 'center'},
{field: 'gender', displayName: '性别', align: 'right'}
],
transformer: {
pageNum: 'currentPage'
}
};

gridCtrl.$onInit();
});

it('$onInit', done => {

const type = 'default'.toUpperCase();

Promise.all([gridCtrl.headerTemplate, gridCtrl.emptyTipsTemplate])
.then(tpls => {
assert.equal(tpls[0], GRID_TEMPLATES[type][0]);
assert.equal(tpls[1], GRID_TEMPLATES[type][2]);

const bodyTpl = rowCellTemplate.replace('{::cell-placeholder}', GRID_TEMPLATES[type][1]);
assert.equal(gridCtrl.bodyTemplate, bodyTpl);

done();
});
});

it('switchSelectAll', () => {
gridCtrl.switchSelectAll(true, [{name: 'kuitos'}, {age: 20}]);
assert.deepEqual(gridCtrl.selectedItems, [{name: 'kuitos'}, {age: 20}]);

gridCtrl.switchSelectAll(false, [{age: 20}]);
assert.deepEqual(gridCtrl.selectedItems, [{name: 'kuitos'}]);
});

it('switchSelectItem', () => {

gridCtrl.switchSelectItem(true, {gender: 'xx'});
assert.deepEqual(gridCtrl.selectedItems, [{name: 'kuitos'}, {gender: 'xx'}]);

gridCtrl.switchSelectItem(false, {gender: 'xx'});
assert.deepEqual(gridCtrl.selectedItems, [{name: 'kuitos'}]);
});

it('isEntitySelected', () => {

assert.isTrue(gridCtrl.isEntitySelected({name: 'kuitos'}));
assert.isFalse(gridCtrl.isEntitySelected({name: 'kuitosx'}));
});

it('$allSelected should auto change', () => {

gridCtrl.opts.data = [{name: 'kuitos'}];
assert.isTrue(gridCtrl.$allSelected);

gridCtrl.opts.data = [{name: 'kuitos'}, {age: 10}];
assert.isFalse(gridCtrl.$allSelected);
});

});


41 changes: 41 additions & 0 deletions src/components/grid/__tests__/test-GridHelper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* @author Kuitos
* @homepage https://github.com/kuitos/
* @since 2016-07-25
*/

import GridHelper from '../GridHelper';

import {assert} from 'chai';

describe('GridHelper', () => {

it('fillOpts', () => {

const opts = {
resource: 'A',
columnsDef: [
{filed: 'name'}
],
showPagination: false
};
const filledOpts = GridHelper.fillOpts(opts);

assert.equal(filledOpts, opts);
assert.equal(filledOpts.resource, 'A');
assert.deepEqual(filledOpts.columnsDef, [{filed: 'name'}]);
assert.includeMembers(Object.keys(filledOpts), [
'resource',
'response',
'queryParams',
'columnsDef',
'externalData',
'showPagination',
'headerTpl',
'cellTpl',
'emptyTipTpl',
'pager'
]);
});

});
2 changes: 1 addition & 1 deletion src/components/grid/tpls/checkbox-header.tpl.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!--带checkbox的表格头部-->
<th class="checkbox" ng-click="$ctrl.selectAll(!$ctrl.$allSelected, $ctrl.opts.data)">
<th class="checkbox" ng-click="$ctrl.switchSelectAll(!$ctrl.$allSelected, $ctrl.opts.data)">
<input type="checkbox" ng-checked="$ctrl.$allSelected">
</th>

Expand Down
2 changes: 1 addition & 1 deletion src/components/grid/tpls/row-cell.tpl.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<tr ng-repeat="entity in $ctrl.opts.data track by $index"
aria-init="{{$selected=$ctrl.isEntitySelected(entity)}}"
ng-class="{'row-selected':$selected}"
ng-click="$selected=!$selected;$ctrl.selectItem(entity, $selected)"
ng-click="$selected=!$selected;$ctrl.switchSelectItem($selected, entity)"
dynamic-attr="{'ng-click':$ctrl.type==='selectable'}">
{::cell-placeholder}
</tr>
97 changes: 97 additions & 0 deletions test/karma.base.conf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/**
* @author Kuitos
* @homepage https://github.com/kuitos/
* @since 2016-07-25
*/

var path = require('path');
var loaders = require('../webpack-common-loaders');

module.exports = {

// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: './',

// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['mocha'],

client: {
mocha: {
timeout: 15000
}
},

// list of files / patterns to load in the browser
files: [
'test.index.js'
],

// list of files to exclude
exclude: [],

// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
'test.index.js': ['webpack']
},

// Webpack
webpack: {
devtool: 'eval',
output: {
pathinfo: true
},
eslint: {
configFile: '.eslintrc',
emitWarning: true,
emitError: true,
formatter: require('eslint-friendly-formatter')
},
module: {
preLoaders: [{
test: /\.js$/,
loader: 'eslint-loader',
exclude: /node_modules/,
include: [path.join(__dirname, '../src')]
}],
loaders: loaders
}

},

// Webpack middleware
webpackMiddleware: {
noInfo: true
},

// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['mocha'],

// web server port
port: 9876,

// enable / disable colors in the output (reporters and logs)
colors: true,

// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
// logLevel: config.LOG_INFO,

// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,

// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['Chrome'],

// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false,

// Concurrency level
// how many browser should be started simultaneous
concurrency: Infinity
};
Loading

0 comments on commit 6afecc9

Please sign in to comment.