{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Z.Data.Vector.SearchSpec where
import qualified Data.List as List
import Data.Word
import qualified Z.Data.Vector as V
import qualified Z.Data.Vector.Search as V
import Test.QuickCheck
import Test.QuickCheck.Function
import Test.QuickCheck.Property
import Test.Hspec
import Test.Hspec.QuickCheck
spec :: Spec
spec = describe "vector-search" $ do
describe "snd . vector find == List.find" $ do
prop "snd .vector find = List.find" $ \ (Fun _ y) x ->
(snd . V.find y . V.pack @V.Vector @Integer $ x) === (List.find y $ x)
prop "snd . vector find = List.find" $ \ (Fun _ y) x ->
(snd . V.find y . V.pack @V.PrimVector @Int $ x) === (List.find y $ x)
prop "snd . vector find = List.find" $ \ (Fun _ y) x ->
(snd . V.find y . V.pack @V.PrimVector @Word8 $ x) === (List.find y $ x)
describe "vector findIndex == maybe List.length List.findIndex" $ do
prop "vector findIndex = maybe List.length List.findIndex" $ \ (Fun _ y) x ->
(V.findIndex y . V.pack @V.Vector @Integer $ x) ===
(maybe (List.length x) id $ List.findIndex y x)
prop "vector findIndex = maybe List.length List.findIndex" $ \ (Fun _ y) x ->
(V.findIndex y . V.pack @V.PrimVector @Int $ x) ===
(maybe (List.length x) id $ List.findIndex y x)
prop "vector findIndex = maybe List.length List.findIndex" $ \ (Fun _ y) x ->
(V.findIndex y . V.pack @V.PrimVector @Word8 $ x) ===
(maybe (List.length x) id $ List.findIndex y x)
describe "vector findIndex == length - findIndexR . reverse - 1" $ do
prop "vector findIndex = length - findIndexR . reverse - 1" $ \ (Fun _ y) x ->
(V.findIndex y . V.pack @V.Vector @Integer $ x) ===
(List.length x - 1 - (V.findIndexR y . V.reverse . V.pack @V.Vector @Integer $ x))
prop "vector findIndex = length - findIndexR . reverse - 1" $ \ (Fun _ y) x ->
(V.findIndex y . V.pack @V.PrimVector @Int $ x) ===
(List.length x - 1 - (V.findIndexR y . V.reverse . V.pack @V.PrimVector @Int $ x))
prop "vector findIndex = length - findIndexR . reverse - 1" $ \ (Fun _ y) x ->
(V.findIndex y . V.pack @V.PrimVector @Word8 $ x) ===
(List.length x - 1 - (V.findIndexR y . V.reverse . V.pack @V.PrimVector @Word8 $ x))
describe "vector elemIndices == List.elemIndices" $ do
prop "vector elemIndices = List.elemIndices" $ \ y x ->
(V.elemIndices y . V.pack @V.Vector @Integer $ x) === (List.elemIndices y $ x)
prop "vector elemIndices = List.elemIndices" $ \ y x ->
(V.elemIndices y . V.pack @V.PrimVector @Int $ x) === (List.elemIndices y $ x)
prop "vector elemIndices = List.elemIndices" $ \ y x ->
(V.elemIndices y . V.pack @V.PrimVector @Word8 $ x) === (List.elemIndices y $ x)
describe "vector filter == List.filter" $ do
prop "vector filter = List.filter" $ \ (Fun _ y) x ->
(V.filter y . V.pack @V.Vector @Integer $ x) === (V.pack . List.filter y $ x)
prop "vector filter = List.filter" $ \ (Fun _ y) x ->
(V.filter y . V.pack @V.PrimVector @Int $ x) === (V.pack . List.filter y $ x)
prop "vector filter = List.filter" $ \ (Fun _ y) x ->
(V.filter y . V.pack @V.PrimVector @Word8 $ x) === (V.pack . List.filter y $ x)
describe "vector partition == List.partition" $ do
prop "vector partition = List.partition" $ \ (Fun _ y) x ->
(V.partition y . V.pack @V.Vector @Integer $ x) ===
(let (a,b) = List.partition y $ x in (V.pack a, V.pack b))
prop "vector partition = List.partition" $ \ (Fun _ y) x ->
(V.partition y . V.pack @V.PrimVector @Int $ x) ===
(let (a,b) = List.partition y $ x in (V.pack a, V.pack b))
prop "vector partition = List.partition" $ \ (Fun _ y) x ->
(V.partition y . V.pack @V.PrimVector @Word8 $ x) ===
(let (a,b) = List.partition y $ x in (V.pack a, V.pack b))
describe "vector indices property" . modifyMaxSuccess (*10) . modifyMaxSize (*10) $ do
prop "subvector at indices should be equal to needle" $ \ needle haystack ->
(let is = V.indices (V.pack needle) (V.pack @V.Vector @Integer $ haystack) False
in all (\i -> List.take (List.length needle) (List.drop i haystack) == needle) is
) === True
prop "subvector at indices should be equal to needle" $ \ needle haystack ->
(let is = V.indices (V.pack needle) (V.pack @V.PrimVector @Int $ haystack) False
in all (\i -> List.take (List.length needle) (List.drop i haystack) == needle) is
) === True
prop "subvector at indices should be equal to needle" $ \ needle haystack ->
(let is = V.indices (V.pack needle) (V.pack @V.PrimVector @Word8 $ haystack) False
in all (\i -> List.take (List.length needle) (List.drop i haystack) == needle) is
) === True
describe "vector indices property" . modifyMaxSuccess (*10) . modifyMaxSize (*10) $ do
prop "indices should not overlapped" $ \ needle haystack ->
(let is = V.indices (V.pack needle) (V.pack @V.Vector @Integer $ haystack) False
is' = drop 1 is
isDiff = List.zipWith (-) is' is
in all (>= List.length needle) isDiff
) === True
prop "indices should not overlapped" $ \ needle haystack ->
(let is = V.indices (V.pack needle) (V.pack @V.PrimVector @Int $ haystack) False
is' = drop 1 is
isDiff = List.zipWith (-) is' is
in all (>= List.length needle) isDiff
) === True
prop "indices should not overlapped" $ \ needle haystack ->
(let is = V.indices (V.pack needle) (V.pack @V.PrimVector @Word8 $ haystack) False
is' = drop 1 is
isDiff = List.zipWith (-) is' is
in all (>= List.length needle) isDiff
) === True
describe "vector indices property (partial match)" $ do
prop "subvector at indices should be equal to needle" $ \ needle haystack ->
(let is = V.indices (V.pack needle) (V.pack @V.Vector @Integer $ haystack) True
in all (\i ->
if (i > 0)
then List.take (List.length needle) (List.drop i haystack) == needle
else (List.drop (List.length haystack + i) haystack) ==
(List.take (0-i) needle)
) is
) === True
prop "subvector at indices should be equal to needle" $ \ needle haystack ->
(let is = V.indices (V.pack needle) (V.pack @V.PrimVector @Int $ haystack) True
in all (\i ->
if (i > 0)
then List.take (List.length needle) (List.drop i haystack) == needle
else (List.drop (List.length haystack + i) haystack) ==
(List.take (0-i) needle)
) is
) === True
prop "subvector at indices should be equal to needle" $ \ needle haystack ->
(let is = V.indices (V.pack needle) (V.pack @V.PrimVector @Word8 $ haystack) True
in all (\i ->
if (i > 0)
then List.take (List.length needle) (List.drop i haystack) == needle
else (List.drop (List.length haystack + i) haystack) ==
(List.take (0-i) needle)
) is
) === True
describe "vector overlapping indices property" . modifyMaxSuccess (*10) . modifyMaxSize (*10) $ do
prop "subvector at indices should be equal to needle" $ \ needle haystack ->
(let is = V.indicesOverlapping (V.pack needle) (V.pack @V.Vector @Integer $ haystack) False
in all (\i -> List.take (List.length needle) (List.drop i haystack) == needle) is
) === True
prop "subvector not at indicesOverlapping should be not equal to needle" $ \ needle haystack ->
(let is = V.indicesOverlapping (V.pack needle) (V.pack @V.Vector @Integer $ haystack) False
is' = filter (`notElem` is) [0..List.length haystack-1]
in all (\i -> List.take (List.length needle) (List.drop i haystack) /= needle) is'
) === True
prop "subvector at indicesOverlapping should be equal to needle" $ \ needle haystack ->
(let is = V.indicesOverlapping (V.pack needle) (V.pack @V.PrimVector @Int $ haystack) False
in all (\i -> List.take (List.length needle) (List.drop i haystack) == needle) is
) === True
prop "subvector not at indicesOverlapping should be not equal to needle" $ \ needle haystack ->
(let is = V.indicesOverlapping (V.pack needle) (V.pack @V.PrimVector @Int $ haystack) False
is' = filter (`notElem` is) [0..List.length haystack-1]
in all (\i -> List.take (List.length needle) (List.drop i haystack) /= needle) is'
) === True
prop "subvector at indicesOverlapping should be equal to needle" $ \ needle haystack ->
(let is = V.indicesOverlapping (V.pack needle) (V.pack @V.PrimVector @Word8 $ haystack) False
in all (\i -> List.take (List.length needle) (List.drop i haystack) == needle) is
) === True
prop "subvector not at indicesOverlapping should be not equal to needle" $ \ needle haystack ->
(let is = V.indicesOverlapping (V.pack needle) (V.pack @V.PrimVector @Word8 $ haystack) False
is' = filter (`notElem` is) [0..List.length haystack-1]
in all (\i -> List.take (List.length needle) (List.drop i haystack) /= needle) is'
) === True
describe "vector indicesOverlapping property (partial match)" $ do
prop "subvector at indicesOverlapping should be equal to needle" $ \ needle haystack ->
(let is = V.indicesOverlapping (V.pack needle) (V.pack @V.Vector @Integer $ haystack) True
in all (\i ->
if (i > 0)
then List.take (List.length needle) (List.drop i haystack) == needle
else (List.drop (List.length haystack + i) haystack) ==
(List.take (0-i) needle)
) is
) === True
prop "subvector at indicesOverlapping should be equal to needle" $ \ needle haystack ->
(let is = V.indicesOverlapping (V.pack needle) (V.pack @V.PrimVector @Int $ haystack) True
in all (\i ->
if (i > 0)
then List.take (List.length needle) (List.drop i haystack) == needle
else (List.drop (List.length haystack + i) haystack) ==
(List.take (0-i) needle)
) is
) === True
prop "subvector at indicesOverlapping should be equal to needle" $ \ needle haystack ->
(let is = V.indicesOverlapping (V.pack needle) (V.pack @V.PrimVector @Word8 $ haystack) True
in all (\i ->
if (i > 0)
then List.take (List.length needle) (List.drop i haystack) == needle
else (List.drop (List.length haystack + i) haystack) ==
(List.take (0-i) needle)
) is
) === True