Skip to content

Commit

Permalink
other: Added basic cast-or-convert tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Luna-Klatzer committed Nov 30, 2024
1 parent 8a3edb8 commit 56e430b
Show file tree
Hide file tree
Showing 7 changed files with 204 additions and 20 deletions.
178 changes: 178 additions & 0 deletions test/module/core/core-functionality/cast-or-convert.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
import type { KipperCompileResult } from "@kipper/core";
import { assert } from "chai";
import * as ts from "typescript";
import { ScriptTarget } from "typescript";
import { compiler, defaultTarget } from ".";
import { testPrintOutput } from "..";

describe("Cast-or-Convert", () => {
describe("as", () => {
it("should convert a value from EXP to T", async () => {
const fileContent = `
var x: str = "123.0";
var y: num = x as num;
print(y);
`;
const instance: KipperCompileResult = await compiler.compile(fileContent, { target: defaultTarget });

assert.isDefined(instance.programCtx);
assert.deepEqual(instance.programCtx?.errors, [], "Expected no compilation errors");

const code = instance.write();
assert.include(code, 'let x: string = "123.0";', "Invalid TypeScript code (Expected different output)");
assert.include(
code,
"let y: number = __kipper.strToNum(x);",
"Invalid TypeScript code (Expected different output)",
);

const jsCode = ts.transpile(code, { target: ScriptTarget.ES2015 });
testPrintOutput((message: any) => assert.equal(message, 123, "Expected different output"), jsCode);
});
});

describe("cast as", () => {
describe("should cast a value from EXP to T and raise no type error", () => {
it("T cast as T", async () => {
const fileContent = `
var x: num = 123;
var y: num = x cast as num;
print(y);
`;
const instance: KipperCompileResult = await compiler.compile(fileContent, { target: defaultTarget });

assert.isDefined(instance.programCtx);
assert.deepEqual(instance.programCtx?.errors, [], "Expected no compilation errors");

const code = instance.write();
assert.include(code, "let x: number = 123;", "Invalid TypeScript code (Expected different output)");
assert.include(code, "let y: number = x as number;", "Invalid TypeScript code (Expected different output)");

const jsCode = ts.transpile(code, { target: ScriptTarget.ES2015 });
testPrintOutput((message: any) => assert.equal(message, 123, "Expected different output"), jsCode);
});

it("class instance cast as obj", async () => {
const fileContent = `
class Test { x: num; constructor() { this.x = 1; } }
var x: Test = new Test();
var y: obj = x cast as obj;
print(y);
`;
const instance: KipperCompileResult = await compiler.compile(fileContent, { target: defaultTarget });

assert.isDefined(instance.programCtx);
assert.deepEqual(instance.programCtx?.errors, [], "Expected no compilation errors");

const code = instance.write();
assert.include(
code,
"class Test {\n x: number;\n constructor()\n {\n this.x = 1;\n }\n}",
"Invalid TypeScript code (Expected different output)",
);
assert.include(code, "let x: Test = new Test();", "Invalid TypeScript code (Expected different output)");
assert.include(code, "let y: object = x as object;", "Invalid TypeScript code (Expected different output)");

const jsCode = ts.transpile(code, { target: ScriptTarget.ES2015 });
testPrintOutput(
(message: any) => assert.deepEqual(message, { x: 1 }, "Expected different output"),
jsCode,
false,
);
});

it("interface cast as obj", async () => {
const fileContent = `
interface Test { x: num; }
var x: Test = { x: 1 };
var y: obj = x cast as obj;
print(y);
`;
const instance: KipperCompileResult = await compiler.compile(fileContent, { target: defaultTarget });

assert.isDefined(instance.programCtx);
assert.deepEqual(instance.programCtx?.errors, [], "Expected no compilation errors");

const code = instance.write();
assert.include(
code,
"interface Test {\n x: number;\n}",
"Invalid TypeScript code (Expected different output)",
);
assert.include(code, "let x: Test = {\n x: 1,\n}", "Invalid TypeScript code (Expected different output)");
assert.include(code, "let y: object = x as object;", "Invalid TypeScript code (Expected different output)");

const jsCode = ts.transpile(code, { target: ScriptTarget.ES2015 });
testPrintOutput(
(message: any) => assert.deepEqual(message, { x: 1 }, "Expected different output"),
jsCode,
false,
);
});

it("class instance cast as interface", async () => {
const fileContent = `
class Test { x: num; constructor() { this.x = 1; } }
interface Test2 { x: num; }
var x: Test = new Test();
var y: Test = x cast as Test2;
print(y);
`;
const instance: KipperCompileResult = await compiler.compile(fileContent, { target: defaultTarget });

assert.isDefined(instance.programCtx);
assert.deepEqual(instance.programCtx?.errors, [], "Expected no compilation errors");

const code = instance.write();
assert.include(
code,
"class Test {\n x: number;\n constructor()\n {\n this.x = 1;\n }\n}",
"Invalid TypeScript code (Expected different output)",
);
assert.include(
code,
"interface Test2 {\n x: number;\n}",
"Invalid TypeScript code (Expected different output)",
);
assert.include(code, "let x: Test = new Test();", "Invalid TypeScript code (Expected different output)");
assert.include(code, "let y: Test = x as Test2;", "Invalid TypeScript code (Expected different output)");
});

it("interface cast as interface", async () => {
const fileContent = `
interface X { x: num; }
interface Y { x: num; y: num; }
var y: Y = { x: 1, y: 2 };
var x: X = y cast as X;
print(x);
`;
const instance: KipperCompileResult = await compiler.compile(fileContent, { target: defaultTarget });

assert.isDefined(instance.programCtx);
assert.deepEqual(instance.programCtx?.errors, [], "Expected no compilation errors");

const code = instance.write();
assert.include(code, "interface X {\n x: number;\n}", "Invalid TypeScript code (Expected different output)");
assert.include(
code,
"interface Y {\n x: number;\n y: number;\n}",
"Invalid TypeScript code (Expected different output)",
);
assert.include(
code,
"let y: Y = {\n x: 1,\n y: 2,\n};",
"Invalid TypeScript code (Expected different output)",
);
assert.include(code, "let x: X = y as X;", "Invalid TypeScript code (Expected different output)");
});
});
});

describe("force as", () => {
// TODO!
});

describe("try as", () => {
// TODO!
});
});
4 changes: 2 additions & 2 deletions test/module/core/core-functionality/comment.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ describe("Comment", () => {
assert.isDefined(instance.programCtx);
assert.deepEqual(instance.programCtx?.errors, [], "Expected no compilation errors");
assert.include(instance.write(), "let x: number = 5;", "Expected variable declaration to be present in output");
assert.include(instance.write(), '__kipper.print("");', "Expected print call to be present in output");
assert.include(instance.write(), '__kipper.print("");', "Expected print to be present in output");
});

