ipa-0.2: test/Main.hs
{-# LANGUAGE PatternSynonyms #-}
-- |
module Main where
import Data.Foldable ( traverse_ )
import Data.Maybe ( isNothing )
import Language.IPA
( Backness(..)
, Height(..)
, IPA(IPA)
, Length(..)
, Manner(..)
, Phonation(..)
, Place(..)
, ReprIPA(toIPA', toIPA, toXSampa', toXSampa)
, Roundedness(..)
, Segment(..)
, SegmentalFeature(..)
, Sibilance(..)
, Stress(Primary)
, SuprasegmentalFeature(..)
, Syllable(..)
, ToneContour(..)
, XSampa(XSampa)
, mkIPA
, pattern ImplosiveConsonant
, pattern PulmonicConsonant
)
import Test.Hspec ( describe
, hspec
, it
, shouldBe
, shouldSatisfy
)
{- HLINT ignore "Redundant do" -}
main :: IO ()
main = ipa >> xsampa
ipa :: IO ()
ipa = hspec $ do
describe "Segments" $ do
it "Rejects nonsense segments" $ do
let phones = toIPA
<$> [ PulmonicConsonant Voiceless
Uvular
(Fricative Sibilant)
, PulmonicConsonant Voiced Velar Flap
, PulmonicConsonant Voiced Pharyngeal Plosive
, PulmonicConsonant Voiceless Glottal Trill
, Vowel NearClose Central Unrounded
, Vowel NearOpen Back Rounded
]
traverse_ (`shouldSatisfy` isNothing) phones
describe "Segmental features" $ do
it "Correctly makes 'Short' a noop" $ do
let vcfu = Vowel Close Front Unrounded
i = toIPA' vcfu
iShort = toIPA' $ WithSegmentalFeature (Length Short) vcfu
i `shouldBe` iShort
it "Chains articulatory features" $ do
let vowel = Vowel Close Back Unrounded
IPA chained = toIPA'
$ WithSegmentalFeature (Length OverLong)
(WithSegmentalFeature Compressed
vowel)
chained `shouldBe` "ɯᵝːː"
describe "Suprasegmentals" $ do
it "Preserves individual segments and order" $ do
let segments = [ ImplosiveConsonant Voiced Bilabial
, Vowel CloseMid Back Unrounded
]
IPA syllable = toIPA' $ Syllable segments
syllable `shouldBe` "ɓɤ"
describe "Suprasegmental features" $ do
it "Chains articulatory features" $ do
let segments = [ PulmonicConsonant Voiced Alveolar Plosive
, Vowel CloseMid Back Rounded
]
syllable = Syllable segments
tone = LexicalToneContour Rising
IPA chained = toIPA'
$ WithSuprasegmentalFeature --
(Stress Primary)
(WithSuprasegmentalFeature tone syllable)
chained `shouldBe` "do˩˥ˈ"
describe "IPA normalization" $ do
it "Normalizes IPA values to NFC" $ do
let oRisingNFD = "o\x0301" -- decomposed form
IPA oRisingIPA = mkIPA oRisingNFD
oRisingIPA `shouldBe` "\x00f3"
xsampa :: IO ()
xsampa = hspec $ do
describe "Suprasegmentals" $ do
it "Preserves individual segments and order" $ do
let segments = [ ImplosiveConsonant Voiced Bilabial
, Vowel CloseMid Back Unrounded
]
XSampa syllable = toXSampa' $ Syllable segments
syllable `shouldBe` "b_<7"
describe "Segmental features" $ do
it "Correctly makes 'Short' a noop" $ do
let vcfu = Vowel Close Front Unrounded
i = toXSampa' vcfu
iShort = toXSampa' $ WithSegmentalFeature (Length Short) vcfu
i `shouldBe` iShort
it "Chains articulatory features" $ do
let vowel = Vowel Close Back Unrounded
XSampa chained = toXSampa'
$ WithSegmentalFeature (Length OverLong)
(WithSegmentalFeature Lowered vowel)
chained `shouldBe` "M_o::"
describe "Segments" $ do
it "Rejects nonsense segments" $ do
let phones = toXSampa
<$> [ PulmonicConsonant Voiceless
Uvular
(Fricative Sibilant)
, PulmonicConsonant Voiced Velar Flap
, PulmonicConsonant Voiced Pharyngeal Plosive
, PulmonicConsonant Voiceless Glottal Trill
, Vowel NearClose Central Unrounded
, Vowel NearOpen Back Rounded
]
traverse_ (`shouldSatisfy` isNothing) phones
describe "Suprasegmental features" $ do
it "Chains articulatory features" $ do
let segments = [ PulmonicConsonant Voiced Alveolar Plosive
, Vowel CloseMid Back Rounded
]
syllable = Syllable segments
tone = LexicalToneContour Rising
XSampa chained = toXSampa'
$ WithSuprasegmentalFeature --
(Stress Primary)
(WithSuprasegmentalFeature tone syllable)
chained `shouldBe` "do_R\""