Commit 9b6ff1ce28f5b85b86a886986ee8d5de7bb87fd9

Authored by huixisheng
1 parent c9c5e751

add test and update webpack config

[new] add test config
[new] add breadcrumb test
[change] update package.json
[new] util.js copied from  element
[unresolved] see test/unit/index.js @todo
.gitignore
... ... @@ -15,5 +15,7 @@ npm-debug.log
15 15 *.swp
16 16 *.swo
17 17 *.log
18   -test/dist/
  18 +examples/dist/
19 19 dist/
  20 +yarn-error.log
  21 +test/unit/coverage
20 22 \ No newline at end of file
... ...
build/webpack.base.config.js
... ... @@ -2,6 +2,10 @@
2 2 * 公共配置
3 3 */
4 4 var webpack = require('webpack');
  5 +var path = require('path');
  6 +function resolve (dir) {
  7 + return path.join(__dirname, '..', dir)
  8 +}
5 9  
6 10 module.exports = {
7 11 // 加载器
... ... @@ -55,6 +59,10 @@ module.exports = {
55 59 ]
56 60 },
57 61 resolve: {
58   - extensions: ['.js', '.vue']
  62 + extensions: ['.js', '.vue'],
  63 + alias: {
  64 + 'vue': 'vue/dist/vue.esm.js',
  65 + '@': resolve('src'),
  66 + }
59 67 }
60 68 };
... ...
build/webpack.dev.config.js
... ... @@ -8,6 +8,7 @@ var webpack = require('webpack');
8 8 var HtmlWebpackPlugin = require('html-webpack-plugin');
9 9 var merge = require('webpack-merge')
10 10 var webpackBaseConfig = require('./webpack.base.config.js');
  11 +var FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
11 12  
12 13  
13 14 module.exports = merge(webpackBaseConfig, {
... ... @@ -35,6 +36,7 @@ module.exports = merge(webpackBaseConfig, {
35 36 inject: true,
36 37 filename: path.join(__dirname, '../examples/dist/index.html'),
37 38 template: path.join(__dirname, '../examples/index.html')
38   - })
  39 + }),
  40 + new FriendlyErrorsPlugin()
39 41 ]
40 42 });
... ...
build/webpack.test.config.js 0 → 100644
  1 +/**
  2 + * 用于单元测试
  3 + */
  4 +
  5 +var webpack = require('webpack')
  6 +var merge = require('webpack-merge')
  7 +var webpackBaseConfig = require('./webpack.base.config.js');
  8 +
  9 +
  10 +var webpackConfig = merge(webpackBaseConfig, {
  11 + // use inline sourcemap for karma-sourcemap-loader
  12 + devtool: '#inline-source-map',
  13 + plugins: [
  14 + new webpack.DefinePlugin({
  15 + 'process.env': {
  16 + NODE_ENV: '"testing"'
  17 + }
  18 + })
  19 + ]
  20 +})
  21 +
  22 +// no need for app entry during tests
  23 +delete webpackConfig.entry
  24 +
  25 +module.exports = webpackConfig
... ...
package.json
... ... @@ -25,7 +25,8 @@
25 25 "dist:prod": "webpack --config build/webpack.dist.prod.config.js",
26 26 "dist": "npm run dist:style && npm run dist:dev && npm run dist:prod",
27 27 "lint": "eslint --fix --ext .js,.vue src",
28   - "test": "npm run dist && npm run lint",
  28 + "unit": "cross-env BABEL_ENV=test karma start test/unit/karma.conf.js --single-run",
  29 + "test": "npm run unit",
