packages feed

devanagari-transliterations-0.1.0.0: test/Spec.hs

import           Data.Char.Devanagari
import           Data.Sequence
import qualified Hedgehog.Gen                          as Gen
import           Test.Hspec
import           Test.Hspec.Hedgehog                   (Gen, forAll, hedgehog,
                                                        tripping)
import           Data.Text (Text, pack)
import qualified Data.Text.IO as TIO                                                      
import Control.Monad (join)

toEither :: Tokenizer -> Text -> Either String (Seq DevanagariToken)
toEither f = Right . f

-- `main` is here so that this module can be run from GHCi on its own.  It is
--  not needed for automatic spec discovery.
main :: IO ()
main = hspec spec

zwnj :: [Char]
zwnj = ['\8204'] -- Zero Width Non Joiner

zwj :: [Char]
zwj = ['\8205'] -- Zero Width Joiner

harvard :: Text
harvard = pack "smAramiM"

iast :: Text
iast = pack "smāramiṃ"

deva :: Text
deva = pack "स्मारमिं"

iso :: Text
iso = pack "smāramiṁ"

spec :: Spec
spec = do
  describe "roundtrip" $
    it "has output identical to input after complex roundtrip" $ do
      let roundtrip = (toIast . fromIso . toIso . fromDevanagari . toDevanagari . fromHarvard . toHarvard . fromIast) iast
      roundtrip `shouldBe` iast
  describe "token based roundtrip" $ do
    it "works for all vowels" $ hedgehog $ do
      x <- forAll (Gen.enumBounded :: Gen Vowel)
      tripping (fromList [Vow x]) toDevanagari (toEither fromDevanagari)
      tripping (fromList [Vow x]) toHarvard (toEither fromHarvard)
      tripping (fromList [Vow x]) toIast (toEither fromIast)
      tripping (fromList [Vow x]) toIso (toEither fromIso)
    it "works for all consonants" $ hedgehog $ do
      x <- forAll (Gen.enumBounded :: Gen Consonant)
      tripping (fromList [Cons x, Vow A]) toDevanagari (toEither fromDevanagari)
      tripping (fromList [Cons x, Vow A]) toHarvard (toEither fromHarvard)
      tripping (fromList [Cons x, Vow A]) toIast (toEither fromIast)
      tripping (fromList [Cons x, Vow A]) toIso (toEither fromIso)
    it "works for all digits" $ hedgehog $ do
      x <- forAll (Gen.enumBounded :: Gen Digit)
      tripping (fromList [Dig x]) toDevanagari (toEither fromDevanagari)
      tripping (fromList [Dig x]) toHarvard (toEither fromHarvard)
      tripping (fromList [Dig x]) toIast (toEither fromIast)
      tripping (fromList [Dig x]) toIso (toEither fromIso)
    it "works for special characters" $ hedgehog $ do
      let specials = [Anusvara, Anunasika, Visarga, Avagraha, Virama, OM, PurnaViram, DeerghViram]
      x <- forAll (Gen.element specials)
      tripping (fromList [x]) toDevanagari (toEither fromDevanagari)

  describe "selectParserByContent" $
    it "selects correct parse function based on input" $ do
      join selectTokenizerByContent deva `shouldBe` fromDevanagari deva
      join selectTokenizerByContent iast `shouldBe` fromIast iast
      join selectTokenizerByContent harvard `shouldBe` fromHarvard harvard
      join selectTokenizerByContent iso `shouldBe` fromIso iso
  describe "tokenize" $
    it "produces correct tokens for any input" $ do
      let expected = fromList [Cons S, Cons M, Vow AA, Cons R, Vow A, Cons M, Vow I, Anusvara]
      tokenize harvard `shouldBe` expected
      tokenize iast `shouldBe` expected
      tokenize deva `shouldBe` expected
      tokenize iso `shouldBe` expected
  describe "ligature handling" $ do
    it "produces correct consonant ligatures " $ do
      let harvard' = pack "sadgamaye"
      (toDevanagari . fromHarvard) harvard' `shouldBe` pack "सद्गमये"
      let harvard'' = pack "vakSyAmi"
      (toDevanagari . fromHarvard) harvard'' `shouldBe` pack "वक्ष्यामि"
    it "adds a virama if a consonant is not followed by a vowel" $ do
      let harvard' = pack "param "
          tokens = tokenize harvard'
      tokens `shouldBe` fromList [Cons P, Vow A, Cons R, Vow A, Cons M, Unmapped ' ']
      toDevanagari tokens `shouldBe` pack "परम् "
    it "adds a virama even without trailing blank" $ do
      let harvard' = pack "param"
          tokens = tokenize harvard'
      tokens `shouldBe` fromList [Cons P, Vow A, Cons R, Vow A, Cons M]
      toDevanagari tokens `shouldBe` pack "परम्"
    it "can detect tokens up to 3 chars" $ do
      let harvard' = pack "parlRRlRRm "
          tokens = tokenize harvard'
      tokens `shouldBe` fromList [Cons P, Vow A, Cons R, Vow LII, Vow LII, Cons M, Unmapped ' ']
      toDevanagari tokens `shouldBe` pack "परॣॡम् "
    it "can enforce usage of an explicit virama to suppress consonant ligatures " $ do
      let harvard' = pack "sad_gamaye"
          deva' = pack ("सद्" ++ zwnj ++ "गमये")
      (toDevanagari . fromHarvard) harvard' `shouldBe` deva'
    it "can enforce usage of regular consonant ligatures instead of complex ligatures" $ do
      let harvard' = pack "vak\\SyAmi"
          deva' = pack ("वक्" ++ zwj ++ "ष्यामि")
      (toDevanagari . fromHarvard) harvard' `shouldBe` deva'
  describe "reading of special chars for viramas" $ do
    it "reads | correctly as PurnaViram" $ do
      let harvard' = pack "OM zAntiH |"
          deva' = pack "ॐ शान्तिः ।"
      (toDevanagari . fromHarvard) harvard' `shouldBe` deva'
    it "reads || correctly as DeerghViram" $ do
      let harvard' = pack "OM zAntiH ||"
          deva' = pack "ॐ शान्तिः ॥"
      (toDevanagari . fromHarvard) harvard' `shouldBe` deva'
    it "handles unmapped characters gracefully" $ do
      let harvard' = pack "rüpel"
          deva' = pack "र्üपेल्"
      (toDevanagari . fromHarvard) harvard' `shouldBe` deva'

  describe "Auto-Documentation" $ do
    it "produces complete markdown Table" $ do
      let mdTokenMap = tokenMapToMd
      TIO.writeFile "tokenMap.md" mdTokenMap
    it "produces complete html Table" $ do
      let htmlTokenMap = tokenMapToHtml
      TIO.writeFile "tokenMap.html" htmlTokenMap