def ns(self) -> Namespace: ns_sym = sym.symbol("test") ns = Namespace(ns_sym) str_ns_alias = sym.symbol("basilisp.string") join_sym = sym.symbol("join") chars_sym = sym.symbol("chars") str_ns = Namespace(str_ns_alias) str_ns.intern(join_sym, Var(ns, join_sym)) str_ns.intern( chars_sym, Var(ns, chars_sym, meta=lmap.map({kw.keyword("private"): True}))) ns.add_alias(str_ns, str_ns_alias) str_alias = sym.symbol("str") ns.add_alias(Namespace(str_alias), str_alias) str_sym = sym.symbol("str") ns.intern(str_sym, Var(ns, str_sym)) is_string_sym = sym.symbol("string?") ns.intern(is_string_sym, Var(ns, is_string_sym)) time_sym = sym.symbol("time") time_alias = sym.symbol("py-time") ns.add_import(time_sym, __import__("time"), time_alias) core_ns = Namespace(sym.symbol("basilisp.core")) map_alias = sym.symbol("map") ns.add_refer(map_alias, Var(core_ns, map_alias)) return ns
def test_find_in_ns( ns_sym: sym.Symbol, var_name: sym.Symbol, intern_val, ): v = Var.intern(ns_sym, var_name, intern_val) v_in_ns = Var.find_in_ns(ns_sym, var_name) assert v == v_in_ns
def test_find( ns_sym: sym.Symbol, var_name: sym.Symbol, intern_val, ): v = Var.intern(ns_sym, var_name, intern_val) ns_qualified_sym = sym.symbol(var_name.name, ns=ns_sym.name) v_in_ns = Var.find(ns_qualified_sym) assert v == v_in_ns
def test_find_safe( ns_sym: sym.Symbol, var_name: sym.Symbol, intern_val, ): v = Var.intern(ns_sym, var_name, intern_val) ns_qualified_sym = sym.symbol(var_name.name, ns=ns_sym.name) v_in_ns = Var.find_safe(ns_qualified_sym) assert v == v_in_ns with pytest.raises(RuntimeException): Var.find_safe(sym.symbol("some-other-var", ns="doesnt.matter"))
def test_cannot_refer_private(ns_cache: atom.Atom[NamespaceMap]): ns1 = get_or_create_ns(sym.symbol("ns1")) var_sym, var_val = sym.symbol("useful-value"), "cool string" var = Var(ns1, var_sym, meta=lmap.map({kw.keyword("private"): True})) var.set_value(var_val) ns1.intern(var_sym, var) ns2 = get_or_create_ns(sym.symbol("ns2")) ns2.add_refer(var_sym, var) assert None is ns2.get_refer(var_sym) assert None is ns2.find(var_sym)
def test_refer(ns_cache: atom.Atom[NamespaceMap]): ns1 = get_or_create_ns(sym.symbol("ns1")) var_sym, var_val = sym.symbol("useful-value"), "cool string" var = Var(ns1, var_sym) var.set_value(var_val) ns1.intern(var_sym, var) ns2 = get_or_create_ns(sym.symbol("ns2")) ns2.add_refer(var_sym, var) assert var is ns2.get_refer(var_sym) assert var_val == ns2.find(var_sym).value
def test_unmap(ns_cache: atom.Atom[NamespaceMap]): ns = get_or_create_ns(sym.symbol("ns1")) var_sym = sym.symbol("useful-value") var_val = "cool string" var = Var(ns, var_sym) var.set_value(var_val) ns.intern(var_sym, var) assert var is ns.find(var_sym) assert var_val == ns.find(var_sym).value ns.unmap(var_sym) assert None is ns.find(var_sym)
def test_dynamic_unbound( ns_sym: sym.Symbol, var_name: sym.Symbol, ): v = Var.intern_unbound(ns_sym, var_name, dynamic=True) assert isinstance(v, Var) assert ns_sym.name == v.ns.name assert var_name == v.name assert not v.is_bound assert v.dynamic assert not v.is_thread_bound assert Unbound(v) == v.root assert Unbound(v) == v.value assert Unbound(v) == v.deref() new_val = kw.keyword("new-val") try: v.push_bindings(new_val) assert v.is_bound assert v.dynamic assert v.is_thread_bound assert Unbound(v) == v.root assert new_val == v.value assert new_val == v.deref() finally: v.pop_bindings() assert not v.is_bound ns = get_or_create_ns(ns_sym) assert None is not ns assert ns.find(var_name) == v
def test_public_var( ns_sym: sym.Symbol, var_name: sym.Symbol, intern_val, ): v = Var.intern(ns_sym, var_name, intern_val) assert not v.is_private
def test_var_watchers(ns_sym: sym.Symbol, var_name: sym.Symbol): v = Var.intern(ns_sym, var_name, 0) assert v is v.remove_watch("nonexistent-watch") watcher1_key = kw.keyword("watcher-the-first") watcher1_vals = [] def watcher1(k, ref, old, new): assert watcher1_key is k assert v is ref watcher1_vals.append((old, new)) v.add_watch(watcher1_key, watcher1) v.alter_root(lambda v: v * 2) # == 0 v.bind_root(4) # == 4 watcher2_key = kw.keyword("watcher-the-second") watcher2_vals = [] def watcher2(k, ref, old, new): assert watcher2_key is k assert v is ref watcher2_vals.append((old, new)) v.add_watch(watcher2_key, watcher2) v.alter_root(lambda v: v * 2) # == 8 v.remove_watch(watcher1_key) v.bind_root(10) # == 10 v.alter_root(lambda v: "a" * v) # == "aaaaaaaaaa" assert [(0, 0), (0, 4), (4, 8)] == watcher1_vals assert [(4, 8), (8, 10), (10, "aaaaaaaaaa")] == watcher2_vals
def test_var_validators(ns_sym: sym.Symbol, var_name: sym.Symbol): v = Var.intern(ns_sym, var_name, 0) even_validator = lambda i: isinstance(i, int) and i % 2 == 0 v.set_validator(even_validator) assert even_validator == v.get_validator() with pytest.raises(ExceptionInfo): v.bind_root(1) with pytest.raises(ExceptionInfo): v.alter_root(lambda i: i + 1) assert 0 == v.root v.bind_root(2) v.set_validator() assert None is v.get_validator() v.alter_root(lambda i: i + 1) assert 3 == v.root with pytest.raises(ExceptionInfo): v.set_validator(even_validator) odd_validator = lambda i: isinstance(i, int) and i % 2 == 1 v.set_validator(odd_validator) with pytest.raises(ExceptionInfo): v.bind_root(2)
def test_private_var( ns_sym: sym.Symbol, var_name: sym.Symbol, intern_val, ): v = Var.intern(ns_sym, var_name, intern_val, meta=lmap.map({kw.keyword("private"): True})) assert v.is_private
def test_var_validators_do_fire_for_thread_local(ns_sym: sym.Symbol, var_name: sym.Symbol): v = Var.intern(ns_sym, var_name, 0, dynamic=True) even_validator = lambda i: isinstance(i, int) and i % 2 == 0 v.set_validator(even_validator) with pytest.raises(ExceptionInfo): v.set_value(5) v.set_value(4) assert 4 == v.value
def test_alter_var_meta( ns_sym: sym.Symbol, var_name: sym.Symbol, intern_val, ): v = Var.intern(ns_sym, var_name, intern_val) assert v.meta is None v.alter_meta(assoc, "type", sym.symbol("str")) assert v.meta == lmap.m(type=sym.symbol("str")) v.alter_meta(assoc, "tag", kw.keyword("async")) assert v.meta == lmap.m(type=sym.symbol("str"), tag=kw.keyword("async"))
def test_reset_var_meta( ns_sym: sym.Symbol, var_name: sym.Symbol, intern_val, ): v = Var.intern(ns_sym, var_name, intern_val) assert v.meta is None v.reset_meta(lmap.map({"type": sym.symbol("str")})) assert v.meta == lmap.m(type=sym.symbol("str")) v.reset_meta(lmap.m(tag=kw.keyword("async"))) assert v.meta == lmap.m(tag=kw.keyword("async"))
def test_intern( ns_sym: sym.Symbol, var_name: sym.Symbol, intern_val, ): meta = lmap.map({kw.keyword("hello"): "there"}) v = Var.intern(ns_sym, var_name, intern_val, meta=meta) assert isinstance(v, Var) assert ns_sym.name == v.ns.name assert var_name == v.name assert v.is_bound assert not v.dynamic assert not v.is_thread_bound assert intern_val == v.root assert intern_val == v.value assert intern_val == v.deref() assert meta == v.meta ns = get_or_create_ns(ns_sym) assert None is not ns assert ns.find(var_name) == v # Check that attempting to re-intern the Var will overwrite meta and dynamic new_meta = lmap.map({kw.keyword("general"): "kenobi"}) new_value = kw.keyword("new-value") re_v = Var.intern(ns_sym, var_name, new_value, dynamic=True, meta=new_meta) assert v is re_v assert ns_sym.name == v.ns.name assert var_name == v.name assert v.is_bound assert v.dynamic assert not v.is_thread_bound assert new_value == v.root assert new_value == v.value assert new_value == v.deref() assert new_meta == v.meta
def test_refer_does_not_shadow_intern(ns_cache: atom.Atom[NamespaceMap]): ns1 = get_or_create_ns(sym.symbol("ns1")) var_sym = sym.symbol("useful-value") var_val1 = "cool string" var1 = Var(ns1, var_sym) var1.set_value(var_val1) ns1.intern(var_sym, var1) ns2 = get_or_create_ns(sym.symbol("ns2")) var_val2 = "lame string" var2 = Var(ns1, var_sym) var2.set_value(var_val2) ns2.intern(var_sym, var2) ns2.add_refer(var_sym, var1) assert var1 is ns2.get_refer(var_sym) assert var_val2 == ns2.find(var_sym).value
def test_intern_unbound( ns_sym: sym.Symbol, var_name: sym.Symbol, ): v = Var.intern_unbound(ns_sym, var_name) assert isinstance(v, Var) assert ns_sym.name == v.ns.name assert var_name == v.name assert not v.is_bound assert not v.dynamic assert not v.is_thread_bound assert Unbound(v) == v.root assert Unbound(v) == v.value assert Unbound(v) == v.deref() ns = get_or_create_ns(ns_sym) assert None is not ns assert ns.find(var_name) == v
def test_intern_does_not_overwrite(ns_cache: atom.Atom[NamespaceMap]): ns = get_or_create_ns(sym.symbol("ns1")) var_sym = sym.symbol("useful-value") var_val1 = "cool string" var1 = Var(ns, var_sym) var1.set_value(var_val1) ns.intern(var_sym, var1) var_val2 = "lame string" var2 = Var(ns, var_sym) var2.set_value(var_val2) ns.intern(var_sym, var2) assert var1 is ns.find(var_sym) assert var_val1 == ns.find(var_sym).value ns.intern(var_sym, var2, force=True) assert var2 is ns.find(var_sym) assert var_val2 == ns.find(var_sym).value
def test_var_bindings_are_noop_for_non_dynamic_var( ns_sym: sym.Symbol, var_name: sym.Symbol, intern_val, ): v = Var.intern(ns_sym, var_name, intern_val) assert v.is_bound assert not v.dynamic assert not v.is_thread_bound assert intern_val == v.root assert intern_val == v.value assert intern_val == v.deref() new_val = kw.keyword("new-val") new_val2 = kw.keyword("other-new-val") try: with pytest.raises(RuntimeException): v.push_bindings(new_val) assert v.is_bound assert not v.dynamic assert not v.is_thread_bound assert intern_val == v.root assert intern_val == v.value assert intern_val == v.deref() v.set_value(new_val2) assert v.is_bound assert not v.dynamic assert not v.is_thread_bound assert new_val2 == v.root assert new_val2 == v.value assert new_val2 == v.deref() finally: with pytest.raises(RuntimeException): v.pop_bindings() assert v.is_bound assert not v.dynamic assert not v.is_thread_bound assert new_val2 == v.root assert new_val2 == v.value assert new_val2 == v.deref()
def test_var_watchers_do_not_fire_for_thread_local(ns_sym: sym.Symbol, var_name: sym.Symbol): v = Var.intern(ns_sym, var_name, 0, dynamic=True) watcher_vals = [] def watcher(k, ref, old, new): assert "watcher" == k assert v is ref watcher_vals.append((old, new)) v.add_watch("watcher", watcher) v.set_value(10) assert not watcher_vals assert 10 == v.value v.alter_root(lambda i: i + 5) assert 5 == v.root assert [(0, 5)] == watcher_vals
def test_alter_var_root( ns_sym: sym.Symbol, var_name: sym.Symbol, intern_val, ): v = Var.intern(ns_sym, var_name, intern_val) new_root = kw.keyword("new-root") alter_args = (1, 2, 3) def alter_root(root, *args): assert intern_val == root assert alter_args == args return new_root v.alter_root(alter_root, *alter_args) assert new_root == v.root assert new_root == v.value assert new_root == v.deref()
def test_dynamic_var( ns_sym: sym.Symbol, var_name: sym.Symbol, intern_val, ): v = Var.intern(ns_sym, var_name, intern_val, dynamic=True) assert v.is_bound assert v.dynamic assert not v.is_thread_bound assert intern_val == v.root assert intern_val == v.value assert intern_val == v.deref() new_val = kw.keyword("new-val") new_val2 = kw.keyword("other-new-val") try: v.push_bindings(new_val) assert v.is_bound assert v.dynamic assert v.is_thread_bound assert intern_val == v.root assert new_val == v.value assert new_val == v.deref() v.set_value(new_val2) assert v.is_bound assert v.dynamic assert v.is_thread_bound assert intern_val == v.root assert new_val2 == v.value assert new_val2 == v.deref() finally: v.pop_bindings() assert v.is_bound assert v.dynamic assert not v.is_thread_bound assert intern_val == v.root assert intern_val == v.value assert intern_val == v.deref()
def test_alter_dynamic_var_root( ns_sym: sym.Symbol, var_name: sym.Symbol, intern_val, ): v = Var.intern(ns_sym, var_name, intern_val, dynamic=True) assert v.is_bound assert v.dynamic assert not v.is_thread_bound assert intern_val == v.root assert intern_val == v.value assert intern_val == v.deref() new_val = kw.keyword("new-val") new_root = kw.keyword("new-root") alter_args = (1, 2, 3) def alter_root(root, *args): assert intern_val == root assert alter_args == args return new_root try: v.push_bindings(new_val) v.alter_root(alter_root, *alter_args) assert v.is_bound assert v.dynamic assert v.is_thread_bound assert new_root == v.root assert new_val == v.value assert new_val == v.deref() finally: v.pop_bindings() assert v.is_bound assert v.dynamic assert not v.is_thread_bound assert new_root == v.root assert new_root == v.value assert new_root == v.deref()
def test_refer_all(ns_cache: atom.Atom[NamespaceMap]): ns1 = get_or_create_ns(sym.symbol("ns1")) var_sym1, var_val1 = sym.symbol("useful-value"), "cool string" var1 = Var(ns1, var_sym1) var1.set_value(var_val1) ns1.intern(var_sym1, var1) var_sym2, var_val2 = sym.symbol("private-value"), "private string" var2 = Var(ns1, var_sym2, meta=lmap.map({kw.keyword("private"): True})) var2.set_value(var_val2) ns1.intern(var_sym2, var2) var_sym3, var_val3 = sym.symbol("existing-value"), "interned string" var3 = Var(ns1, var_sym3) var3.set_value(var_val3) ns1.intern(var_sym3, var3) ns2 = get_or_create_ns(sym.symbol("ns2")) var_val4 = "some other value" var4 = Var(ns2, var_sym3) var4.set_value(var_val4) ns2.intern(var_sym3, var4) ns2.refer_all(ns1) assert var1 is ns2.get_refer(var_sym1) assert var1 is ns2.find(var_sym1) assert var_val1 == ns2.find(var_sym1).value assert None is ns2.get_refer(var_sym2) assert None is ns2.find(var_sym2) assert var3 is ns2.get_refer(var_sym3) assert var4 is ns2.find(var_sym3) assert var_val4 == ns2.find(var_sym3).value