[gitconv @ tests/Commands.hs: add emptySong for convenience]
[libmpd-haskell.git] / tests / Commands.hs
blobae85d61faa171125ffe75394fc41f35eb660124b
1 {-# OPTIONS_GHC -fno-warn-missing-signatures #-}
3 -- |
4 -- This module provides a way of verifying that the interface to the MPD
5 -- commands is correct. It does so by capturing the data flow between the
6 -- command and a dummy socket, checking the captured data against a set of
7 -- predefined values that are known to be correct. Of course, this does not
8 -- verify that the external behaviour is correct, it's simply a way of
9 -- catching silly mistakes and subtle bugs in the interface itself, without
10 -- having to actually send any requests to a real server.
12 module Main (main) where
14 import Network.MPD.Commands
15 import Network.MPD.Core (Response)
16 import Network.MPD.StringConn
18 import Control.Monad
19 import Prelude hiding (repeat)
20 import Text.Printf
22 main = mapM_ (\(n, f) -> f >>= \x -> printf "%-14s: %s\n" n x) tests
23 where tests = [("enableOutput", testEnableOutput)
24 ,("disableOutput", testDisableOutput)
25 ,("outputs", testOutputs)
26 ,("update0", testUpdate0)
27 ,("update1", testUpdate1)
28 ,("updateMany", testUpdateMany)
29 ,("find", testFind)
30 ,("list(Nothing)", testListNothing)
31 ,("list(Just)", testListJust)
32 ,("listAll", testListAll)
33 ,("lsInfo", testLsInfo)
34 ,("listAllInfo", testListAllInfo)
35 ,("search", testSearch)
36 ,("count", testCount)
37 ,("add", testAdd)
38 ,("add_", testAdd_)
39 ,("addId", testAddId)
40 ,("clear", testClear)
41 ,("currentSong(_)", testCurrentSongStopped)
42 ,("currentSong(>)", testCurrentSongPlaying)
43 ,("delete0", testDelete0)
44 ,("delete1", testDelete1)
45 ,("delete2", testDelete2)
46 ,("load", testLoad)
47 ,("move0", testMove0)
48 ,("move1", testMove1)
49 ,("move2", testMove2)
50 ,("rm", testRm)
51 ,("rename", testRename)
52 ,("save", testSave)
53 ,("swap0", testSwap0)
54 ,("swap1", testSwap1)
55 ,("shuffle", testShuffle)
56 ,("crossfade", testCrossfade)
57 ,("play", testPlay)
58 ,("pause", testPause)
59 ,("stop", testStop)
60 ,("next", testNext)
61 ,("previous", testPrevious)
62 ,("random", testRandom)
63 ,("repeat", testRepeat)
64 ,("setVolume", testSetVolume)
65 ,("volume", testVolume)
66 ,("clearError", testClearError)
67 ,("commands", testCommands)
68 ,("notCommands", testNotCommands)
69 ,("tagTypes", testTagTypes)
70 ,("urlHandlers", testUrlHandlers)
71 ,("ping", testPing)
74 test a b c = liftM (showResult b) $ testMPD a b (return Nothing) c
76 test_ a b = test a (Right ()) b
78 showResult :: (Show a) => Response a -> Result a -> String
79 showResult _ Ok = "passed"
80 showResult expectedResult (Failure result mms) =
81 "*** FAILURE ***" ++
82 concatMap (\(x,y) -> "\n expected request: " ++ show x ++
83 "\n actual request: " ++ show y) mms ++
84 "\n expected result: " ++ show expectedResult ++
85 "\n actual result: " ++ show result
87 emptySong = Song { sgArtist = ""
88 , sgAlbum = ""
89 , sgTitle = ""
90 , sgFilePath = ""
91 , sgGenre = ""
92 , sgName = ""
93 , sgComposer = ""
94 , sgPerformer = ""
95 , sgLength = 0
96 , sgDate = 0
97 , sgTrack = (0,0)
98 , sgDisc = (0,0)
99 , sgIndex = Nothing }
103 -- Admin commands
106 testEnableOutput = test_ [("enableoutput 1", Right "OK")] (enableOutput 1)
108 testDisableOutput = test_ [("disableoutput 1", Right "OK")] (disableOutput 1)
110 testOutputs =
111 test [("outputs", Right $ unlines ["outputid: 0"
112 ,"outputname: SoundCard0"
113 ,"outputenabled: 1"
114 ,"outputid: 1"
115 ,"outputname: SoundCard1"
116 ,"outputenabled: 0"
117 ,"OK"])]
118 (Right [Device { dOutputID = 0
119 , dOutputName = "SoundCard0"
120 , dOutputEnabled = True }
121 ,Device { dOutputID = 1
122 , dOutputName = "SoundCard1"
123 , dOutputEnabled = False }])
124 outputs
126 testUpdate0 = test_ [("update", Right "updating_db: 1\nOK")] (update [])
128 testUpdate1 =
129 test_ [("update \"foo\"", Right "updating_db: 1\nOK")]
130 (update ["foo"])
132 testUpdateMany =
133 test_ [("command_list_begin\nupdate \"foo\"\nupdate \"bar\"\n\
134 \command_list_end", Right "updating_db: 1\nOK")]
135 (update ["foo","bar"])
138 -- Database commands
141 testFind =
142 test [("find Artist \"Foo\"", Right "file: dir/Foo-Bar.ogg\n\
143 \Time: 60\n\
144 \Artist: Foo\n\
145 \Title: Bar\n\
146 \OK")]
147 (Right [Song { sgArtist = "Foo"
148 , sgAlbum = ""
149 , sgTitle = "Bar"
150 , sgFilePath = "dir/Foo-Bar.ogg"
151 , sgGenre = ""
152 , sgName = ""
153 , sgComposer = ""
154 , sgPerformer = ""
155 , sgLength = 60
156 , sgDate = 0
157 , sgTrack = (0,0)
158 , sgDisc = (0,0)
159 , sgIndex = Nothing
161 (find (Query Artist "Foo"))
163 testListNothing =
164 test [("list Title", Right "Title: Foo\nTitle: Bar\nOK")]
165 (Right ["Foo", "Bar"])
166 (list Title Nothing)
168 testListJust =
169 test [("list Title Artist \"Muzz\"", Right "Title: Foo\nOK")]
170 (Right ["Foo"])
171 (list Title (Just $ Query Artist "Muzz"))
173 testListAll =
174 test [("listall \"\"", Right "directory: FooBand\n\
175 \directory: FooBand/album1\n\
176 \file: FooBand/album1/01 - songA.ogg\n\
177 \file: FooBand/album1/02 - songB.ogg\nOK")]
178 (Right ["FooBand/album1/01 - songA.ogg"
179 ,"FooBand/album1/02 - songB.ogg"])
180 (listAll "")
182 testLsInfo =
183 test [("lsinfo \"\"", Right "directory: Foo\ndirectory: Bar\nOK")]
184 (Right [Left "Bar", Left "Foo"])
185 (lsInfo "")
187 testListAllInfo =
188 test [("listallinfo \"\"", Right "directory: Foo\ndirectory: Bar\nOK")]
189 (Right [Left "Bar", Left "Foo"])
190 (listAllInfo "")
192 testSearch =
193 test [("search Artist \"oo\"", Right "file: dir/Foo-Bar.ogg\n\
194 \Time: 60\n\
195 \Artist: Foo\n\
196 \Title: Bar\n\
197 \OK")]
198 (Right [Song { sgArtist = "Foo"
199 , sgAlbum = ""
200 , sgTitle = "Bar"
201 , sgFilePath = "dir/Foo-Bar.ogg"
202 , sgGenre = ""
203 , sgName = ""
204 , sgComposer = ""
205 , sgPerformer = ""
206 , sgLength = 60
207 , sgDate = 0
208 , sgTrack = (0,0)
209 , sgDisc = (0,0)
210 , sgIndex = Nothing
212 (search (Query Artist "oo"))
214 testCount =
215 test [("count Title \"Foo\"", Right "songs: 1\nplaytime: 60\nOK")]
216 (Right (Count 1 60))
217 (count (Query Title "Foo"))
220 -- Playlist commands
223 testAdd =
224 test [("add \"foo\"", Right "OK"),
225 ("listall \"foo\"", Right "file: Foo\nfile: Bar\nOK")]
226 (Right ["Foo", "Bar"])
227 (add "" "foo")
229 testAdd_ = test_ [("add \"foo\"", Right "OK")] (add_ "" "foo")
231 testAddId =
232 test [("addid \"dir/Foo-Bar.ogg\"", Right "Id: 20\nOK")]
233 (Right 20)
234 (addId "dir/Foo-Bar.ogg")
236 testClear = test_ [("playlistclear \"foo\"", Right "OK")] (clear "foo")
238 testCurrentSongStopped =
239 test [("status", Right "repeat: 0\n\
240 \random: 0\n\
241 \playlist: 253\n\
242 \playlistlength: 0\n\
243 \xfade: 0\n\
244 \state: stop\nOK")]
245 (Right Nothing)
246 (currentSong)
248 testCurrentSongPlaying =
249 test [("status", Right "volume: 80\n\
250 \repeat: 0\n\
251 \random: 0\n\
252 \playlist: 252\n\
253 \playlistlength: 21\n\
254 \xfade: 0\n\
255 \state: play\n\
256 \song: 20\n\
257 \songid: 238\n\
258 \time: 158:376\n\
259 \bitrate: 192\n\
260 \audio: 44100:16:2\n\
261 \OK")
262 ,("currentsong", Right "file: dir/Foo-Bar.ogg\n\
263 \Time: 60\n\
264 \Artist: Foo\n\
265 \Title: Bar\n\
266 \OK")]
267 (Right . Just $ Song { sgArtist = "Foo"
268 , sgAlbum = ""
269 , sgTitle = "Bar"
270 , sgFilePath = "dir/Foo-Bar.ogg"
271 , sgGenre = ""
272 , sgName = ""
273 , sgComposer = ""
274 , sgPerformer = ""
275 , sgLength = 60
276 , sgDate = 0
277 , sgTrack = (0,0)
278 , sgDisc = (0,0)
279 , sgIndex = Nothing
281 (currentSong)
283 testDelete0 = test_ [("delete 1", Right "OK")] (delete "" (Pos 1))
285 testDelete1 = test_ [("deleteid 1", Right "OK")] (delete "" (ID 1))
287 testDelete2 = test_ [("playlistdelete \"foo\" 1", Right "OK")] (delete "foo" (Pos 1))
289 testLoad = test_ [("load \"foo\"", Right "OK")] (load "foo")
291 testMove0 = test_ [("move 1 2", Right "OK")] (move "" (Pos 1) 2)
293 testMove1 = test_ [("moveid 1 2", Right "OK")] (move "" (ID 1) 2)
295 testMove2 = test_ [("playlistmove \"foo\" 1 2", Right "OK")] (move "foo" (Pos 1) 2)
297 testRm = test_ [("rm \"foo\"", Right "OK")] (rm "foo")
299 testRename = test_ [("rename \"foo\" \"bar\"", Right "OK")] (rename "foo" "bar")
301 testSave = test_ [("save \"foo\"", Right "OK")] (save "foo")
303 testSwap0 = test_ [("swap 1 2", Right "OK")] (swap (Pos 1) (Pos 2))
305 testSwap1 = test_ [("swapid 1 2", Right "OK")] (swap (ID 1) (ID 2))
307 testShuffle = test_ [("shuffle", Right "OK")] shuffle
310 -- Playback commands
313 testCrossfade = test_ [("crossfade 0", Right "OK")] (crossfade 0)
315 testPlay = test_ [("play", Right "OK")] (play Nothing)
317 testPause = test_ [("pause 0", Right "OK")] (pause False)
319 testStop = test_ [("stop", Right "OK")] stop
321 testNext = test_ [("next", Right "OK")] next
323 testPrevious = test_ [("previous", Right "OK")] previous
325 testRandom = test_ [("random 0", Right "OK")] (random False)
327 testRepeat = test_ [("repeat 0", Right "OK")] (repeat False)
329 testSetVolume = test_ [("setvol 10", Right "OK")] (setVolume 10)
331 testVolume = test_ [("volume 10", Right "OK")] (volume 10)
334 -- Miscellaneous commands
337 testClearError = test_ [("clearerror", Right "OK")] clearError
339 testCommands =
340 test [("commands", Right "command: foo\ncommand: bar")]
341 (Right ["foo", "bar"])
342 commands
344 testNotCommands =
345 test [("notcommands", Right "command: foo\ncommand: bar")]
346 (Right ["foo", "bar"])
347 notCommands
349 testTagTypes =
350 test [("tagtypes", Right "tagtype: foo\ntagtype: bar")]
351 (Right ["foo", "bar"])
352 tagTypes
354 testUrlHandlers =
355 test [("urlhandlers", Right "urlhandler: foo\nurlhandler: bar")]
356 (Right ["foo", "bar"])
357 urlHandlers
359 testPing = test_ [("ping", Right "OK")] ping
362 -- Extensions\/shortcuts