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_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_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_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_define():
    """Test of simple define statement.

    The `define` form is used to define new bindings in the environment."""

    env = Environment()
    evaluate(parse("(define x 1000)"), env)
    assert_equals(1000, env.lookup("x"))
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_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_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_simple_lookup():
    """An environment should store variables and provide lookup."""

    env = Environment({"var": 42})
    assert_equals(42, env.lookup("var"))
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"))