annotate tests/test_cmdline_util.py @ 424:12a7f01c633b

Update docstrings
author Amine Sehili <amine.sehili@gmail.com>
date Sat, 19 Oct 2024 15:21:43 +0200
parents 5e2fe07cd12f
children c5b4178aa80f
rev   line source
amine@269 1 import os
amine@403 2 from collections import namedtuple
amine@403 3 from tempfile import TemporaryDirectory
amine@403 4 from unittest.mock import patch
amine@403 5
amine@400 6 import pytest
amine@267 7
amine@267 8 from auditok.cmdline_util import (
amine@273 9 _AUDITOK_LOGGER,
amine@403 10 KeywordArguments,
amine@403 11 initialize_workers,
amine@267 12 make_kwargs,
amine@267 13 make_logger,
amine@267 14 )
amine@421 15 from auditok.exceptions import ArgumentError
amine@271 16 from auditok.workers import (
amine@418 17 AudioEventsJoinerWorker,
amine@403 18 CommandLineWorker,
amine@403 19 PlayerWorker,
amine@403 20 PrintWorker,
amine@403 21 RegionSaverWorker,
amine@271 22 StreamSaverWorker,
amine@271 23 )
amine@267 24
amine@400 25 _ArgsNamespace = namedtuple(
amine@400 26 "_ArgsNamespace",
amine@267 27 [
amine@267 28 "input",
amine@292 29 "max_read",
amine@267 30 "analysis_window",
amine@267 31 "sampling_rate",
amine@267 32 "sample_width",
amine@267 33 "channels",
amine@267 34 "use_channel",
amine@267 35 "input_format",
amine@267 36 "output_format",
amine@267 37 "large_file",
amine@267 38 "frame_per_buffer",
amine@267 39 "input_device_index",
amine@267 40 "save_stream",
amine@292 41 "save_detections_as",
amine@418 42 "join_detections",
amine@267 43 "plot",
amine@267 44 "save_image",
amine@267 45 "min_duration",
amine@267 46 "max_duration",
amine@267 47 "max_silence",
amine@267 48 "drop_trailing_silence",
amine@267 49 "strict_min_duration",
amine@267 50 "energy_threshold",
amine@267 51 "echo",
amine@292 52 "progress_bar",
amine@267 53 "command",
amine@267 54 "quiet",
amine@267 55 "printf",
amine@267 56 "time_format",
amine@267 57 "timestamp_format",
amine@267 58 ],
amine@267 59 )
amine@267 60
amine@267 61
amine@400 62 @pytest.mark.parametrize(
amine@418 63 "save_stream, save_detections_as, join_detections, plot, save_image, use_channel, exp_use_channel, exp_record", # noqa: B950
amine@400 64 [
amine@418 65 # no_record_no_join
amine@418 66 ("stream.ogg", None, None, False, None, "mix", "mix", False),
amine@418 67 # no_record_plot_join
amine@418 68 ("stream.ogg", None, 1.0, True, None, None, None, False),
amine@400 69 # no_record_save_image
amine@418 70 ("stream.ogg", None, None, True, "image.png", None, None, False),
amine@400 71 # record_plot
amine@418 72 (None, None, None, True, None, None, None, True),
amine@400 73 # record_save_image
amine@418 74 (None, None, None, False, "image.png", None, None, True),
amine@400 75 # int_use_channel
amine@418 76 ("stream.ogg", None, None, False, None, "1", 1, False),
amine@400 77 # save_detections_as
amine@418 78 ("stream.ogg", "{id}.wav", None, False, None, None, None, False),
amine@400 79 ],
amine@400 80 ids=[
amine@418 81 "no_record_no_join",
amine@400 82 "no_record_plot",
amine@400 83 "no_record_save_image",
amine@400 84 "record_plot",
amine@400 85 "record_save_image",
amine@400 86 "int_use_channel",
amine@400 87 "save_detections_as",
amine@400 88 ],
amine@400 89 )
amine@400 90 def test_make_kwargs(
amine@400 91 save_stream,
amine@400 92 save_detections_as,
amine@418 93 join_detections,
amine@400 94 plot,
amine@400 95 save_image,
amine@400 96 use_channel,
amine@400 97 exp_use_channel,
amine@400 98 exp_record,
amine@400 99 ):
amine@400 100 args = (
amine@400 101 "file",
amine@400 102 30,
amine@400 103 0.01,
amine@400 104 16000,
amine@400 105 2,
amine@400 106 2,
amine@400 107 use_channel,
amine@400 108 "raw",
amine@400 109 "ogg",
amine@400 110 True,
amine@400 111 None,
amine@400 112 1,
amine@267 113 save_stream,
amine@292 114 save_detections_as,
amine@418 115 join_detections,
amine@267 116 plot,
amine@267 117 save_image,
amine@400 118 0.2,
amine@400 119 10,
amine@400 120 0.3,
amine@400 121 False,
amine@400 122 False,
amine@400 123 55,
amine@400 124 )
amine@400 125 misc = (
amine@400 126 False,
amine@400 127 False,
amine@400 128 None,
amine@400 129 True,
amine@400 130 None,
amine@400 131 "TIME_FORMAT",
amine@400 132 "TIMESTAMP_FORMAT",
amine@400 133 )
amine@400 134 args_ns = _ArgsNamespace(*(args + misc))
amine@267 135
amine@400 136 io_kwargs = {
amine@400 137 "input": "file",
amine@400 138 "max_read": 30,
amine@400 139 "block_dur": 0.01,
amine@400 140 "sampling_rate": 16000,
amine@400 141 "sample_width": 2,
amine@400 142 "channels": 2,
amine@400 143 "use_channel": exp_use_channel,
amine@400 144 "save_stream": save_stream,
amine@400 145 "save_detections_as": save_detections_as,
amine@418 146 "join_detections": join_detections,
amine@400 147 "audio_format": "raw",
amine@400 148 "export_format": "ogg",
amine@400 149 "large_file": True,
amine@400 150 "frames_per_buffer": None,
amine@400 151 "input_device_index": 1,
amine@400 152 "record": exp_record,
amine@400 153 }
amine@267 154
amine@400 155 split_kwargs = {
amine@400 156 "min_dur": 0.2,
amine@400 157 "max_dur": 10,
amine@400 158 "max_silence": 0.3,
amine@400 159 "drop_trailing_silence": False,
amine@400 160 "strict_min_dur": False,
amine@400 161 "energy_threshold": 55,
amine@400 162 }
amine@267 163
amine@400 164 miscellaneous = {
amine@400 165 "echo": False,
amine@400 166 "command": None,
amine@400 167 "progress_bar": False,
amine@400 168 "quiet": True,
amine@400 169 "printf": None,
amine@400 170 "time_format": "TIME_FORMAT",
amine@400 171 "timestamp_format": "TIMESTAMP_FORMAT",
amine@400 172 }
amine@267 173
amine@400 174 expected = KeywordArguments(io_kwargs, split_kwargs, miscellaneous)
amine@400 175 kwargs = make_kwargs(args_ns)
amine@400 176 assert kwargs == expected
amine@267 177
amine@268 178
amine@421 179 def test_make_kwargs_error():
amine@421 180
amine@421 181 args = (
amine@421 182 "file",
amine@421 183 30,
amine@421 184 0.01,
amine@421 185 16000,
amine@421 186 2,
amine@421 187 2,
amine@421 188 1,
amine@421 189 "raw",
amine@421 190 "ogg",
amine@421 191 True,
amine@421 192 None,
amine@421 193 1,
amine@421 194 None, # save_stream
amine@421 195 None,
amine@421 196 1.0, # join_detections
amine@421 197 None,
amine@421 198 None,
amine@421 199 0.2,
amine@421 200 10,
amine@421 201 0.3,
amine@421 202 False,
amine@421 203 False,
amine@421 204 55,
amine@421 205 False,
amine@421 206 False,
amine@421 207 None,
amine@421 208 True,
amine@421 209 None,
amine@421 210 "TIME_FORMAT",
amine@421 211 "TIMESTAMP_FORMAT",
amine@421 212 )
amine@421 213
amine@421 214 args_ns = _ArgsNamespace(*args)
amine@421 215 expected_err_msg = "using --join-detections/-j requires "
amine@421 216 expected_err_msg += "--save-stream/-O to be specified."
amine@421 217 with pytest.raises(ArgumentError) as arg_err:
amine@421 218 make_kwargs(args_ns)
amine@421 219 assert str(arg_err.value) == expected_err_msg
amine@421 220
amine@421 221
amine@400 222 def test_make_logger_stderr_and_file(capsys):
amine@400 223 with TemporaryDirectory() as tmpdir:
amine@400 224 file = os.path.join(tmpdir, "file.log")
amine@400 225 logger = make_logger(stderr=True, file=file)
amine@400 226 assert logger.name == _AUDITOK_LOGGER
amine@400 227 assert len(logger.handlers) == 2
amine@400 228 assert logger.handlers[1].stream.name == file
amine@400 229 logger.info("This is a debug message")
amine@400 230 captured = capsys.readouterr()
amine@400 231 assert "This is a debug message" in captured.err
amine@400 232
amine@400 233
amine@400 234 def test_make_logger_None():
amine@400 235 logger = make_logger(stderr=False, file=None)
amine@400 236 assert logger is None
amine@400 237
amine@400 238
amine@418 239 def test_initialize_workers_all_plus_full_stream_saver():
amine@400 240 with patch("auditok.cmdline_util.player_for") as patched_player_for:
amine@269 241 with TemporaryDirectory() as tmpdir:
amine@400 242 export_filename = os.path.join(tmpdir, "output.wav")
amine@418 243 reader, tokenizer_worker = initialize_workers(
amine@271 244 input="tests/data/test_16KHZ_mono_400Hz.wav",
amine@400 245 save_stream=export_filename,
amine@400 246 export_format="wave",
amine@400 247 save_detections_as="{id}.wav",
amine@418 248 join_detections=None,
amine@400 249 echo=True,
amine@400 250 progress_bar=False,
amine@400 251 command="some command",
amine@400 252 quiet=False,
amine@400 253 printf="abcd",
amine@400 254 time_format="%S",
amine@400 255 timestamp_format="%h:%M:%S",
amine@400 256 )
amine@400 257 reader.stop()
amine@400 258 assert patched_player_for.called
amine@400 259 assert isinstance(reader, StreamSaverWorker)
amine@400 260 for obs, cls in zip(
amine@418 261 tokenizer_worker._observers,
amine@400 262 [
amine@400 263 RegionSaverWorker,
amine@400 264 PlayerWorker,
amine@400 265 CommandLineWorker,
amine@400 266 PrintWorker,
amine@400 267 ],
amine@418 268 strict=True,
amine@418 269 ):
amine@418 270 assert isinstance(obs, cls)
amine@418 271
amine@418 272
amine@418 273 def test_initialize_workers_all_plus_audio_event_joiner():
amine@418 274 with patch("auditok.cmdline_util.player_for") as patched_player_for:
amine@418 275 with TemporaryDirectory() as tmpdir:
amine@418 276 export_filename = os.path.join(tmpdir, "output.wav")
amine@418 277 reader, tokenizer_worker = initialize_workers(
amine@418 278 input="tests/data/test_16KHZ_mono_400Hz.wav",
amine@418 279 save_stream=export_filename,
amine@418 280 export_format="wave",
amine@418 281 save_detections_as="{id}.wav",
amine@418 282 join_detections=1,
amine@418 283 echo=True,
amine@418 284 progress_bar=False,
amine@418 285 command="some command",
amine@418 286 quiet=False,
amine@418 287 printf="abcd",
amine@418 288 time_format="%S",
amine@418 289 timestamp_format="%h:%M:%S",
amine@418 290 )
amine@418 291 assert patched_player_for.called
amine@418 292 assert not isinstance(reader, StreamSaverWorker)
amine@418 293 for obs, cls in zip(
amine@418 294 tokenizer_worker._observers,
amine@418 295 [
amine@418 296 AudioEventsJoinerWorker,
amine@418 297 RegionSaverWorker,
amine@418 298 PlayerWorker,
amine@418 299 CommandLineWorker,
amine@418 300 PrintWorker,
amine@418 301 ],
amine@418 302 strict=True,
amine@400 303 ):
amine@400 304 assert isinstance(obs, cls)
amine@400 305
amine@400 306
amine@400 307 def test_initialize_workers_no_RegionSaverWorker():
amine@400 308 with patch("auditok.cmdline_util.player_for") as patched_player_for:
amine@400 309 with TemporaryDirectory() as tmpdir:
amine@400 310 export_filename = os.path.join(tmpdir, "output.wav")
amine@418 311 reader, tokenizer_worker = initialize_workers(
amine@400 312 input="tests/data/test_16KHZ_mono_400Hz.wav",
amine@400 313 save_stream=export_filename,
amine@271 314 export_format="wave",
amine@271 315 save_detections_as=None,
amine@418 316 join_detections=None,
amine@271 317 echo=True,
amine@271 318 progress_bar=False,
amine@400 319 command="some command",
amine@400 320 quiet=False,
amine@400 321 printf="abcd",
amine@400 322 time_format="%S",
amine@400 323 timestamp_format="%h:%M:%S",
amine@400 324 )
amine@400 325 reader.stop()
amine@400 326 assert patched_player_for.called
amine@400 327 assert isinstance(reader, StreamSaverWorker)
amine@400 328 for obs, cls in zip(
amine@418 329 tokenizer_worker._observers,
amine@418 330 [PlayerWorker, CommandLineWorker, PrintWorker],
amine@418 331 strict=True,
amine@400 332 ):
amine@400 333 assert isinstance(obs, cls)
amine@400 334
amine@400 335
amine@400 336 def test_initialize_workers_no_PlayerWorker():
amine@400 337 with patch("auditok.cmdline_util.player_for") as patched_player_for:
amine@400 338 with TemporaryDirectory() as tmpdir:
amine@400 339 export_filename = os.path.join(tmpdir, "output.wav")
amine@418 340 reader, tokenizer_worker = initialize_workers(
amine@400 341 input="tests/data/test_16KHZ_mono_400Hz.wav",
amine@400 342 save_stream=export_filename,
amine@400 343 export_format="wave",
amine@400 344 save_detections_as="{id}.wav",
amine@418 345 join_detections=None,
amine@400 346 echo=False,
amine@400 347 progress_bar=False,
amine@400 348 command="some command",
amine@400 349 quiet=False,
amine@400 350 printf="abcd",
amine@400 351 time_format="%S",
amine@400 352 timestamp_format="%h:%M:%S",
amine@400 353 )
amine@400 354 reader.stop()
amine@400 355 assert not patched_player_for.called
amine@400 356 assert isinstance(reader, StreamSaverWorker)
amine@400 357 for obs, cls in zip(
amine@418 358 tokenizer_worker._observers,
amine@400 359 [RegionSaverWorker, CommandLineWorker, PrintWorker],
amine@418 360 strict=True,
amine@400 361 ):
amine@400 362 assert isinstance(obs, cls)
amine@400 363
amine@400 364
amine@400 365 def test_initialize_workers_no_CommandLineWorker():
amine@400 366 with patch("auditok.cmdline_util.player_for") as patched_player_for:
amine@400 367 with TemporaryDirectory() as tmpdir:
amine@400 368 export_filename = os.path.join(tmpdir, "output.wav")
amine@418 369 reader, tokenizer_worker = initialize_workers(
amine@400 370 input="tests/data/test_16KHZ_mono_400Hz.wav",
amine@400 371 save_stream=export_filename,
amine@400 372 export_format="wave",
amine@400 373 save_detections_as="{id}.wav",
amine@418 374 join_detections=None,
amine@400 375 echo=True,
amine@400 376 progress_bar=False,
amine@271 377 command=None,
amine@400 378 quiet=False,
amine@400 379 printf="abcd",
amine@400 380 time_format="%S",
amine@400 381 timestamp_format="%h:%M:%S",
amine@400 382 )
amine@400 383 reader.stop()
amine@400 384 assert patched_player_for.called
amine@400 385 assert isinstance(reader, StreamSaverWorker)
amine@400 386 for obs, cls in zip(
amine@418 387 tokenizer_worker._observers,
amine@418 388 [RegionSaverWorker, PlayerWorker, PrintWorker],
amine@418 389 strict=True,
amine@400 390 ):
amine@400 391 assert isinstance(obs, cls)
amine@400 392
amine@400 393
amine@400 394 def test_initialize_workers_no_PrintWorker():
amine@400 395 with patch("auditok.cmdline_util.player_for") as patched_player_for:
amine@400 396 with TemporaryDirectory() as tmpdir:
amine@400 397 export_filename = os.path.join(tmpdir, "output.wav")
amine@418 398 reader, tokenizer_worker = initialize_workers(
amine@400 399 input="tests/data/test_16KHZ_mono_400Hz.wav",
amine@400 400 save_stream=export_filename,
amine@400 401 export_format="wave",
amine@400 402 save_detections_as="{id}.wav",
amine@418 403 join_detections=None,
amine@400 404 echo=True,
amine@400 405 progress_bar=False,
amine@400 406 command="some command",
amine@271 407 quiet=True,
amine@271 408 printf="abcd",
amine@271 409 time_format="%S",
amine@271 410 timestamp_format="%h:%M:%S",
amine@271 411 )
amine@400 412 reader.stop()
amine@400 413 assert patched_player_for.called
amine@400 414 assert isinstance(reader, StreamSaverWorker)
amine@400 415 for obs, cls in zip(
amine@418 416 tokenizer_worker._observers,
amine@400 417 [RegionSaverWorker, PlayerWorker, CommandLineWorker],
amine@418 418 strict=True,
amine@400 419 ):
amine@400 420 assert isinstance(obs, cls)
amine@337 421
amine@337 422
amine@400 423 def test_initialize_workers_no_observers():
amine@400 424 with patch("auditok.cmdline_util.player_for") as patched_player_for:
amine@418 425 reader, tokenizer_worker = initialize_workers(
amine@400 426 input="tests/data/test_16KHZ_mono_400Hz.wav",
amine@400 427 save_stream=None,
amine@400 428 export_format="wave",
amine@400 429 save_detections_as=None,
amine@400 430 echo=True,
amine@400 431 progress_bar=False,
amine@400 432 command=None,
amine@400 433 quiet=True,
amine@400 434 printf="abcd",
amine@400 435 time_format="%S",
amine@400 436 timestamp_format="%h:%M:%S",
amine@400 437 )
amine@400 438 assert patched_player_for.called
amine@400 439 assert not isinstance(reader, StreamSaverWorker)
amine@418 440 assert len(tokenizer_worker._observers) == 1