Skip to content

Commit

Permalink
test: add test file for transform mode and feature testing
Browse files Browse the repository at this point in the history
  • Loading branch information
mertcanaltin committed Aug 12, 2024
1 parent 68fce06 commit c5bfca2
Show file tree
Hide file tree
Showing 2 changed files with 207 additions and 0 deletions.
20 changes: 20 additions & 0 deletions test/snapshots/transform.test.js.snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,23 @@ exports[`should perform transformation without source maps 1`] = `
exports[`should perform transformation without source maps and filename 1`] = `
"var Foo;\\n(function(Foo) {\\n Foo[Foo[\\"Bar\\"] = 7] = \\"Bar\\";\\n Foo[Foo[\\"Baz\\"] = 2] = \\"Baz\\";\\n})(Foo || (Foo = {}));\\nx = 7;\\n"
`;

exports[`should transform TypeScript class decorators with multiple decorators 1`] = `
"@sealed\\n@log\\nclass BugReport {\\n type = \\"report\\";\\n title;\\n constructor(t){\\n this.title = t;\\n }\\n}\\nfunction sealed(constructor) {\\n Object.seal(constructor);\\n Object.seal(constructor.prototype);\\n}\\nfunction log(constructor) {\\n console.log(\\"Creating instance of\\", constructor.name);\\n}\\nconst report = new BugReport(\\"Test\\");\\n"
`;

exports[`should transform TypeScript class fields 1`] = `
"class Counter {\\n count = 0;\\n increment() {\\n this.count++;\\n }\\n}\\n"
`;

exports[`should transform TypeScript namespaces with additional functionality 1`] = `
"var Validation;\\n(function(Validation) {\\n const lettersRegexp = /^[A-Za-z]+$/;\\n class LettersOnlyValidator {\\n isAcceptable(s) {\\n return lettersRegexp.test(s);\\n }\\n static createValidator() {\\n return new LettersOnlyValidator();\\n }\\n }\\n Validation.LettersOnlyValidator = LettersOnlyValidator;\\n})(Validation || (Validation = {}));\\nconst validator = Validation.LettersOnlyValidator.createValidator();\\nconst isValid = validator.isAcceptable(\\"test\\");\\n// Exporting these for VM context\\nglobalThis.validator = validator;\\nglobalThis.isValid = isValid;\\n"
`;

exports[`should transform TypeScript private class fields 1`] = `
"class Counter {\\n #count = 0;\\n increment() {\\n this.#count++;\\n }\\n getCount() {\\n return this.#count;\\n }\\n}\\n"
`;

exports[`should transform TypeScript type annotations and type guards 1`] = `
"function isString(value) {\\n return typeof value === 'string';\\n}\\n"
`;
187 changes: 187 additions & 0 deletions test/transform.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,190 @@ test("should perform transformation with error", (t) => {
assert.strictEqual(context.x, 7);
t.assert.snapshot(map);
});

test("should transform TypeScript class fields", (t) => {
const inputCode = `
class Counter {
count: number = 0;
increment() {
this.count++;
}
}
`;
const { code } = transformSync(inputCode, {
mode: "transform",
sourceMap: true,
});
t.assert.snapshot(code);

const context = { result: null };
vm.createContext(context);
vm.runInContext(
`
${code}
const counter = new Counter();
counter.increment();
result = counter.count;
`,
context,
);
assert.strictEqual(context.result, 1, "Counter should increment to 1");
});

test("should transform TypeScript private class fields", (t) => {
const inputCode = `
class Counter {
#count: number = 0;
increment() {
this.#count++;
}
getCount(): number {
return this.#count;
}
}
`;
const { code } = transformSync(inputCode, {
mode: "transform",
sourceMap: true,
});
t.assert.snapshot(code);

const context = { result: null };
vm.createContext(context);
vm.runInContext(
`
${code}
const counter = new Counter();
counter.increment();
result = counter.getCount();
`,
context,
);
assert.strictEqual(
context.result,
1,
"Counter private field should increment to 1",
);
});

test("should transform TypeScript type annotations and type guards", (t) => {
const inputCode = `
function isString(value: unknown): value is string {
return typeof value === 'string';
}
`;
const { code } = transformSync(inputCode, {
mode: "transform",
sourceMaps: true,
});
t.assert.snapshot(code);

const context = { result: null };
vm.createContext(context);
vm.runInContext(
`
${code}
const check = isString("hello");
result = check;
`,
context,
);
assert.strictEqual(
context.result,
true,
"Should recognize 'hello' as a string",
);
});

test("should transform TypeScript class decorators with multiple decorators", (t) => {
const inputCode = `
@sealed
@log
class BugReport {
type = "report";
title: string;
constructor(t: string) {
this.title = t;
}
}
function sealed(constructor: Function) {
Object.seal(constructor);
Object.seal(constructor.prototype);
}
function log(constructor: Function) {
console.log("Creating instance of", constructor.name);
}
const report = new BugReport("Test");
`;

const { code } = transformSync(inputCode, {
mode: "transform",
sourceMap: true,
});

t.assert.snapshot(code);

try {
const script = new vm.Script(code);
const context = vm.createContext({});
context.report = null;
script.runInContext(context);

assert.ok(context.report, "Report instance should exist");
assert.strictEqual(
context.report.type,
"report",
"Report type should be 'report'",
);
assert.strictEqual(
context.report.title,
"Test",
"Report title should be 'Test'",
);
} catch (err) {
console.error("Error executing script:", err);
}
});

test("should transform TypeScript namespaces with additional functionality", (t) => {
const inputCode = `
namespace Validation {
export interface StringValidator {
isAcceptable(s: string): boolean;
}
const lettersRegexp = /^[A-Za-z]+$/;
export class LettersOnlyValidator implements StringValidator {
isAcceptable(s: string) {
return lettersRegexp.test(s);
}
static createValidator(): LettersOnlyValidator {
return new LettersOnlyValidator();
}
}
}
const validator = Validation.LettersOnlyValidator.createValidator();
const isValid = validator.isAcceptable("test");
// Exporting these for VM context
(globalThis as any).validator = validator;
(globalThis as any).isValid = isValid;
`;

const { code } = transformSync(inputCode, {
mode: "transform",
sourceMap: true,
});

t.assert.snapshot(code);

const script = new vm.Script(code);
const context = vm.createContext({});
script.runInContext(context);

assert.ok(context.validator, "Validator instance should exist");
assert.strictEqual(context.isValid, true, "String should be valid");
});

0 comments on commit c5bfca2

Please sign in to comment.