Skip to content

Commit

Permalink
Add tests about the following:
Browse files Browse the repository at this point in the history
- Closing over of later variables
- Closing over method parameters
- Closed closure in functions
  • Loading branch information
melvic-ybanez committed Oct 28, 2023
1 parent b819604 commit bd5f2d7
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 21 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ If everything works correctly, your console should print a bunch of assertion re
[Success] Ducks should quack!
[Success] Denji should say 'Woof!'
[Success] Class properties should be updated
Ran 92 tests. Successful: 92. Failed: 0.
Ran 96 tests. Successful: 96. Failed: 0.
```
The tests themselves are written in Dry (while the `testDry` command is written in Scala). You can see the directory containing them here: https://github.com/melvic-ybanez/dry/tree/main/tests. All the files in that directory that start with `test_` and have the Dry extension will be picked up by the `testDry` command.

Expand Down
24 changes: 12 additions & 12 deletions tests/test_assignment.dry
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,21 @@ def test_associativity() {

// assignment is right-associative
a = b = c;
assert_equals("a is equal to c", a, c);
assert_equals("b is equal to c", b, c);
assert_equals("c is equal to c", c, c);
assert_equals("Leftmost equals rightmost", a, c);
assert_equals("Middle equals rightmost", b, c);
assert_equals("Rightmost equals rightmost", c, c);
}

def test_rhs() {
let a = "before";
let c = a = "after";

assert_equals("a = 'after'", a, "after");
assert_equals("c = 'after'", c, "after");
assert_equals("Middle gets the RHS value", a, "after");
assert_equals("Leftmost gets the RHS value", c, "after");
}

def test_lhs() {
assert_error("rhs should not be an undefined variable", Errors.UNDEFINED_VARIABLE,
assert_error("RHS should not be an undefined variable", Errors.UNDEFINED_VARIABLE,
lambda() { unknown = "what"; });
}

Expand All @@ -29,18 +29,18 @@ test_lhs();

// global
let a = "before";
assert_equals("a = 'before'", a, "before");
assert_equals("Global init value", a, "before");
a = "after";
assert_equals("a = 'after'", a, "after");
assert_equals("Global update value", a, "after");

// local
{
let a = "before";
assert_equals("a = 'before'", a, "before");
assert_equals("Local init value", a, "before");

a = "after";
assert_equals("a = 'after'", a, "after");
assert_equals("Local updated value", a, "after");

assert_equals("a = 'arg'", a = "arg", "arg");
assert_equals("a = 'arg'", a, "arg");
assert_equals("Assignment returned value", a = "arg", "arg");
assert_equals("Local updated via assignment", a, "arg");
}
63 changes: 55 additions & 8 deletions tests/test_closures.dry
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@ def test_assign_to_closure() {
{
let local = "local";
def f_() {
assert_equals("`local` should be 'local'", local, "local");
assert_equals("Capture var", local, "local");
local = "after f";
assert_equals("`local` should be 'after f'", local, "after f");
assert_equals("Updated captured var ", local, "after f");
}
f = f_;

def g_() {
assert_equals("`local` should be 'after f'", local, "after f");
assert_equals("Capture updated var", local, "after f");
local = "after g";
assert_equals("`local` should be 'after g'", local, "after g");
assert_equals("Update updated var", local, "after g");
}
g = g_;
}
Expand All @@ -33,25 +33,72 @@ def test_assign_to_shadowed_later() {

let a = "inner";
assign();
assert_equals("`a` should be 'inner'", a, "inner");
assert_equals("Var declared after closure", a, "inner");
}

assert_equals("`a` should be 'assigned'", a, "assigned");
assert_equals("Var updated due to closure", a, "assigned");
}

def test_close_over_function_param() {
let f;

def foo(param) {
def f_() {
assert_equals("Expected parameter value: 'param'", param, "param");
assert_equals("Close over function param", param, "param");
}
f = f_;
}
foo("param");
f();
}

// see the comment in the following source file for the explanation:
// https://github.com/munificent/craftinginterpreters/blob/master/test/closure/close_over_later_variable.lox
def test_close_over_later_variable() {
let a = "a";
let b = "b";

def g() {
assert_equals("Close over later var", b, "b");
assert_equals("Close over earlier var", a, "a");
}

g();
}

def test_close_over_method_param() {
let f;

class Foo {
def method(param) {
def f_() {
assert_equals("Close over method param", param, "param");
}
f = f_;
}
}

Foo().method("param");
f();
}

def test_closed_closure_in_function() {
let f;

{
let local = "local";
def f_() {
assert_equals("Closed closure in function", local, "local");
}
f = f_;
}

f();
}

test_assign_to_closure();
test_assign_to_shadowed_later();
test_close_over_function_param();
test_close_over_function_param();
test_close_over_later_variable();
test_close_over_method_param();
test_closed_closure_in_function();

0 comments on commit bd5f2d7

Please sign in to comment.