Add command parsing tests, decoding function tests
parent
ebb710e416
commit
3b7fec89a5
|
@ -1,7 +1,7 @@
|
||||||
"""Parsing arguments and starting program from command line"""
|
"""Parsing arguments and starting program from command line"""
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
from sys import exit
|
from sys import argv, exit
|
||||||
|
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
from soundfile import available_formats as available_audio_formats
|
from soundfile import available_formats as available_audio_formats
|
||||||
|
@ -25,13 +25,16 @@ examples:
|
||||||
Start decoding SSTV signal at 50.5 seconds into the audio
|
Start decoding SSTV signal at 50.5 seconds into the audio
|
||||||
$ sstv -d audio.ogg -s 50.50"""
|
$ sstv -d audio.ogg -s 50.50"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, shell_args=None):
|
||||||
"""Handle command line arguments"""
|
"""Handle command line arguments"""
|
||||||
|
|
||||||
self._audio_file = None
|
self._audio_file = None
|
||||||
self._output_file = None
|
self._output_file = None
|
||||||
|
|
||||||
self.args = self.parse_args()
|
if shell_args is None:
|
||||||
|
self.args = self.parse_args(argv[1:])
|
||||||
|
else:
|
||||||
|
self.args = self.parse_args(shell_args)
|
||||||
|
|
||||||
def __enter__(self):
|
def __enter__(self):
|
||||||
return self
|
return self
|
||||||
|
@ -62,8 +65,6 @@ examples:
|
||||||
default=0.0, dest="skip")
|
default=0.0, dest="skip")
|
||||||
parser.add_argument("-V", "--version", action="version",
|
parser.add_argument("-V", "--version", action="version",
|
||||||
version=version)
|
version=version)
|
||||||
parser.add_argument("-v", "--verbose", action="count", default=1,
|
|
||||||
help="increase output to the terminal")
|
|
||||||
parser.add_argument("--list-modes", action="store_true",
|
parser.add_argument("--list-modes", action="store_true",
|
||||||
dest="list_modes",
|
dest="list_modes",
|
||||||
help="list supported SSTV modes")
|
help="list supported SSTV modes")
|
||||||
|
@ -75,11 +76,11 @@ examples:
|
||||||
help="list supported image file formats")
|
help="list supported image file formats")
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def parse_args(self):
|
def parse_args(self, shell_args):
|
||||||
"""Parse command line arguments"""
|
"""Parse command line arguments"""
|
||||||
|
|
||||||
parser = self.init_args()
|
parser = self.init_args()
|
||||||
args = parser.parse_args()
|
args = parser.parse_args(shell_args)
|
||||||
|
|
||||||
self._audio_file = args.audio_file
|
self._audio_file = args.audio_file
|
||||||
self._output_file = args.output_file
|
self._output_file = args.output_file
|
||||||
|
|
Binary file not shown.
|
@ -0,0 +1,64 @@
|
||||||
|
"""Test cases for the CLI code"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import unittest
|
||||||
|
from io import StringIO
|
||||||
|
|
||||||
|
from sstv.command import SSTVCommand
|
||||||
|
|
||||||
|
|
||||||
|
class SSTVCommandTestCase(unittest.TestCase):
|
||||||
|
"""Test SSTVCommand class"""
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
"""Capture standard input/error using StringIO instance"""
|
||||||
|
sys.stdout = StringIO()
|
||||||
|
sys.stderr = StringIO()
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
"""Reset standard output/error"""
|
||||||
|
sys.stdout = sys.__stdout__
|
||||||
|
sys.stderr = sys.__stderr__
|
||||||
|
|
||||||
|
def test_arg_parser_output(self):
|
||||||
|
"""Test --list-modes flag outputs correctly"""
|
||||||
|
with self.assertRaises(SystemExit):
|
||||||
|
SSTVCommand(["--list-modes"])
|
||||||
|
modes = "Supported modes: Robot 36, Robot 72, Martin 2, Martin 1, Scottie 2, Scottie 1, Scottie DX"
|
||||||
|
self.assertEqual(sys.stdout.getvalue().strip(), modes, "List of modes not equal")
|
||||||
|
|
||||||
|
def test_arg_parser_decode_error(self):
|
||||||
|
"""Test decode flag with no input"""
|
||||||
|
with self.assertRaises(SystemExit):
|
||||||
|
SSTVCommand(["-d"])
|
||||||
|
self.assertIn("expected one argument", sys.stderr.getvalue().strip(),
|
||||||
|
"Wrong argument error message not present in output")
|
||||||
|
|
||||||
|
with self.assertRaises(SystemExit):
|
||||||
|
SSTVCommand(["--decode"])
|
||||||
|
self.assertIn("expected one argument", sys.stderr.getvalue().strip(),
|
||||||
|
"'Wrong argument' error message not present in output")
|
||||||
|
|
||||||
|
with self.assertRaises(SystemExit):
|
||||||
|
SSTVCommand(["-d", "./test/data/abc123"])
|
||||||
|
self.assertIn("No such file or directory", sys.stderr.getvalue().strip(),
|
||||||
|
"'No file' error message not present in output")
|
||||||
|
|
||||||
|
def test_arg_parser_decode_success(self):
|
||||||
|
"""Test decode flag with no input"""
|
||||||
|
args = SSTVCommand(["-d", "./test/data/m1.ogg"]).args
|
||||||
|
self.assertTrue(hasattr(args, "audio_file"),
|
||||||
|
"audio_file attribute not set")
|
||||||
|
self.assertEqual(args.audio_file.name, "./test/data/m1.ogg",
|
||||||
|
"Audio file name not set correctly")
|
||||||
|
self.assertTrue(hasattr(args, "skip"),
|
||||||
|
"skip attribute not set")
|
||||||
|
self.assertEqual(args.skip, 0.0,
|
||||||
|
"skip value not set to default value")
|
||||||
|
|
||||||
|
def test_arg_parser_decode_set_skip(self):
|
||||||
|
args = SSTVCommand(["-d", "./test/data/m1.ogg", "-s", "15.50"]).args
|
||||||
|
self.assertTrue(hasattr(args, "skip"),
|
||||||
|
"skip attribute not set")
|
||||||
|
self.assertEqual(args.skip, 15.5,
|
||||||
|
"skip value not set correctly")
|
|
@ -0,0 +1,28 @@
|
||||||
|
"""Test cases for the decoder code"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from sstv.decode import barycentric_peak_interp, calc_lum, SSTVDecoder
|
||||||
|
|
||||||
|
|
||||||
|
class SSTVDecoderTestCase(unittest.TestCase):
|
||||||
|
"""Test SSTVDecoder class"""
|
||||||
|
|
||||||
|
def test_calc_lum(self):
|
||||||
|
self.assertEqual(calc_lum(1450), 0)
|
||||||
|
self.assertEqual(calc_lum(2350), 255)
|
||||||
|
self.assertEqual(calc_lum(1758.1531), 82)
|
||||||
|
|
||||||
|
def test_barycentric_peak_interp(self):
|
||||||
|
bins = [100, 50, 0, 25, 50, 75, 100, 200, 150, 100]
|
||||||
|
# Left neighbour is higher, so result must be smaller/equal
|
||||||
|
self.assertLess(barycentric_peak_interp(bins, 9), 9)
|
||||||
|
# Right neighbour is smaller and no left, so it must be smaller
|
||||||
|
self.assertLessEqual(barycentric_peak_interp(bins, 0), 0)
|
||||||
|
# Right neighbour is larger than left, so x must increase
|
||||||
|
self.assertGreaterEqual(barycentric_peak_interp(bins, 7), 7)
|
||||||
|
|
||||||
|
bins = [1, 2, 2, 2, 1]
|
||||||
|
# Centre 2 surrounded by 2s should result in no change
|
||||||
|
self.assertEqual(barycentric_peak_interp(bins, 2), 2)
|
Loading…
Reference in New Issue