diff --git a/.gitignore b/.gitignore
index 19514b87..c5cfd2b4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,5 +15,7 @@ npm-debug.log
*.swp
*.swo
*.log
-test/dist/
+examples/dist/
dist/
+yarn-error.log
+test/unit/coverage
\ No newline at end of file
diff --git a/README.md b/README.md
index 6f88487f..dd61e872 100644
--- a/README.md
+++ b/README.md
@@ -53,7 +53,7 @@
- [x] Tabs
- [x] Dropdown
- [ ] Page
-- [ ] Breadcrumb
+- [x] Breadcrumb
- [x] Steps
- [ ] LoadingBar
- [x] Circle
@@ -76,7 +76,7 @@
## Install
-### Install vue-webpack project in the first place
+### Install vue-webpack project in the first place
Use [iview-project](https://github.com/iview/iview-project)(Recommended) Or [vue-cli](https://github.com/vuejs/vue-cli)
diff --git a/build/webpack.base.config.js b/build/webpack.base.config.js
new file mode 100644
index 00000000..2a258deb
--- /dev/null
+++ b/build/webpack.base.config.js
@@ -0,0 +1,68 @@
+/**
+ * 公共配置
+ */
+var webpack = require('webpack');
+var path = require('path');
+function resolve (dir) {
+ return path.join(__dirname, '..', dir)
+}
+
+module.exports = {
+ // 加载器
+ module: {
+ // https://doc.webpack-china.org/guides/migrating/#module-loaders-module-rules
+ rules: [
+ {
+ // https://vue-loader.vuejs.org/en/configurations/extract-css.html
+ test: /\.vue$/,
+ loader: 'vue-loader',
+ options: {
+ loaders: {
+ css: 'vue-style-loader!css-loader',
+ less: 'vue-style-loader!css-loader!less-loader'
+ },
+ postLoaders: {
+ html: 'babel-loader'
+ }
+ }
+ },
+ {
+ test: /\.js$/,
+ loader: 'babel-loader', exclude: /node_modules/
+ },
+ {
+ test: /\.css$/,
+ use: [
+ 'style-loader',
+ 'css-loader',
+ 'autoprefixer-loader'
+ ]
+ },
+ {
+ test: /\.less$/,
+ use: [
+ 'style-loader',
+ 'css-loader',
+ 'less-loader'
+ ]
+ },
+ {
+ test: /\.scss$/,
+ use: [
+ 'style-loader',
+ 'css-loader',
+ 'sass-loader?sourceMap'
+ ]
+ },
+ { test: /\.(gif|jpg|png|woff|svg|eot|ttf)\??.*$/, loader: 'url-loader?limit=8192'},
+ { test: /\.(html|tpl)$/, loader: 'html-loader' }
+ ]
+ },
+ resolve: {
+ extensions: ['.js', '.vue'],
+ alias: {
+ 'vue': 'vue/dist/vue.esm.js',
+ '@': resolve('src'),
+ }
+ }
+};
diff --git a/build/webpack.dev.config.js b/build/webpack.dev.config.js
index 6c442115..699d29eb 100644
--- a/build/webpack.dev.config.js
+++ b/build/webpack.dev.config.js
@@ -6,109 +6,37 @@ var path = require('path');
var webpack = require('webpack');
// var ExtractTextPlugin = require('extract-text-webpack-plugin');
var HtmlWebpackPlugin = require('html-webpack-plugin');
+var merge = require('webpack-merge')
+var webpackBaseConfig = require('./webpack.base.config.js');
+var FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
-module.exports = {
+
+module.exports = merge(webpackBaseConfig, {
// 入口
entry: {
- main: './test/main',
+ main: './examples/main',
vendors: ['vue', 'vue-router']
},
// 输出
output: {
- path: path.join(__dirname, '../test/dist'),
+ path: path.join(__dirname, '../examples/dist'),
publicPath: '',
filename: '[name].js',
chunkFilename: '[name].chunk.js'
},
- // 加载器
- module: {
- // https://doc.webpack-china.org/guides/migrating/#module-loaders-module-rules
- rules: [
- {
- // https://vue-loader.vuejs.org/en/configurations/extract-css.html
- test: /\.vue$/,
- loader: 'vue-loader',
- options: {
- loaders: {
- css: 'vue-style-loader!css-loader',
- less: 'vue-style-loader!css-loader!less-loader'
- },
- postLoaders: {
- html: 'babel-loader'
- }
- }
- },
- // { test: /\.vue$/, loader: 'vue' },
- // Module build failed: Error: The node API for `babel` has been moved to `babel-core`.
- // https://github.com/babel/babel-loader/blob/master/README.md#the-node-api-for-babel-has-been-moved-to-babel-core
- {
- test: /\.js$/,
- loader: 'babel-loader', exclude: /node_modules/
- },
- {
- test: /\.css$/,
- use: [
- 'style-loader',
- 'css-loader',
- 'autoprefixer-loader'
- ]
- },
- {
- test: /\.less$/,
- use: [
- 'style-loader',
- 'css-loader',
- 'less-loader'
- ]
- // loader: 'style!css!less'
- },
- {
- test: /\.scss$/,
- use: [
- 'style-loader',
- 'css-loader',
- 'sass-loader?sourceMap'
- ]
- // loader: 'style!css!sass?sourceMap'
- },
- { test: /\.(gif|jpg|png|woff|svg|eot|ttf)\??.*$/, loader: 'url-loader?limit=8192'},
- { test: /\.(html|tpl)$/, loader: 'html-loader' }
- ]
- },
- // vue: {
- // loaders: {
- // css: ExtractTextPlugin.extract(
- // "style-loader",
- // "css-loader?sourceMap",
- // {
- // publicPath: "/test/dist/"
- // }
- // ),
- // less: ExtractTextPlugin.extract(
- // 'vue-style-loader',
- // 'css-loader!less-loader'
- // ),
- // js: 'babel'
- // }
- // },
resolve: {
- // require时省略的扩展名,如:require('module') 不需要module.js
- extensions: ['.js', '.vue'],
alias: {
iview: '../../src/index',
vue: 'vue/dist/vue.js'
}
},
plugins: [
- // new ExtractTextPlugin({ filename: '[name].css', disable: false, allChunks: true }),
- // new ExtractTextPlugin("[name].css",{ allChunks : true,resolve : ['modules'] }), // 提取CSS
- // https://doc.webpack-china.org/plugins/commons-chunk-plugin/
new webpack.optimize.CommonsChunkPlugin({ name: 'vendors', filename: 'vendor.bundle.js' }),
new HtmlWebpackPlugin({
inject: true,
- filename: path.join(__dirname, '../test/dist/index.html'),
- template: path.join(__dirname, '../test/index.html') // 模版文件
- })
- // new webpack.optimize.CommonsChunkPlugin('vendors', 'vendors.js'), // 提取第三方库
+ filename: path.join(__dirname, '../examples/dist/index.html'),
+ template: path.join(__dirname, '../examples/index.html')
+ }),
+ new FriendlyErrorsPlugin()
]
-};
+});
diff --git a/build/webpack.dist.dev.config.js b/build/webpack.dist.dev.config.js
index 3aac363f..eab3547c 100644
--- a/build/webpack.dist.dev.config.js
+++ b/build/webpack.dist.dev.config.js
@@ -1,7 +1,9 @@
var path = require('path');
var webpack = require('webpack');
+var merge = require('webpack-merge')
+var webpackBaseConfig = require('./webpack.base.config.js');
-module.exports = {
+module.exports = merge(webpackBaseConfig, {
entry: {
main: './src/index.js'
},
@@ -21,26 +23,6 @@ module.exports = {
amd: 'vue'
}
},
- resolve: {
- extensions: ['.js', '.vue']
- },
- module: {
- rules: [
- {
- test: /\.vue$/,
- loader: 'vue-loader',
- options: {
- postLoaders: {
- html: 'babel-loader'
- }
- }
- },
- {
- test: /\.js$/,
- loader: 'babel-loader', exclude: /node_modules/
- }
- ]
- },
plugins: [
new webpack.DefinePlugin({
'process.env': {
@@ -48,4 +30,4 @@ module.exports = {
}
})
]
-}
+});
diff --git a/build/webpack.dist.prod.config.js b/build/webpack.dist.prod.config.js
index 81703bb1..34a6a896 100644
--- a/build/webpack.dist.prod.config.js
+++ b/build/webpack.dist.prod.config.js
@@ -1,7 +1,11 @@
var path = require('path');
var webpack = require('webpack');
+var merge = require('webpack-merge')
+var webpackBaseConfig = require('./webpack.base.config.js');
-module.exports = {
+
+
+module.exports = merge(webpackBaseConfig, {
entry: {
main: './src/index.js'
},
@@ -21,26 +25,6 @@ module.exports = {
amd: 'vue'
}
},
- resolve: {
- extensions: ['.js', '.vue']
- },
- module: {
- rules: [
- {
- test: /\.vue$/,
- loader: 'vue-loader',
- options: {
- postLoaders: {
- html: 'babel-loader'
- }
- }
- },
- {
- test: /\.js$/,
- loader: 'babel-loader', exclude: /node_modules/
- }
- ]
- },
plugins: [
new webpack.DefinePlugin({
'process.env': {
@@ -53,4 +37,4 @@ module.exports = {
}
})
]
-}
+});
diff --git a/build/webpack.test.config.js b/build/webpack.test.config.js
new file mode 100644
index 00000000..6c3212b7
--- /dev/null
+++ b/build/webpack.test.config.js
@@ -0,0 +1,25 @@
+/**
+ * 用于单元测试
+ */
+
+var webpack = require('webpack')
+var merge = require('webpack-merge')
+var webpackBaseConfig = require('./webpack.base.config.js');
+
+
+var webpackConfig = merge(webpackBaseConfig, {
+ // use inline sourcemap for karma-sourcemap-loader
+ devtool: '#inline-source-map',
+ plugins: [
+ new webpack.DefinePlugin({
+ 'process.env': {
+ NODE_ENV: '"testing"'
+ }
+ })
+ ]
+})
+
+// no need for app entry during tests
+delete webpackConfig.entry
+
+module.exports = webpackConfig
diff --git a/test/app.vue b/examples/app.vue
similarity index 97%
rename from test/app.vue
rename to examples/app.vue
index 4278a1fc..283fa189 100644
--- a/test/app.vue
+++ b/examples/app.vue
@@ -39,6 +39,7 @@ li + li { border-left: solid 1px #bbb; padding-left: 10px; margin-left: 10px; }
Poptip
Slider
Dropdown
+ Breadcrumb
diff --git a/test/index.html b/examples/index.html
similarity index 100%
rename from test/index.html
rename to examples/index.html
diff --git a/test/main.js b/examples/main.js
similarity index 96%
rename from test/main.js
rename to examples/main.js
index 3e7625bd..edcc5324 100644
--- a/test/main.js
+++ b/examples/main.js
@@ -120,6 +120,10 @@ const router = new VueRouter({
{
path: '/dropdown',
component: require('./routers/dropdown.vue')
+ },
+ {
+ path: '/breadcrumb',
+ component: require('./routers/breadcrumb.vue')
}
]
});
diff --git a/test/routers/affix.vue b/examples/routers/affix.vue
similarity index 100%
rename from test/routers/affix.vue
rename to examples/routers/affix.vue
diff --git a/test/routers/alert.vue b/examples/routers/alert.vue
similarity index 100%
rename from test/routers/alert.vue
rename to examples/routers/alert.vue
diff --git a/test/routers/badge.vue b/examples/routers/badge.vue
similarity index 100%
rename from test/routers/badge.vue
rename to examples/routers/badge.vue
diff --git a/examples/routers/breadcrumb.vue b/examples/routers/breadcrumb.vue
new file mode 100644
index 00000000..057bce55
--- /dev/null
+++ b/examples/routers/breadcrumb.vue
@@ -0,0 +1,35 @@
+
+
+
+
+ Home4
+ Components
+ Breadcrumb
+
+
+
+ Home
+
+ ->
+
+
+
+ Breadcrumb
+
+ ->
+
+
+ Breadcrumb
+
+
+
+
\ No newline at end of file
diff --git a/test/routers/button.vue b/examples/routers/button.vue
similarity index 100%
rename from test/routers/button.vue
rename to examples/routers/button.vue
diff --git a/test/routers/card.vue b/examples/routers/card.vue
similarity index 100%
rename from test/routers/card.vue
rename to examples/routers/card.vue
diff --git a/test/routers/carousel.vue b/examples/routers/carousel.vue
similarity index 100%
rename from test/routers/carousel.vue
rename to examples/routers/carousel.vue
diff --git a/test/routers/cascader.vue b/examples/routers/cascader.vue
similarity index 100%
rename from test/routers/cascader.vue
rename to examples/routers/cascader.vue
diff --git a/test/routers/checkbox.vue b/examples/routers/checkbox.vue
similarity index 100%
rename from test/routers/checkbox.vue
rename to examples/routers/checkbox.vue
diff --git a/test/routers/circle.vue b/examples/routers/circle.vue
similarity index 100%
rename from test/routers/circle.vue
rename to examples/routers/circle.vue
diff --git a/test/routers/collapse.vue b/examples/routers/collapse.vue
similarity index 100%
rename from test/routers/collapse.vue
rename to examples/routers/collapse.vue
diff --git a/test/routers/date.vue b/examples/routers/date.vue
similarity index 100%
rename from test/routers/date.vue
rename to examples/routers/date.vue
diff --git a/test/routers/dropdown.vue b/examples/routers/dropdown.vue
similarity index 100%
rename from test/routers/dropdown.vue
rename to examples/routers/dropdown.vue
diff --git a/test/routers/form.vue b/examples/routers/form.vue
similarity index 100%
rename from test/routers/form.vue
rename to examples/routers/form.vue
diff --git a/test/routers/grid.vue b/examples/routers/grid.vue
similarity index 100%
rename from test/routers/grid.vue
rename to examples/routers/grid.vue
diff --git a/test/routers/input-number.vue b/examples/routers/input-number.vue
similarity index 100%
rename from test/routers/input-number.vue
rename to examples/routers/input-number.vue
diff --git a/test/routers/input.vue b/examples/routers/input.vue
similarity index 100%
rename from test/routers/input.vue
rename to examples/routers/input.vue
diff --git a/test/routers/menu.vue b/examples/routers/menu.vue
similarity index 100%
rename from test/routers/menu.vue
rename to examples/routers/menu.vue
diff --git a/test/routers/message.vue b/examples/routers/message.vue
similarity index 100%
rename from test/routers/message.vue
rename to examples/routers/message.vue
diff --git a/test/routers/more.vue b/examples/routers/more.vue
similarity index 100%
rename from test/routers/more.vue
rename to examples/routers/more.vue
diff --git a/test/routers/notice.vue b/examples/routers/notice.vue
similarity index 100%
rename from test/routers/notice.vue
rename to examples/routers/notice.vue
diff --git a/test/routers/page.vue b/examples/routers/page.vue
similarity index 100%
rename from test/routers/page.vue
rename to examples/routers/page.vue
diff --git a/test/routers/poptip.vue b/examples/routers/poptip.vue
similarity index 100%
rename from test/routers/poptip.vue
rename to examples/routers/poptip.vue
diff --git a/test/routers/progress.vue b/examples/routers/progress.vue
similarity index 100%
rename from test/routers/progress.vue
rename to examples/routers/progress.vue
diff --git a/test/routers/radio.vue b/examples/routers/radio.vue
similarity index 100%
rename from test/routers/radio.vue
rename to examples/routers/radio.vue
diff --git a/test/routers/rate.vue b/examples/routers/rate.vue
similarity index 100%
rename from test/routers/rate.vue
rename to examples/routers/rate.vue
diff --git a/test/routers/select.vue b/examples/routers/select.vue
similarity index 100%
rename from test/routers/select.vue
rename to examples/routers/select.vue
diff --git a/test/routers/slider.vue b/examples/routers/slider.vue
similarity index 100%
rename from test/routers/slider.vue
rename to examples/routers/slider.vue
diff --git a/test/routers/steps.vue b/examples/routers/steps.vue
similarity index 100%
rename from test/routers/steps.vue
rename to examples/routers/steps.vue
diff --git a/test/routers/switch.vue b/examples/routers/switch.vue
similarity index 100%
rename from test/routers/switch.vue
rename to examples/routers/switch.vue
diff --git a/test/routers/table.vue b/examples/routers/table.vue
similarity index 100%
rename from test/routers/table.vue
rename to examples/routers/table.vue
diff --git a/test/routers/tabs.vue b/examples/routers/tabs.vue
similarity index 100%
rename from test/routers/tabs.vue
rename to examples/routers/tabs.vue
diff --git a/test/routers/tag.vue b/examples/routers/tag.vue
similarity index 100%
rename from test/routers/tag.vue
rename to examples/routers/tag.vue
diff --git a/test/routers/timeline.vue b/examples/routers/timeline.vue
similarity index 100%
rename from test/routers/timeline.vue
rename to examples/routers/timeline.vue
diff --git a/test/routers/tooltip.vue b/examples/routers/tooltip.vue
similarity index 100%
rename from test/routers/tooltip.vue
rename to examples/routers/tooltip.vue
diff --git a/test/routers/transfer.vue b/examples/routers/transfer.vue
similarity index 100%
rename from test/routers/transfer.vue
rename to examples/routers/transfer.vue
diff --git a/test/routers/tree.vue b/examples/routers/tree.vue
similarity index 100%
rename from test/routers/tree.vue
rename to examples/routers/tree.vue
diff --git a/test/routers/upload.vue b/examples/routers/upload.vue
similarity index 100%
rename from test/routers/upload.vue
rename to examples/routers/upload.vue
diff --git a/package.json b/package.json
index 23aa8688..569b65d1 100644
--- a/package.json
+++ b/package.json
@@ -25,7 +25,8 @@
"dist:prod": "webpack --config build/webpack.dist.prod.config.js",
"dist": "npm run dist:style && npm run dist:dev && npm run dist:prod",
"lint": "eslint --fix --ext .js,.vue src",
- "test": "npm run dist && npm run lint",
+ "unit": "cross-env BABEL_ENV=test karma start test/unit/karma.conf.js --single-run",
+ "test": "npm run lint && npm run unit",
"prepublish": "npm run dist"
},
"repository": {
@@ -54,11 +55,15 @@
"babel-plugin-transform-runtime": "^6.12.0",
"babel-preset-es2015": "^6.9.0",
"babel-runtime": "^6.11.6",
+ "chai": "^3.5.0",
+ "cross-env": "^3.1.4",
"css-loader": "^0.23.1",
"eslint": "^3.12.2",
"eslint-plugin-html": "^1.7.0",
"extract-text-webpack-plugin": "^2.0.0",
"file-loader": "^0.8.5",
+ "friendly-errors-webpack-plugin": "^1.6.1",
+ "function-bind": "^1.1.0",
"gulp": "^3.9.1",
"gulp-autoprefixer": "^3.1.1",
"gulp-clean-css": "^2.0.13",
@@ -66,8 +71,21 @@
"gulp-rename": "^1.2.2",
"html-loader": "^0.3.0",
"html-webpack-plugin": "^2.28.0",
+ "karma": "^1.4.1",
+ "karma-coverage": "^1.1.1",
+ "karma-mocha": "^1.3.0",
+ "karma-phantomjs-launcher": "^1.0.2",
+ "karma-sinon-chai": "^1.2.4",
+ "karma-sourcemap-loader": "^0.3.7",
+ "karma-spec-reporter": "0.0.26",
+ "karma-webpack": "^2.0.2",
"less": "^2.7.1",
"less-loader": "^2.2.3",
+ "lolex": "^1.5.2",
+ "mocha": "^3.2.0",
+ "phantomjs-prebuilt": "^2.1.13",
+ "sinon": "^1.17.7",
+ "sinon-chai": "^2.8.0",
"style-loader": "^0.13.1",
"url-loader": "^0.5.7",
"vue": "^2.2.1",
@@ -78,6 +96,11 @@
"vue-style-loader": "^1.0.0",
"vue-template-compiler": "^2.2.1",
"webpack": "^2.2.1",
- "webpack-dev-server": "^2.4.1"
+ "webpack-dev-server": "^2.4.1",
+ "webpack-merge": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 4.0.0",
+ "npm": ">= 3.0.0"
}
}
diff --git a/src/components/breadcrumb/breadcrumb-item.vue b/src/components/breadcrumb/breadcrumb-item.vue
index 427d2655..0a7af614 100644
--- a/src/components/breadcrumb/breadcrumb-item.vue
+++ b/src/components/breadcrumb/breadcrumb-item.vue
@@ -6,8 +6,10 @@
-
- {{{ separator }}}
+
+
+
+
@@ -18,12 +20,17 @@
props: {
href: {
type: String
- },
- separator: {
- type: String,
- default: '/'
}
},
+ data () {
+ return {
+ separator: '',
+ showSeparator: false
+ };
+ },
+ mounted () {
+ this.showSeparator = this.$slots.separator !== undefined;
+ },
computed: {
linkClasses () {
return `${prefixCls}-link`;
diff --git a/src/components/breadcrumb/breadcrumb.vue b/src/components/breadcrumb/breadcrumb.vue
index 81b89a6c..8f4a7d94 100644
--- a/src/components/breadcrumb/breadcrumb.vue
+++ b/src/components/breadcrumb/breadcrumb.vue
@@ -18,7 +18,7 @@
return `${prefixCls}`;
}
},
- compiled () {
+ mounted () {
this.updateChildren();
},
methods: {
diff --git a/src/index.js b/src/index.js
index dbc99497..5aa84e8d 100644
--- a/src/index.js
+++ b/src/index.js
@@ -5,7 +5,7 @@ import Affix from './components/affix';
import Alert from './components/alert';
// import BackTop from './components/back-top';
import Badge from './components/badge';
-// import Breadcrumb from './components/breadcrumb';
+import Breadcrumb from './components/breadcrumb';
import Button from './components/button';
import Card from './components/card';
import Carousel from './components/carousel';
@@ -51,8 +51,8 @@ const iview = {
Alert,
// BackTop,
Badge,
- // Breadcrumb,
- // BreadcrumbItem: Breadcrumb.Item,
+ Breadcrumb,
+ BreadcrumbItem: Breadcrumb.Item,
// iButton: Button,
Button,
ButtonGroup: Button.Group,
diff --git a/test/unit/index.js b/test/unit/index.js
new file mode 100644
index 00000000..b282cc31
--- /dev/null
+++ b/test/unit/index.js
@@ -0,0 +1,18 @@
+import Vue from 'vue';
+Vue.config.productionTip = false;
+
+// Polyfill fn.bind() for PhantomJS
+/* eslint-disable no-extend-native */
+Function.prototype.bind = require('function-bind');
+
+// require all test files (files that ends with .spec.js)
+const testsContext = require.context('./specs', true, /\.spec$/);
+testsContext.keys().forEach(testsContext);
+
+// require all src files except main.js for coverage.
+// you can also change this to match only the subset of files that
+// you want coverage for.
+// const srcContext = require.context('../../src', true, /^\.\/(?!main(\.js)?$)/);
+// @todo
+const srcContext = require.context('../../src/components/breadcrumb', true, /^\.\/(?!styles.*?(\.less)?$)/);
+srcContext.keys().forEach(srcContext);
diff --git a/test/unit/karma.conf.js b/test/unit/karma.conf.js
new file mode 100644
index 00000000..2fe05ea0
--- /dev/null
+++ b/test/unit/karma.conf.js
@@ -0,0 +1,33 @@
+// This is a karma config file. For more details see
+// http://karma-runner.github.io/0.13/config/configuration-file.html
+// we are also using it with karma-webpack
+// https://github.com/webpack/karma-webpack
+
+var webpackConfig = require('../../build/webpack.test.config.js');
+
+module.exports = function (config) {
+ config.set({
+ // to run in additional browsers:
+ // 1. install corresponding karma launcher
+ // http://karma-runner.github.io/0.13/config/browsers.html
+ // 2. add it to the `browsers` array below.
+ browsers: ['PhantomJS'],
+ frameworks: ['mocha', 'sinon-chai'],
+ reporters: ['spec', 'coverage'],
+ files: ['./index.js'],
+ preprocessors: {
+ './index.js': ['webpack', 'sourcemap']
+ },
+ webpack: webpackConfig,
+ webpackMiddleware: {
+ noInfo: true,
+ },
+ coverageReporter: {
+ dir: './coverage',
+ reporters: [
+ { type: 'lcov', subdir: '.' },
+ { type: 'text-summary' },
+ ]
+ },
+ });
+};
diff --git a/test/unit/specs/breadcrumb.spec.js b/test/unit/specs/breadcrumb.spec.js
new file mode 100644
index 00000000..3166c415
--- /dev/null
+++ b/test/unit/specs/breadcrumb.spec.js
@@ -0,0 +1,24 @@
+import { createVue, destroyVM } from '../util';
+
+describe('Breadcrumb.vue', () => {
+ let vm;
+ afterEach(() => {
+ destroyVM(vm);
+ });
+ it('create', done => {
+ vm = createVue(`
+
+ Home4
+ Components
+ Breadcrumb
+
+ `);
+ expect(vm.$el.querySelectorAll('.ivu-breadcrumb-item-link').length).to.equal(3);
+
+ vm.$nextTick(_ => {
+ // console.log(vm.$el.querySelector('.ivu-breadcrumb-item-separator').innerHTML);
+ expect(vm.$el.querySelector('.ivu-breadcrumb-item-separator').innerHTML).to.equal('=>');
+ done();
+ });
+ });
+});
\ No newline at end of file
diff --git a/test/unit/util.js b/test/unit/util.js
new file mode 100644
index 00000000..47cd3313
--- /dev/null
+++ b/test/unit/util.js
@@ -0,0 +1,85 @@
+import Vue from 'vue';
+import iView from '../../src/index';
+
+Vue.use(iView);
+
+let id = 0;
+
+const createElm = function() {
+ const elm = document.createElement('div');
+
+ elm.id = 'app' + ++id;
+ document.body.appendChild(elm);
+
+ return elm;
+};
+
+/**
+ * 回收 vm
+ * @param {Object} vm
+ */
+exports.destroyVM = function(vm) {
+ vm.$el &&
+ vm.$el.parentNode &&
+ vm.$el.parentNode.removeChild(vm.$el);
+};
+
+/**
+ * 创建一个 Vue 的实例对象
+ * @param {Object|String} Compo 组件配置,可直接传 template
+ * @param {Boolean=false} mounted 是否添加到 DOM 上
+ * @return {Object} vm
+ */
+exports.createVue = function(Compo, mounted = false) {
+ const elm = createElm();
+
+ if (Object.prototype.toString.call(Compo) === '[object String]') {
+ Compo = { template: Compo };
+ }
+ return new Vue(Compo).$mount(mounted === false ? null : elm);
+};
+
+/**
+ * 创建一个测试组件实例
+ * @link http://vuejs.org/guide/unit-testing.html#Writing-Testable-Components
+ * @param {Object} Compo - 组件对象
+ * @param {Object} propsData - props 数据
+ * @param {Boolean=false} mounted - 是否添加到 DOM 上
+ * @return {Object} vm
+ */
+exports.createTest = function(Compo, propsData = {}, mounted = false) {
+ if (propsData === true || propsData === false) {
+ mounted = propsData;
+ propsData = {};
+ }
+ const elm = createElm();
+ const Ctor = Vue.extend(Compo);
+ return new Ctor({ propsData }).$mount(mounted === false ? null : elm);
+};
+
+/**
+ * 触发一个事件
+ * mouseenter, mouseleave, mouseover, keyup, change, click 等
+ * @param {Element} elm
+ * @param {String} name
+ * @param {*} opts
+ */
+exports.triggerEvent = function(elm, name, ...opts) {
+ let eventName;
+
+ if (/^mouse|click/.test(name)) {
+ eventName = 'MouseEvents';
+ } else if (/^key/.test(name)) {
+ eventName = 'KeyboardEvent';
+ } else {
+ eventName = 'HTMLEvents';
+ }
+ const evt = document.createEvent(eventName);
+
+ evt.initEvent(name, ...opts);
+ elm.dispatchEvent
+ ? elm.dispatchEvent(evt)
+ : elm.fireEvent('on' + name, evt);
+
+ return elm;
+};