mirror of
https://github.com/leafOfTree/vim-vue-plugin.git
synced 2026-11-04 19:32:53 +08:00
Add cases for attribute highlight on and off, block syntax by lang and emmet-vim group names, OnChangeVueSyntax(), matchit, .wpy, initial_indent as syntax and tag.syntax, and syntax after reloading. Also check indenting a file after removing all indent with g:test_flatten, which fails before the end tag fix as closing tags at column 0 were taken as block end tags.
This commit is contained in:
23 files changed
+281
-15
No files matched your search
@@ -217,7 +217,14 @@ Run tests with Vim and Neovim, whichever is installed
|
|||||||
./test/run.sh basic template # Only these cases
|
./test/run.sh basic template # Only these cases
|
||||||
```
|
```
|
||||||
|
|
||||||
Each case is a `.vue` file in [test/cases](test/cases), with an optional `.vim` file for the config and syntax checks. A case fails if indenting the whole file changes it, a check fails, or there is an error message. Tests also run on GitHub Actions for each push and pull request.
|
Each case is a `.vue` or `.wpy` file in [test/cases](test/cases), with an optional `.vim` file for the config and checks. A case fails if
|
||||||
|
|
||||||
|
- indenting the whole file changes it
|
||||||
|
- with `g:test_flatten`, indenting the file after removing all indent doesn't restore it
|
||||||
|
- a check in `Check()` fails, such as syntax, `GetVueTag()`, `GetVueSyntax()` or fold level
|
||||||
|
- there is an error message
|
||||||
|
|
||||||
|
Tests also run on GitHub Actions for each push and pull request.
|
||||||
|
|
||||||
## Acknowledgments & Refs
|
## Acknowledgments & Refs
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
" Without attribute and keyword highlight
|
||||||
|
let g:vim_vue_plugin_config = {'attribute': 0, 'keyword': 0}
|
||||||
|
let g:test_flatten = 1
|
||||||
|
|
||||||
|
function! Check()
|
||||||
|
call ExpectSyntax('@click', 'VueKey')
|
||||||
|
call ExpectSyntax('toggle', 'VueValue')
|
||||||
|
call ExpectNoSyntax('$t', 'VueInject')
|
||||||
|
call ExpectNoSyntax('1"', 'javaScriptNumber')
|
||||||
|
call ExpectSyntax('message', 'VueExpression')
|
||||||
|
call ExpectEqual(matchstr(execute('highlight VueKey'), 'links to \zs\S\+'),
|
||||||
|
\ 'htmlArg', 'VueKey link')
|
||||||
|
call ExpectNoSyntax('data', 'vueObjectFuncName')
|
||||||
|
endfunction
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<template>
|
||||||
|
<div @click="toggle(item)" :title="$t('title')" v-if="count > 1">
|
||||||
|
<p>{{ message }}</p>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
" Template syntax with attribute highlight
|
||||||
|
let g:vim_vue_plugin_config = {'attribute': 1}
|
||||||
|
let g:test_flatten = 1
|
||||||
|
|
||||||
|
function! Check()
|
||||||
|
" Directives
|
||||||
|
call ExpectSyntax(':class', 'VueKey')
|
||||||
|
call ExpectSyntax('@click', 'VueKey')
|
||||||
|
call ExpectSyntax('v-if', 'VueKey')
|
||||||
|
" Values as expressions
|
||||||
|
call ExpectSyntax('1"', 'javaScriptNumber')
|
||||||
|
call ExpectSyntax('$t', 'VueInject')
|
||||||
|
call ExpectSyntax("'title'", 'javaScriptStringS')
|
||||||
|
" Components and attributes
|
||||||
|
normal! gg
|
||||||
|
call ExpectSyntax('MyComponent', 'VueComponentName')
|
||||||
|
call ExpectSyntax('ref=', 'htmlArg')
|
||||||
|
call ExpectSyntax('data-id', 'htmlArg')
|
||||||
|
call ExpectSyntax('my-component', 'VueComponentName')
|
||||||
|
call ExpectSyntax('transition', 'VueComponentName')
|
||||||
|
" Interpolation
|
||||||
|
call ExpectSyntax('{{', 'VueBrace')
|
||||||
|
call ExpectSyntax('message', 'VueExpression')
|
||||||
|
call ExpectEqual(matchstr(execute('highlight VueKey'), 'links to \zs\S\+'),
|
||||||
|
\ 'Type', 'VueKey link')
|
||||||
|
endfunction
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<template>
|
||||||
|
<div :class="{ active: isActive }" @click="toggle(item)" v-if="count > 1">
|
||||||
|
<MyComponent ref="comp" data-id="1" :title="$t('title')" />
|
||||||
|
<my-component v-model="text"></my-component>
|
||||||
|
<transition name="fade">
|
||||||
|
<p>{{ message.toUpperCase() }}</p>
|
||||||
|
</transition>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
count: 0,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -5,3 +5,15 @@ let g:vim_vue_plugin_config = {
|
|||||||
\ 'style': ['css'],
|
\ 'style': ['css'],
|
||||||
\},
|
\},
|
||||||
\}
|
\}
|
||||||
|
let g:test_flatten = 1
|
||||||
|
packadd matchit
|
||||||
|
|
||||||
|
" Jump between tags with % by matchit. Use :normal for its mapping
|
||||||
|
function! Check()
|
||||||
|
for [lnum, col, expected] in [[1, 2, [3, '/template']], [2, 4, [2, '/p']]]
|
||||||
|
call cursor(lnum, col)
|
||||||
|
normal %
|
||||||
|
call ExpectEqual([line('.'), matchstr(getline('.'), '\%'.col('.').'c/\w\+')],
|
||||||
|
\ expected, printf('after %% from line %d col %d', lnum, col))
|
||||||
|
endfor
|
||||||
|
endfunction
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
" OnChangeVueSyntax() is called when syntax under cursor changes. It's
|
||||||
|
" defined before the plugin is loaded
|
||||||
|
let g:vim_vue_plugin_config = {
|
||||||
|
\'syntax': {
|
||||||
|
\ 'template': ['html'],
|
||||||
|
\ 'script': ['javascript', 'typescript'],
|
||||||
|
\ 'style': ['css', 'scss'],
|
||||||
|
\},
|
||||||
|
\}
|
||||||
|
let g:test_changes = []
|
||||||
|
|
||||||
|
function! OnChangeVueSyntax(syntax)
|
||||||
|
call add(g:test_changes, a:syntax)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! Check()
|
||||||
|
for lnum in [2, 3, 6, 6, 10, 2]
|
||||||
|
call cursor(lnum, 1)
|
||||||
|
doautocmd CursorMoved
|
||||||
|
endfor
|
||||||
|
call ExpectEqual(g:test_changes, ['html', 'typescript', 'scss', 'html'],
|
||||||
|
\ 'syntax changes')
|
||||||
|
call ExpectEqual(GetVueSyntax(), 'html', 'GetVueSyntax()')
|
||||||
|
call ExpectTag(6, 'script')
|
||||||
|
call ExpectTag(10, 'style')
|
||||||
|
endfunction
|
||||||
|
let g:test_flatten = 1
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
<template>
|
||||||
|
<div></div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
const a: number = 1
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
$a: 1px;
|
||||||
|
</style>
|
||||||
@@ -13,3 +13,28 @@ let g:vim_vue_plugin_config = {
|
|||||||
\'foldexpr': 1,
|
\'foldexpr': 1,
|
||||||
\'full_syntax': ['scss', 'less'],
|
\'full_syntax': ['scss', 'less'],
|
||||||
\}
|
\}
|
||||||
|
|
||||||
|
" Block tag, syntax by lang="..." or the first in config, and block group
|
||||||
|
" with css prefix for emmet-vim
|
||||||
|
function! Check()
|
||||||
|
call ExpectBlock('div.set', 'template', 'pug', 'pugTemplateBlock')
|
||||||
|
call ExpectBlock('<template></template>', 'template', 'html', 'htmlTemplateBlock')
|
||||||
|
call ExpectBlock('export default', 'script', 'javascript', 'javascriptScriptBlock')
|
||||||
|
call ExpectBlock('import Vue', 'script', 'typescript', 'typescriptScriptBlock')
|
||||||
|
call ExpectBlock('# Assignment', 'script', 'coffee', 'coffeeScriptBlock')
|
||||||
|
call ExpectBlock('p {', 'style', 'css', 'cssStyleBlock')
|
||||||
|
call ExpectBlock('$a: 100px', 'style', 'scss', 'cssScssStyleBlock')
|
||||||
|
call ExpectBlock('$w: 128px', 'style', 'sass', 'sassStyleBlock')
|
||||||
|
call ExpectBlock('@list: 10 12', 'style', 'less', 'cssLessStyleBlock')
|
||||||
|
call ExpectBlock("@import 'vendor'", 'style', 'stylus', 'cssStylusStyleBlock')
|
||||||
|
call ExpectBlock('"requiresAuth"', 'route', 'json', 'jsonRouteBlock')
|
||||||
|
call ExpectBlock('# This is', 'docs', 'markdown', 'markdownDocsBlock')
|
||||||
|
call ExpectBlock('en:', 'i18n', 'yaml', 'yamlI18nBlock')
|
||||||
|
call ExpectBlock('"en"', 'i18n', 'json', 'jsonI18nBlock')
|
||||||
|
|
||||||
|
" Syntax from a sync point, as after jumping to the end
|
||||||
|
silent edit!
|
||||||
|
normal! G
|
||||||
|
call search('"en"', 'bW')
|
||||||
|
call ExpectEqual(GetVueSyntax(), 'json', 'syntax at the end after reload')
|
||||||
|
endfunction
|
||||||
@@ -13,3 +13,4 @@ function! Check()
|
|||||||
call ExpectFoldlevel(lnum, levels[lnum - 1])
|
call ExpectFoldlevel(lnum, levels[lnum - 1])
|
||||||
endfor
|
endfor
|
||||||
endfunction
|
endfunction
|
||||||
|
let g:test_flatten = 1
|
||||||
@@ -7,3 +7,4 @@ let g:vim_vue_plugin_config = {
|
|||||||
\},
|
\},
|
||||||
\'initial_indent': ['script', 'style', 'codepen-additional'],
|
\'initial_indent': ['script', 'style', 'codepen-additional'],
|
||||||
\}
|
\}
|
||||||
|
let g:test_flatten = 1
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
" initial_indent as `syntax` and `tag.syntax`
|
||||||
|
let g:vim_vue_plugin_config = {
|
||||||
|
\'syntax': {
|
||||||
|
\ 'script': ['javascript'],
|
||||||
|
\ 'style': ['css', 'scss'],
|
||||||
|
\ 'i18n': ['json', 'yaml'],
|
||||||
|
\},
|
||||||
|
\'initial_indent': ['scss', 'i18n.json'],
|
||||||
|
\}
|
||||||
|
let g:test_flatten = 1
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
<script>
|
||||||
|
export default {}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.a {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.b {
|
||||||
|
color: blue;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<i18n>
|
||||||
|
{
|
||||||
|
"en": {
|
||||||
|
"hello": "Hello"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</i18n>
|
||||||
|
|
||||||
|
<i18n lang="yaml">
|
||||||
|
en:
|
||||||
|
hello: Hello
|
||||||
|
</i18n>
|
||||||
@@ -14,3 +14,4 @@ function! Check()
|
|||||||
call ExpectSyntax('computed', 'vueObjectKey')
|
call ExpectSyntax('computed', 'vueObjectKey')
|
||||||
call ExpectSyntax('mounted', 'vueObjectFuncName')
|
call ExpectSyntax('mounted', 'vueObjectFuncName')
|
||||||
endfunction
|
endfunction
|
||||||
|
let g:test_flatten = 1
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
" .wpy for miniprogram, with initial indent for script and style by default
|
||||||
|
let g:test_flatten = 1
|
||||||
|
|
||||||
|
function! Check()
|
||||||
|
call ExpectSyntax('view', 'VueCustomTag')
|
||||||
|
call ExpectSyntax('wx:if', 'VueKey')
|
||||||
|
call ExpectSyntax('show', 'VueExpression')
|
||||||
|
call ExpectSyntax('text', 'VueCustomTag')
|
||||||
|
endfunction
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
<template>
|
||||||
|
<view wx:if="{{ show }}" class="greeting">
|
||||||
|
<text>{{ greeting }}</text>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data: function () {
|
||||||
|
return {
|
||||||
|
greeting: 'Hello'
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.greeting {
|
||||||
|
font-size: 2em;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -20,3 +20,4 @@ function! CheckSync()
|
|||||||
\.string(SyntaxList()))
|
\.string(SyntaxList()))
|
||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
let g:test_flatten = 1
|
||||||
@@ -8,3 +8,4 @@ let g:vim_vue_plugin_config = {
|
|||||||
\'keyword': 1,
|
\'keyword': 1,
|
||||||
\'foldexpr': 1,
|
\'foldexpr': 1,
|
||||||
\}
|
\}
|
||||||
|
let g:test_flatten = 1
|
||||||
@@ -16,3 +16,4 @@ function! Check()
|
|||||||
call ExpectNoSyntax('value < 3', 'vue3Keyword')
|
call ExpectNoSyntax('value < 3', 'vue3Keyword')
|
||||||
call ExpectSyntax('defineExpose', 'vue3Keyword')
|
call ExpectSyntax('defineExpose', 'vue3Keyword')
|
||||||
endfunction
|
endfunction
|
||||||
|
let g:test_flatten = 1
|
||||||
@@ -16,3 +16,4 @@ function! Check()
|
|||||||
call ExpectNoSyntax('/docs', 'markdownDocsBlock')
|
call ExpectNoSyntax('/docs', 'markdownDocsBlock')
|
||||||
call ExpectSyntax('/docs', 'markdownDocsBlock')
|
call ExpectSyntax('/docs', 'markdownDocsBlock')
|
||||||
endfunction
|
endfunction
|
||||||
|
let g:test_flatten = 1
|
||||||
@@ -13,3 +13,4 @@ function! Check()
|
|||||||
call ExpectSyntax('global', 'cssPseudoClassId')
|
call ExpectSyntax('global', 'cssPseudoClassId')
|
||||||
call ExpectSyntax('deep', 'cssPseudoClassId')
|
call ExpectSyntax('deep', 'cssPseudoClassId')
|
||||||
endfunction
|
endfunction
|
||||||
|
let g:test_flatten = 1
|
||||||
+1
-1
@@ -17,7 +17,7 @@ done
|
|||||||
if [ $# -gt 0 ]; then
|
if [ $# -gt 0 ]; then
|
||||||
cases=$*
|
cases=$*
|
||||||
else
|
else
|
||||||
cases=$(ls test/cases/*.vue | sed 's#.*/##; s#\.vue$##')
|
cases=$(ls test/cases/*.vue test/cases/*.wpy 2>/dev/null | sed 's#.*/##; s#\.[a-z]*$##')
|
||||||
fi
|
fi
|
||||||
|
|
||||||
out=$(mktemp)
|
out=$(mktemp)
|
||||||
|
|||||||
+49
-13
@@ -1,9 +1,12 @@
|
|||||||
" Run one test case, see test/run.sh
|
" Run one test case, see test/run.sh
|
||||||
" VUE_TEST_CASE=basic vim -N -u NONE -i NONE -S test/run.vim
|
" VUE_TEST_CASE=basic vim -N -u NONE -i NONE -S test/run.vim
|
||||||
"
|
"
|
||||||
" A case is test/cases/<name>.vue, with optional test/cases/<name>.vim to set
|
" A case is test/cases/<name>.vue (or .wpy), with optional
|
||||||
" g:vim_vue_plugin_config and define Check() for more assertions. It fails if
|
" test/cases/<name>.vim to set g:vim_vue_plugin_config and define Check() for
|
||||||
|
" more assertions. It fails if
|
||||||
" - indenting the whole file changes it
|
" - indenting the whole file changes it
|
||||||
|
" - with g:test_flatten, indenting the file without any indent doesn't
|
||||||
|
" restore it
|
||||||
" - Check() calls Fail() or an Expect*() function fails
|
" - Check() calls Fail() or an Expect*() function fails
|
||||||
" - there are error messages
|
" - there are error messages
|
||||||
"
|
"
|
||||||
@@ -13,6 +16,7 @@ set nocompatible
|
|||||||
let s:root = expand('<sfile>:p:h:h')
|
let s:root = expand('<sfile>:p:h:h')
|
||||||
let s:name = $VUE_TEST_CASE
|
let s:name = $VUE_TEST_CASE
|
||||||
let s:case = s:root.'/test/cases/'.s:name
|
let s:case = s:root.'/test/cases/'.s:name
|
||||||
|
let s:file = filereadable(s:case.'.vue') ? s:case.'.vue' : s:case.'.wpy'
|
||||||
let s:errors = []
|
let s:errors = []
|
||||||
|
|
||||||
" Plugin first, before Vim's placeholder vue syntax and indent files
|
" Plugin first, before Vim's placeholder vue syntax and indent files
|
||||||
@@ -60,6 +64,26 @@ function! ExpectFoldlevel(lnum, level)
|
|||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! ExpectEqual(actual, expected, desc)
|
||||||
|
if a:actual !=# a:expected
|
||||||
|
call Fail(printf('%s should be %s, but got %s',
|
||||||
|
\ a:desc, string(a:expected), string(a:actual)))
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Search pattern forward from cursor and check the block there by
|
||||||
|
" GetVueTag(), GetVueSyntax() and the block syntax group at the line end
|
||||||
|
function! ExpectBlock(pattern, tag, syntax, group)
|
||||||
|
if !search('\V'.a:pattern, 'W')
|
||||||
|
return Fail('not found: '.a:pattern)
|
||||||
|
endif
|
||||||
|
let desc = printf('%s at line %d: ', a:pattern, line('.'))
|
||||||
|
call ExpectEqual(GetVueTag(), a:tag, desc.'tag')
|
||||||
|
call ExpectEqual(GetVueSyntax(), a:syntax, desc.'syntax')
|
||||||
|
let group = synIDattr(synstack(line('.'), col('$') - 1)[0], 'name')
|
||||||
|
call ExpectEqual(group, a:group, desc.'block group')
|
||||||
|
endfunction
|
||||||
|
|
||||||
function! ExpectTag(lnum, tag)
|
function! ExpectTag(lnum, tag)
|
||||||
if GetVueTag(a:lnum) !=# a:tag
|
if GetVueTag(a:lnum) !=# a:tag
|
||||||
call Fail(printf('tag at line %d should be %s, but got %s',
|
call Fail(printf('tag at line %d should be %s, but got %s',
|
||||||
@@ -74,22 +98,34 @@ filetype plugin indent on
|
|||||||
syntax on
|
syntax on
|
||||||
|
|
||||||
messages clear
|
messages clear
|
||||||
execute 'silent edit '.fnameescape(s:case.'.vue')
|
execute 'silent edit '.fnameescape(s:file)
|
||||||
redraw
|
redraw
|
||||||
|
|
||||||
|
function! s:ExpectLines(lines, desc)
|
||||||
|
let actual = getline(1, '$')
|
||||||
|
if actual == a:lines
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
let i = 0
|
||||||
|
while i < len(a:lines) && get(actual, i) ==# a:lines[i]
|
||||||
|
let i += 1
|
||||||
|
endwhile
|
||||||
|
call Fail(printf('%s changed line %d: expected %s, but got %s',
|
||||||
|
\ a:desc, i + 1, string(get(a:lines, i, '')), string(get(actual, i, ''))))
|
||||||
|
endfunction
|
||||||
|
|
||||||
" Indent
|
" Indent
|
||||||
let s:lines = getline(1, '$')
|
let s:lines = getline(1, '$')
|
||||||
silent normal! gg=G
|
silent normal! gg=G
|
||||||
let s:indented = getline(1, '$')
|
call s:ExpectLines(s:lines, 'indent')
|
||||||
if s:indented != s:lines
|
silent edit!
|
||||||
let s:lnum = 0
|
|
||||||
while s:lnum < len(s:lines) && get(s:indented, s:lnum) ==# s:lines[s:lnum]
|
" Indent without any indent
|
||||||
let s:lnum += 1
|
if get(g:, 'test_flatten', 0)
|
||||||
endwhile
|
silent %s/^\s\+//e
|
||||||
call Fail(printf('indent changed at line %d: expected %s, but got %s',
|
silent normal! gg=G
|
||||||
\ s:lnum + 1, string(get(s:lines, s:lnum, '')),
|
call s:ExpectLines(s:lines, 'indent from flat')
|
||||||
\ string(get(s:indented, s:lnum, ''))))
|
silent edit!
|
||||||
silent undo
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
" Assertions
|
" Assertions
|
||||||
|
|||||||
Reference in new issue
Block a user