Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extract common sample logic into a class #868

Merged
merged 36 commits into from
Mar 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
09ba333
init
pushkine Jan 18, 2021
91e7009
Merge remote-tracking branch 'upstream/master'
pushkine Feb 14, 2021
5924cf3
Merge remote-tracking branch 'upstream/master'
pushkine Feb 22, 2021
8d23f64
init
pushkine Feb 25, 2021
1d4a307
indent using spaces
pushkine Feb 25, 2021
2a62d01
end with breakline
pushkine Feb 25, 2021
bd8c1bf
yarn lock
pushkine Feb 25, 2021
d245308
Merge remote-tracking branch 'upstream/master'
pushkine Mar 8, 2021
3860741
init
pushkine Mar 8, 2021
dc56d37
fix
pushkine Mar 8, 2021
3732855
esm
pushkine Mar 8, 2021
6b3cd1a
fix
pushkine Mar 9, 2021
2868216
Merge branch 'typescript-tests-2' into typescript-tests
pushkine Mar 9, 2021
fa4862e
Update yarn.lock
pushkine Mar 9, 2021
51ceb0c
Merge remote-tracking branch 'upstream/master'
pushkine Mar 9, 2021
1eece76
Merge remote-tracking branch 'upstream/master' into typescript-tests
pushkine Mar 9, 2021
349f64d
Update rollup.config.test.js
pushkine Mar 9, 2021
6a52674
Update rollup.config.test.js
pushkine Mar 9, 2021
7196cc7
Update rollup.config.test.js
pushkine Mar 9, 2021
74c6c42
update
pushkine Mar 9, 2021
56f883b
Merge branch 'test-build-dts' into typescript-tests
pushkine Mar 9, 2021
2a6e1c0
Update package.json
pushkine Mar 9, 2021
ea48a96
Update index.ts
pushkine Mar 9, 2021
3233908
Update helpers.ts
pushkine Mar 9, 2021
abacc06
init
pushkine Mar 9, 2021
047d94f
Update helpers.ts
pushkine Mar 9, 2021
8db7186
Merge branch 'master' into share-sample-logic
pushkine Mar 9, 2021
0f42fb2
Merge remote-tracking branch 'upstream/master'
pushkine Mar 9, 2021
72ca6bb
Merge branch 'master' into share-sample-logic
pushkine Mar 9, 2021
397c56d
Revert "Merge branch 'master' into share-sample-logic"
pushkine Mar 9, 2021
93e794f
update
pushkine Mar 9, 2021
afdb5f0
Update helpers.ts
pushkine Mar 9, 2021
5027748
Update helpers.ts
pushkine Mar 9, 2021
68fa7c2
Update index.ts
pushkine Mar 9, 2021
440266c
cleanup
dummdidumm Mar 10, 2021
df10340
lint
dummdidumm Mar 10, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
185 changes: 133 additions & 52 deletions packages/svelte2tsx/test/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,90 +1,171 @@
import fs from 'fs';
import assert from 'assert';
import { TestFunction } from 'mocha';
import svelte2tsx from './build/index';
import { htmlx2jsx } from './build/htmlxtojsx';

