Skip to content

unit tests in single file (fixes #223) #247

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions karma.conf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module.exports = function (config) {
config.set({
preprocessors: {
'**/*.vue': ['webpack', 'sourcemap']
},
webpack: {
devtool: 'inline-source-map',
module: {
loaders: [
{ test: /\.vue$/, loader: './index.js' }
]
}
},
frameworks: ['mocha', 'chai'],
files: ['test/*.vue'],
plugins: [
require('karma-webpack'),
require('karma-mocha'),
require('karma-chai'),
require('karma-chrome-launcher'),
require('karma-phantomjs-launcher'),
require('karma-sourcemap-loader')
]
})
}
79 changes: 57 additions & 22 deletions lib/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ module.exports = function (content) {
var parts = parse(content, fileName, this.sourceMap)
var hasLocalStyles = false
var output = 'var __vue_script__, __vue_template__\n'
var testOutput = ''

// check if there are any template syntax errors
var templateWarnings = parts.template.length && parts.template[0].warnings
Expand All @@ -163,29 +164,58 @@ module.exports = function (content) {
output += getRequire('style', style, i, style.scoped)
})

// add require for script
var script
if (parts.script.length) {
script = parts.script[0]
output +=
'__vue_script__ = ' + (
script.src
? getRequireForImport('script', script, 0)
: getRequire('script', script, 0)
)
// check and warn named exports
if (!this.minimize) {
output +=
'if (__vue_script__ &&\n' +
' __vue_script__.__esModule &&\n' +
' Object.keys(__vue_script__).length > 1) {\n' +
' console.warn(' + JSON.stringify(
'[vue-loader] ' + path.relative(process.cwd(), filePath) +
': named exports in *.vue files are ignored.'
) + ')' +
'}\n'
// add requires for scripts
var hasScript = false
parts.script.forEach(function (script, i) {
var requireStr = script.src
? getRequireForImport('script', script, i)
: getRequire('script', script, i)
if (script.test === undefined) {
// only one script without test attribute
if (hasScript) {
throw new Error(
'[vue-loader] Only one <script> tag is ' +
'allowed inside a Vue component.'
)
}
hasScript = true
output += '__vue_script__ = ' + requireStr
// check and warn named exports
if (!this.minimize) {
output +=
'if (__vue_script__ &&\n' +
' __vue_script__.__esModule &&\n' +
' Object.keys(__vue_script__).length > 1) {\n' +
' console.warn(' + JSON.stringify(
'[vue-loader] ' + path.relative(process.cwd(), filePath) +
': named exports in *.vue files are ignored.'
) + ')' +
'}\n'
}
} else if (!this.minimize && process.env.NODE_ENV !== 'production') {
switch (script.test) {
case 'karma':
// mount the vue component and bind to `this`
testOutput +=
'if (window._karma__ !== "null") {\n' +
' var Vue = require("vue")\n' +
' var vueComp = Vue.extend(module.exports)\n' +
' vueComp = new vueComp()\n' +
' document.body.appendChild(vueComp.$mount().$el)\n' +
' window.vueTestComp = vueComp\n' +
' ' + requireStr.replace('require("!!', 'require("!!imports-loader?this=>window.vueTestComp!') +
' delete window.vueTestComp\n' +
'}\n'
break
default:
// bind the unmounted vue component to `this`
testOutput +=
'window.vueTestComp = module.exports\n' +
requireStr.replace('require("!!', 'require("!!imports-loader?this=>window.vueTestComp!') +
'window.vueTestComp = null\n'
}
}
}
})

// add require for template
var template
Expand Down Expand Up @@ -242,6 +272,11 @@ module.exports = function (content) {
'}'
}

// add tests if available
if (testOutput) {
output += '\n' + testOutput
}

// done
return output
}
Expand Down
14 changes: 7 additions & 7 deletions lib/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ module.exports = function (content, filename, needMap) {
var type = node.tagName
var lang = getAttribute(node, 'lang')
var src = getAttribute(node, 'src')
var test = getAttribute(node, 'test')
var scoped = getAttribute(node, 'scoped') != null
var warnings = null
var map = null
Expand All @@ -48,12 +49,9 @@ module.exports = function (content, filename, needMap) {
}

// node count check
if (
(type === 'script' || type === 'template') &&
output[type].length > 0
) {
if (type === 'template' && output[type].length > 0) {
throw new Error(
'[vue-loader] Only one <script> or <template> tag is ' +
'[vue-loader] Only one <template> tag is ' +
'allowed inside a Vue component.'
)
}
Expand All @@ -74,7 +72,8 @@ module.exports = function (content, filename, needMap) {
} else if (type === 'script') {
output.script.push({
src: src,
lang: lang
lang: lang,
test: test
})
}
return
Expand Down Expand Up @@ -153,7 +152,8 @@ module.exports = function (content, filename, needMap) {
scoped: scoped,
content: result,
map: map && map.toJSON(),
warnings: warnings
warnings: warnings,
test: test
})
})

