diff --git a/src/Internal/Tools/Hashdict.elm b/src/Internal/Tools/Hashdict.elm index b8be6a9..f2e4fdb 100644 --- a/src/Internal/Tools/Hashdict.elm +++ b/src/Internal/Tools/Hashdict.elm @@ -1,7 +1,7 @@ module Internal.Tools.Hashdict exposing ( Hashdict , empty, singleton, insert, remove, removeKey - , isEmpty, member, memberKey, get, size + , isEmpty, member, memberKey, get, size, isEqual , keys, values, toList, fromList , rehash, union , encode, decoder, softDecoder @@ -25,7 +25,7 @@ This allows you to store values based on an externally defined identifier. ## Query -@docs isEmpty, member, memberKey, get, size +@docs isEmpty, member, memberKey, get, size, isEqual ## Lists @@ -151,6 +151,14 @@ insert v (Hashdict h) = Hashdict { h | values = Dict.insert (h.hash v) v h.values } +{-| Since the Hashdict contains a hash function, the == operator does not work +simply. Instead, you should use the isEqual operator. +-} +isEqual : Hashdict a -> Hashdict a -> Bool +isEqual h1 h2 = + toList h1 == toList h2 + + {-| Determine if a hashdict is empty. -} isEmpty : Hashdict a -> Bool diff --git a/tests/Test/Tools/Hashdict.elm b/tests/Test/Tools/Hashdict.elm new file mode 100644 index 0000000..500503c --- /dev/null +++ b/tests/Test/Tools/Hashdict.elm @@ -0,0 +1,174 @@ +module Test.Tools.Hashdict exposing (..) + +import Expect +import Fuzz exposing (Fuzzer) +import Internal.Tools.Hashdict as Hashdict exposing (Hashdict) +import Internal.Values.Event as Event +import Json.Decode as D +import Json.Encode as E +import Test exposing (..) +import Test.Values.Event as TestEvent + + +fuzzer : (a -> String) -> Fuzzer a -> Fuzzer (Hashdict a) +fuzzer toHash fuz = + Fuzz.map (Hashdict.fromList toHash) (Fuzz.list fuz) + + +eventFuzzer : Fuzzer (Hashdict Event.Event) +eventFuzzer = + fuzzer .eventId TestEvent.fuzzer + + +suite : Test +suite = + describe "Hashdict" + [ describe "empty" + [ test "empty isEmpty" + (Hashdict.empty identity + |> Hashdict.isEmpty + |> Expect.equal True + |> always + ) + , fuzz TestEvent.fuzzer + "Nothing is member" + (\event -> + Hashdict.empty .eventId + |> Hashdict.member event + |> Expect.equal False + ) + , fuzz Fuzz.string + "No key is member" + (\key -> + Hashdict.empty identity + |> Hashdict.memberKey key + |> Expect.equal False + ) + , fuzz Fuzz.string + "Get gets Nothing" + (\key -> + Hashdict.empty identity + |> Hashdict.get key + |> Expect.equal Nothing + ) + , test "Size is zero" + (Hashdict.empty identity + |> Hashdict.size + |> Expect.equal 0 + |> always + ) + , test "No keys" + (Hashdict.empty identity + |> Hashdict.keys + |> Expect.equal [] + |> always + ) + , test "No values" + (Hashdict.empty identity + |> Hashdict.values + |> Expect.equal [] + |> always + ) + , test "To list is []" + (Hashdict.empty identity + |> Hashdict.toList + |> Expect.equal [] + |> always + ) + , test "From list is empty" + ([] + |> Hashdict.fromList (\x -> x) + |> Hashdict.isEqual (Hashdict.empty identity) + |> Expect.equal True + |> always + ) + , test "Empty + empty == empty" + (Hashdict.empty identity + |> Hashdict.union (Hashdict.empty String.toUpper) + |> Hashdict.isEqual (Hashdict.empty String.toLower) + |> Expect.equal True + |> always + ) + , fuzz (Fuzz.intRange 0 10) + "JSON encode -> JSON decode" + (\indent -> + Hashdict.empty identity + |> Hashdict.encode E.string + |> E.encode indent + |> D.decodeString (Hashdict.decoder identity D.string) + |> Result.map (Hashdict.isEqual (Hashdict.empty String.toUpper)) + |> Expect.equal (Ok True) + ) + ] + , describe "singleton" + [ fuzz TestEvent.fuzzer + "singletong = empty + insert" + (\event -> + Hashdict.empty .eventId + |> Hashdict.insert event + |> Hashdict.isEqual (Hashdict.singleton .eventId event) + |> Expect.equal True + ) + , fuzz TestEvent.fuzzer + "Singleton - event = empty" + (\event -> + Hashdict.singleton .eventId event + |> Hashdict.remove event + |> Hashdict.isEqual (Hashdict.empty .sender) + |> Expect.equal True + ) + , fuzz TestEvent.fuzzer + "Singletong - event (key) = empty" + (\event -> + Hashdict.singleton .eventId event + |> Hashdict.removeKey event.eventId + |> Hashdict.isEqual (Hashdict.empty .sender) + |> Expect.equal True + ) + , fuzz TestEvent.fuzzer + "not isEmpty" + (\event -> + Hashdict.singleton .eventId event + |> Hashdict.isEmpty + |> Expect.equal False + ) + , fuzz TestEvent.fuzzer + "member" + (\event -> + Hashdict.singleton .eventId event + |> Hashdict.member event + |> Expect.equal True + ) + , fuzz TestEvent.fuzzer + "memberKey" + (\event -> + Hashdict.singleton .eventId event + |> Hashdict.memberKey event.eventId + |> Expect.equal True + ) + , fuzz TestEvent.fuzzer + "False memberKey" + (\event -> + if event.eventId == event.roomId then + Expect.pass + + else + Hashdict.singleton .eventId event + |> Hashdict.memberKey event.roomId + |> Expect.equal False + ) + ] + , describe "JSON" + [ fuzz2 eventFuzzer + (Fuzz.intRange 0 10) + "JSON encode -> JSON decode" + (\hashdict indent -> + hashdict + |> Hashdict.encode Event.encode + |> E.encode indent + |> D.decodeString (Hashdict.decoder .eventId Event.decoder) + |> Result.map Hashdict.toList + |> Expect.equal (Ok <| Hashdict.toList hashdict) + ) + ] + ]