lame-0.1.0: tests/Codec/Audio/LAMESpec.hs
--
-- Tests for the ‘lame’ package.
--
-- Copyright © 2017 Mark Karpov <markkarpov@openmailbox.org>
--
-- Redistribution and use in source and binary forms, with or without
-- modification, are permitted provided that the following conditions are
-- met:
--
-- * Redistributions of source code must retain the above copyright notice,
-- this list of conditions and the following disclaimer.
--
-- * Redistributions in binary form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in the
-- documentation and/or other materials provided with the distribution.
--
-- * Neither the name Mark Karpov nor the names of contributors may be used
-- to endorse or promote products derived from this software without
-- specific prior written permission.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS “AS IS” AND ANY
-- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
-- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-- STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-- POSSIBILITY OF SUCH DAMAGE.
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
module Codec.Audio.LAMESpec
( spec )
where
import Codec.Audio.LAME
import Control.Monad
import Data.Default.Class
import Data.Text (Text)
import Data.Word (Word8)
import Sound.HTagLib
import System.Directory
import System.FilePath
import System.IO.Temp (withSystemTempDirectory)
import Test.Hspec
import qualified Data.Text as T
data Info = Info
{ infoTitle :: Title
, infoArtist :: Artist
, infoAlbum :: Album
, infoComment :: Comment
, infoGenre :: Genre
, infoYear :: Maybe Year
, infoTrackNumber :: Maybe TrackNumber
, infoDuration :: Duration
, infoBitRate :: BitRate
, infoSampleRate :: SampleRate
, infoChannels :: Channels
} deriving (Eq, Show)
spec :: Spec
spec =
describe "encodeMp3" $
withVariousWaves $
it "produces correct MP3 file" $ \(ipath, opath) -> do
encodeMp3 def
{ encoderTagTitle = pure tagTitle
, encoderTagArtist = pure tagArtist
, encoderTagAlbum = pure tagAlbum
, encoderTagYear = pure tagYear
, encoderTagComment = pure tagComment
, encoderTagTrack = pure tagTrack
, encoderTagGenre = pure tagGenre }
ipath
opath
Info {..} <- getTags' opath MPEG $ Info
<$> titleGetter
<*> artistGetter
<*> albumGetter
<*> commentGetter
<*> genreGetter
<*> yearGetter
<*> trackNumberGetter
<*> durationGetter
<*> bitRateGetter
<*> sampleRateGetter
<*> channelsGetter
unTitle infoTitle `shouldBe` tagTitle
unArtist infoArtist `shouldBe` tagArtist
unAlbum infoAlbum `shouldBe` tagAlbum
fmap (T.pack . show . unYear) infoYear `shouldBe` pure tagYear
unComment infoComment `shouldBe` tagComment
fmap unTrackNumber infoTrackNumber `shouldBe`
(pure . fromIntegral . fst) tagTrack
unGenre infoGenre `shouldBe` tagGenre
unDuration infoDuration `shouldBe` 1
unBitRate infoBitRate `shouldBe` 128
unSampleRate infoSampleRate `shouldBe` 44100
unChannels infoChannels `shouldBe` 2
----------------------------------------------------------------------------
-- Helpers
-- | Run given test with various WAVE files.
withVariousWaves :: SpecWith (FilePath, FilePath) -> SpecWith ()
withVariousWaves m =
forM_ waveFiles $ \(path, desc) ->
context ("when given " ++ desc) (around (withSandbox path) m)
-- | Make a temporary copy of given file and provide the path to the file in
-- a sandbox directory. Automatically remove the files when the test
-- finishes.
withSandbox :: FilePath -> ActionWith (FilePath, FilePath) -> IO ()
withSandbox path action =
withSystemTempDirectory "lame-test" $ \dir -> do
let ipath = dir </> "файл" -- testing Unicode
opath = dir </> "результат"
copyFile path ipath
action (ipath, opath)
waveFiles :: [(FilePath, String)]
waveFiles =
[ ( "audio-samples/16bit-int.wav"
, "2 channels 44100 Hz 16 bit PCM" )
, ( "audio-samples/32bit-float.wav"
, "2 channels 44100 Hz 32 bit float PCM" )
, ( "audio-samples/64bit-float.wav"
, "2 channels 44100 Hz 64 bit float PCM" )
]
tagTitle, tagArtist, tagAlbum, tagYear, tagComment, tagGenre :: Text
tagTitle = "Название"
tagArtist = "Исполнитель"
tagAlbum = "Альбом"
tagYear = "2017"
tagComment = "Комментарий тут…"
tagGenre = "Жанр"
tagTrack :: (Word8, Maybe Word8)
tagTrack = (1, Just 10)