1
0
Fork 0

Add command parsing tests, decoding function tests

master
James Taylor 2019-11-03 16:51:02 +00:00
parent ebb710e416
commit 3b7fec89a5
5 changed files with 100 additions and 7 deletions

View File

@ -1,7 +1,7 @@
"""Parsing arguments and starting program from command line"""
import argparse
from sys import exit
from sys import argv, exit
from PIL import Image
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
$ sstv -d audio.ogg -s 50.50"""
def __init__(self):
def __init__(self, shell_args=None):
"""Handle command line arguments"""
self._audio_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):
return self
@ -62,8 +65,6 @@ examples:
default=0.0, dest="skip")
parser.add_argument("-V", "--version", action="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",
dest="list_modes",
help="list supported SSTV modes")
@ -75,11 +76,11 @@ examples:
help="list supported image file formats")
return parser
def parse_args(self):
def parse_args(self, shell_args):
"""Parse command line arguments"""
parser = self.init_args()
args = parser.parse_args()
args = parser.parse_args(shell_args)
self._audio_file = args.audio_file
self._output_file = args.output_file

0
test/__init__.py 100644
View File

BIN
test/data/m1.ogg 100644

Binary file not shown.

View File

@ -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")

View File

@ -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)