29 30 "prepublish": "npm run dist"
30 31 },
31 32 "repository": {
... ... @@ -54,11 +55,14 @@
54 55 "babel-plugin-transform-runtime": "^6.12.0",
55 56 "babel-preset-es2015": "^6.9.0",
56 57 "babel-runtime": "^6.11.6",
  58 + "chai": "^3.5.0",
  59 + "cross-env": "^3.1.4",
57 60 "css-loader": "^0.23.1",
58 61 "eslint": "^3.12.2",
59 62 "eslint-plugin-html": "^1.7.0",
60 63 "extract-text-webpack-plugin": "^2.0.0",
61 64 "file-loader": "^0.8.5",
  65 + "friendly-errors-webpack-plugin": "^1.6.1",
62 66 "gulp": "^3.9.1",
63 67 "gulp-autoprefixer": "^3.1.1",
64 68 "gulp-clean-css": "^2.0.13",
... ... @@ -66,8 +70,21 @@
66 70 "gulp-rename": "^1.2.2",
67 71 "html-loader": "^0.3.0",
68 72 "html-webpack-plugin": "^2.28.0",
  73 + "karma": "^1.4.1",
  74 + "karma-coverage": "^1.1.1",
  75 + "karma-mocha": "^1.3.0",
  76 + "karma-phantomjs-launcher": "^1.0.2",
  77 + "karma-sinon-chai": "^1.2.4",
  78 + "karma-sourcemap-loader": "^0.3.7",
  79 + "karma-spec-reporter": "0.0.26",
  80 + "karma-webpack": "^2.0.2",
69 81 "less": "^2.7.1",
70 82 "less-loader": "^2.2.3",
  83 + "lolex": "^1.5.2",
  84 + "mocha": "^3.2.0",
  85 + "phantomjs-prebuilt": "^2.1.13",
  86 + "sinon": "^1.17.7",
  87 + "sinon-chai": "^2.8.0",
71 88 "style-loader": "^0.13.1",
72 89 "url-loader": "^0.5.7",
73 90 "vue": "^2.2.1",
... ... @@ -80,5 +97,9 @@
80 97 "webpack": "^2.2.1",
81 98 "webpack-dev-server": "^2.4.1",
82 99 "webpack-merge": "^3.0.0"
  100 + },
  101 + "engines": {
  102 + "node": ">= 4.0.0",
  103 + "npm": ">= 3.0.0"
83 104 }
84 105 }
... ...
test deleted
test/unit/index.js 0 → 100644
  1 +import Vue from 'vue';
  2 +Vue.config.productionTip = false;
  3 +
  4 +// Polyfill fn.bind() for PhantomJS
  5 +/* eslint-disable no-extend-native */
  6 +Function.prototype.bind = require('function-bind');
  7 +
  8 +// require all test files (files that ends with .spec.js)
  9 +const testsContext = require.context('./specs', true, /\.spec$/);
  10 +testsContext.keys().forEach(testsContext);
  11 +
  12 +// require all src files except main.js for coverage.
  13 +// you can also change this to match only the subset of files that
  14 +// you want coverage for.
  15 +// const srcContext = require.context('../../src', true, /^\.\/(?!main(\.js)?$)/);
  16 +// @todo
  17 +const srcContext = require.context('../../src/components/breadcrumb', true, /^\.\/(?!styles.*?(\.less)?$)/);
  18 +srcContext.keys().forEach(srcContext);
... ...
test/unit/karma.conf.js 0 → 100644
  1 +// This is a karma config file. For more details see
  2 +// http://karma-runner.github.io/0.13/config/configuration-file.html
  3 +// we are also using it with karma-webpack
  4 +// https://github.com/webpack/karma-webpack
  5 +
  6 +var webpackConfig = require('../../build/webpack.test.config.js');
  7 +
  8 +module.exports = function (config) {
  9 + config.set({
  10 + // to run in additional browsers:
  11 + // 1. install corresponding karma launcher
  12 + // http://karma-runner.github.io/0.13/config/browsers.html
  13 + // 2. add it to the `browsers` array below.
  14 + browsers: ['PhantomJS'],
  15 + frameworks: ['mocha', 'sinon-chai'],
  16 + reporters: ['spec', 'coverage'],
  17 + files: ['./index.js'],
  18 + preprocessors: {
  19 + './index.js': ['webpack', 'sourcemap']
  20 + },
  21 + webpack: webpackConfig,
  22 + webpackMiddleware: {
  23 + noInfo: true,
  24 + },
  25 + coverageReporter: {
  26 + dir: './coverage',
  27 + reporters: [
  28 + { type: 'lcov', subdir: '.' },
  29 + { type: 'text-summary' },
  30 + ]
  31 + },
  32 + });
  33 +};
