Skip to content

Commit

Permalink
fix(glob): properly handles tailing comma (#8181)
Browse files Browse the repository at this point in the history
  • Loading branch information
antfu committed May 15, 2022
1 parent 7752b56 commit 462be8e
Show file tree
Hide file tree
Showing 2 changed files with 237 additions and 54 deletions.
253 changes: 203 additions & 50 deletions packages/vite/src/node/__tests__/plugins/importGlob/parse.test.ts
Expand Up @@ -8,7 +8,11 @@ async function run(input: string) {
process.cwd(),
(id) => id
)
return items.map((i) => ({ globs: i.globs, options: i.options }))
return items.map((i) => ({
globs: i.globs,
options: i.options,
start: i.start
}))
}

async function runError(input: string) {
Expand All @@ -23,31 +27,66 @@ describe('parse positives', async () => {
it('basic', async () => {
expect(
await run(`
import.meta.importGlob(\'./modules/*.ts\')
import.meta.glob(\'./modules/*.ts\')
`)
).toMatchInlineSnapshot(`
[
{
"globs": [
"./modules/*.ts",
],
"options": {},
"start": 5,
},
]
`)
).toMatchInlineSnapshot('[]')
})

it('array', async () => {
expect(
await run(`
import.meta.importGlob([\'./modules/*.ts\', './dir/*.{js,ts}\'])
import.meta.glob([\'./modules/*.ts\', './dir/*.{js,ts}\'])
`)
).toMatchInlineSnapshot(`
[
{
"globs": [
"./modules/*.ts",
"./dir/*.{js,ts}",
],
"options": {},
"start": 5,
},
]
`)
).toMatchInlineSnapshot('[]')
})

it('options with multilines', async () => {
expect(
await run(`
import.meta.importGlob([
import.meta.glob([
\'./modules/*.ts\',
"!./dir/*.{js,ts}"
], {
eager: true,
import: 'named'
})
`)
).toMatchInlineSnapshot('[]')
).toMatchInlineSnapshot(`
[
{
"globs": [
"./modules/*.ts",
"!./dir/*.{js,ts}",
],
"options": {
"eager": true,
"import": "named",
},
"start": 5,
},
]
`)
})

it('options with multilines', async () => {
Expand All @@ -68,6 +107,7 @@ describe('parse positives', async () => {
"/dir/**",
],
"options": {},
"start": 21,
},
]
`)
Expand Down Expand Up @@ -98,6 +138,99 @@ describe('parse positives', async () => {
"raw": true,
},
},
"start": 21,
},
]
`)
})

it('object properties - 1', async () => {
expect(
await run(`
export const pageFiles = {
'.page': import.meta.glob('/**/*.page.*([a-zA-Z0-9])')
};`)
).toMatchInlineSnapshot(`
[
{
"globs": [
"/**/*.page.*([a-zA-Z0-9])",
],
"options": {},
"start": 47,
},
]
`)
})

it('object properties - 2', async () => {
expect(
await run(`
export const pageFiles = {
'.page': import.meta.glob('/**/*.page.*([a-zA-Z0-9])'),
};`)
).toMatchInlineSnapshot(`
[
{
"globs": [
"/**/*.page.*([a-zA-Z0-9])",
],
"options": {},
"start": 47,
},
]
`)
})

it('object properties - 3', async () => {
expect(
await run(`
export const pageFiles = {
'.page.client': import.meta.glob('/**/*.page.client.*([a-zA-Z0-9])'),
'.page.server': import.meta.glob('/**/*.page.server.*([a-zA-Z0-9])'),
};`)
).toMatchInlineSnapshot(`
[
{
"globs": [
"/**/*.page.client.*([a-zA-Z0-9])",
],
"options": {},
"start": 54,
},
{
"globs": [
"/**/*.page.server.*([a-zA-Z0-9])",
],
"options": {},
"start": 130,
},
]
`)
})

