diff --git a/test/snapshots/transform-decorator-namespace.test.js.snapshot b/test/snapshots/transform-decorator-namespace.test.js.snapshot deleted file mode 100644 index 5bb1cbe17..000000000 --- a/test/snapshots/transform-decorator-namespace.test.js.snapshot +++ /dev/null @@ -1,7 +0,0 @@ -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 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" -`; diff --git a/test/snapshots/transform-feature.test.js.snapshot b/test/snapshots/transform-feature.test.js.snapshot deleted file mode 100644 index 284c5bc5a..000000000 --- a/test/snapshots/transform-feature.test.js.snapshot +++ /dev/null @@ -1,11 +0,0 @@ -exports[`should transform TypeScript class fields 1`] = ` -"class Counter {\\n count = 0;\\n increment() {\\n this.count++;\\n }\\n}\\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" -`; diff --git a/test/snapshots/transform.test.js.snapshot b/test/snapshots/transform.test.js.snapshot index d3b585678..301f2ef4c 100644 --- a/test/snapshots/transform.test.js.snapshot +++ b/test/snapshots/transform.test.js.snapshot @@ -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" +`; diff --git a/test/transform-decorator-namespace.test.js b/test/transform-decorator-namespace.test.js deleted file mode 100644 index 3d7038738..000000000 --- a/test/transform-decorator-namespace.test.js +++ /dev/null @@ -1,106 +0,0 @@ -const { test, snapshot } = require("node:test"); -const assert = require("node:assert"); -const path = require("node:path"); -const vm = require("node:vm"); -const { transformSync } = require("../dist/index.js"); - -snapshot.setResolveSnapshotPath((testPath) => { - return path.join( - __dirname, - "snapshots", - `${path.basename(testPath)}.snapshot`, - ); -}); - -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"); -}); diff --git a/test/transform-feature.test.js b/test/transform-feature.test.js deleted file mode 100644 index 5e75f1910..000000000 --- a/test/transform-feature.test.js +++ /dev/null @@ -1,107 +0,0 @@ -const { test, snapshot } = require("node:test"); -const { transformSync } = require("../dist/index.js"); -const assert = require("node:assert"); -const path = require("node:path"); -const vm = require("node:vm"); - -snapshot.setResolveSnapshotPath((testPath) => { - return path.join( - __dirname, - "snapshots", - `${path.basename(testPath)}.snapshot`, - ); -}); - -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", - ); -}); diff --git a/test/transform.test.js b/test/transform.test.js index 5f7a32087..76d3c72f6 100644 --- a/test/transform.test.js +++ b/test/transform.test.js @@ -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"); +});