... ...
test/unit/specs/breadcrumb.spec.js 0 → 100644
  1 +import { createVue, destroyVM } from '../util';
  2 +
  3 +describe('Breadcrumb.vue', () => {
  4 + let vm;
  5 + afterEach(() => {
  6 + destroyVM(vm);
  7 + });
  8 + it('create', done => {
  9 + vm = createVue(`
  10 + <Breadcrumb separator="<b class='demo-breadcrumb-separator'>=></b>">
  11 + <Breadcrumb-item href="/">Home4</Breadcrumb-item>
  12 + <Breadcrumb-item href="/components/breadcrumb">Components</Breadcrumb-item>
  13 + <Breadcrumb-item>Breadcrumb</Breadcrumb-item>
  14 + </Breadcrumb>
  15 + `);
  16 + expect(vm.$el.querySelectorAll('.ivu-breadcrumb-item-link').length).to.equal(3);
  17 +
  18 + vm.$nextTick(_ => {
  19 + // console.log(vm.$el.querySelector('.ivu-breadcrumb-item-separator').innerHTML);
  20 + expect(vm.$el.querySelector('.ivu-breadcrumb-item-separator').innerHTML).to.equal('<b class="demo-breadcrumb-separator">=&gt;</b>');
  21 + done();
  22 + });
  23 + });
  24 +});
0 25 \ No newline at end of file
... ...
test/unit/util.js 0 → 100644
  1 +import Vue from 'vue';
  2 +import iView from '../../src/index';
  3 +
  4 +Vue.use(iView);
  5 +
  6 +let id = 0;
  7 +
  8 +const createElm = function() {
  9 + const elm = document.createElement('div');
  10 +
  11 + elm.id = 'app' + ++id;
  12 + document.body.appendChild(elm);
  13 +
  14 + return elm;
  15 +};
  16 +
  17 +/**
  18 + * 回收 vm
  19 + * @param {Object} vm
  20 + */
  21 +exports.destroyVM = function(vm) {
  22 + vm.$el &&
  23 + vm.$el.parentNode &&
  24 + vm.$el.parentNode.removeChild(vm.$el);
  25 +};
  26 +
  27 +/**
  28 + * 创建一个 Vue 的实例对象
  29 + * @param {Object|String} Compo 组件配置,可直接传 template
  30 + * @param {Boolean=false} mounted 是否添加到 DOM 上
  31 + * @return {Object} vm
  32 + */
  33 +exports.createVue = function(Compo, mounted = false) {
  34 + const elm = createElm();
  35 +
  36 + if (Object.prototype.toString.call(Compo) === '[object String]') {
  37 + Compo = { template: Compo };
  38 + }
  39 + return new Vue(Compo).$mount(mounted === false ? null : elm);
  40 +};
  41 +
  42 +/**
  43 + * 创建一个测试组件实例
  44 + * @link http://vuejs.org/guide/unit-testing.html#Writing-Testable-Components
  45 + * @param {Object} Compo - 组件对象
  46 + * @param {Object} propsData - props 数据
  47 + * @param {Boolean=false} mounted - 是否添加到 DOM 上
  48 + * @return {Object} vm
  49 + */
  50 +exports.createTest = function(Compo, propsData = {}, mounted = false) {
  51 + if (propsData === true || propsData === false) {
  52 + mounted = propsData;
  53 + propsData = {};
  54 + }
  55 + const elm = createElm();
  56 + const Ctor = Vue.extend(Compo);
  57 + return new Ctor({ propsData }).$mount(mounted === false ? null : elm);
  58 +};
  59 +
  60 +/**
  61 + * 触发一个事件
  62 + * mouseenter, mouseleave, mouseover, keyup, change, click 等
  63 + * @param {Element} elm
  64 + * @param {String} name
  65 + * @param {*} opts
  66 + */
  67 +exports.triggerEvent = function(elm, name, ...opts) {
  68 + let eventName;
  69 +
  70 + if (/^mouse|click/.test(name)) {
  71 + eventName = 'MouseEvents';
  72 + } else if (/^key/.test(name)) {
  73 + eventName = 'KeyboardEvent';
  74 + } else {
  75 + eventName = 'HTMLEvents';
  76 + }
  77 + const evt = document.createEvent(eventName);
  78 +
  79 + evt.initEvent(name, ...opts);
  80 + elm.dispatchEvent
  81 + ? elm.dispatchEvent(evt)
  82 + : elm.fireEvent('on' + name, evt);
  83 +
  84 + return elm;
  85 +};
... ...