packages feed

uniform-strings-0.1.3.1: test/Uniform/Strings/Utilities_test.hs

 -----------------------------------------------------------------------------
--
-- Module      :  Strings
-- Copyright   :
--
-- | a module with a class for strings, sucht that the normal ops are
--  all polymorphic for string and text (and total)
-- the string (i.e. [Char]) functions are the semantic definitions,
-- the other implementation are tested against these.
-- except intercalate, which returns Maybe
-- (the corresponding restrictions for the unlines and unwords functions are not enforced)
--
-- performance can be improved by using the "native" functions
-- could be expanded

-- class niceStrings can be replaced or integrated in the generic strings
-- it may be useful to have more than one show like operation
-----------------------------------------------------------------------------
{-# OPTIONS_GHC -F -pgmF htfpp #-}
{-# LANGUAGE FlexibleContexts      #-}
{-# LANGUAGE FlexibleInstances     #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables   #-}
{-# LANGUAGE TypeFamilies          #-}
{-# LANGUAGE TypeSynonymInstances  #-}
{-# LANGUAGE OverloadedStrings
    , RecordWildCards     #-}

{-# LANGUAGE DeriveGeneric, DeriveAnyClass #-}
{-# OPTIONS_GHC -fno-warn-missing-methods #-}
{-# OPTIONS_GHC -w #-}

module Uniform.Strings.Utilities_test
    where

import Uniform.Zero
import Uniform.ListForm
import  Uniform.Strings.Utilities
import  Uniform.Strings.Conversion

--import           Algebra.Laws             as Law
import           Test.Framework
import Data.Text.Arbitrary
import           Test.Invariant           as Rule  

-- probably better just to move these module to package uniform-algebra
-- but there is so far only zero

import           Data.Char                (isSpace, isLower, toLower, toUpper)
import           Text.Printf              (PrintfArg, PrintfType, printf)

import           Data.List                as L
--import qualified Data.Vector              as V
import           GHC.Exts                 (IsString (..))

--import qualified Data.List.Split          as S
import           Data.Maybe
import           Data.Monoid
import           Data.Text                (Text)
import qualified Data.Text                as T
--import           Safe
-- import           Uniform.Error            (fromJustNote)
-- not possible, because Error is based on String
--import           Uniform.StringConversion
import qualified Data.ByteString.Lazy as Lazy
import Uniform.Properties


prop_zero_mknull_string :: String -> Bool
prop_zero_mknull_string = prop_zero_mknull

prop_assoz_string :: String -> String -> String -> Bool
prop_assoz_string  = prop_assoz

prop_concat_string :: [String] -> Bool
prop_concat_string  =  prop_concat

prop_filterChar_string :: String -> Bool
prop_filterChar_string a = all (cond)    af
      where
          cond x = x `notElem` ['a', '\r', '1']
          af = (filterChar cond a)


--
prop_zero_mknull_text :: Text -> Bool
prop_zero_mknull_text = prop_zero_mknull

prop_assoz_text :: Text -> Text -> Text -> Bool
prop_assoz_text  = prop_assoz

prop_concat_text :: [Text] -> Bool
prop_concat_text  =  prop_concat

prop_filterChar_text :: Text -> Bool
prop_filterChar_text = prop_filterChar



-- tests that text operations have same semantics than string2maybe    putIOwords  =liftIOstrings
prop_unwords :: [String]  -> Bool
prop_unwords =     unwords' . map s2t  <=>  s2t . unwords

prop_words =  words' . s2t <=> map s2t . words

-- not invertible for [""] and not when strings include " "
-- same problem as intervalate!
-- same problem for lines and unlines
--prop_wordsInverse :: [String] -> Bool
--prop_wordsInverse = inverts words' unwords'

prop_unlines = unlines' . map s2t <=>  s2t . unlines
prop_lines = lines' . s2t <=> map s2t . lines

prop_append :: String -> String -> Bool
prop_append a b = append' (s2t a) (s2t b) == s2t  (append a  b)

prop_append2 :: String -> String -> Bool
prop_append2 a b = append a b == reverse (append (reverse b) (reverse a))

prop_null = null' . s2t <=> null
-- prop_toUpper = toUpper' . s2t <=> s2t . toUpper'  -- failed for "\223" sz ligature
prop_toLower = toLower' . s2t <=> s2t . toLower'

--prop_toLowerInvers :: String -> Bool
--prop_toLowerInvers = inverts toLower' toUpper'

prop_toLower1 :: String -> Bool
prop_toLower1 = idempotent toLower'
prop_toLower2 :: Text -> Bool
prop_toLower2 = idempotent toLower'

prop_toUpper1 :: String -> Bool
prop_toUpper1 = idempotent toUpper'
prop_toUpper2 :: Text -> Bool
prop_toUpper2 = idempotent toUpper'

-- conversin of lowercase to uper and back is not inverse
--prop_inverse_toUpper :: String -> Bool
--prop_inverse_toUpper a = inverts toLower' toUpper' (toLower' a)
--
--prop_inverse_toUpperT :: Text -> Bool
--prop_inverse_toUpperT a = inverts toLower' toUpper' (toLower' a)

--prop_inverse_toLower :: String -> Bool
--prop_inverse_toLower a = inverts toUpper' toLower' (toUpper' a)
--
--prop_inverse_toLowerT :: Text -> Bool
--prop_inverse_toLowerT a = inverts toUpper' toLower' (toUpper' a)

prop_isPrefixOf a b = isPrefixOf' (s2t a) (s2t b) == isPrefixOf' a b
prop_isInfixOf' a b = isInfixOf' (s2t a) (s2t b) == isInfixOf' a b
prop_stripPrefix'f a b = stripPrefix' (s2t a) (s2t b) == fmap s2t  (stripPrefix' a b)

prop_stripPrefix2 :: String -> String -> Bool
prop_stripPrefix2 a b = stripPrefix' a (append' a b) == Just b

-- establish inverse for strings
prop_inverse_intercalate :: String -> [String] -> Bool
prop_inverse_intercalate s a = maybe True (isJust . fmap (a==) . splitOn' s) ( intercalate' s a )
--prop_intercalate :: String -> [String] -> Bool
--prop_intercalate a b = intercalate' (s2t a) (map s2t b) ==  fmap s2t (intercalate' a b)

prop_trim = trim' . s2t  <=> s2t . trim'
prop_trim2 :: String -> Bool
prop_trim2 = idempotent trim'
prop_trim3 :: Text -> Bool
prop_trim3 = idempotent trim'

prop_splitOn_text a b = splitOn' (s2t a) (s2t b)  == fmap (map s2t) (splitOn' a b)
prop_splitOn_bytestring a b =
        splitOn' (s2bu a) (s2bu b)  == fmap (map s2bu) (splitOn' a b)

prop_splitOn_intercalate :: String -> [String] -> Bool
prop_splitOn_intercalate a b =
    if null a then True
        else if any (a `isInfixOf'`) b then True
                else    (maybe True  (b==))  (maybe Nothing (splitOn' a)
                            ( intercalate' a $ b))
        -- fails on "" [""]

test_splitOn = assertBool ( Just [] == splitOn' [] ("a"::String))
test_bu2s = assertEqual ("a"::String) (toString . t2bu $ ("a" :: Text))

--test_show'_forText = assertEqual ("a"::String) (show' ("a"::String))
-- gives overlapping with [a]
test_show'_forString = assertEqual ("a"::Text) (show' ("a"::Text))

--stringTest :: IO Bool
--stringTest = do
--    let
--        r1 = splitOn'  (""::String) ("a"::String)   :: Maybe [String]
--        r2 = splitOn'  (""::Text) ("a"::Text)  :: Maybe [Text]
--        v1 = S.splitOn  (""::String) ("a"::String)   ::  [String]
----        v2 = T.splitOn   (""::Text) ("a"::Text)  ::  [Text]  -- produces error
--        w1 = S.splitOn  ("x"::String) ("a"::String)   ::  [String]
--        w2 = T.splitOn   ("x"::Text) ("a"::Text)  ::  [Text]
--        c1 = L.intercalate  ("a"::String) ([]::[String])   :: String
--        c2 = T.intercalate  ("a"::Text) ([]::[Text])   ::Text
--        d1 = intercalate' ("a"::String) ([]::[String])   ::Maybe String
--        d2 = intercalate' ("a"::Text) ([]::[Text])   ::Maybe Text
--    putIOwordsS ["splitOn on empty input \nfor string", show r1]
--    putIOwords ["\nfor text", show  r2, "--"]
--    putIOwordsS ["S.splitOn on empty input \nfor string", show v1] --  ["","a"]
----    putIOwords ["\nT. for text", show  v2, "--"] -- produces error
--    putIOwordsS ["S.splitOn on x input \nfor string", show w1] --  ["","a"]
--    putIOwords ["\nT. for text", show  w2, "--"] -- produces error
--    putIOwords ["intercalate for string",  c1, "-"]
--    putIOwords ["intercalate for text",   t2s c2, "-"]
--    putIOwords ["intercalate' for string", show  c1, "-"]
--    putIOwords ["intercalate' for text",   show  c2, "-"]
--    return True