diff --git a/test/js/update.ts b/test/js/update.ts index 6bea051bf9..5c4a16b2c0 100644 --- a/test/js/update.ts +++ b/test/js/update.ts @@ -1,4 +1,4 @@ -import {replaceIfUpdated } from "../tiny-glob"; +import { update_expected } from "../update"; // this file will replace all the expected.js files with their _actual // equivalents. Only use it when you're sure that you haven't @@ -19,7 +19,8 @@ function loadConfig(file) { throw err; } } -replaceIfUpdated((compile, check, get_relative) => { + +update_expected((compile, check, get_relative) => { check( "expected.js", compile(loadConfig(get_relative("_config.js")).options).js.code.replace( diff --git a/test/parser/update.ts b/test/parser/update.ts index fd7123cd74..b5f5e89fc3 100644 --- a/test/parser/update.ts +++ b/test/parser/update.ts @@ -1,10 +1,10 @@ -import { replaceIfUpdated } from "../tiny-glob"; +import { update_expected } from "../update"; // this file will replace all the expected.js files with their _actual // equivalents. Only use it when you're sure that you haven't // broken anything! -replaceIfUpdated((compile, check) => { +update_expected((compile, check) => { try { check("output.json", compile({ generate: false }).ast); } catch (e) { diff --git a/test/tiny-glob.ts b/test/tiny-glob.ts deleted file mode 100644 index 788f60c4ac..0000000000 --- a/test/tiny-glob.ts +++ /dev/null @@ -1,317 +0,0 @@ -import { readdirSync, lstatSync, statSync, readFileSync, writeFileSync } from 'fs'; -import { normalize, dirname, join, resolve, relative } from 'path'; -import assert from "assert"; -// MIT -// tiny-glob, globrex and globalyzer by Terkel Gjervig - -const CHARS = { '{': '}', '(': ')', '[': ']' }; -const STRICT = /\\(.)|(^!|\*|[\].+)]\?|\[[^\\\]]+\]|\{[^\\}]+\}|\(\?[:!=][^\\)]+\)|\([^|]+\|[^\\)]+\)|(\\).|([@?!+*]\(.*\)))/; -const RELAXED = /\\(.)|(^!|[*?{}()[\]]|\(\?)/; -const isWin = process.platform === 'win32'; -const SEP = isWin ? `\\\\+` : `\\/`; -const SEP_ESC = isWin ? `\\\\` : `/`; -const GLOBSTAR = `((?:[^/]*(?:/|$))*)`; -const WILDCARD = `([^/]*)`; -const GLOBSTAR_SEGMENT = `((?:[^${SEP_ESC}]*(?:${SEP_ESC}|$))*)`; -const WILDCARD_SEGMENT = `([^${SEP_ESC}]*)`; -const isHidden = /(^|[\\/])\.[^\\/.]/g; -let CACHE = {}; -function isglob(str, { strict = true } = {}) { - if (str === '') return false; - let match; - const rgx = strict ? STRICT : RELAXED; - while ((match = rgx.exec(str))) { - if (match[2]) return true; - let idx = match.index + match[0].length; - const open = match[1]; - const close = open ? CHARS[open] : null; - let n; - if (open && close) if ((n = str.indexOf(close, idx)) !== -1) idx = n + 1; - str = str.slice(idx); - } - return false; -} -function parent(str, { strict = false } = {}) { - str = normalize(str).replace(/\/|\\/, '/'); - if (/[{[].*[/]*.*[}]]$/.test(str)) str += '/'; - str += 'a'; - do str = dirname(str); - while (isglob(str, { strict }) || /(^|[^\\])([{[]|\([^)]+$)/.test(str)); - return str.replace(/\\([*?|[\](){}])/g, '$1'); -} -function globalyzer(pattern, opts = {}) { - let base = parent(pattern, opts); - const isGlob = isglob(pattern, opts); - let glob; - if (base != '.') { - if ((glob = pattern.substr(base.length)).startsWith('/')) glob = glob.substr(1); - } else glob = pattern; - if (!isGlob) glob = (base = dirname(pattern)) !== '.' ? pattern.substr(base.length) : pattern; - if (glob.startsWith('./')) glob = glob.substr(2); - if (glob.startsWith('/')) glob = glob.substr(1); - return { base, glob, isGlob }; -} -function globrex(glob, { extended = false, globstar = false, strict = false, filepath = false, flags = '' } = {}) { - let regex = ''; - let segment = ''; - const path = { - regex: '', - segments: [], - globstar: undefined, - }; - let inGroup = false; - let inRange = false; - const ext = []; - function add(str, { split = false, last = false, only = '' } = {}) { - if (only !== 'path') regex += str; - if (filepath && only !== 'regex') { - path.regex += str === '\\/' ? SEP : str; - if (split) { - if (last) segment += str; - if (segment !== '') { - if (!flags.includes('g')) segment = `^${segment}$`; // change it 'includes' - path.segments.push(new RegExp(segment, flags)); - } - segment = ''; - } else { - segment += str; - } - } - } - const escaped = (condition, str = c) => add(condition ? str : `//${c}`); - let c; - let n; - for (let i = 0; i < glob.length; i++) { - c = glob[i]; - n = glob[i + 1]; - if (['\\', '$', '^', '.', '='].includes(c)) { - add(`\\${c}`); - continue; - } - switch (c) { - case '/': { - add(`\\${c}`, { split: true }); - if (n === '/' && !strict) regex += '?'; - break; - } - case '|': - case '(': { - escaped(ext.length); - break; - } - case ')': { - if (ext.length) { - add(c); - const type = ext.pop(); - if (type === '@') { - add('{1}'); - } else if (type === '!') { - add('([^/]*)'); - } else { - add(type); - } - } else add(`\\${c}`); - break; - } - case '+': { - if (n === '(' && extended) { - ext.push(c); - } else add(`\\${c}`); - break; - } - case '!': { - if (extended) { - if (inRange) { - add('^'); - break; - } else if (n === '(') { - ext.push(c); - i++; - } - } - escaped(extended && n === '(', '(?!'); - break; - } - case '?': { - if (extended && n === '(') { - ext.push(c); - } else { - escaped(extended, '.'); - } - break; - } - case '[': { - if (inRange && n === ':') { - i++; // skip [ - let value = ''; - while (glob[++i] !== ':') value += glob[i]; - if (value === 'alnum') add('(\\w|\\d)'); - else if (value === 'space') add('\\s'); - else if (value === 'digit') add('\\d'); - i++; // skip last ] - break; - } else if (extended) inRange = true; - escaped(extended); - break; - } - case ']': { - if (extended) inRange = false; - escaped(extended); - break; - } - case '{': { - if (extended) inGroup = true; - escaped(extended, '('); - break; - } - case '}': { - if (extended) inGroup = false; - escaped(extended, ')'); - break; - } - case ',': { - escaped(inGroup, '|'); - break; - } - case '*': { - if (n === '(' && extended) { - ext.push(c); - break; - } - const prevChar = glob[i - 1]; - let starCount = 1; - while (glob[i + 1] === '*') { - starCount++; - i++; - } - const nextChar = glob[i + 1]; - if (!globstar) add('.*'); - else { - const isGlobstar = - starCount > 1 && (prevChar === '/' || prevChar === void 0) && (nextChar === '/' || nextChar === void 0); - if (isGlobstar) { - add(GLOBSTAR, { only: 'regex' }); - add(GLOBSTAR_SEGMENT, { only: 'path', last: true, split: true }); - i++; - } else { - add(WILDCARD, { only: 'regex' }); - add(WILDCARD_SEGMENT, { only: 'path' }); - } - } - break; - } - case '@': { - if (extended && n === '(') ext.push(c); - else add(c); - break; - } - default: - add(c); - } - } - const g = flags.includes('g'); - return { - regex: new RegExp(g ? regex : `^${regex}$`, flags), - path: filepath - ? { - segments: [...path.segments, new RegExp(g ? segment : `^${segment}$`, flags)], - regex: new RegExp(g ? path.regex : `^${path.regex}$`, flags), - globstar: new RegExp(!g ? `^${GLOBSTAR_SEGMENT}$` : GLOBSTAR_SEGMENT, flags), - } - : undefined, - }; -} -function walk(output, prefix, lexer, filesOnly, dot, cwd, dirname = '', level = 0) { - const rgx = lexer.segments[level]; - const dir = join(cwd, prefix, dirname); - const files = readdirSync(dir); - let i = 0; - let file; - const len = files.length; - - let fullpath; - let relpath; - let stats; - let isMatch; - for (; i < len; i++) { - fullpath = join(dir, (file = files[i])); - relpath = dirname ? join(dirname, file) : file; - if (!dot && isHidden.test(relpath)) continue; - isMatch = lexer.regex.test(relpath); - if ((stats = CACHE[relpath]) === void 0) CACHE[relpath] = stats = lstatSync(fullpath); - if (!stats.isDirectory()) { - isMatch && output.push(relative(cwd, fullpath)); - continue; - } - if (rgx && !rgx.test(file)) continue; - if (!filesOnly && isMatch) output.push(join(prefix, relpath)); - walk(output, prefix, lexer, filesOnly, dot, cwd, relpath, rgx && rgx.toString() !== lexer.globstar && ++level); - } -} -export function glob(str: string, { cwd = '.', absolute = false, filesOnly = false, dot = false, flush = false }) { - if (!str) return []; - const glob = globalyzer(str); - if (!glob.isGlob) { - try { - const resolved = resolve(cwd, str); - const dirent = statSync(resolved); - if (filesOnly && !dirent.isFile()) return []; - - return absolute ? [resolved] : [str]; - } catch (err) { - if (err.code != 'ENOENT') throw err; - - return []; - } - } - if (flush) CACHE = {}; - const matches = []; - const { path } = globrex(glob.glob, { filepath: true, globstar: true, extended: true }); - //@ts-ignore - path.globstar = path.globstar.toString(); - walk(matches, glob.base, path, filesOnly, dot, cwd, '.', 0); - return absolute ? matches.map((x) => resolve(cwd, x)) : matches; -} -export function replaceIfUpdated(run, cwd) { - const svelte = (function loadSvelte() { - const resolved = require.resolve("../compiler.js"); - delete require.cache[resolved]; - return require(resolved); - })(); - glob("samples/*/input.svelte", { cwd }).forEach((dir) => { - function compile(options) { - return svelte.compile( - readFileSync(`${cwd}/${dir}`, "utf-8") - .replace(/\s+$/, "") - .replace(/\r/g, ""), - options - ); - } - function check(target, value) { - const path = `${cwd}/${dir.replace("input.svelte", target)}`; - try { - const previous = readFileSync(path, "utf-8"); - if (typeof value === "object") { - assert.deepEqual( - JSON.parse(previous), - JSON.parse(JSON.stringify(value)) - ); - } else { - assert.equal( - previous.replace(/\s+$/, "").replace(/\r/g, ""), - (value = value.replace(/\s+$/, "").replace(/\r/g, "")) - ); - } - } catch (e) { - if (typeof value === "object") - value = JSON.stringify(value, null, "\t"); - writeFileSync(path, value); - } - } - function get_relative(name) { - return `${cwd}/${dir.replace("input.svelte", name)}`; - } - - run(compile, check, get_relative); - }); -} \ No newline at end of file diff --git a/test/update.ts b/test/update.ts new file mode 100644 index 0000000000..02b75a68de --- /dev/null +++ b/test/update.ts @@ -0,0 +1,46 @@ +import { readFileSync, writeFileSync } from 'fs'; +import glob from 'tiny-glob/sync'; +import assert from "assert"; +export function update_expected(run, cwd) { + const svelte = (function loadSvelte() { + const resolved = require.resolve("../compiler.js"); + delete require.cache[resolved]; + return require(resolved); + })(); + glob("samples/*/input.svelte", { cwd }).forEach((dir) => { + function compile(options) { + return svelte.compile( + readFileSync(`${cwd}/${dir}`, "utf-8") + .replace(/\s+$/, "") + .replace(/\r/g, ""), + options + ); + } + function check(target, value) { + const path = `${cwd}/${dir.replace("input.svelte", target)}`; + try { + const previous = readFileSync(path, "utf-8"); + if (typeof value === "object") { + assert.deepEqual( + JSON.parse(previous), + JSON.parse(JSON.stringify(value)) + ); + } else { + assert.equal( + previous.replace(/\s+$/, "").replace(/\r/g, ""), + (value = value.replace(/\s+$/, "").replace(/\r/g, "")) + ); + } + } catch (e) { + if (typeof value === "object") + value = JSON.stringify(value, null, "\t"); + writeFileSync(path, value); + } + } + function get_relative(name) { + return `${cwd}/${dir.replace("input.svelte", name)}`; + } + + run(compile, check, get_relative); + }); +} \ No newline at end of file