Expand Down
14 changes: 13 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@
"homepage": "https://github.com/vuejs/vue-loader",
"scripts": {
"lint": "eslint lib",
"test": "eslint lib && mocha test/test.js --slow 5000 --timeout 10000",
"test:mocha": "mocha test/test.js --slow 5000 --timeout 10000",
"test:karma": "karma start --browsers PhantomJS --single-run",
"test": "npm run lint && npm run test:mocha && npm run test:karma",
"docs": "cd docs && gitbook serve",
"deploy-docs": "bash ./docs/deploy.sh"
},
Expand Down Expand Up @@ -68,17 +70,27 @@
"expose-loader": "^0.7.1",
"extract-text-webpack-plugin": "^1.0.1",
"file-loader": "^0.8.5",
"imports-loader": "^0.6.5",
"inject-loader": "^2.0.1",
"jade": "^1.11.0",
"jsdom": "^8.5.0",
"karma": "^0.13.22",
"karma-chai": "^0.1.0",
"karma-chrome-launcher": "^1.0.1",
"karma-mocha": "^1.0.1",
"karma-phantomjs-launcher": "^1.0.0",
"karma-sourcemap-loader": "^0.3.7",
"karma-webpack": "^1.7.0",
"mkdirp": "^0.5.1",
"mocha": "^2.2.5",
"node-libs-browser": "^1.0.0",
"phantomjs-prebuilt": "^2.1.7",
"postcss": "^5.0.21",
"rimraf": "^2.4.0",
"stylus": "^0.54.5",
"stylus-loader": "^2.0.0",
"sugarss": "^0.1.3",
"vue": "^1.0.24",
"vue-hot-reload-api": "^1.2.0",
"vue-html-loader": "^1.0.0",
"vue-style-loader": "^1.0.0",
Expand Down
14 changes: 14 additions & 0 deletions test/autoprefix.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<style>
body {
transform: scale(1);
}
</style>
<script test>
var styles = window.document.querySelectorAll('style')
var style = styles[styles.length-1].textContent
describe("vue-loader", function () {
it('autoprefix', function () {
expect(style).to.contain('body {\n -webkit-transform: scale(1);\n transform: scale(1);\n}')
})
})
</script>
31 changes: 31 additions & 0 deletions test/basic.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<script>
module.exports = {
data () {
return {
msg: 'Hello from Component A!'
}
}
}
</script>
<template>
<h2 class="red">{{msg}}</h2>
</template>

<style>
comp-a h2 {
color: #f00;
}
</style>

<script test>
var module = window.vueTestComp
var styles = window.document.querySelectorAll('style')
var style = styles[styles.length-1].textContent
describe("vue-loader", function () {
it('basic', function () {
expect(module.template).to.contain('<h2 class="red">{{msg}}</h2>')
expect(module.data().msg).to.contain('Hello from Component A!')
expect(style).to.contain('comp-a h2 {\n color: #f00;\n}')
})
})
</script>
5 changes: 0 additions & 5 deletions test/fixtures/autoprefix.vue

This file was deleted.

19 changes: 0 additions & 19 deletions test/fixtures/basic.vue

This file was deleted.

19 changes: 0 additions & 19 deletions test/fixtures/pre.vue

This file was deleted.

1 change: 0 additions & 1 deletion test/fixtures/script-import.vue

This file was deleted.

1 change: 0 additions & 1 deletion test/fixtures/template-import.vue

This file was deleted.

27 changes: 27 additions & 0 deletions test/karma.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<template>
<h2 class="red">{{msg}}</h2>
</template>

<script>
module.exports = {
data () {
return {
msg: 'Hello from Component A!'
}
}
}
</script>


<script test="karma">
var module = window.vueTestComp
describe("vue-loader", function () {
it('karma', function () {
expect(module.$el).to.exist
expect(module.msg).to.contain('Hello from Component A!')
})
after(function () {
module.$destroy(true)
})
})
</script>
36 changes: 36 additions & 0 deletions test/preprocessors.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<style lang="stylus">
font-stack = Helvetica, sans-serif
primary-color = #999
body
font 100% font-stack
color primary-color
</style>

<template lang="jade">
h1 This is the app
comp-a
comp-b
</template>

<script lang="coffee">
module.exports =
data: ->
msg: 'Hello from coffee!'
</script>

<script test>
var module = window.vueTestComp
var styles = window.document.querySelectorAll('style')
var style = styles[styles.length-1].textContent
describe("vue-loader", function () {
it('preprocessors', function () {
expect(module.template).to.contain(
'<h1>This is the app</h1>' +
'<comp-a></comp-a>' +
'<comp-b></comp-b>'
)
expect(module.data().msg).to.contain('Hello from coffee!')
expect(style).to.contain('body {\n font: 100% Helvetica, sans-serif;\n color: #999;\n}')
})
})
</script>
10 changes: 10 additions & 0 deletions test/script-import.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<script src="./fixtures/script-import.js"></script>

<script test>
var module = window.vueTestComp
describe("vue-loader", function () {
it('script import', function () {
expect(module.data().msg).to.contain('Hello from Component A!')
})
})
</script>
10 changes: 10 additions & 0 deletions test/template-import.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<template lang="jade" src="./fixtures/template-import.jade"></template>

<script test>
var module = window.vueTestComp
describe("vue-loader", function () {
it('template import', function () {
expect(module.template).to.contain('<div><h1>hello</h1></div>')
})
})
</script>
Loading