wwvbpy/src/wwvb/testcli.py
Jeff Epler df39d0eab6
Test DUT1 data against leapseconddata
.. fix the leap seconds in 1972, which are not in Bulletin A.

.. add the moment of the leap second to the `dut1table`
outut, which is otherwise confusing to intuit

.. allow processing a local copy of the finals2000A file, for quicker
turnaround when developing updateiers
2022-10-08 13:40:56 -05:00

231 lines
8.3 KiB
Python

#!/usr/bin/python3
"""Test most wwvblib commandline programs"""
# Copyright (C) 2011-2020 Jeff Epler <jepler@gmail.com>
# SPDX-FileCopyrightText: 2021 Jeff Epler
#
# SPDX-License-Identifier: GPL-3.0-only
# pylint: disable=invalid-name
import os
import subprocess
import sys
import unittest
coverage_add = (
("-m", "coverage", "run", "--branch", "-p") if "COVERAGE_RUN" in os.environ else ()
)
class CLITestCase(unittest.TestCase):
"""Test various CLI commands within wwvbpy"""
def assertProgramOutput(self, expected: str, *args: str) -> None:
"""Check the output from invoking a program matches the expected"""
env = os.environ.copy()
env["PYTHONIOENCODING"] = "utf-8"
actual = subprocess.check_output(
args, stdin=subprocess.DEVNULL, encoding="utf-8", env=env
)
self.assertMultiLineEqual(expected, actual, f"args={args}")
def assertProgramOutputStarts(self, expected: str, *args: str) -> None:
"""Check the output from invoking a program matches the expected"""
env = os.environ.copy()
env["PYTHONIOENCODING"] = "utf-8"
actual = subprocess.check_output(
args, stdin=subprocess.DEVNULL, encoding="utf-8", env=env
)
self.assertMultiLineEqual(expected, actual[: len(expected)], f"args={args}")
def assertModuleOutput(self, expected: str, *args: str) -> None:
"""Check the output from invoking a `python -m modulename` program matches the expected"""
return self.assertProgramOutput(
expected, sys.executable, *coverage_add, "-m", *args
)
def assertModuleOutputStarts(self, expected: str, *args: str) -> None:
"""Check the output from invoking a `python -m modulename` program matches the expected"""
return self.assertProgramOutputStarts(
expected, sys.executable, *coverage_add, "-m", *args
)
def assertProgramError(self, *args: str) -> None:
"""Check the output from invoking a program fails"""
env = os.environ.copy()
env["PYTHONIOENCODING"] = "utf-8"
with self.assertRaises(subprocess.SubprocessError):
subprocess.check_output(
args,
stdin=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
encoding="utf-8",
env=env,
)
def assertModuleError(self, *args: str) -> None:
"""Check the output from invoking a `python -m modulename` program fails"""
return self.assertProgramError(sys.executable, *coverage_add, "-m", *args)
def test_gen(self) -> None:
"""test wwvb.gen"""
self.assertModuleOutput(
"""\
WWVB timecode: year=2020 days=001 hour=12 min=30 dst=0 ut1=-200 ly=1 ls=0
2020-001 12:30 201100000200010001020000000002000100010200100001020000010002
""",
"wwvb.gen",
"-m",
"1",
"2020-1-1 12:30",
)
self.assertModuleOutput(
"""\
WWVB timecode: year=2020 days=001 hour=12 min=30 dst=0 ut1=-200 ly=1 ls=0
2020-001 12:30 201100000200010001020000000002000100010200100001020000010002
""",
"wwvb.gen",
"-m",
"1",
"2020",
"1",
"12",
"30",
)
self.assertModuleOutput(
"""\
WWVB timecode: year=2020 days=001 hour=12 min=30 dst=0 ut1=-200 ly=1 ls=0
2020-001 12:30 201100000200010001020000000002000100010200100001020000010002
""",
"wwvb.gen",
"-m",
"1",
"2020",
"1",
"1",
"12",
"30",
)
self.assertModuleError("wwvb.gen", "-m", "1", "2021", "7")
# Asserting a leap second
self.assertModuleOutput(
"""\
WWVB timecode: year=2020 days=001 hour=12 min=30 dst=0 ut1=-500 ly=1 ls=1
2020-001 12:30 201100000200010001020000000002000100010201010001020000011002
""",
"wwvb.gen",
"-m",
"1",
"-s",
"2020-1-1 12:30",
)
# Asserting a different ut1 value
self.assertModuleOutput(
"""\
WWVB timecode: year=2020 days=001 hour=12 min=30 dst=0 ut1=-300 ly=1 ls=0
2020-001 12:30 201100000200010001020000000002000100010200110001020000010002
""",
"wwvb.gen",
"-m",
"1",
"-d",
"-300",
"2020-1-1 12:30",
)
def test_dut1table(self) -> None:
"""Test the dut1table program"""
self.assertModuleOutputStarts(
"""\
1972-01-01 -0.2 182 LS on 1972-06-30 23:59:60 UTC
1972-07-01 0.8 123
1972-11-01 0.0 30
1972-12-01 -0.2 31 LS on 1972-12-31 23:59:60 UTC
""",
"wwvb.dut1table",
)
def test_json(self) -> None:
"""Test the JSON output format"""
self.assertModuleOutput(
"""\
[{"year": 2021, "days": 340, "hour": 3, "minute": 40, "amplitude": "210000000200000001120011001002000000010200010001020001000002", "phase": "111110011011010101000100100110011110001110111010111101001011"}, {"year": 2021, "days": 340, "hour": 3, "minute": 41, "amplitude": "210000001200000001120011001002000000010200010001020001000002", "phase": "001010011100100011000101110000100001101000001111101100000010"}]
""",
"wwvb.gen",
"-m",
"2",
"--style",
"json",
"--channel",
"both",
"2021-12-6 3:40",
)
self.assertModuleOutput(
"""\
[{"year": 2021, "days": 340, "hour": 3, "minute": 40, "amplitude": "210000000200000001120011001002000000010200010001020001000002"}, {"year": 2021, "days": 340, "hour": 3, "minute": 41, "amplitude": "210000001200000001120011001002000000010200010001020001000002"}]
""",
"wwvb.gen",
"-m",
"2",
"--style",
"json",
"--channel",
"amplitude",
"2021-12-6 3:40",
)
self.assertModuleOutput(
"""\
[{"year": 2021, "days": 340, "hour": 3, "minute": 40, "phase": "111110011011010101000100100110011110001110111010111101001011"}, {"year": 2021, "days": 340, "hour": 3, "minute": 41, "phase": "001010011100100011000101110000100001101000001111101100000010"}]
""",
"wwvb.gen",
"-m",
"2",
"--style",
"json",
"--channel",
"phase",
"2021-12-6 3:40",
)
def test_sextant(self) -> None:
"""Test the sextant output format"""
self.assertModuleOutput(
"""\
WWVB timecode: year=2021 days=340 hour=03 min=40 dst=0 ut1=-100 ly=0 ls=0 --style=sextant
2021-340 03:40 🬋🬩🬋🬹🬩🬹🬩🬹🬩🬹🬍🬎🬍🬎🬩🬹🬩🬹🬋🬍🬩🬹🬩🬹🬍🬎🬩🬹🬍🬎🬩🬹🬍🬎🬋🬹🬋🬎🬋🬍🬍🬎🬩🬹🬋🬎🬋🬎🬩🬹🬍🬎🬋🬎🬩🬹🬩🬹🬋🬍🬍🬎🬩🬹🬩🬹🬩🬹🬩🬹🬍🬎🬍🬎🬋🬎🬩🬹🬋🬩🬩🬹🬍🬎🬩🬹🬋🬹🬩🬹🬍🬎🬩🬹🬋🬎🬩🬹🬋🬩🬩🬹🬩🬹🬍🬎🬋🬹🬍🬎🬍🬎🬩🬹🬍🬎🬩🬹🬋🬩
2021-340 03:41 🬋🬍🬋🬎🬩🬹🬍🬎🬩🬹🬍🬎🬍🬎🬩🬹🬋🬹🬋🬩🬍🬎🬍🬎🬩🬹🬍🬎🬍🬎🬍🬎🬩🬹🬋🬹🬋🬎🬋🬍🬍🬎🬩🬹🬋🬎🬋🬹🬩🬹🬩🬹🬋🬎🬍🬎🬍🬎🬋🬍🬩🬹🬍🬎🬍🬎🬍🬎🬍🬎🬩🬹🬩🬹🬋🬎🬩🬹🬋🬍🬍🬎🬍🬎🬍🬎🬋🬎🬩🬹🬩🬹🬩🬹🬋🬹🬩🬹🬋🬍🬩🬹🬩🬹🬍🬎🬋🬎🬍🬎🬍🬎🬍🬎🬍🬎🬩🬹🬋🬍
""",
"wwvb.gen",
"-m",
"2",
"--style",
"sextant",
"2021-12-6 3:40",
)
def test_decode(self) -> None:
"""Test the commandline decoder"""
self.assertModuleOutput(
"""\
201100000200100001020011001012000000010200010001020001000002
year=2021 days=350 hour=22 min=30 dst=0 ut1=-100 ly=0 ls=0
""",
"wwvb.decode",
"201100000200100001020011001012000000010200010001020001000002",
)
self.assertModuleOutput(
"""\
201101111200100001020011001012000000010200010001020001000002
""",
"wwvb.decode",
"201101111200100001020011001012000000010200010001020001000002",
)