from toolz.utils import raises
from toolz.dicttoolz import merge, valmap, keymap, update_in, assoc


inc = lambda x: x + 1


def test_merge():
    assert merge({1: 1, 2: 2}, {3: 4}) == {1: 1, 2: 2, 3: 4}


def test_valmap():
    assert valmap(inc, {1: 1, 2: 2}) == {1: 2, 2: 3}


def test_keymap():
    assert keymap(inc, {1: 1, 2: 2}) == {2: 1, 3: 2}


def test_assoc():
    assert assoc({}, "a", 1) == {"a": 1}
    assert assoc({"a": 1}, "a", 3) == {"a": 3}
    assert assoc({"a": 1}, "b", 3) == {"a": 1, "b": 3}


def test_update_in():
    assert update_in({"a": 0}, ["a"], inc) == {"a": 1}
    assert update_in({"a": 0, "b": 1}, ["b"], str) == {"a": 0, "b": "1"}
    assert (update_in({"t": 1,
                       "v": {"a": 0}}, ["v", "a"], inc) ==
            {"t": 1, "v": {"a": 1}})
    # Handle missing element one deep:
    assert update_in({}, ["z"], str) == {"z": "None"}
    # Same semantics as Clojure, raises an error if going deeper than
    # one level into a dict which doesn't have the initial key:
    assert raises(AttributeError,
                  lambda: update_in({}, ["z", "q"], str))

@@ -505,24 +505,97 @@
 1, %22b%22: 3%7D%0A%0A
+    d = %7B'x': 1%7D%0A    oldd = d%0A    assoc(d, 'x', 2)%0A    assert d is oldd%0A%0A
 %0Adef test_up
@@ -1179,8 +1179,89 @@
 , str))%0A
+%0A    d = %7B'x': 1%7D%0A    oldd = d%0A    update_in(d, %5B'x'%5D, inc)%0A    assert d is oldd%0A

test immutability in assoc/update-in