it("Multi line", async () => {
Expand All @@ -20,6 +20,6 @@ describe("Comment", () => {
assert.isDefined(instance.programCtx);
assert.deepEqual(instance.programCtx?.errors, [], "Expected no compilation errors");
assert.include(instance.write(), "let x: number = 5;", "Expected variable declaration to be present in output");
assert.include(instance.write(), '__kipper.print("");', "Expected print call to be present in output");
assert.include(instance.write(), '__kipper.print("");', "Expected print to be present in output");
});
});
12 changes: 6 additions & 6 deletions test/module/core/core-functionality/comparisons.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { testPrintOutput } from "..";

describe("Comparisons", () => {
it("==", async () => {
const fileContent = 'var x: num = 4;\nif (x == 4) call print("Works");';
const fileContent = 'var x: num = 4;\nif (x == 4) print("Works");';
const instance: KipperCompileResult = await compiler.compile(fileContent, { target: defaultTarget });

assert.isDefined(instance.programCtx);
Expand All @@ -26,7 +26,7 @@ describe("Comparisons", () => {
});

it("!=", async () => {
const fileContent = 'var x: num = 4;\nif (x != 5) call print("Works");';
const fileContent = 'var x: num = 4;\nif (x != 5) print("Works");';
const instance: KipperCompileResult = await compiler.compile(fileContent, { target: defaultTarget });

assert.isDefined(instance.programCtx);
Expand All @@ -44,7 +44,7 @@ describe("Comparisons", () => {
});

it("<", async () => {
const fileContent = 'var x: num = 4;\nif (x < 5) call print("Works");';
const fileContent = 'var x: num = 4;\nif (x < 5) print("Works");';
const instance: KipperCompileResult = await compiler.compile(fileContent, { target: defaultTarget });

assert.isDefined(instance.programCtx);
Expand All @@ -62,7 +62,7 @@ describe("Comparisons", () => {
});

it("<=", async () => {
const fileContent = 'var x: num = 4;\nif (x <= 5) call print("Works");';
const fileContent = 'var x: num = 4;\nif (x <= 5) print("Works");';
const instance: KipperCompileResult = await compiler.compile(fileContent, { target: defaultTarget });

assert.isDefined(instance.programCtx);
Expand All @@ -80,7 +80,7 @@ describe("Comparisons", () => {
});

it(">", async () => {
const fileContent = 'var x: num = 5;\nif (x > 4) call print("Works");';
const fileContent = 'var x: num = 5;\nif (x > 4) print("Works");';
const instance: KipperCompileResult = await compiler.compile(fileContent, { target: defaultTarget });

assert.isDefined(instance.programCtx);
Expand All @@ -98,7 +98,7 @@ describe("Comparisons", () => {
});

it(">=", async () => {
const fileContent = 'var x: num = 5;\nif (x >= 4) call print("Works");';
const fileContent = 'var x: num = 5;\nif (x >= 4) print("Works");';
const instance: KipperCompileResult = await compiler.compile(fileContent, { target: defaultTarget });

assert.isDefined(instance.programCtx);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ describe("Expression Statements", () => {
});

it("three expressions", async () => {
const fileContent = 'call print("x"), call print("y"), call print("z");';
const fileContent = 'print("x"), print("y"), print("z");';
const instance: KipperCompileResult = await compiler.compile(fileContent, { target: defaultTarget });

assert.isDefined(instance.programCtx);
Expand Down
2 changes: 1 addition & 1 deletion test/module/core/core-functionality/functions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ describe("Functions", () => {
});

it("Call", async () => {
const fileContent = 'def test() -> void { call print("Works"); return; }';
const fileContent = 'def test() -> void { print("Works"); return; }';
const instance: KipperCompileResult = await compiler.compile(fileContent, { target: defaultTarget });

assert.isDefined(instance.programCtx);
Expand Down
16 changes: 8 additions & 8 deletions test/module/core/core-functionality/logical-expressions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { testPrintOutput } from "..";
describe("Logical expressions", () => {
describe("Logical AND", () => {
it("true && true", async () => {
const fileContent = 'var x: num = 4;\nif (x > 3 && x < 5) { call print("Works"); }';
const fileContent = 'var x: num = 4;\nif (x > 3 && x < 5) { print("Works"); }';
const instance: KipperCompileResult = await compiler.compile(fileContent, { target: defaultTarget });

assert.isDefined(instance.programCtx);
Expand All @@ -35,7 +35,7 @@ describe("Logical expressions", () => {
});

it("true && false", async () => {
const fileContent = 'var x: num = 4;\nif (x > 3 && x < 2) { call print("Works"); }';
const fileContent = 'var x: num = 4;\nif (x > 3 && x < 2) { print("Works"); }';
const instance: KipperCompileResult = await compiler.compile(fileContent, { target: defaultTarget });

assert.isDefined(instance.programCtx);
Expand All @@ -53,7 +53,7 @@ describe("Logical expressions", () => {
});

it("false && true", async () => {
const fileContent = 'var x: num = 4;\nif (x > 5 && x < 3) { call print("Works"); }';
const fileContent = 'var x: num = 4;\nif (x > 5 && x < 3) { print("Works"); }';
const instance: KipperCompileResult = await compiler.compile(fileContent, { target: defaultTarget });

assert.isDefined(instance.programCtx);
Expand All @@ -71,7 +71,7 @@ describe("Logical expressions", () => {
});

it("false && false", async () => {
const fileContent = 'var x: num = 4;\nif (x > 5 && x < 8) { call print("Works"); }';
const fileContent = 'var x: num = 4;\nif (x > 5 && x < 8) { print("Works"); }';
const instance: KipperCompileResult = await compiler.compile(fileContent, { target: defaultTarget });

assert.isDefined(instance.programCtx);
Expand All @@ -91,7 +91,7 @@ describe("Logical expressions", () => {

describe("Logical OR", () => {
it("true || true", async () => {
const fileContent = 'var x: num = 4;\nif (x > 3 || x < 5) { call print("Works"); }';
const fileContent = 'var x: num = 4;\nif (x > 3 || x < 5) { print("Works"); }';
const instance: KipperCompileResult = await compiler.compile(fileContent, { target: defaultTarget });

assert.isDefined(instance.programCtx);
Expand All @@ -109,7 +109,7 @@ describe("Logical expressions", () => {
});

it("true || false", async () => {
const fileContent = 'var x: num = 4;\nif (x > 3 || x < 2) { call print("Works"); }';
const fileContent = 'var x: num = 4;\nif (x > 3 || x < 2) { print("Works"); }';
const instance: KipperCompileResult = await compiler.compile(fileContent, { target: defaultTarget });

assert.isDefined(instance.programCtx);
Expand All @@ -127,7 +127,7 @@ describe("Logical expressions", () => {
});

it("false || true", async () => {
const fileContent = 'var x: num = 4;\nif (x > 5 || x < 3) { call print("Works"); }';
const fileContent = 'var x: num = 4;\nif (x > 5 || x < 3) { print("Works"); }';
const instance: KipperCompileResult = await compiler.compile(fileContent, { target: defaultTarget });

assert.isDefined(instance.programCtx);
Expand All @@ -145,7 +145,7 @@ describe("Logical expressions", () => {
});

it("false || false", async () => {
const fileContent = 'var x: num = 4;\nif (x > 5 || x > 8) { call print("Works"); }';
const fileContent = 'var x: num = 4;\nif (x > 5 || x > 8) { print("Works"); }';
const instance: KipperCompileResult = await compiler.compile(fileContent, { target: defaultTarget });

assert.isDefined(instance.programCtx);
Expand Down
10 changes: 8 additions & 2 deletions test/module/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,16 @@
* assert the output and throw an error if the output is invalid.
* @param jsProgram The program that was compiled to JavaScript that should be evaluated. This program should contain a
* translated 'print' function call.
* @param forceString Is per default true and will enforce that the output is a string. If set to false, the output will
* be the raw value and can therefore be any type.
*/
export function testPrintOutput(newConsoleLog: (message: any) => void, jsProgram: string): void {
export function testPrintOutput(
newConsoleLog: (message: any) => void,
jsProgram: string,
forceString: boolean = true,
): void {
const oldConsoleLog = console.log;
console.log = (v: any) => newConsoleLog(String(v));
console.log = (v: any) => newConsoleLog(forceString ? String(v) : v);
eval(jsProgram); // Eval the program, which should call the 'print' function.
console.log = oldConsoleLog;
}

0 comments on commit 56e430b

Please sign in to comment.