nri-prelude-0.7.0.0: tests/ArraySpec.hs
module ArraySpec (tests) where
import Array
import qualified Expect
import qualified Fuzz
import qualified List
import NriPrelude hiding (map)
import Test (Test, describe, fuzz, fuzz2, test)
tests :: Test
tests =
describe
"Array tests"
[ initTests,
isEmptyTests,
lengthTests,
getSetTests,
conversionTests,
transformTests,
sliceTests
]
limit :: Int
limit = 10000
size :: Fuzz.Fuzzer Int
size = Fuzz.intRange 1 limit
toLimit :: Int -> Fuzz.Fuzzer Int
toLimit x = Fuzz.intRange x limit
initTests :: Test
initTests =
describe
"Initialization"
[ fuzz size "initialize" <| \size_ ->
initialize size_ identity
|> toList
|> Expect.equal (List.range 0 (size_ - 1)),
fuzz size "push" <| \size_ ->
size_
- 1
|> List.range 0
|> List.foldl push empty
|> Expect.equal (initialize size_ identity),
test "initialize non-identity" <| \() ->
initialize 4 (\n -> n * n)
|> toList
|> Expect.equal
[0, 1, 4, 9],
test "initialize empty" <| \() ->
initialize 0 identity
|> toList
|> Expect.equal [],
test "initialize negative" <| \() ->
initialize (-2) identity
|> toList
|> Expect.equal []
]
isEmptyTests :: Test
isEmptyTests =
describe
"isEmpty"
[ test "all empty arrays are equal" <| \() ->
empty
|> Expect.equal
(fromList [] :: Array ()),
test "empty array" <| \() ->
isEmpty empty
|> Expect.equal True,
test "empty converted array" <| \() ->
isEmpty (fromList [])
|> Expect.equal True,
test "non-empty array" <| \() ->
isEmpty (fromList [1 :: Int])
|> Expect.equal False
]
lengthTests :: Test
lengthTests =
describe
"Length"
[ test "empty array" <| \() ->
Expect.equal (length empty) 0,
fuzz size "non-empty array" <| \size_ ->
initialize size_ identity
|> length
|> Expect.equal size_,
fuzz size "push" <| \size_ ->
initialize size_ identity
|> push size_
|> length
|> Expect.equal (size_ + 1),
fuzz size "append" <| \size_ ->
initialize (size_ // 2) identity
|> append (initialize size_ identity)
|> length
|> Expect.equal (size_ + (size_ // 2)),
fuzz size "set does not increase" <| \size_ ->
initialize size_ identity
|> set (size_ // 2) 1
|> length
|> Expect.equal size_,
fuzz (toLimit 100) "big slice" <| \size_ ->
initialize size_ identity
|> slice 35 (-35)
|> length
|> Expect.equal (size_ - 70),
fuzz2
(Fuzz.intRange (-32) (-1))
(toLimit 100)
"small slice end"
<| \n size_ ->
initialize size_ identity
|> slice 0 n
|> length
|> Expect.equal (size_ + n)
]
getSetTests :: Test
getSetTests =
describe
"Get and set"
[ fuzz2 size size "can retrieve element" <| \x y ->
let n = min x y
size_ = max x y
in get n (initialize (size_ + 1) identity)
|> Expect.equal (Just n),
fuzz2
(Fuzz.intRange 1 50)
(toLimit 100)
"out of bounds retrieval returns nothing"
<| \n size_ ->
let arr = initialize size_ identity
in Expect.all
[ \() -> Expect.equal (get (negate n) arr) Nothing,
\() -> Expect.equal (get (size_ + n) arr) Nothing
]
(),
fuzz2 size size "set replaces value" <| \x y ->
let n = min x y
size_ = max x y
in initialize (size_ + 1) identity
|> set n 5
|> get n
|> Expect.equal (Just 5),
fuzz2
(Fuzz.intRange 1 50)
size
"set out of bounds returns original array"
<| \n size_ ->
let arr = initialize size_ identity
in set (negate n) 5 arr
|> set (size_ + n) 5
|> Expect.equal arr,
test "Retrieval works from tail" <| \() ->
initialize 1035 identity
|> set 1030 5
|> get 1030
|> Expect.equal (Just 5)
]
conversionTests :: Test
conversionTests =
describe
"Conversion"
[ fuzz size "back and forth" <| \size_ ->
let ls = List.range 0 (size_ - 1)
in fromList ls
|> toList
|> Expect.equal ls,
fuzz size "indexed" <| \size_ ->
initialize size_ (1 +)
|> toIndexedList
|> Expect.equal
( toList
( initialize
size_
(\idx -> (idx, idx + 1))
)
)
]
transformTests :: Test
transformTests =
describe
"Transform"
[ fuzz size "foldl" <| \size_ ->
initialize size_ identity
|> foldl (:) []
|> Expect.equal
( List.reverse (List.range 0 (size_ - 1))
),
fuzz size "foldr" <| \size_ ->
initialize size_ identity
|> foldr (:) []
|> Expect.equal (List.range 0 (size_ - 1)),
fuzz size "filter" <| \size_ ->
initialize size_ identity
|> filter (\a -> modBy 2 a == 0)
|> toList
|> Expect.equal
( List.filter
(\a -> modBy 2 a == 0)
(List.range 0 (size_ - 1))
),
fuzz size "map" <| \size_ ->
initialize size_ identity
|> map (1 +)
|> Expect.equal (initialize size_ (1 +)),
fuzz size "indexedMap" <| \size_ ->
repeat size_ 5
|> indexedMap (*)
|> Expect.equal (initialize size_ (5 *)),
fuzz size "push appends one element" <| \size_ ->
initialize size_ identity
|> push size_
|> Expect.equal (initialize (size_ + 1) identity),
fuzz (Fuzz.intRange 1 1050) "append" <| \size_ ->
initialize size_ (size_ +)
|> append (initialize size_ identity)
|> Expect.equal (initialize (size_ * 2) identity),
fuzz2 size (Fuzz.intRange 1 32) "small appends" <| \s1 s2 ->
initialize s2 (s1 +)
|> append (initialize s1 identity)
|> Expect.equal (initialize (s1 + s2) identity)
]
sliceTests :: Test
sliceTests =
let smallSample = fromList (List.range 1 8)
in describe
"Slice"
[ fuzz2 (Fuzz.intRange (-50) (-1)) (toLimit 100) "both" <| \n size_ ->
initialize size_ identity
|> slice (abs n) n
|> Expect.equal
( initialize
(size_ + n + n)
(\idx -> idx - n)
),
fuzz2 (Fuzz.intRange (-50) (-1)) (toLimit 100) "left" <| \n size_ ->
let arr = initialize size_ identity
in slice (abs n) (length arr) arr
|> Expect.equal
( initialize (size_ + n) (\idx -> idx - n)
),
fuzz2 (Fuzz.intRange (-50) (-1)) (toLimit 100) "right" <| \n size_ ->
initialize size_ identity
|> slice 0 n
|> Expect.equal (initialize (size_ + n) identity),
fuzz size "slicing all but the last item" <| \size_ ->
initialize size_ identity
|> slice (-1) size_
|> toList
|> Expect.equal [size_ - 1],
test "both small" <| \() ->
slice 2 5 smallSample
|> toList
|> Expect.equal (List.range 3 5),
test "start small" <| \() ->
slice 2 (length smallSample) smallSample
|> toList
|> Expect.equal (List.range 3 8),
test "negative" <| \() ->
slice (-5) (-2) smallSample
|> toList
|> Expect.equal (List.range 4 6),
test "impossible" <| \() ->
slice (-1) (-2) smallSample
|> toList
|> Expect.equal [],
test "crash" <| \() ->
repeat (33 * 32) 1
|> slice 0 1
|> Expect.equal (repeat 1 1 :: Array Int)
]