hmp3-ng-2.18.0: test/LexerSpec.hs
module LexerSpec (tests) where
import Test.Tasty
import Test.Tasty.HUnit
import qualified Data.ByteString.Char8 as P
import Lexer (doP, doF, doS, doI)
import Syntax
tests :: TestTree
tests = testGroup "Lexer"
[ testGroup "doP (status messages)"
[ testCase "0 is Stopped" $ doP "0" @?= S Stopped
, testCase "1 is Paused" $ doP "1" @?= S Paused
, testCase "2 is Playing" $ doP "2" @?= S Playing
, testCase "3 is Playing" $ doP "3" @?= S Playing
, testCase "empty is Playing" $ doP "" @?= S Playing
, testCase "garbage is Playing" $ doP "xyz" @?= S Playing
]
, testGroup "doF (frame messages)"
[ testCase "all four fields parse" $
doF "123 456 12.34 56.78" @?= R (Frame 123 456 12.34 56.78)
, testCase "negative timeLeft is clamped to zero" $
doF "0 0 0.00 -1.00" @?= R (Frame 0 0 0.00 0)
]
, testGroup "doS (info messages)"
[ testCase "userinfo combines version, bitrate, kHz" $
doS "1.0 1 44100 stereo 0 0 2 0 0 0 128 0"
@?= I (Info "mpeg 1.0 128kbit/s 44kHz")
]
, testGroup "doI (track info / id3)"
[ testCase "non-id3 input becomes Left filename" $
doI "song.mp3"
@?= F (File (Left "song.mp3"))
, testCase "non-id3 input is trimmed" $
doI " song.mp3 "
@?= F (File (Left "song.mp3"))
, testCase "id3 with title only" $
doI ("ID3:" <> field30 "Title")
@?= F (File (Right (Id3 "Title" "" "" "Title")))
, testCase "id3 with title and artist" $
doI ("ID3:" <> field30 "Title" <> field30 "Artist")
@?= F (File (Right (Id3 "Title" "Artist" "" "Artist : Title")))
, testCase "id3 with title, artist, and album" $
doI ("ID3:" <> field30 "Title" <> field30 "Artist" <> field30 "Album")
@?= F (File (Right (Id3 "Title" "Artist" "Album" "Artist : Album : Title")))
, testCase "id3 with empty title falls back to Left of trimmed input" $
-- mpg123 sometimes returns ID3 records with a blank title; rather than
-- present an empty track name, the parser exposes the raw line.
doI ("ID3:" <> field30 "" <> field30 "Artist")
@?= F (File (Left ("ID3:" <> P.replicate 30 ' ' <> "Artist")))
]
]
-- Pad/truncate a ByteString to exactly 30 characters with trailing spaces,
-- matching the fixed-width field convention used by mpg123 ID3 output.
field30 :: P.ByteString -> P.ByteString
field30 b = P.take 30 (b <> P.replicate 30 ' ')