annotate tests/test_cmdline_util.py @ 297:7259b1eb9329

Refactor StreamTokenizer - Remove unused code - accept a callable validator - update doc
author Amine Sehili <amine.sehili@gmail.com>
date Tue, 08 Oct 2019 19:48:13 +0100
parents 9907db0843cb
children 9741b52f194a
rev   line source
amine@269 1 import os
amine@267 2 from unittest import TestCase
amine@271 3 from unittest.mock import patch
amine@269 4 from tempfile import TemporaryDirectory
amine@267 5 from collections import namedtuple
amine@267 6 from genty import genty, genty_dataset
amine@267 7
amine@267 8 from auditok.cmdline_util import (
amine@273 9 _AUDITOK_LOGGER,
amine@267 10 make_kwargs,
amine@291 11 make_duration_formatter,
amine@267 12 make_logger,
amine@267 13 initialize_workers,
amine@267 14 KeywordArguments,
amine@267 15 )
amine@271 16 from auditok.workers import (
amine@271 17 StreamSaverWorker,
amine@271 18 RegionSaverWorker,
amine@271 19 PlayerWorker,
amine@271 20 CommandLineWorker,
amine@271 21 PrintWorker,
amine@271 22 )
amine@267 23 from auditok.exceptions import TimeFormatError
amine@267 24
amine@267 25 _ArgsNamespece = namedtuple(
amine@267 26 "_ArgsNamespece",
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@267 42 "plot",
amine@267 43 "save_image",
amine@267 44 "min_duration",
amine@267 45 "max_duration",
amine@267 46 "max_silence",
amine@267 47 "drop_trailing_silence",
amine@267 48 "strict_min_duration",
amine@267 49 "energy_threshold",
amine@267 50 "echo",
amine@292 51 "progress_bar",
amine@267 52 "command",
amine@267 53 "quiet",
amine@267 54 "printf",
amine@267 55 "time_format",
amine@267 56 "timestamp_format",
amine@267 57 ],
amine@267 58 )
amine@267 59
amine@267 60
amine@267 61 @genty
amine@292 62 class TestCmdLineUtil(TestCase):
amine@267 63 @genty_dataset(
amine@292 64 no_record=("stream.ogg", None, False, None, "mix", "mix", False),
amine@292 65 no_record_plot=("stream.ogg", None, True, None, None, None, False),
amine@267 66 no_record_save_image=(
amine@267 67 "stream.ogg",
amine@292 68 None,
amine@267 69 True,
amine@267 70 "image.png",
amine@267 71 None,
amine@267 72 None,
amine@267 73 False,
amine@267 74 ),
amine@292 75 record_plot=(None, None, True, None, None, None, True),
amine@292 76 record_save_image=(None, None, False, "image.png", None, None, True),
amine@292 77 int_use_channel=("stream.ogg", None, False, None, "1", 1, False),
amine@292 78 save_detections_as=("stream.ogg", "{id}.wav", False, None, None, None, False)
amine@267 79 )
amine@267 80 def test_make_kwargs(
amine@267 81 self,
amine@267 82 save_stream,
amine@292 83 save_detections_as,
amine@267 84 plot,
amine@267 85 save_image,
amine@267 86 use_channel,
amine@267 87 exp_use_channel,
amine@267 88 exp_record,
amine@267 89 ):
amine@267 90
amine@267 91 args = (
amine@267 92 "file",
amine@267 93 30,
amine@267 94 0.01,
amine@267 95 16000,
amine@267 96 2,
amine@267 97 2,
amine@267 98 use_channel,
amine@267 99 "raw",
amine@267 100 "ogg",
amine@267 101 True,
amine@267 102 None,
amine@267 103 1,
amine@267 104 save_stream,
amine@292 105 save_detections_as,
amine@267 106 plot,
amine@267 107 save_image,
amine@267 108 0.2,
amine@267 109 10,
amine@267 110 0.3,
amine@267 111 False,
amine@267 112 False,
amine@267 113 55,
amine@267 114 )
amine@292 115 misc = (False, False, None, True, None, "TIME_FORMAT", "TIMESTAMP_FORMAT")
amine@267 116 args_ns = _ArgsNamespece(*(args + misc))
amine@267 117
amine@267 118 io_kwargs = {
amine@267 119 "input": "file",
amine@267 120 "max_read": 30,
amine@267 121 "block_dur": 0.01,
amine@267 122 "sampling_rate": 16000,
amine@267 123 "sample_width": 2,
amine@267 124 "channels": 2,
amine@267 125 "use_channel": exp_use_channel,
amine@267 126 "save_stream": save_stream,
amine@292 127 "save_detections_as": save_detections_as,
amine@267 128 "audio_format": "raw",
amine@267 129 "export_format": "ogg",
amine@267 130 "large_file": True,
amine@267 131 "frames_per_buffer": None,
amine@267 132 "input_device_index": 1,
amine@267 133 "record": exp_record,
amine@267 134 }
amine@267 135
amine@267 136 split_kwargs = {
amine@267 137 "min_dur": 0.2,
amine@267 138 "max_dur": 10,
amine@267 139 "max_silence": 0.3,
amine@267 140 "drop_trailing_silence": False,
amine@267 141 "strict_min_dur": False,
amine@267 142 "energy_threshold": 55,
amine@267 143 }
amine@267 144
amine@267 145 miscellaneous = {
amine@267 146 "echo": False,
amine@267 147 "command": None,
amine@292 148 "progress_bar": False,
amine@267 149 "quiet": True,
amine@267 150 "printf": None,
amine@267 151 "time_format": "TIME_FORMAT",
amine@267 152 "timestamp_format": "TIMESTAMP_FORMAT",
amine@267 153 }
amine@267 154
amine@267 155 expected = KeywordArguments(io_kwargs, split_kwargs, miscellaneous)
amine@267 156 kwargs = make_kwargs(args_ns)
amine@267 157 self.assertEqual(kwargs, expected)
amine@268 158
amine@268 159 @genty_dataset(
amine@268 160 only_seconds=("%S", 5400, "5400.000"),
amine@268 161 only_millis=("%I", 5400, "5400000"),
amine@268 162 full=("%h:%m:%s.%i", 3725.365, "01:02:05.365"),
amine@268 163 full_zero_hours=("%h:%m:%s.%i", 1925.075, "00:32:05.075"),
amine@268 164 full_zero_minutes=("%h:%m:%s.%i", 3659.075, "01:00:59.075"),
amine@268 165 full_zero_seconds=("%h:%m:%s.%i", 3720.075, "01:02:00.075"),
amine@268 166 full_zero_millis=("%h:%m:%s.%i", 3725, "01:02:05.000"),
amine@268 167 duplicate_directive=(
amine@268 168 "%h %h:%m:%s.%i %s",
amine@268 169 3725.365,
amine@268 170 "01 01:02:05.365 05",
amine@268 171 ),
amine@268 172 no_millis=("%h:%m:%s", 3725, "01:02:05"),
amine@268 173 no_seconds=("%h:%m", 3725, "01:02"),
amine@268 174 no_minutes=("%h", 3725, "01"),
amine@268 175 no_hours=("%m:%s.%i", 3725, "02:05.000"),
amine@268 176 )
amine@291 177 def test_make_duration_formatter(self, fmt, duration, expected):
amine@291 178 formatter = make_duration_formatter(fmt)
amine@268 179 result = formatter(duration)
amine@268 180 self.assertEqual(result, expected)
amine@268 181
amine@268 182 @genty_dataset(
amine@268 183 duplicate_only_seconds=("%S %S",),
amine@268 184 duplicate_only_millis=("%I %I",),
amine@268 185 unknown_directive=("%x",),
amine@268 186 )
amine@291 187 def test_make_duration_formatter_error(self, fmt):
amine@268 188 with self.assertRaises(TimeFormatError):
amine@291 189 make_duration_formatter(fmt)
amine@269 190
amine@273 191 def test_make_logger_stderr_and_file(self):
amine@269 192 with TemporaryDirectory() as tmpdir:
amine@269 193 file = os.path.join(tmpdir, "file.log")
amine@273 194 logger = make_logger(stderr=True, file=file)
amine@273 195 self.assertEqual(logger.name, _AUDITOK_LOGGER)
amine@269 196 self.assertEqual(len(logger.handlers), 2)
amine@273 197 self.assertEqual(logger.handlers[0].stream.name, "<stderr>")
amine@269 198 self.assertEqual(logger.handlers[1].stream.name, file)
amine@269 199
amine@269 200 def test_make_logger_None(self):
amine@273 201 logger = make_logger(stderr=False, file=None)
amine@269 202 self.assertIsNone(logger)
amine@271 203
amine@271 204 def test_initialize_workers_all(self):
amine@271 205 with patch("auditok.cmdline_util.player_for") as patched_player_for:
amine@285 206 with TemporaryDirectory() as tmpdir:
amine@285 207 export_filename = os.path.join(tmpdir, "output.wav")
amine@285 208 reader, observers = initialize_workers(
amine@285 209 input="tests/data/test_16KHZ_mono_400Hz.wav",
amine@285 210 save_stream=export_filename,
amine@285 211 export_format="wave",
amine@285 212 save_detections_as="{id}.wav",
amine@285 213 echo=True,
amine@285 214 progress_bar=False,
amine@285 215 command="some command",
amine@285 216 quiet=False,
amine@285 217 printf="abcd",
amine@285 218 time_format="%S",
amine@285 219 timestamp_format="%h:%M:%S",
amine@285 220 )
amine@285 221 reader.stop()
amine@285 222 self.assertTrue(patched_player_for.called)
amine@285 223 self.assertIsInstance(reader, StreamSaverWorker)
amine@285 224 for obs, cls in zip(
amine@285 225 observers,
amine@285 226 [
amine@285 227 RegionSaverWorker,
amine@285 228 PlayerWorker,
amine@285 229 CommandLineWorker,
amine@285 230 PrintWorker,
amine@285 231 ],
amine@285 232 ):
amine@285 233 self.assertIsInstance(obs, cls)
amine@271 234
amine@271 235 def test_initialize_workers_no_RegionSaverWorker(self):
amine@271 236 with patch("auditok.cmdline_util.player_for") as patched_player_for:
amine@285 237 with TemporaryDirectory() as tmpdir:
amine@285 238 export_filename = os.path.join(tmpdir, "output.wav")
amine@285 239 reader, observers = initialize_workers(
amine@285 240 input="tests/data/test_16KHZ_mono_400Hz.wav",
amine@285 241 save_stream=export_filename,
amine@285 242 export_format="wave",
amine@285 243 save_detections_as=None,
amine@285 244 echo=True,
amine@285 245 progress_bar=False,
amine@285 246 command="some command",
amine@285 247 quiet=False,
amine@285 248 printf="abcd",
amine@285 249 time_format="%S",
amine@285 250 timestamp_format="%h:%M:%S",
amine@285 251 )
amine@285 252 reader.stop()
amine@285 253 self.assertTrue(patched_player_for.called)
amine@285 254 self.assertIsInstance(reader, StreamSaverWorker)
amine@285 255 for obs, cls in zip(
amine@285 256 observers, [PlayerWorker, CommandLineWorker, PrintWorker]
amine@285 257 ):
amine@285 258 self.assertIsInstance(obs, cls)
amine@271 259
amine@271 260 def test_initialize_workers_no_PlayerWorker(self):
amine@271 261 with patch("auditok.cmdline_util.player_for") as patched_player_for:
amine@285 262 with TemporaryDirectory() as tmpdir:
amine@285 263 export_filename = os.path.join(tmpdir, "output.wav")
amine@285 264 reader, observers = initialize_workers(
amine@285 265 input="tests/data/test_16KHZ_mono_400Hz.wav",
amine@285 266 save_stream=export_filename,
amine@285 267 export_format="wave",
amine@285 268 save_detections_as="{id}.wav",
amine@285 269 echo=False,
amine@285 270 progress_bar=False,
amine@285 271 command="some command",
amine@285 272 quiet=False,
amine@285 273 printf="abcd",
amine@285 274 time_format="%S",
amine@285 275 timestamp_format="%h:%M:%S",
amine@285 276 )
amine@285 277 reader.stop()
amine@285 278 self.assertFalse(patched_player_for.called)
amine@285 279 self.assertIsInstance(reader, StreamSaverWorker)
amine@285 280 for obs, cls in zip(
amine@285 281 observers,
amine@285 282 [RegionSaverWorker, CommandLineWorker, PrintWorker],
amine@285 283 ):
amine@285 284 self.assertIsInstance(obs, cls)
amine@271 285
amine@271 286 def test_initialize_workers_no_CommandLineWorker(self):
amine@271 287 with patch("auditok.cmdline_util.player_for") as patched_player_for:
amine@285 288 with TemporaryDirectory() as tmpdir:
amine@285 289 export_filename = os.path.join(tmpdir, "output.wav")
amine@285 290 reader, observers = initialize_workers(
amine@285 291 input="tests/data/test_16KHZ_mono_400Hz.wav",
amine@285 292 save_stream=export_filename,
amine@285 293 export_format="wave",
amine@285 294 save_detections_as="{id}.wav",
amine@285 295 echo=True,
amine@285 296 progress_bar=False,
amine@285 297 command=None,
amine@285 298 quiet=False,
amine@285 299 printf="abcd",
amine@285 300 time_format="%S",
amine@285 301 timestamp_format="%h:%M:%S",
amine@285 302 )
amine@285 303 reader.stop()
amine@285 304 self.assertTrue(patched_player_for.called)
amine@285 305 self.assertIsInstance(reader, StreamSaverWorker)
amine@285 306 for obs, cls in zip(
amine@285 307 observers, [RegionSaverWorker, PlayerWorker, PrintWorker]
amine@285 308 ):
amine@285 309 self.assertIsInstance(obs, cls)
amine@271 310
amine@271 311 def test_initialize_workers_no_PrintWorker(self):
amine@271 312 with patch("auditok.cmdline_util.player_for") as patched_player_for:
amine@285 313 with TemporaryDirectory() as tmpdir:
amine@285 314 export_filename = os.path.join(tmpdir, "output.wav")
amine@285 315 reader, observers = initialize_workers(
amine@285 316 input="tests/data/test_16KHZ_mono_400Hz.wav",
amine@285 317 save_stream=export_filename,
amine@285 318 export_format="wave",
amine@285 319 save_detections_as="{id}.wav",
amine@285 320 echo=True,
amine@285 321 progress_bar=False,
amine@285 322 command="some command",
amine@285 323 quiet=True,
amine@285 324 printf="abcd",
amine@285 325 time_format="%S",
amine@285 326 timestamp_format="%h:%M:%S",
amine@285 327 )
amine@285 328 reader.stop()
amine@285 329 self.assertTrue(patched_player_for.called)
amine@285 330 self.assertIsInstance(reader, StreamSaverWorker)
amine@285 331 for obs, cls in zip(
amine@285 332 observers,
amine@285 333 [RegionSaverWorker, PlayerWorker, CommandLineWorker],
amine@285 334 ):
amine@285 335 self.assertIsInstance(obs, cls)
amine@271 336
amine@271 337 def test_initialize_workers_no_observers(self):
amine@271 338 with patch("auditok.cmdline_util.player_for") as patched_player_for:
amine@271 339 reader, observers = initialize_workers(
amine@271 340 input="tests/data/test_16KHZ_mono_400Hz.wav",
amine@271 341 save_stream=None,
amine@271 342 export_format="wave",
amine@271 343 save_detections_as=None,
amine@271 344 echo=True,
amine@271 345 progress_bar=False,
amine@271 346 command=None,
amine@271 347 quiet=True,
amine@271 348 printf="abcd",
amine@271 349 time_format="%S",
amine@271 350 timestamp_format="%h:%M:%S",
amine@271 351 )
amine@271 352 self.assertTrue(patched_player_for.called)
amine@271 353 self.assertFalse(isinstance(reader, StreamSaverWorker))
amine@271 354 self.assertTrue(len(observers), 0)