def test_lookup_from_inner_env(): """The `extend` function returns a new environment extended with more bindings.""" env = Environment({"foo": 42}) env = env.extend({"bar": True}) assert_equals(42, env.lookup("foo")) assert_equals(True, env.lookup("bar"))
def test_lookup_on_missing_raises_exception(): """When looking up an undefined symbol, an error should be raised. The error message should contain the relevant symbol, and inform that it has not been defined.""" with assert_raises_regexp(LispError, "my-missing-var"): empty_env = Environment() empty_env.lookup("my-missing-var")
def test_extend_returns_new_environment(): """The extend method should create a new environment, leaving the old one unchanged.""" env = Environment({"foo": 1}) extended = env.extend({"foo": 2}) assert_equals(1, env.lookup("foo")) assert_equals(2, extended.lookup("foo"))
def test_lookup_deeply_nested_var(): """Extending overwrites old bindings to the same variable name.""" env = Environment({ "a": 1 }).extend({ "b": 2 }).extend({ "c": 3 }).extend({"foo": 100}) assert_equals(100, env.lookup("foo"))
def test_define(): """Test of simple define statement. The `define` form is used to define new bindings in the environment. A `define` call should result in a change in the environment. What you return from evaluating the definition is not important (although it affects what is printed in the REPL).""" env = Environment() evaluate(parse("(define x 1000)"), env) assert_equals(1000, env.lookup("x"))
def test_calling_very_simple_function_in_environment(): """A call to a symbol corresponds to a call to its value in the environment. When a symbol is the first element of the AST list, it is resolved to its value in the environment (which should be a function closure). An AST with the variables replaced with its value should then be evaluated instead.""" env = Environment() evaluate(parse("(define add (lambda (x y) (+ x y)))"), env) assert_is_instance(env.lookup("add"), Closure) result = evaluate(parse("(add 1 2)"), env) assert_equals(3, result)
def test_set_changes_environment_in_place(): """When calling `set` the environment should be updated""" env = Environment() env.set("foo", 2) assert_equals(2, env.lookup("foo"))
def test_simple_lookup(): """An environment should store variables and provide lookup.""" env = Environment({"var": 42}) assert_equals(42, env.lookup("var"))