export function benchmark(fn) {
export function benchmark(fn: () => void) {
return -Date.now() + (fn(), Date.now());
}

export function readFileSync(path) {
export function readFileSync(path: string) {
return fs.existsSync(path)
? fs.readFileSync(path, 'utf-8').replace(/\r\n/g, '\n').replace(/\s+$/, '')
: null;
}

function check_dir(path, { allowed = [], required = allowed }) {
const unchecked = new Set(required);
const unknown = [];
loop: for (const fileName of fs.readdirSync(path)) {
for (const name of unchecked) {
if ('*' === name[0] ? fileName.endsWith(name.slice(1)) : name === fileName) {
unchecked.delete(name);
continue loop;
class Sample {
readonly folder: string[];
readonly directory: string;
private skipped = false;

constructor(dir: string, readonly name: string) {
this.directory = `${dir}/samples/${name}`;
this.folder = fs.readdirSync(this.directory);
}

check_dir({ required = [], allowed = required }: { allowed?: string[]; required?: string[] }) {
const unchecked = new Set(required);
const unknown = [];

loop: for (const fileName of this.folder) {
for (const name of unchecked) {
if ('*' === name[0] ? fileName.endsWith(name.slice(1)) : name === fileName) {
unchecked.delete(name);
continue loop;
}
}
for (const name of allowed) {
if ('*' === name[0] ? fileName.endsWith(name.slice(1)) : name === fileName) {
continue loop;
}
}
unknown.push(fileName);
}
for (const name of allowed) {
if ('*' === name[0] ? fileName.endsWith(name.slice(1)) : name === fileName) {
continue loop;

if (unknown.length) {
const errors =
unknown.map((name) => `Unexpected file "${name}"`).join('\n') +
`\nat ${this.directory}`;
if (process.env.CI) {
throw new Error('\n' + errors);
} else {
after(() => {
console.log(errors);
});
}
}
unknown.push(fileName);

if (unchecked.size) {
throw new Error(
`Expected file${unchecked.size === 1 ? '' : 's'} ${[...unchecked]
.map((str) => `"${str}"`)
.join(', ')} in "${this.directory}"`
);
}
}
if (unknown.length !== 0) {
after(() => {
for (const name of unknown) {
const msg = `Unexpected file ${path.split('/').slice(-1)}/${name}`;
if (process.env.CI) {
throw new Error(msg);
} else {
console.info(msg);
}

it(fn: () => void) {
let _it = it;

if (this.name.startsWith('.')) {
_it = it.skip as TestFunction;
} else if (this.name.endsWith('.solo')) {
_it = it.only as TestFunction;
}

const sample = this;

_it(this.name, function () {
try {
fn();
if (sample.skipped) this.skip();
} catch (err) {
if (sample.skipped) this.skip();
throw err;
}
});
}
if (unchecked.size !== 0) {
throw new Error(
`Expected file(s) ${[...unchecked].map((str) => `"${str}"`).join(', ')} in ${path}`
);

has(file: string) {
return this.folder.includes(file);
}

get(file: string) {
return readFileSync(`${this.directory}/${file}`);
}

generate(fileName: string, content: string) {
const path = `${this.directory}/${fileName}`;
if (process.env.CI) {
throw new Error(`Forgot to generate expected sample result at "${path}"`);
}
after(() => {
fs.writeFileSync(path, content);
console.info(`(generated) ${this.name}/${fileName}`);
});
this.skipped = true;
}

eval(fileName: string, ...args: any[]) {
const fn = require(`${this.directory}/${fileName}`);
fn(...args);
}
}

export function test_samples(dir, transform, tsx) {
for (const testName of fs.readdirSync(`${dir}/samples`)) {
const path = `${dir}/samples/${testName}`;
const expected_path = `${path}/expected.${tsx}`;
const has_expected = fs.existsSync(expected_path);
const solo = testName.endsWith('.solo');
const skip = testName.startsWith('.');
check_dir(path, {
type TransformSampleFn = (
input: string,
config: {
fileName: string;
sampleName: string;
emitOnTemplateError: boolean;
}
) => ReturnType<typeof htmlx2jsx | typeof svelte2tsx>;

export function test_samples(dir: string, transform: TransformSampleFn, tsx: 'jsx' | 'tsx') {
for (const sample of each_sample(dir)) {
const svelteFile = sample.folder.find((f) => f.endsWith('.svelte'));

sample.check_dir({
required: ['*.svelte'],
allowed: ['expected.js', `expected.${tsx}`, 'test.js']
});
(skip ? it.skip : solo ? it.only : it)(testName, function () {
const testJsPath = `${path}/test.js`;
if (fs.existsSync(testJsPath)) {
const test = require(testJsPath);
test();

const shouldGenerateExpected = !sample.has(`expected.${tsx}`);

sample.it(function () {
if (sample.has('test.js')) {
sample.eval('test.js');
return;
}
const input = sample.get(svelteFile);
const config = {
fileName: svelteFile,
sampleName: sample.name,
emitOnTemplateError: false
};

const { filename, content } = get_input_content(path);
const output = transform(content, testName, filename);
if (!has_expected) {
after(() => {
fs.writeFileSync(expected_path, output.code);
console.info(`Generated ${testName}/expected.${tsx}`);
});
this.skip();
const output = transform(input, config);

if (shouldGenerateExpected) {
sample.generate(`expected.${tsx}`, output.code);
} else {
assert.strictEqual(output.code, readFileSync(expected_path));
assert.strictEqual(output.code, sample.get(`expected.${tsx}`));
}
if (fs.existsSync(`${path}/expected.js`)) {
const run = require(`${path}/expected.js`);
run(output);

if (sample.has('expected.js')) {
sample.eval('expected.js', output);
}
});
}
}

export function* each_sample(dir: string) {
for (const name of fs.readdirSync(`${dir}/samples`)) {
yield new Sample(dir, name);
}
}

/**
*
* @param {string} dirPath
Expand Down
9 changes: 5 additions & 4 deletions packages/svelte2tsx/test/svelte2tsx/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ import { test_samples } from '../helpers';
describe('svelte2tsx', () => {
test_samples(
__dirname,
(input, testName, filename) => {
(input, { sampleName, fileName, emitOnTemplateError }) => {
return svelte2tsx(input, {
strictMode: testName.includes('strictMode'),
isTsFile: testName.startsWith('ts-'),
filename
strictMode: sampleName.includes('strictMode'),
isTsFile: sampleName.startsWith('ts-'),
filename: fileName,
emitOnTemplateError
});
},
'tsx'
Expand Down
1 change: 1 addition & 0 deletions packages/svelte2tsx/test/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"compilerOptions": {
"types": ["@types/node", "@types/mocha"],
"target": "esnext",
"module": "commonjs",
"moduleResolution": "node",
Expand Down