chore: TypeScript to JavaScript + JSDoc for tests (#8526)

pull/8566/head
Yuichiro Yamashita 1 year ago committed by GitHub
parent 8ffd2112bc
commit 384927dbf3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,9 +1,12 @@
const is_unit_test = process.env.UNIT_TEST;
module.exports = {
file: is_unit_test ? [] : ['test/test.ts'],
file: is_unit_test ? [] : ['test/test.js'],
require: [
'sucrase/register'
],
"node-option": [
"experimental-modules"
]
};

@ -16,7 +16,7 @@ const page = `
const assert = fs.readFileSync(`${__dirname}/assert.js`, 'utf-8');
describe('custom-elements', function() {
describe('custom-elements', function () {
// Note: Increase the timeout in preparation for restarting Chromium due to SIGSEGV.
this.timeout(10000);
let svelte;
@ -81,6 +81,7 @@ describe('custom-elements', function() {
const bundle = await rollup({
input: `${__dirname}/samples/${dir}/test.js`,
plugins: [
// @ts-ignore -- TODO: fix this
{
resolveId(importee) {
if (importee === 'svelte/internal' || importee === './internal') {

@ -4,11 +4,15 @@ import glob from 'tiny-glob/sync';
import * as path from 'path';
import * as fs from 'fs';
import * as colors from 'kleur';
export const assert = (assert$1 as unknown) as typeof assert$1 & { htmlEqual: (actual: string, expected: string, message?: string) => void, htmlEqualWithOptions: (actual: string, expected: string, options: { preserveComments?: boolean, withoutNormalizeHtml?: boolean }, message?: string) => void };
/**
* @type {typeof assert$1 & { htmlEqual: (actual: string, expected: string, message?: string) => void, htmlEqualWithOptions: (actual: string, expected: string, options: { preserveComments?: boolean, withoutNormalizeHtml?: boolean }, message?: string) => void }}
*/
export const assert = /** @type {any} */ (assert$1);
// for coverage purposes, we need to test source files,
// but for sanity purposes, we need to test dist files
export function loadSvelte(test: boolean = false) {
export function loadSvelte(test = false) {
process.env.TEST = test ? 'true' : '';
const resolved = require.resolve('../compiler.js');
@ -68,7 +72,7 @@ for (const key of Object.getOwnPropertyNames(global)) {
}
// implement mock scroll
window.scrollTo = function(pageXOffset, pageYOffset) {
window.scrollTo = function (pageXOffset, pageYOffset) {
window.pageXOffset = pageXOffset;
window.pageYOffset = pageYOffset;
};
@ -140,7 +144,14 @@ function cleanChildren(node) {
}
}
export function normalizeHtml(window, html, { removeDataSvelte = false, preserveComments = false }: { removeDataSvelte?: boolean, preserveComments?: boolean }) {
/**
*
* @param {Window} window
* @param {string} html
* @param {{ removeDataSvelte?: boolean, preserveComments?: boolean }} param2
* @returns
*/
export function normalizeHtml(window, html, { removeDataSvelte = false, preserveComments = false }) {
try {
const node = window.document.createElement('div');
node.innerHTML = html
@ -155,11 +166,18 @@ export function normalizeHtml(window, html, { removeDataSvelte = false, preserve
}
}
export function normalizeNewline(html: string) {
/**
* @param {string} html
* @returns {string}
*/
export function normalizeNewline(html) {
return html.replace(/\r\n/g, '\n');
}
export function setupHtmlEqual(options: { removeDataSvelte?: boolean } = {}) {
/**
* @param {{ removeDataSvelte?: boolean }} options
*/
export function setupHtmlEqual(options = {}) {
const window = env();
// eslint-disable-next-line no-import-assign
@ -170,8 +188,15 @@ export function setupHtmlEqual(options: { removeDataSvelte?: boolean } = {}) {
message
);
};
// eslint-disable-next-line no-import-assign
assert.htmlEqualWithOptions = (actual: string, expected: string, { preserveComments, withoutNormalizeHtml }: { preserveComments?: boolean, withoutNormalizeHtml?: boolean }, message?: string) => {
/**
*
* @param {string} actual
* @param {string} expected
* @param {{ preserveComments?: boolean, withoutNormalizeHtml?: boolean }} param2
* @param {string?} message
*/
assert.htmlEqualWithOptions = (actual, expected, { preserveComments, withoutNormalizeHtml }, message) => {
assert.deepEqual(
withoutNormalizeHtml
? normalizeNewline(actual).replace(/(\sdata-svelte-h="[^"]+")/g, options.removeDataSvelte ? '' : '$1')
@ -252,7 +277,8 @@ const original_set_timeout = global.setTimeout;
export function useFakeTimers() {
const callbacks = [];
global.setTimeout = function(fn) {
// @ts-ignore
global.setTimeout = function (fn) {
callbacks.push(fn);
};
@ -289,7 +315,14 @@ export function prettyPrintPuppeteerAssertionError(message) {
}
}
export async function retryAsync<T>(fn: () => Promise<T>, maxAttempts: number = 3, interval: number = 1000): Promise<T> {
/**
*
* @param {() => Promise<import ('puppeteer').Browser>} fn
* @param {number} maxAttempts
* @param {number} interval
* @returns {Promise<import ('puppeteer').Browser>}
*/
export async function retryAsync(fn, maxAttempts = 3, interval = 1000) {
let attempts = 0;
while (attempts <= maxAttempts) {
try {
@ -301,8 +334,15 @@ export async function retryAsync<T>(fn: () => Promise<T>, maxAttempts: number =
}
}
// NOTE: Chromium may exit with SIGSEGV, so retry in that case
export async function executeBrowserTest<T>(browser, launchPuppeteer: () => Promise<T>, additionalAssertion: () => void, onError: (err: Error) => void) {
/**
* NOTE: Chromium may exit with SIGSEGV, so retry in that case
* @param {import ('puppeteer').Browser} browser
* @param {() => Promise<import ('puppeteer').Browser>} launchPuppeteer
* @param {() => void} additionalAssertion
* @param {(err: Error) => void} onError
* @returns {Promise<import ('puppeteer').Browser>}
*/
export async function executeBrowserTest(browser, launchPuppeteer, additionalAssertion, onError) {
let count = 0;
do {
count++;
@ -310,6 +350,7 @@ export async function executeBrowserTest<T>(browser, launchPuppeteer: () => Prom
const page = await browser.newPage();
page.on('console', (type) => {
// @ts-ignore -- TODO: Fix type
console[type._type](type._text);
});
@ -318,7 +359,10 @@ export async function executeBrowserTest<T>(browser, launchPuppeteer: () => Prom
console.error(error);
});
await page.goto('http://localhost:6789');
const result = await page.evaluate(() => test(document.querySelector('main')));
const result = await page.evaluate(() => {
// @ts-ignore -- It runs in browser context.
return test(document.querySelector('main'));
});
if (result) console.log(result);
additionalAssertion();
await page.close();

@ -19,7 +19,7 @@ describe('hydration', () => {
before(() => {
const svelte = loadSvelte();
require.extensions['.svelte'] = function(module, filename) {
require.extensions['.svelte'] = function (module, filename) {
const options = Object.assign(
{
filename,
@ -135,6 +135,6 @@ describe('hydration', () => {
}
fs.readdirSync(`${__dirname}/samples`).forEach(dir => {
runTest(dir, null);
runTest(dir);
});
});

@ -67,7 +67,7 @@ describe('ssr', () => {
format: 'cjs'
};
require('../../register')(compileOptions);
require('../../register.js')(compileOptions);
const Component = require(`${dir}/main.svelte`).default;
@ -174,7 +174,7 @@ describe('ssr', () => {
glob('**/*.svelte', { cwd }).forEach(file => {
if (file[0] === '_') return;
const dir = `${cwd}/_output/ssr`;
const dir = `${cwd}/_output/ssr`;
const out = `${dir}/${file.replace(/\.svelte$/, '.js')}`;
if (fs.existsSync(out)) {
@ -208,12 +208,12 @@ describe('ssr', () => {
if (config.ssrHtml) {
assert.htmlEqualWithOptions(html, config.ssrHtml, {
preserveComments: compileOptions.preserveComments,
preserveComments: compileOptions.preserveComments,
withoutNormalizeHtml: config.withoutNormalizeHtml
});
} else if (config.html) {
assert.htmlEqualWithOptions(html, config.html, {
preserveComments: compileOptions.preserveComments,
preserveComments: compileOptions.preserveComments,
withoutNormalizeHtml: config.withoutNormalizeHtml
});
}

@ -2,15 +2,17 @@ const fs = require('fs');
require('source-map-support').install();
process.env.TEST = true;
process.env.TEST = 'true';
require.extensions['.js'] = function(module, filename) {
require.extensions['.js'] = function (module, filename) {
const exports = [];
let code = fs.readFileSync(filename, 'utf-8')
.replace(/^import \* as (\w+) from ['"]([^'"]+)['"];?/gm, 'var $1 = require("$2");')
.replace(/^import (\w+) from ['"]([^'"]+)['"];?/gm, 'var {default: $1} = require("$2");')
.replace(/^import \* as (\S+) from ['"]([^'"]+)['"];?/gm, 'var $1 = require("$2");')
.replace(/^import {([^}]+)} from ['"](.+)['"];?/gm, 'var {$1} = require("$2");')
.replace(/^import (\S+),\s+?{([^}]+)} from ['"](.+)['"];?/gm, 'var {default: $1, $2} = require("$3");')
.replace(/^import (\S+) from ['"]([./][^'"]+)['"];?/gm, 'var {default: $1} = require("$2");')
.replace(/^import (\S+) from ['"]([^'"]+)['"];?/gm, 'var $1 = require("$2");')
.replace(/^export default /gm, 'exports.default = ')
.replace(/^export (const|let|var|class|function|async\s+function) (\w+)/gm, (match, type, name) => {
exports.push(name);

@ -2,20 +2,19 @@ import * as assert from 'assert';
import { getLocator } from 'locate-character';
import MagicString, { Bundle } from 'magic-string';
type AssertMappedParameters = {
code: string;
filename?: string;
input: string | ReturnType<typeof getLocator>;
input_code?: string;
preprocessed: any;
};
/**
* @typedef {{ code: string; filename?: string; input: string | ReturnType<typeof getLocator>; input_code?: string; preprocessed: any; }} AssertMappedParameters
*/
/**
* @param {AssertMappedParameters} param
*/
export function assert_mapped(
{ code, filename, input, input_code, preprocessed }: AssertMappedParameters
{ code, filename, input, input_code, preprocessed }
) {
const locate_input = typeof input === 'function' ? input : getLocator(input);
if (filename === undefined) filename = 'input.svelte';
if (input_code === undefined) input_code = code;
if (input_code === undefined) input_code = code;
const source_loc = locate_input(input_code);
assert.notEqual(
@ -43,14 +42,15 @@ export function assert_mapped(
);
}
type AssertNotMappedParameters = {
code: string;
filename?: string;
preprocessed: any;
};
/**
* @typedef {{ code: string; filename?: string; preprocessed: any; }} AssertNotMappedParameters
*/
/**
* @param {AssertNotMappedParameters} param
*/
export function assert_not_mapped(
{ code, filename, preprocessed }: AssertNotMappedParameters
{ code, filename, preprocessed }
) {
if (filename === undefined) filename = 'input.svelte';
@ -73,9 +73,14 @@ export function assert_not_mapped(
);
}
/**
* @param {string} code
* @param {ReturnType<typeof getLocator>} locate
* @param {string} filename
*/
export function assert_not_located(
code: string,
locate: ReturnType<typeof getLocator>,
code,
locate,
filename = 'input.svelte'
) {
assert.equal(
@ -85,8 +90,14 @@ export function assert_not_located(
);
}
/**
* @param {Array<{ code: string | MagicString, filename: string }>} inputs
* @param {string} filename
* @param {string} separator
* @returns
*/
export function magic_string_bundle(
inputs: Array<{ code: string | MagicString, filename: string }>,
inputs,
filename = 'bundle.js',
separator = '\n'
) {
@ -107,7 +118,12 @@ export function magic_string_bundle(
};
}
export function magic_string_preprocessor_result(filename: string, src: MagicString) {
/**
* @param {string} filename
* @param {MagicString} src
* @returns
*/
export function magic_string_preprocessor_result(filename, src) {
return {
code: src.toString(),
map: src.generateMap({
@ -118,7 +134,12 @@ export function magic_string_preprocessor_result(filename: string, src: MagicStr
};
}
export function magic_string_replace_all(src: MagicString, search: string, replace: string) {
/**
* @param {MagicString} src
* @param {string} search
* @param {string} replace
*/
export function magic_string_replace_all(src, search, replace) {
let idx = src.original.indexOf(search);
if (idx == -1) throw new Error('search not found in src');
do {

@ -101,6 +101,7 @@ describe('store', () => {
describe('readable', () => {
it('creates a readable store', () => {
let running;
/** @type {import('svelte/store').Subscriber<unknown>} */
let tick;
const store = readable(undefined, set => {
@ -163,11 +164,12 @@ describe('store', () => {
});
});
/** @type {any} */
const fake_observable = {
subscribe(fn) {
fn(42);
return {
unsubscribe: () => {}
unsubscribe: () => { }
};
}
};
@ -290,7 +292,7 @@ describe('store', () => {
});
it('derived dependency does not update and shared ancestor updates', () => {
const root = writable({ a: 0, b:0 });
const root = writable({ a: 0, b: 0 });
const values = [];
const a = derived(root, $root => {
@ -451,6 +453,7 @@ describe('store', () => {
assert.equal(get(readableStore), 2);
assert.equal(get(readableStore), get(writableStore));
// @ts-ignore
assert.throws(() => readableStore.set(3));
});

@ -1,14 +1,14 @@
const glob = require('tiny-glob/sync.js');
require('./setup');
require('./setup.js');
// bind internal to jsdom
require('./helpers.ts');
require('./helpers.js');
require('../internal');
console.clear();
const test_folders = glob('*/index.ts', { cwd: 'test' });
const test_folders = glob('*/index.js', { cwd: 'test' });
const solo_folders = test_folders.filter(folder => /\.solo/.test(folder));
if (solo_folders.length) {
Loading…
Cancel
Save