├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── package.json ├── preprocessor.js ├── test ├── src │ ├── counter-html-ts.vue │ ├── counter-js.vue │ ├── counter-ts.ts │ └── counter-ts.vue ├── test │ ├── __snapshots__ │ │ ├── counter-html-ts.spec.js.snap │ │ ├── counter-js.spec.js.snap │ │ └── counter-ts.spec.ts.snap │ ├── counter-html-ts.spec.js │ ├── counter-js.spec.js │ └── counter-ts.spec.ts └── types │ └── html2jade.d.ts └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.gitignore.io/api/macos,windows,linux,visualstudiocode,webstorm,sublimetext,node,git 2 | 3 | ### macOS ### 4 | *.DS_Store 5 | .AppleDouble 6 | .LSOverride 7 | 8 | # Icon must end with two \r 9 | Icon 10 | 11 | 12 | # Thumbnails 13 | ._* 14 | 15 | # Files that might appear in the root of a volume 16 | .DocumentRevisions-V100 17 | .fseventsd 18 | .Spotlight-V100 19 | .TemporaryItems 20 | .Trashes 21 | .VolumeIcon.icns 22 | .com.apple.timemachine.donotpresent 23 | 24 | # Directories potentially created on remote AFP share 25 | .AppleDB 26 | .AppleDesktop 27 | Network Trash Folder 28 | Temporary Items 29 | .apdisk 30 | 31 | 32 | ### Windows ### 33 | # Windows image file caches 34 | Thumbs.db 35 | ehthumbs.db 36 | 37 | # Folder config file 38 | Desktop.ini 39 | 40 | # Recycle Bin used on file shares 41 | $RECYCLE.BIN/ 42 | 43 | # Windows Installer files 44 | *.cab 45 | *.msi 46 | *.msm 47 | *.msp 48 | 49 | # Windows shortcuts 50 | *.lnk 51 | 52 | 53 | ### Linux ### 54 | *~ 55 | 56 | # temporary files which can be created if a process still has a handle open of a deleted file 57 | .fuse_hidden* 58 | 59 | # KDE directory preferences 60 | .directory 61 | 62 | # Linux trash folder which might appear on any partition or disk 63 | .Trash-* 64 | 65 | 66 | ### VisualStudioCode ### 67 | .vscode/* 68 | !.vscode/settings.json 69 | !.vscode/tasks.json 70 | !.vscode/launch.json 71 | 72 | 73 | ### WebStorm ### 74 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm 75 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 76 | 77 | # User-specific stuff: 78 | .idea/workspace.xml 79 | .idea/tasks.xml 80 | .idea/dictionaries 81 | .idea/vcs.xml 82 | .idea/jsLibraryMappings.xml 83 | 84 | # Sensitive or high-churn files: 85 | .idea/dataSources.ids 86 | .idea/dataSources.xml 87 | .idea/dataSources.local.xml 88 | .idea/sqlDataSources.xml 89 | .idea/dynamic.xml 90 | .idea/uiDesigner.xml 91 | 92 | # Gradle: 93 | .idea/gradle.xml 94 | .idea/libraries 95 | 96 | # Mongo Explorer plugin: 97 | .idea/mongoSettings.xml 98 | 99 | ## File-based project format: 100 | *.iws 101 | 102 | ## Plugin-specific files: 103 | 104 | # IntelliJ 105 | /out/ 106 | 107 | # mpeltonen/sbt-idea plugin 108 | .idea_modules/ 109 | 110 | # JIRA plugin 111 | atlassian-ide-plugin.xml 112 | 113 | # Crashlytics plugin (for Android Studio and IntelliJ) 114 | com_crashlytics_export_strings.xml 115 | crashlytics.properties 116 | crashlytics-build.properties 117 | fabric.properties 118 | 119 | ### WebStorm Patch ### 120 | # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 121 | 122 | # *.iml 123 | # modules.xml 124 | # .idea/misc.xml 125 | # *.ipr 126 | 127 | 128 | ### SublimeText ### 129 | # cache files for sublime text 130 | *.tmlanguage.cache 131 | *.tmPreferences.cache 132 | *.stTheme.cache 133 | 134 | # workspace files are user-specific 135 | *.sublime-workspace 136 | 137 | # project files should be checked into the repository, unless a significant 138 | # proportion of contributors will probably not be using SublimeText 139 | # *.sublime-project 140 | 141 | # sftp configuration file 142 | sftp-config.json 143 | 144 | # Package control specific files 145 | Package Control.last-run 146 | Package Control.ca-list 147 | Package Control.ca-bundle 148 | Package Control.system-ca-bundle 149 | Package Control.cache/ 150 | Package Control.ca-certs/ 151 | bh_unicode_properties.cache 152 | 153 | # Sublime-github package stores a github token in this file 154 | # https://packagecontrol.io/packages/sublime-github 155 | GitHub.sublime-settings 156 | 157 | 158 | ### Node ### 159 | /.npmrc 160 | # Logs 161 | logs 162 | *.log 163 | npm-debug.log* 164 | 165 | # Runtime data 166 | pids 167 | *.pid 168 | *.seed 169 | *.pid.lock 170 | 171 | # Directory for instrumented libs generated by jscoverage/JSCover 172 | lib-cov 173 | 174 | # Coverage directory used by tools like istanbul 175 | coverage 176 | 177 | # nyc test coverage 178 | .nyc_output 179 | 180 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 181 | .grunt 182 | 183 | # node-waf configuration 184 | .lock-wscript 185 | 186 | # Compiled binary addons (http://nodejs.org/api/addons.html) 187 | build/Release 188 | 189 | # Dependency directories 190 | node_modules 191 | jspm_packages 192 | 193 | # Optional npm cache directory 194 | .npm 195 | 196 | # Optional REPL history 197 | .node_repl_history 198 | 199 | 200 | ### Git ### 201 | *.orig -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "6" 4 | script: npm run prepublish 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Locoslab GmbH 4 | Copyright (c) 2014-2016 Evan You for portions used from https://github.com/vuejs/vueify 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # :snowflake: DEPRECATION NOTICE :snowflake: 2 | Official TypeScript and Jest support has been added to Vue.js 2.x, which has changed considerably since this repository has been created. We recommend to start new projects with [Vue CLI](https://cli.vuejs.org/). 3 | 4 | # vue-typescript-jest 5 | Jest `preprocessor.js` for Vue.js components (supporting html and pug) and TypeScript. 6 | 7 | Portions of this project are heavily based on parts of [vueify](https://github.com/vuejs/vueify) (Copyright (c) 2014-2016 Evan You). 8 | 9 | ## Usage 10 | * Install: `npm install --save-dev vue-typescript-jest` 11 | * This package does not declare any dependencies: install the preferred versions of TypeScript, Jest, Vue.js, and vueify. Cf. [`package.json`](package.json) for the versions used during development. 12 | * Add the following snippet to `package.json` (adapting testRegex to your project layout) 13 | ```js 14 | "scripts": { 15 | "test": "jest" 16 | }, 17 | "jest": { 18 | "transform": { 19 | ".*\\.(ts|vue)$": "/node_modules/vue-typescript-jest/preprocessor.js" 20 | }, 21 | "moduleFileExtensions": [ 22 | "ts", 23 | "js", 24 | "vue" 25 | ], 26 | "testRegex": "/test/.*\\.(ts|js)$", 27 | "coveragePathIgnorePatterns": [ 28 | "/node_modules/", 29 | "/test/.*\\.(ts|js)$", 30 | "/.*\\.vue$" 31 | ] 32 | }, 33 | ``` 34 | 35 | * For Jest v16 (earlier versions not tested), use the following instead of `transform` 36 | ```js 37 | "scriptPreprocessor": "/node_modules/vue-typescript-jest/preprocessor.js", 38 | ``` 39 | 40 | * Make sure a suitable `tsconfig.json` is present to specify your required TypeScript compiler options 41 | * Write a test for a Vue.js component 42 | ```typescript 43 | /// 44 | 45 | import Vue = require('vue') 46 | // see note about importing *.vue files 47 | import CounterTs = require('./counter-ts.vue') 48 | 49 | // basic unit testing 50 | describe('counter-ts.vue', () => { 51 | it('should initialize correctly', () => { 52 | const vm = new Vue({ 53 | el: document.createElement('div'), 54 | render: (h) => h(CounterTs), 55 | }) 56 | expect(vm.$el.querySelector('div span').textContent).toBe('counter-ts') 57 | expect(vm.$el.querySelector('div span:nth-child(2)').textContent).toBe('1') 58 | }) 59 | }) 60 | 61 | // or use snapshot testing, e.g., with html2jade 62 | function clickNthButton(el: HTMLElement, n: number) { 63 | (el.querySelector('div button:nth-of-type(' + n + ')')).click() 64 | } 65 | import html2jade = require('html2jade') 66 | 67 | describe('counter-ts.vue', () => { 68 | it('should just work', () => new Promise(function(resolve, reject) { 69 | const vm = new Vue({ 70 | el: document.createElement('div'), 71 | render: (h) => h(CounterTs), 72 | }) 73 | clickNthButton(vm.$el, 1) 74 | clickNthButton(vm.$el, 3) 75 | clickNthButton(vm.$el, 2) 76 | Vue.nextTick( () => { 77 | html2jade.convertHtml(vm.$el.innerHTML, {bodyless: true}, (err: any, jade: string) => { 78 | expect(jade).toMatchSnapshot() 79 | resolve() 80 | }) 81 | }) 82 | })) 83 | }) 84 | ``` 85 | 86 | * Use jest as usual, e.g., `npm test -- --watch` 87 | 88 | ### Notes 89 | * This project looks for `tsconfig.json` starting in the directory of the source file and continuing up in the directory tree 90 | * Only the `compilerOptions` subtree of `tsconfig.json` is used 91 | * To use `import` with `*.vue` files in TypeScript code, cf. 92 | * To further simplify snapshot testing with Jest and html2jade, cf. 93 | * To use TypeScript classes as Vue.js components, cf. 94 | 95 | * Inline TypeScript code in a `*.vue` file is not supported. We prefer separate files to make use of existing IDE/editor and tooling support for TypeScript files. Instead, import the TypeScript module as follows 96 | ```html 97 | 100 | 103 | ``` 104 | * Code coverage of `*.vue` files fails as the generated code contains a `with` statement that trips the babylon parser: use `coveragePathIgnorePatterns` as shown above to ignore the `*.vue` files 105 | 106 | ## Contributing 107 | Contributions including bug reports, tests, and documentation are more than welcome. To get started with development: 108 | ``` bash 109 | # once: install dependencies 110 | npm install 111 | 112 | # run unit tests in watch mode 113 | npm test -- --watch 114 | 115 | # lint & test 116 | npm run prepublish 117 | ``` 118 | 119 | ## License 120 | [MIT](http://opensource.org/licenses/MIT) 121 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-typescript-jest", 3 | "version": "0.3.1", 4 | "description": "Jest preprocessor.js for Vue.js components and TypeScript", 5 | "author": "Locoslab GmbH", 6 | "homepage": "https://github.com/locoslab/vue-typescript-jest", 7 | "bugs": "https://github.com/locoslab/vue-typescript-jest/issues", 8 | "repository": "locoslab/vue-typescript-jest", 9 | "license": "MIT", 10 | "main": "./preprocessor.js", 11 | "files": [ 12 | "preprocessor.js" 13 | ], 14 | "keywords": [ 15 | "jest", 16 | "vue", 17 | "vueify", 18 | "typescript", 19 | "pug" 20 | ], 21 | "scripts": { 22 | "test": "jest", 23 | "prepublish": "eslint preprocessor.js && jest --no-cache --coverage" 24 | }, 25 | "jest": { 26 | "transform": { 27 | ".*\\.(ts|vue)$": "/preprocessor.js" 28 | }, 29 | "moduleFileExtensions": [ 30 | "ts", 31 | "js", 32 | "vue" 33 | ], 34 | "testRegex": "/test/test/.*\\.(ts|js)$", 35 | "coveragePathIgnorePatterns": [ 36 | "/node_modules/", 37 | "/test/test/.*\\.(ts|js)$", 38 | "/.*\\.vue$" 39 | ] 40 | }, 41 | "devDependencies": { 42 | "@types/jest": "^19.0.0", 43 | "babel-core": "^6.0.0", 44 | "babel-plugin-transform-runtime": "^6.0.0", 45 | "babel-preset-es2015": "^6.0.0", 46 | "babel-runtime": "^6.0.0", 47 | "eslint": "^3.7.0", 48 | "eslint-config-locoslab": "0.1.0", 49 | "html2jade": "^0.8.4", 50 | "jest-cli": "^19.0.0", 51 | "pug": "^2.0.0-beta6", 52 | "typescript": "^2.0.3", 53 | "vue": "^2.0.7", 54 | "vue-template-compiler": "^2.0.7", 55 | "vue-template-es2015-compiler": "^1.2.2", 56 | "vue-typescript-import-dts": "^2.0.0" 57 | }, 58 | "babel": { 59 | "presets": [ 60 | "es2015" 61 | ] 62 | }, 63 | "eslintConfig": { 64 | "extends": "locoslab", 65 | "env": { 66 | "node": true 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /preprocessor.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const path = require('path') 3 | 4 | var defaultBabelOptions = { 5 | presets: ['es2015'], 6 | plugins: ['transform-runtime'], 7 | } 8 | 9 | function ts(src, filePath) { 10 | // Microsoft's ts.findConfigFilepath does not work under Windows (hard coded '/' as directory separator) 11 | // https://github.com/Microsoft/TypeScript/pull/9625 probably fixes this but is open since July 11th 12 | function findConfigFile(filePath) { 13 | let prev = null 14 | do { 15 | const testPath = path.join(filePath, 'tsconfig.json') 16 | if (fs.existsSync(testPath)) { 17 | return testPath 18 | } 19 | prev = filePath 20 | filePath = path.dirname(filePath) 21 | } while (prev !== filePath) 22 | return undefined 23 | } 24 | const ts = require('typescript') 25 | const tsConfigPath = findConfigFile(filePath) 26 | if (!tsConfigPath) { 27 | throw 'tsconfig.json not found for ' + filePath 28 | } 29 | const tsOptions = require(tsConfigPath) 30 | const options = { 31 | compilerOptions: tsOptions.compilerOptions, 32 | moduleName: '', 33 | reportDiagnostics: true, 34 | fileName: filePath, 35 | } 36 | const res = ts.transpileModule(src, options) 37 | if (res.diagnostics.length > 0) { 38 | let err = '' 39 | res.diagnostics.forEach(diagnostic => { 40 | const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start) 41 | const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n') 42 | err += `${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}\n` 43 | }) 44 | throw err 45 | } 46 | return res.outputText 47 | } 48 | 49 | function babel(src) { 50 | let babelc 51 | try { 52 | babelc = require('babel-core') 53 | } catch (e) { 54 | // do nothing 55 | } 56 | if (babelc) { 57 | return babelc.transform(src, defaultBabelOptions).code 58 | } else { 59 | return src 60 | } 61 | } 62 | 63 | // this is heavily based on vueify (Copyright (c) 2014-2016 Evan You) 64 | function vue(src, filePath) { 65 | function toFunction (code) { 66 | const transpile = require('vue-template-es2015-compiler') 67 | return transpile('function render () {' + code + '}') 68 | } 69 | const vueCompiler = require('vue-template-compiler') 70 | const parts = vueCompiler.parseComponent(src, { pad: true }) 71 | let script = '' 72 | if (!parts.script.lang) { 73 | script = babel(parts.script.content) 74 | } else { 75 | throw filePath + ': unknown 15 | -------------------------------------------------------------------------------- /test/src/counter-js.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 42 | -------------------------------------------------------------------------------- /test/src/counter-ts.ts: -------------------------------------------------------------------------------- 1 | const thisIsTypescript: string = 'counter-ts' 2 | export default { 3 | data () { 4 | return { 5 | name: thisIsTypescript, 6 | counter: 0 7 | } 8 | }, 9 | methods: { 10 | inc: function() { 11 | this.counter++ 12 | }, 13 | dec: function() { 14 | this.counter-- 15 | }, 16 | uncoveredFunction: function() { 17 | this.counter *= 2 18 | } 19 | }, 20 | computed: { 21 | inverse: { 22 | get: function() { 23 | return -this.counter 24 | }, 25 | set: function(value: number) { 26 | this.counter = -value 27 | } 28 | }, 29 | }, 30 | created: function () { 31 | this.counter++ 32 | }, 33 | name: 'counter-ts' 34 | } 35 | -------------------------------------------------------------------------------- /test/src/counter-ts.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 14 | -------------------------------------------------------------------------------- /test/test/__snapshots__/counter-html-ts.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`counter-html-ts.vue should just work 1`] = ` 4 | "span(style='display: inline-block; width: 6em;') counter-ts 5 | | 6 | span(style='display: inline-block; width: 3em; text-align: center;') -3 7 | | 8 | button(href='#', style='display: inline-block; width: 2em;') + 9 | | 10 | button(href='#', style='display: inline-block; width: 2em;') - 11 | | 12 | button(href='#', style='display: inline-block; width: 2em;') ! 13 | | 14 | span(style='display: inline-block; width: 3em; text-align: center;') 3 15 | " 16 | `; 17 | -------------------------------------------------------------------------------- /test/test/__snapshots__/counter-js.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`counter-js.vue should just work 1`] = ` 4 | "span(style='display: inline-block; width: 6em;') counter-js 5 | span(style='display: inline-block; width: 3em; text-align: center;') -3 6 | button(href='#', style='display: inline-block; width: 2em;') + 7 | button(href='#', style='display: inline-block; width: 2em;') - 8 | button(href='#', style='display: inline-block; width: 2em;') ! 9 | span(style='display: inline-block; width: 3em; text-align: center;') 3 10 | " 11 | `; 12 | -------------------------------------------------------------------------------- /test/test/__snapshots__/counter-ts.spec.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`counter-ts.vue should just work 1`] = ` 4 | "span(style='display: inline-block; width: 6em;') counter-ts 5 | span(style='display: inline-block; width: 3em; text-align: center;') -3 6 | button(href='#', style='display: inline-block; width: 2em;') + 7 | button(href='#', style='display: inline-block; width: 2em;') - 8 | button(href='#', style='display: inline-block; width: 2em;') ! 9 | span(style='display: inline-block; width: 3em; text-align: center;') 3 10 | " 11 | `; 12 | -------------------------------------------------------------------------------- /test/test/counter-html-ts.spec.js: -------------------------------------------------------------------------------- 1 | const Vue = require('vue') 2 | const html2jade = require('html2jade') 3 | 4 | const CounterHtmlTs = require('../src/counter-html-ts.vue') 5 | 6 | describe('counter-html-ts.vue', () => { 7 | it('should initialize correctly', () => { 8 | const vm = new Vue({ 9 | el: document.createElement('div'), 10 | render: (h) => h(CounterHtmlTs), 11 | }) 12 | expect(vm.$el.querySelector('div span').textContent).toBe('counter-ts') 13 | expect(vm.$el.querySelector('div span:nth-child(2)').textContent).toBe('1') 14 | }) 15 | }) 16 | 17 | describe('counter-html-ts.vue', () => { 18 | it('should just work', () => new Promise(function(resolve, reject) { 19 | const vm = new Vue({ 20 | el: document.createElement('div'), 21 | render: (h) => h(CounterHtmlTs), 22 | }) 23 | vm.$el.querySelector('div button:nth-of-type(1)').click() 24 | vm.$el.querySelector('div button:nth-of-type(3)').click() 25 | vm.$el.querySelector('div button:nth-of-type(2)').click() 26 | Vue.nextTick( () => { 27 | html2jade.convertHtml(vm.$el.innerHTML, {bodyless: true}, (err, jade) => { 28 | expect(jade).toMatchSnapshot() 29 | resolve() 30 | }) 31 | }) 32 | })) 33 | }) 34 | -------------------------------------------------------------------------------- /test/test/counter-js.spec.js: -------------------------------------------------------------------------------- 1 | const Vue = require('vue') 2 | const html2jade = require('html2jade') 3 | 4 | const CounterJs = require('../src/counter-js.vue') 5 | 6 | describe('counter-js.vue', () => { 7 | it('should initialize correctly', () => { 8 | const vm = new Vue({ 9 | el: document.createElement('div'), 10 | render: (h) => h(CounterJs), 11 | }) 12 | expect(vm.$el.querySelector('div span').textContent).toBe('counter-js') 13 | expect(vm.$el.querySelector('div span:nth-child(2)').textContent).toBe('1') 14 | }) 15 | }) 16 | 17 | describe('counter-js.vue', () => { 18 | it('should just work', () => new Promise(function(resolve, reject) { 19 | const vm = new Vue({ 20 | el: document.createElement('div'), 21 | render: (h) => h(CounterJs), 22 | }) 23 | vm.$el.querySelector('div button:nth-of-type(1)').click() 24 | vm.$el.querySelector('div button:nth-of-type(3)').click() 25 | vm.$el.querySelector('div button:nth-of-type(2)').click() 26 | Vue.nextTick( () => { 27 | html2jade.convertHtml(vm.$el.innerHTML, {bodyless: true}, (err, jade) => { 28 | expect(jade).toMatchSnapshot() 29 | resolve() 30 | }) 31 | }) 32 | })) 33 | }) 34 | -------------------------------------------------------------------------------- /test/test/counter-ts.spec.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import Vue = require('vue') 4 | // see note about importing *.vue files 5 | import CounterTs = require('../src/counter-ts.vue') 6 | 7 | // basic unit testing 8 | describe('counter-ts.vue', () => { 9 | it('should initialize correctly', () => { 10 | const vm = new Vue({ 11 | el: document.createElement('div'), 12 | render: (h) => h(CounterTs), 13 | }) 14 | expect(vm.$el.querySelector('div span').textContent).toBe('counter-ts') 15 | expect(vm.$el.querySelector('div span:nth-child(2)').textContent).toBe('1') 16 | }) 17 | }) 18 | 19 | // or use snapshot testing, e.g., with html2jade 20 | function clickNthButton(el: HTMLElement, n: number) { 21 | (el.querySelector('div button:nth-of-type(' + n + ')')).click() 22 | } 23 | import html2jade = require('html2jade') 24 | 25 | describe('counter-ts.vue', () => { 26 | it('should just work', () => new Promise(function(resolve, reject) { 27 | const vm = new Vue({ 28 | el: document.createElement('div'), 29 | render: (h) => h(CounterTs), 30 | }) 31 | clickNthButton(vm.$el, 1) 32 | clickNthButton(vm.$el, 3) 33 | clickNthButton(vm.$el, 2) 34 | Vue.nextTick( () => { 35 | html2jade.convertHtml(vm.$el.innerHTML, {bodyless: true}, (err: any, jade: string) => { 36 | expect(jade).toMatchSnapshot() 37 | resolve() 38 | }) 39 | }) 40 | })) 41 | }) 42 | -------------------------------------------------------------------------------- /test/types/html2jade.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'html2jade' { 2 | function convertHtml(html: string, options?: Object, callback?: (err: any, jade: string) => void): void 3 | function convertDocument(html: string, options?: Object, callback?: (err: any, jade: string) => void): void 4 | } 5 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "noImplicitAny": true, 6 | "strictNullChecks": true, 7 | "sourceMap": false, 8 | "pretty": true, 9 | "lib": ["es5", "dom", "es2015.promise"], 10 | "types": ["vue-typescript-import-dts"] 11 | }, 12 | "exclude": [ 13 | "node_modules" 14 | ], 15 | "atom": { 16 | "rewriteTsconfig": false 17 | }, 18 | "compileOnSave": false 19 | } 20 | --------------------------------------------------------------------------------