Janiczek / elm-common-tests / CommonTests.Dict

isDict : DictAPI d -> Test

Given a record of your Dict functions, this function will run a comprehensive suite of tests against them, comparing them to the elm/core Dict.

It will:

The process above will run on both your Dict and the elm/core Dict in tandem. (The same commands will run for both.)

There should be no visible difference in behaviour: eg. order of items given from toList should be the same.

This helps prevent subtle surprises when users switch between Dict implementations, like update key (\_ -> Nothing) not removing items from the Dict (a real bug in one of the 3rd-party Dicts!).

isUnorderedDict : DictAPI d -> Test

Same as isDict, but doesn't care about the order of lists gathered from query Dict functions like keys, toList, partition etc.

(Note folds on unordered lists might also behave differently if your combining function is not commutative, given the order is not guaranteed. As such, this test suite will only check that all items are used in the fold.)


type alias DictAPI d =
{ dictToString : d -> String
, empty : Maybe d
, singleton : Maybe (String -> Basics.Int -> d)
, fromList : Maybe (List ( String
, Basics.Int ) -> d)
, insert : Maybe (String -> Basics.Int -> d -> d)
, remove : Maybe (String -> d -> d)
, update : Maybe (String -> (Maybe Basics.Int -> Maybe Basics.Int) -> d -> d)
, map : Maybe ((String -> Basics.Int -> Basics.Int) -> d -> d)
, filter : Maybe ((String -> Basics.Int -> Basics.Bool) -> d -> d)
, union : Maybe (d -> d -> d)
, intersect : Maybe (d -> d -> d)
, diff : Maybe (d -> d -> d)
, size : Maybe (d -> Basics.Int)
, isEmpty : Maybe (d -> Basics.Bool)
, member : Maybe (String -> d -> Basics.Bool)
, get : Maybe (String -> d -> Maybe Basics.Int)
, toList : Maybe (d -> List ( String
, Basics.Int ))
, foldl : Maybe ((String -> Basics.Int -> List Basics.Int -> List Basics.Int) -> List Basics.Int -> d -> List Basics.Int)
, foldr : Maybe ((String -> Basics.Int -> List Basics.Int -> List Basics.Int) -> List Basics.Int -> d -> List Basics.Int)
, partition : Maybe ((String -> Basics.Int -> Basics.Bool) -> d -> ( d
, d ))
, keys : Maybe (d -> List String)
, values : Maybe (d -> List Basics.Int)
, merge : Maybe ((String -> Basics.Int -> List Basics.Int -> List Basics.Int) -> (String -> Basics.Int -> Basics.Int -> List Basics.Int -> List Basics.Int) -> (String -> Basics.Int -> List Basics.Int -> List Basics.Int) -> d -> d -> List Basics.Int -> List Basics.Int) 
}

Provide your functions. Typically something like the below example.

Note: you can opt out of testing some functions with Nothing, but beware: not providing eg. toList will result in almost no tests being actually ran.

-- Debug.toString
{ dictToString = Debug.toString

-- Creation
, empty = Just <| OpaqueDict.empty identity
, singleton = Just <| OpaqueDict.singleton identity
, fromList = Just <| OpaqueDict.fromList identity

-- Updating
, insert = Just OpaqueDict.insert
, update = Just OpaqueDict.update
, remove = Just OpaqueDict.remove
, map = Just OpaqueDict.map
, filter = Just OpaqueDict.filter
, union = Just OpaqueDict.union
, intersect = Just OpaqueDict.intersect
, diff = Just OpaqueDict.diff

-- Querying
, size = Just OpaqueDict.size
, isEmpty = Just OpaqueDict.isEmpty
, member = Just OpaqueDict.member
, get = Just OpaqueDict.get
, toList = Just OpaqueDict.toList
, foldl = Just OpaqueDict.foldl
, foldr = Just OpaqueDict.foldr
, partition = Just OpaqueDict.partition
, keys = Just OpaqueDict.keys
, values = Just OpaqueDict.values
, merge = Just OpaqueDict.merge
}