Skip to content

Closures: Added tests from the current closures PR #1393

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

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from 4 commits
Commits
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
10 changes: 10 additions & 0 deletions tests/compiler/closure-common-js-patterns.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"asc_flags": [
"--runtime full",
"--use ASC_RTRACE=1"
],
"stderr": [
"AS100: Not implemented: Closures",
"AS100: Not implemented: Closures"
]
}
183 changes: 183 additions & 0 deletions tests/compiler/closure-common-js-patterns.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
// NOTE torch2424 6/15/20: This test has a lot of errors skipped. Closures is currently a WIP

// Common use cases / concepts for closures, as covered in articles like:
// https://medium.com/@dis_is_patrick/practical-uses-for-closures-c65640ae7304
// https://stackoverflow.com/questions/2728278/what-is-a-practical-use-for-a-closure-in-javascript
// https://softwareengineering.stackexchange.com/questions/285941/why-would-a-program-use-a-closure
// https://medium.com/@prashantramnyc/what-is-an-iife-in-javascript-24baf0febf08

// Currently, IIFEs and simple Function Factories work
// But my advanced Function Factory Pub Sub, and weird function namespacing does not
// Due to runtime and/or compilation errors :)

// IIFE (Immediately Invoked function expressions)
// Used for encapsulating data usually

// Simple IIFE
let myData = ((): boolean => {
return true;
})();

assert(myData == true);

// Constructor IIFE?
// Don't know why someone wouldn't just use their class, but yeah

class IIFEReturn {
myBool: boolean
myFunc: (x: i32) => i32
}

let myInstanceThing = ((): IIFEReturn => {
return {
myBool: true,
myFunc: (x: i32) => {
return x + 1;
}
};
})();

assert(myInstanceThing.myBool == true);
assert(myInstanceThing.myFunc(24) == 25);

// Function Factories
// Closures that create specific functions

// Simple function that will change depending on input
type generatedFunc = () => i32;
let myFactory = (x: i32): generatedFunc => {
let myFunc = (): i32 => {
return 24 + x;
};

return myFunc;
};

let generatedPlusOne: generatedFunc = myFactory(1);
let generatedPlusTwo: generatedFunc = myFactory(2);

// For some reason, couldn't do
// Cannot invoke an expression whose type lacks a call signature. Type 'closure-common-js-patterns/myFactory' has no compatible call signatures.
// assert(myFactory(1)() == 25);
assert(generatedPlusOne() == 25);
assert(generatedPlusTwo() == 26);

// I often will use this for like Pub/Sub stuff

type SubFunc = () => void;
type UnSubFunc = () => void;
let subscriptions = new Array<SubFunc>();
let globalSubVar: i32 = 0;

function subscribe(funcToCallOnPub: SubFunc): UnSubFunc {
subscriptions.push(funcToCallOnPub);
return (): void => {
let funcIndex = subscriptions.indexOf(funcToCallOnPub);
subscriptions.splice(funcIndex, 1);
};
}

function publish(): void {
for(let i = 0; i < subscriptions.length; i++) {
// Can't call directly? Get a Type error
// ERROR TS2757: Type '() => void' has no call signatures.
// Noticed some other weird type errors if I don't declare the function type
// But I also am meh at typescripte signatures haha!
// subscriptions[i]();

let subFunc = subscriptions[i];
subFunc();
}
}

let plusOne = (): void => {
globalSubVar += 1;
};

let plusTwo = (): void => {
globalSubVar += 1;
};


let unsubPlusOne: () => void = subscribe(plusOne);
let unsubPlusTwo: () => void = subscribe(plusTwo);

assert(globalSubVar == 0);
assert(subscriptions.length == 2);

publish();

assert(globalSubVar == 3);
assert(subscriptions.length == 2);

unsubPlusOne();

assert(globalSubVar == 3);
assert(subscriptions.length == 1);

publish();

assert(globalSubVar == 5);
assert(subscriptions.length == 1);

unsubPlusTwo();

assert(globalSubVar == 5);
assert(subscriptions.length == 0);

publish();

assert(globalSubVar == 5);
assert(subscriptions.length == 0);


// TODO (torch2424 6/15/20): Uncomment this test once closures is fully implemented
/*

// Namespacing private functions
// Again, kind of weird, they should probably just make a class, but it's another interesting test

class Chunk {
totalSize: i32;
usedSize: i32;
write: (size: i32) => void;
}

let getChunk = (): Chunk => {
let chunk: Chunk = {
totalSize: 1024,
usedSize: 0,
write: (x: i32): void => {}
};

let growChunk = (): void => {
chunk.totalSize += 1024;
}

let allocateForChunk = (amount: i32): void => {
if (chunk.usedSize + amount <= chunk.totalSize) {
chunk.usedSize += amount;
} else {
// growChunk(chunk);
// allocateForChunk(chunk, amount);
}
}

chunk.write = (x: i32) => {
allocateForChunk(x);
}

return chunk;

}

let myChunk: Chunk = getChunk();

assert(myChunk.totalSize == 1024);
assert(myChunk.usedSize == 0);

myChunk.write(1025);

assert(myChunk.totalSize == 2048);
assert(myChunk.usedSize == 1025);
*/
Empty file.
9 changes: 9 additions & 0 deletions tests/compiler/closure-limitations-runtime.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"asc_flags": [
"--runtime full"
],
"stderr": [
"AS100: Not implemented: Closures"
],
"skipInstantiate": true
}
7 changes: 7 additions & 0 deletions tests/compiler/closure-limitations-runtime.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export function exportedClosureReturns(): (value: i32) => i32 {
var $local0 = 0;
return function inner(value: i32): i32 {
return $local0;
};
}
exportedClosureReturns();
Empty file.
11 changes: 11 additions & 0 deletions tests/compiler/closure-limitations.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"asc_flags": [
"--runtime none"
],
"stderr": [
"AS100: Not implemented: Closures",
"AS100: Not implemented: Closures",
"AS100: Not implemented: Closures",
"EOF"
]
}
22 changes: 22 additions & 0 deletions tests/compiler/closure-limitations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
function closureWrites(): (value: i32) => i32 {
var $local0 = 0;
return function inner(value: i32) {
$local0 = $local0 + 1;
return $local0;
};
}
closureWrites();

function inScopeNestedCalls(): (value: i32) => i32 {
var x = 0;
var f = (): i32 => {
return x;
};
var p = (value: i32): i32 => {
return f();
};
return p;
}
inScopeNestedCalls();

ERROR("EOF");
6 changes: 6 additions & 0 deletions tests/compiler/closure-passing-functions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"asc_flags": [
"--runtime full",
"--use ASC_RTRACE=1"
]
}
Loading