it('array item', async () => {
expect(
await run(`
export const pageFiles = [
import.meta.glob('/**/*.page.client.*([a-zA-Z0-9])'),
import.meta.glob('/**/*.page.server.*([a-zA-Z0-9])'),
]`)
).toMatchInlineSnapshot(`
[
{
"globs": [
"/**/*.page.client.*([a-zA-Z0-9])",
],
"options": {},
"start": 38,
},
{
"globs": [
"/**/*.page.server.*([a-zA-Z0-9])",
],
"options": {},
"start": 98,
},
]
`)
Expand All @@ -106,97 +239,117 @@ describe('parse positives', async () => {

describe('parse negatives', async () => {
it('syntax error', async () => {
expect(await runError('import.meta.importGlob(')).toMatchInlineSnapshot(
'undefined'
expect(await runError('import.meta.glob(')).toMatchInlineSnapshot(
'[SyntaxError: Unexpected token (1:17)]'
)
})

it('empty', async () => {
expect(await runError('import.meta.importGlob()')).toMatchInlineSnapshot(
'undefined'
expect(await runError('import.meta.glob()')).toMatchInlineSnapshot(
'[Error: Invalid glob import syntax: Expected 1-2 arguments, but got 0]'
)
})

it('3 args', async () => {
expect(
await runError('import.meta.importGlob("", {}, {})')
).toMatchInlineSnapshot('undefined')
await runError('import.meta.glob("", {}, {})')
).toMatchInlineSnapshot(
'[Error: Invalid glob import syntax: Expected 1-2 arguments, but got 3]'
)
})

it('in string', async () => {
expect(await runError('"import.meta.importGlob()"')).toBeUndefined()
expect(await runError('"import.meta.glob()"')).toBeUndefined()
})

it('variable', async () => {
expect(await runError('import.meta.importGlob(hey)')).toMatchInlineSnapshot(
'undefined'
expect(await runError('import.meta.glob(hey)')).toMatchInlineSnapshot(
'[Error: Invalid glob import syntax: Could only use literals]'
)
})

it('template', async () => {
// eslint-disable-next-line no-template-curly-in-string
expect(
await runError('import.meta.importGlob(`hi ${hey}`)')
).toMatchInlineSnapshot('undefined')
await runError('import.meta.glob(`hi ${hey}`)')
).toMatchInlineSnapshot(
'[Error: Invalid glob import syntax: Could only use literals]'
)
})

it('be string', async () => {
expect(await runError('import.meta.importGlob(1)')).toMatchInlineSnapshot(
'undefined'
expect(await runError('import.meta.glob(1)')).toMatchInlineSnapshot(
'[Error: Invalid glob import syntax: Expected glob to be a string, but got "number"]'
)
})

it('be array variable', async () => {
expect(await runError('import.meta.glob([hey])')).toMatchInlineSnapshot(
'[Error: Invalid glob import syntax: Could only use literals]'
)
expect(
await runError('import.meta.importGlob([hey])')
).toMatchInlineSnapshot('undefined')
expect(
await runError('import.meta.importGlob(["1", hey])')
).toMatchInlineSnapshot('undefined')
await runError('import.meta.glob(["1", hey])')
).toMatchInlineSnapshot(
'[Error: Invalid glob import syntax: Could only use literals]'
)
})

it('options', async () => {
expect(
await runError('import.meta.importGlob("hey", hey)')
).toMatchInlineSnapshot('undefined')
expect(
await runError('import.meta.importGlob("hey", [])')
).toMatchInlineSnapshot('undefined')
await runError('import.meta.glob("hey", hey)')
).toMatchInlineSnapshot(
'[Error: Invalid glob import syntax: Expected the second argument o to be a object literal, but got "Identifier"]'
)
expect(await runError('import.meta.glob("hey", [])')).toMatchInlineSnapshot(
'[Error: Invalid glob import syntax: Expected the second argument o to be a object literal, but got "ArrayExpression"]'
)
})

it('options props', async () => {
expect(
await runError('import.meta.importGlob("hey", { hey: 1 })')
).toMatchInlineSnapshot('undefined')
await runError('import.meta.glob("hey", { hey: 1 })')
).toMatchInlineSnapshot(
'[Error: Invalid glob import syntax: Unknown options hey]'
)
expect(
await runError('import.meta.importGlob("hey", { import: hey })')
).toMatchInlineSnapshot('undefined')
await runError('import.meta.glob("hey", { import: hey })')
).toMatchInlineSnapshot(
'[Error: Invalid glob import syntax: Could only use literals]'
)
expect(
await runError('import.meta.importGlob("hey", { eager: 123 })')
).toMatchInlineSnapshot('undefined')
await runError('import.meta.glob("hey", { eager: 123 })')
).toMatchInlineSnapshot(
'[Error: Invalid glob import syntax: Expected the type of option "eager" to be "boolean", but got "number"]'
)
})

it('options query', async () => {
expect(
await runError(
'import.meta.importGlob("./*.js", { as: "raw", query: "hi" })'
)
).toMatchInlineSnapshot('undefined')
await runError('import.meta.glob("./*.js", { as: "raw", query: "hi" })')
).toMatchInlineSnapshot(
'[Error: Invalid glob import syntax: Options "as" and "query" cannot be used together]'
)
expect(
await runError('import.meta.importGlob("./*.js", { query: 123 })')
).toMatchInlineSnapshot('undefined')
await runError('import.meta.glob("./*.js", { query: 123 })')
).toMatchInlineSnapshot(
'[Error: Invalid glob import syntax: Expected query to be a string, but got "number"]'
)
expect(
await runError('import.meta.importGlob("./*.js", { query: { foo: {} } })')
).toMatchInlineSnapshot('undefined')
await runError('import.meta.glob("./*.js", { query: { foo: {} } })')
).toMatchInlineSnapshot(
'[Error: Invalid glob import syntax: Could only use literals]'
)
expect(
await runError(
'import.meta.importGlob("./*.js", { query: { foo: hey } })'
)
).toMatchInlineSnapshot('undefined')
await runError('import.meta.glob("./*.js", { query: { foo: hey } })')
).toMatchInlineSnapshot(
'[Error: Invalid glob import syntax: Could only use literals]'
)
expect(
await runError(
'import.meta.importGlob("./*.js", { query: { foo: 123, ...a } })'
'import.meta.glob("./*.js", { query: { foo: 123, ...a } })'
)
).toMatchInlineSnapshot('undefined')
).toMatchInlineSnapshot(
'[Error: Invalid glob import syntax: Could only use literals]'
)
})
})

0 comments on commit 462be8e

Please sign in to comment.