From f5143327b243fc616f37252d76bd31f2690b088d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20Elio=20Petten=C3=B2?= Date: Mon, 16 Mar 2020 18:51:27 +0000 Subject: Move tests to be organized within the source directory. This should simplify maintaining the tests in the long run, and allows mypy to more thoroughly check for types. --- glucometerutils/drivers/tests/__init__.py | 0 glucometerutils/drivers/tests/test_contourusb.py | 114 +++++++++++++++++++ glucometerutils/drivers/tests/test_fsoptium.py | 32 ++++++ glucometerutils/drivers/tests/test_otultra2.py | 43 +++++++ glucometerutils/drivers/tests/test_otultraeasy.py | 23 ++++ glucometerutils/drivers/tests/test_td4277.py | 28 +++++ glucometerutils/support/tests/__init__.py | 0 .../support/tests/test_construct_extras.py | 72 ++++++++++++ glucometerutils/support/tests/test_freestyle.py | 22 ++++ glucometerutils/support/tests/test_lifescan.py | 20 ++++ glucometerutils/tests/__init__.py | 0 glucometerutils/tests/test_common.py | 124 +++++++++++++++++++++ mypy.ini | 3 + setup.cfg | 2 - test/__init__.py | 9 -- test/test_common.py | 124 --------------------- test/test_construct_extras.py | 72 ------------ test/test_contourusb.py | 114 ------------------- test/test_freestyle.py | 22 ---- test/test_fsoptium.py | 32 ------ test/test_lifescan.py | 20 ---- test/test_otultra2.py | 43 ------- test/test_otultraeasy.py | 23 ---- test/test_td4277.py | 28 ----- 24 files changed, 481 insertions(+), 489 deletions(-) create mode 100644 glucometerutils/drivers/tests/__init__.py create mode 100644 glucometerutils/drivers/tests/test_contourusb.py create mode 100644 glucometerutils/drivers/tests/test_fsoptium.py create mode 100644 glucometerutils/drivers/tests/test_otultra2.py create mode 100644 glucometerutils/drivers/tests/test_otultraeasy.py create mode 100644 glucometerutils/drivers/tests/test_td4277.py create mode 100644 glucometerutils/support/tests/__init__.py create mode 100644 glucometerutils/support/tests/test_construct_extras.py create mode 100644 glucometerutils/support/tests/test_freestyle.py create mode 100755 glucometerutils/support/tests/test_lifescan.py create mode 100644 glucometerutils/tests/__init__.py create mode 100644 glucometerutils/tests/test_common.py delete mode 100644 test/__init__.py delete mode 100644 test/test_common.py delete mode 100644 test/test_construct_extras.py delete mode 100644 test/test_contourusb.py delete mode 100644 test/test_freestyle.py delete mode 100644 test/test_fsoptium.py delete mode 100755 test/test_lifescan.py delete mode 100644 test/test_otultra2.py delete mode 100644 test/test_otultraeasy.py delete mode 100644 test/test_td4277.py diff --git a/glucometerutils/drivers/tests/__init__.py b/glucometerutils/drivers/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/glucometerutils/drivers/tests/test_contourusb.py b/glucometerutils/drivers/tests/test_contourusb.py new file mode 100644 index 0000000..3b8b547 --- /dev/null +++ b/glucometerutils/drivers/tests/test_contourusb.py @@ -0,0 +1,114 @@ +# -*- coding: utf-8 -*- +# +# SPDX-License-Identifier: MIT +"""Tests for the common ContourUSB functions..""" + +# pylint: disable=protected-access,missing-docstring + +from unittest.mock import Mock + +from absl.testing import absltest +from glucometerutils.support import contourusb + + +class TestContourUSB(absltest.TestCase): + + header_record = b"\x04\x021H|\\^&||7w3LBL|Bayer7390^01.24\\01.04\\09.02.20^7390-2336773^7403-|A=1^C=63^G=1^I=0200^R=0^S=1^U=0^V=10600^X=070070070070180130150250^Y=360126090050099050300089^Z=1|1714||||||1|201909221304\r\x17D7\r\n\x05" + + mock_dev = Mock() + + def test_get_datetime(self): + import datetime + + self.datetime = "201908071315" # returned by + self.assertEqual( + datetime.datetime(2019, 8, 7, 13, 15), + contourusb.ContourHidDevice.get_datetime(self), + ) + + def test_RECORD_FORMAT_match(self): + # first decode the header record frame + header_record_decoded = self.header_record.decode() + stx = header_record_decoded.find("\x02") + + _RECORD_FORMAT = contourusb._RECORD_FORMAT + result = _RECORD_FORMAT.match(header_record_decoded[stx:]).group("text") + + self.assertEqual( + "H|\\^&||7w3LBL|Bayer7390^01.24\\01.04\\09.02.20^7390-2336773^7403-|A=1^C=63^G=1^I=0200^R=0^S=1^U=0^V=10600^X=070070070070180130150250^Y=360126090050099050300089^Z=1|1714||||||1|201909221304", + result, + ) + + def test_parse_header_record(self): + + _HEADER_RECORD_RE = contourusb._HEADER_RECORD_RE + _RECORD_FORMAT = contourusb._RECORD_FORMAT + + header_record_decoded = self.header_record.decode() + stx = header_record_decoded.find("\x02") + + result = _RECORD_FORMAT.match(header_record_decoded[stx:]).group("text") + contourusb.ContourHidDevice.parse_header_record(self.mock_dev, result) + + self.assertEqual(self.mock_dev.field_del, "\\") + self.assertEqual(self.mock_dev.repeat_del, "^") + self.assertEqual(self.mock_dev.component_del, "&") + self.assertEqual(self.mock_dev.escape_del, "|") + + self.assertEqual(self.mock_dev.product_code, "Bayer7390") + + self.assertEqual(self.mock_dev.dig_ver, "01.24") + self.assertEqual(self.mock_dev.anlg_ver, "01.04") + self.assertEqual(self.mock_dev.agp_ver, "09.02.20") + self.assertEqual(self.mock_dev.serial_num, "7390-2336773") + self.assertEqual(self.mock_dev.sku_id, "7403-") + self.assertEqual(self.mock_dev.res_marking, "1") + self.assertEqual(self.mock_dev.config_bits, "63") + self.assertEqual(self.mock_dev.lang, "1") + self.assertEqual(self.mock_dev.interv, "0200") + self.assertEqual(self.mock_dev.ref_method, "0") + self.assertEqual(self.mock_dev.internal, "1") + self.assertEqual(self.mock_dev.unit, "0") + self.assertEqual(self.mock_dev.lo_bound, "10") + self.assertEqual(self.mock_dev.hi_bound, "600") + + self.assertEqual(self.mock_dev.hypo_limit, "070") + self.assertEqual(self.mock_dev.overall_low, "070") + self.assertEqual(self.mock_dev.pre_food_low, "070") + self.assertEqual(self.mock_dev.post_food_low, "070") + self.assertEqual(self.mock_dev.overall_high, "180") + self.assertEqual(self.mock_dev.pre_food_high, "130") + self.assertEqual(self.mock_dev.post_food_high, "150") + self.assertEqual(self.mock_dev.hyper_limit, "250") + + self.assertEqual(self.mock_dev.upp_hyper, "360") + self.assertEqual(self.mock_dev.low_hyper, "126") + self.assertEqual(self.mock_dev.upp_hypo, "090") + self.assertEqual(self.mock_dev.low_hypo, "050") + self.assertEqual(self.mock_dev.upp_low_target, "099") + self.assertEqual(self.mock_dev.low_low_target, "050") + self.assertEqual(self.mock_dev.upp_hi_target, "300") + self.assertEqual(self.mock_dev.low_hi_target, "089") + self.assertEqual(self.mock_dev.trends, "1") + self.assertEqual(self.mock_dev.total, "1714") + self.assertEqual(self.mock_dev.spec_ver, "1") + + self.assertEqual(self.mock_dev.datetime, "201909221304") + + # TO-DO checksum and checkframe unit tests + + def test_parse_result_record(self): + # first decode the header record frame + result_record = "R|8|^^^Glucose|133|mg/dL^P||B/X||201202052034" + result_dict = contourusb.ContourHidDevice.parse_result_record( + self.mock_dev, result_record + ) + + self.assertEqual(result_dict["record_type"], "R") + self.assertEqual(result_dict["seq_num"], "8") + self.assertEqual(result_dict["test_id"], "Glucose") + self.assertEqual(result_dict["value"], "133") + self.assertEqual(result_dict["unit"], "mg/dL") + self.assertEqual(result_dict["ref_method"], "P") + self.assertEqual(result_dict["markers"], "B/X") + self.assertEqual(result_dict["datetime"], "201202052034") diff --git a/glucometerutils/drivers/tests/test_fsoptium.py b/glucometerutils/drivers/tests/test_fsoptium.py new file mode 100644 index 0000000..bdc76f8 --- /dev/null +++ b/glucometerutils/drivers/tests/test_fsoptium.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +# +# SPDX-License-Identifier: MIT +"""Tests for the FreeStyle Optium driver.""" + +# pylint: disable=protected-access,missing-docstring + +import datetime + +from absl.testing import parameterized +from glucometerutils import exceptions +from glucometerutils.drivers import fsoptium + + +class TestFreeStyleOptium(parameterized.TestCase): + @parameterized.parameters( + ("Clock:\tApr 22 2014\t02:14:37", datetime.datetime(2014, 4, 22, 2, 14, 37)), + ("Clock:\tJul 10 2013\t14:26:44", datetime.datetime(2013, 7, 10, 14, 26, 44)), + ("Clock:\tSep 29 2013\t17:35:34", datetime.datetime(2013, 9, 29, 17, 35, 34)), + ) + def test_parse_clock(self, datestr, datevalue): + self.assertEqual(fsoptium._parse_clock(datestr), datevalue) + + @parameterized.parameters( + ("Apr 22 2014 02:14:37",), + ("Clock:\tXxx 10 2013\t14:26",), + ("Clock:\tSep 29 2013\t17:35:22.34",), + ("Foo",), + ) + def test_parse_clock_invalid(self, datestr): + with self.assertRaises(exceptions.InvalidResponse): + fsoptium._parse_clock(datestr) diff --git a/glucometerutils/drivers/tests/test_otultra2.py b/glucometerutils/drivers/tests/test_otultra2.py new file mode 100644 index 0000000..6b36602 --- /dev/null +++ b/glucometerutils/drivers/tests/test_otultra2.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# +# SPDX-License-Identifier: MIT +"""Tests for the LifeScan OneTouch Ultra 2 driver.""" + +# pylint: disable=protected-access,missing-docstring + +from unittest import mock + +from absl.testing import parameterized +from glucometerutils import exceptions +from glucometerutils.drivers import otultra2 +from glucometerutils.support import lifescan + + +class TestOTUltra2(parameterized.TestCase): + def test_checksum(self): + checksum = otultra2._calculate_checksum(b"T") + self.assertEqual(0x0054, checksum) + + def test_checksum_full(self): + checksum = otultra2._calculate_checksum(b'T "SAT","08/03/13","22:12:00 "') + self.assertEqual(0x0608, checksum) + + @parameterized.named_parameters( + ("_missing_checksum", b"INVALID", lifescan.MissingChecksum), + ("_short", b".\r", exceptions.InvalidResponse), + ("_generic", b"% 2500\r", exceptions.InvalidResponse), + ( + "_invalid_serial_number", + b'@ "12345678O" 0297\r', + lifescan.InvalidSerialNumber, + ), + ("_invalid_checksum", b"% 1337\r", exceptions.InvalidChecksum), + ("_broken_checksum", b"% 13AZ\r", lifescan.MissingChecksum), + ) + def test_invalid_response(self, returned_string, expected_exception): + with mock.patch("serial.Serial") as mock_serial: + mock_serial.return_value.readline.return_value = returned_string + + device = otultra2.Device("mockdevice") + with self.assertRaises(expected_exception): + device.get_serial_number() diff --git a/glucometerutils/drivers/tests/test_otultraeasy.py b/glucometerutils/drivers/tests/test_otultraeasy.py new file mode 100644 index 0000000..c6fce83 --- /dev/null +++ b/glucometerutils/drivers/tests/test_otultraeasy.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +# +# SPDX-License-Identifier: MIT +"""Tests for the LifeScan OneTouch Ultra Easy driver.""" + +# pylint: disable=protected-access,missing-docstring + +from absl.testing import absltest +from glucometerutils.drivers import otultraeasy + + +class ConstructTest(absltest.TestCase): + def test_make_packet_ack(self): + self.assertEqual( + b"\x02\x06\x08\x03\xc2\x62", + otultraeasy._make_packet(b"", False, False, False, True), + ) + + def test_make_packet_version_request(self): + self.assertEqual( + b"\x02\x09\x03\x05\x0d\x02\x03\x08\x9f", + otultraeasy._make_packet(b"\x05\x0d\x02", True, True, False, False), + ) diff --git a/glucometerutils/drivers/tests/test_td4277.py b/glucometerutils/drivers/tests/test_td4277.py new file mode 100644 index 0000000..fbd4aa2 --- /dev/null +++ b/glucometerutils/drivers/tests/test_td4277.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +# +# SPDX-License-Identifier: MIT +"""Tests for the TD-4277 driver.""" + +# pylint: disable=protected-access,missing-docstring + +import datetime + +from absl.testing import parameterized +from glucometerutils import exceptions +from glucometerutils.drivers import td4277 +from glucometerutils.support import lifescan + + +class TestTD4277Nexus(parameterized.TestCase): + @parameterized.parameters( + (b"\x21\x24\x0e\x15", datetime.datetime(2018, 1, 1, 21, 14)), + (b"\x21\x26\x0e\x15", datetime.datetime(2019, 1, 1, 21, 14)), + (b"\x04\x27\x25\x0d", datetime.datetime(2019, 8, 4, 13, 37)), + ) + def test_parse_datetime(self, message, date): + self.assertEqual(td4277._parse_datetime(message), date) + + def test_making_message(self): + self.assertEqual( + td4277._make_packet(0x22, 0), b"\x51\x22\x00\x00\x00\x00\xa3\x16" + ) diff --git a/glucometerutils/support/tests/__init__.py b/glucometerutils/support/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/glucometerutils/support/tests/test_construct_extras.py b/glucometerutils/support/tests/test_construct_extras.py new file mode 100644 index 0000000..6bba873 --- /dev/null +++ b/glucometerutils/support/tests/test_construct_extras.py @@ -0,0 +1,72 @@ +# -*- coding: utf-8 -*- +# +# SPDX-License-Identifier: MIT +"""Tests for the common routines.""" + +# pylint: disable=protected-access,missing-docstring + +import datetime + +import construct + +from absl.testing import absltest +from glucometerutils.support import construct_extras + +_TEST_DATE1 = datetime.datetime(1970, 1, 2, 0, 0) +_TEST_DATE2 = datetime.datetime(1971, 1, 1, 0, 0) +_TEST_DATE3 = datetime.datetime(1970, 1, 1, 0, 0) + +_NEW_EPOCH = 31536000 # datetime.datetime(1971, 1, 1, 0, 0) + + +class TestTimestamp(absltest.TestCase): + def test_build_unix_epoch(self): + self.assertEqual( + construct_extras.Timestamp(construct.Int32ul).build(_TEST_DATE1), + b"\x80\x51\x01\x00", + ) + + def test_parse_unix_epoch(self): + self.assertEqual( + construct_extras.Timestamp(construct.Int32ul).parse(b"\x803\xe1\x01"), + _TEST_DATE2, + ) + + def test_build_custom_epoch(self): + self.assertEqual( + construct_extras.Timestamp(construct.Int32ul, epoch=_NEW_EPOCH).build( + _TEST_DATE2 + ), + b"\x00\x00\x00\x00", + ) + + def test_parse_custom_epoch(self): + self.assertEqual( + construct_extras.Timestamp(construct.Int32ul, epoch=_NEW_EPOCH).parse( + b"\x00\x00\x00\x00" + ), + _TEST_DATE2, + ) + + def test_build_custom_epoch_negative_failure(self): + with self.assertRaises(construct.core.FormatFieldError): + construct_extras.Timestamp(construct.Int32ul, epoch=_NEW_EPOCH).build( + _TEST_DATE1 + ) + + def test_build_custom_epoch_negative_success(self): + self.assertEqual( + construct_extras.Timestamp(construct.Int32sl, epoch=_NEW_EPOCH).build( + _TEST_DATE1 + ), + b"\x00\x1e\x20\xfe", + ) + + def test_build_varint(self): + self.assertEqual( + construct_extras.Timestamp(construct.VarInt).build(_TEST_DATE3), b"\x00" + ) + + def test_invalid_value(self): + with self.assertRaises(AssertionError): + construct_extras.Timestamp(construct.Int32ul).build("foo") diff --git a/glucometerutils/support/tests/test_freestyle.py b/glucometerutils/support/tests/test_freestyle.py new file mode 100644 index 0000000..fb3f3b9 --- /dev/null +++ b/glucometerutils/support/tests/test_freestyle.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# +# SPDX-License-Identifier: MIT +"""Tests for the common FreeStyle functions..""" + +# pylint: disable=protected-access,missing-docstring + +from absl.testing import absltest +from glucometerutils.support import freestyle + + +class TestFreeStyle(absltest.TestCase): + def test_outgoing_command(self): + """Test the generation of a new outgoing message.""" + + self.assertEqual( + b"\0\x17\7command\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", + freestyle._FREESTYLE_MESSAGE.build( + {"message_type": 23, "command": b"command"} + ), + ) diff --git a/glucometerutils/support/tests/test_lifescan.py b/glucometerutils/support/tests/test_lifescan.py new file mode 100755 index 0000000..b50b5d6 --- /dev/null +++ b/glucometerutils/support/tests/test_lifescan.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# +# SPDX-License-Identifier: MIT +"""Tests for the LifeScan OneTouch Ultra Mini driver.""" + +# pylint: disable=protected-access,missing-docstring + +import array + +from absl.testing import absltest +from glucometerutils.support import lifescan + + +class TestChecksum(absltest.TestCase): + def test_crc(self): + self.assertEqual(0x41CD, lifescan.crc_ccitt(b"\x02\x06\x06\x03")) + + def test_crc_array(self): + cmd_array = array.array("B", b"\x02\x06\x08\x03") + self.assertEqual(0x62C2, lifescan.crc_ccitt(cmd_array)) diff --git a/glucometerutils/tests/__init__.py b/glucometerutils/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/glucometerutils/tests/test_common.py b/glucometerutils/tests/test_common.py new file mode 100644 index 0000000..3e733e3 --- /dev/null +++ b/glucometerutils/tests/test_common.py @@ -0,0 +1,124 @@ +# -*- coding: utf-8 -*- +# +# SPDX-License-Identifier: MIT +"""Tests for the common routines.""" + +# pylint: disable=protected-access,missing-docstring + +import datetime + +from absl.testing import parameterized +from glucometerutils import common + + +class TestGlucoseConversion(parameterized.TestCase): + def test_convert_to_mmol(self): + self.assertEqual( + 5.56, + common.convert_glucose_unit(100, common.Unit.MG_DL, common.Unit.MMOL_L), + ) + + def test_convert_to_mgdl(self): + self.assertEqual( + 180, common.convert_glucose_unit(10, common.Unit.MMOL_L, common.Unit.MG_DL) + ) + + @parameterized.parameters(list(common.Unit)) + def test_convert_identity(self, unit): + self.assertEqual(100, common.convert_glucose_unit(100, unit, unit)) + + @parameterized.parameters([unit.value for unit in common.Unit]) + def test_convert_identity_str(self, unit_str): + self.assertEqual(100, common.convert_glucose_unit(100, unit_str, unit_str)) + + @parameterized.parameters( + (common.Unit.MMOL_L, "foo"), + ("foo", common.Unit.MG_DL), + (None, common.Unit.MG_DL), + (common.Meal.NONE, common.Unit.MG_DL), + ) + def test_invalid_values(self, from_unit, to_unit): + with self.assertRaises(Exception): + common.convert_glucose_unit(100, from_unit, to_unit) + + +class TestGlucoseReading(parameterized.TestCase): + + TEST_DATETIME = datetime.datetime(2018, 1, 1, 0, 30, 45) + + def test_minimal(self): + reading = common.GlucoseReading(self.TEST_DATETIME, 100) + self.assertEqual( + reading.as_csv(common.Unit.MG_DL), + '"2018-01-01 00:30:45","100.00","","blood sample",""', + ) + + @parameterized.named_parameters( + ("_mgdl", common.Unit.MG_DL, 100), ("_mmoll", common.Unit.MMOL_L, 5.56) + ) + def test_value(self, unit, expected_value): + reading = common.GlucoseReading(self.TEST_DATETIME, 100) + self.assertAlmostEqual(reading.get_value_as(unit), expected_value, places=2) + + @parameterized.named_parameters( + ( + "_meal_none", + {"meal": common.Meal.NONE}, + '"2018-01-01 00:30:45","100.00","","blood sample",""', + ), + ( + "_meal_before", + {"meal": common.Meal.BEFORE}, + '"2018-01-01 00:30:45","100.00","Before Meal","blood sample",""', + ), + ( + "_meal_after", + {"meal": common.Meal.AFTER}, + '"2018-01-01 00:30:45","100.00","After Meal","blood sample",""', + ), + ( + "_measurement_blood", + {"measure_method": common.MeasurementMethod.BLOOD_SAMPLE}, + '"2018-01-01 00:30:45","100.00","","blood sample",""', + ), + ( + "_measurement_cgm", + {"measure_method": common.MeasurementMethod.CGM}, + '"2018-01-01 00:30:45","100.00","","CGM",""', + ), + ( + "_comment", + {"comment": "too much"}, + '"2018-01-01 00:30:45","100.00","","blood sample","too much"', + ), + ( + "_comment_quoted", + {"comment": '"too" much'}, + '"2018-01-01 00:30:45","100.00","","blood sample",""too" much"', + ), + ) + def test_csv(self, kwargs_dict, expected_csv): + reading = common.GlucoseReading(self.TEST_DATETIME, 100, **kwargs_dict) + self.assertEqual(reading.as_csv(common.Unit.MG_DL), expected_csv) + + +class TestMeterInfo(parameterized.TestCase): + @parameterized.named_parameters( + ("_no_serial_number", {}, "Serial Number: N/A\n"), + ("_serial_number", {"serial_number": 1234}, "Serial Number: 1234\n"), + ("_no_version_information", {}, "Version Information:\n N/A\n"), + ( + "_version_information_1", + {"version_info": ["test"]}, + "Version Information:\n test\n", + ), + ( + "_version_information_2", + {"version_info": ["test", "test2"]}, + "Version Information:\n test\n test2\n", + ), + ("_default_native_unit", {}, "Native Unit: mg/dL\n"), + ) + def test_meter_info(self, kwargs_dict, expected_fragment): + info = common.MeterInfo(self.id(), **kwargs_dict) + self.assertIn(expected_fragment, str(info)) diff --git a/mypy.ini b/mypy.ini index 0d124c8..a7c0c85 100644 --- a/mypy.ini +++ b/mypy.ini @@ -1,6 +1,9 @@ [mypy] python_version = 3.7 +[mypy-absl.testing.*] +ignore_missing_imports = True + [mypy-serial] ignore_missing_imports = True diff --git a/setup.cfg b/setup.cfg index cd71828..81b33c5 100644 --- a/setup.cfg +++ b/setup.cfg @@ -10,6 +10,4 @@ norecursedirs = build venv .env -testpaths = - test timeout = 120 diff --git a/test/__init__.py b/test/__init__.py deleted file mode 100644 index 139fd0c..0000000 --- a/test/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ -# -*- coding: utf-8 -*- -# -# SPDX-License-Identifier: MIT -"""Add the top-level module to the PYTHONPATH.""" - -import os -import sys - -sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) diff --git a/test/test_common.py b/test/test_common.py deleted file mode 100644 index 3e733e3..0000000 --- a/test/test_common.py +++ /dev/null @@ -1,124 +0,0 @@ -# -*- coding: utf-8 -*- -# -# SPDX-License-Identifier: MIT -"""Tests for the common routines.""" - -# pylint: disable=protected-access,missing-docstring - -import datetime - -from absl.testing import parameterized -from glucometerutils import common - - -class TestGlucoseConversion(parameterized.TestCase): - def test_convert_to_mmol(self): - self.assertEqual( - 5.56, - common.convert_glucose_unit(100, common.Unit.MG_DL, common.Unit.MMOL_L), - ) - - def test_convert_to_mgdl(self): - self.assertEqual( - 180, common.convert_glucose_unit(10, common.Unit.MMOL_L, common.Unit.MG_DL) - ) - - @parameterized.parameters(list(common.Unit)) - def test_convert_identity(self, unit): - self.assertEqual(100, common.convert_glucose_unit(100, unit, unit)) - - @parameterized.parameters([unit.value for unit in common.Unit]) - def test_convert_identity_str(self, unit_str): - self.assertEqual(100, common.convert_glucose_unit(100, unit_str, unit_str)) - - @parameterized.parameters( - (common.Unit.MMOL_L, "foo"), - ("foo", common.Unit.MG_DL), - (None, common.Unit.MG_DL), - (common.Meal.NONE, common.Unit.MG_DL), - ) - def test_invalid_values(self, from_unit, to_unit): - with self.assertRaises(Exception): - common.convert_glucose_unit(100, from_unit, to_unit) - - -class TestGlucoseReading(parameterized.TestCase): - - TEST_DATETIME = datetime.datetime(2018, 1, 1, 0, 30, 45) - - def test_minimal(self): - reading = common.GlucoseReading(self.TEST_DATETIME, 100) - self.assertEqual( - reading.as_csv(common.Unit.MG_DL), - '"2018-01-01 00:30:45","100.00","","blood sample",""', - ) - - @parameterized.named_parameters( - ("_mgdl", common.Unit.MG_DL, 100), ("_mmoll", common.Unit.MMOL_L, 5.56) - ) - def test_value(self, unit, expected_value): - reading = common.GlucoseReading(self.TEST_DATETIME, 100) - self.assertAlmostEqual(reading.get_value_as(unit), expected_value, places=2) - - @parameterized.named_parameters( - ( - "_meal_none", - {"meal": common.Meal.NONE}, - '"2018-01-01 00:30:45","100.00","","blood sample",""', - ), - ( - "_meal_before", - {"meal": common.Meal.BEFORE}, - '"2018-01-01 00:30:45","100.00","Before Meal","blood sample",""', - ), - ( - "_meal_after", - {"meal": common.Meal.AFTER}, - '"2018-01-01 00:30:45","100.00","After Meal","blood sample",""', - ), - ( - "_measurement_blood", - {"measure_method": common.MeasurementMethod.BLOOD_SAMPLE}, - '"2018-01-01 00:30:45","100.00","","blood sample",""', - ), - ( - "_measurement_cgm", - {"measure_method": common.MeasurementMethod.CGM}, - '"2018-01-01 00:30:45","100.00","","CGM",""', - ), - ( - "_comment", - {"comment": "too much"}, - '"2018-01-01 00:30:45","100.00","","blood sample","too much"', - ), - ( - "_comment_quoted", - {"comment": '"too" much'}, - '"2018-01-01 00:30:45","100.00","","blood sample",""too" much"', - ), - ) - def test_csv(self, kwargs_dict, expected_csv): - reading = common.GlucoseReading(self.TEST_DATETIME, 100, **kwargs_dict) - self.assertEqual(reading.as_csv(common.Unit.MG_DL), expected_csv) - - -class TestMeterInfo(parameterized.TestCase): - @parameterized.named_parameters( - ("_no_serial_number", {}, "Serial Number: N/A\n"), - ("_serial_number", {"serial_number": 1234}, "Serial Number: 1234\n"), - ("_no_version_information", {}, "Version Information:\n N/A\n"), - ( - "_version_information_1", - {"version_info": ["test"]}, - "Version Information:\n test\n", - ), - ( - "_version_information_2", - {"version_info": ["test", "test2"]}, - "Version Information:\n test\n test2\n", - ), - ("_default_native_unit", {}, "Native Unit: mg/dL\n"), - ) - def test_meter_info(self, kwargs_dict, expected_fragment): - info = common.MeterInfo(self.id(), **kwargs_dict) - self.assertIn(expected_fragment, str(info)) diff --git a/test/test_construct_extras.py b/test/test_construct_extras.py deleted file mode 100644 index 6bba873..0000000 --- a/test/test_construct_extras.py +++ /dev/null @@ -1,72 +0,0 @@ -# -*- coding: utf-8 -*- -# -# SPDX-License-Identifier: MIT -"""Tests for the common routines.""" - -# pylint: disable=protected-access,missing-docstring - -import datetime - -import construct - -from absl.testing import absltest -from glucometerutils.support import construct_extras - -_TEST_DATE1 = datetime.datetime(1970, 1, 2, 0, 0) -_TEST_DATE2 = datetime.datetime(1971, 1, 1, 0, 0) -_TEST_DATE3 = datetime.datetime(1970, 1, 1, 0, 0) - -_NEW_EPOCH = 31536000 # datetime.datetime(1971, 1, 1, 0, 0) - - -class TestTimestamp(absltest.TestCase): - def test_build_unix_epoch(self): - self.assertEqual( - construct_extras.Timestamp(construct.Int32ul).build(_TEST_DATE1), - b"\x80\x51\x01\x00", - ) - - def test_parse_unix_epoch(self): - self.assertEqual( - construct_extras.Timestamp(construct.Int32ul).parse(b"\x803\xe1\x01"), - _TEST_DATE2, - ) - - def test_build_custom_epoch(self): - self.assertEqual( - construct_extras.Timestamp(construct.Int32ul, epoch=_NEW_EPOCH).build( - _TEST_DATE2 - ), - b"\x00\x00\x00\x00", - ) - - def test_parse_custom_epoch(self): - self.assertEqual( - construct_extras.Timestamp(construct.Int32ul, epoch=_NEW_EPOCH).parse( - b"\x00\x00\x00\x00" - ), - _TEST_DATE2, - ) - - def test_build_custom_epoch_negative_failure(self): - with self.assertRaises(construct.core.FormatFieldError): - construct_extras.Timestamp(construct.Int32ul, epoch=_NEW_EPOCH).build( - _TEST_DATE1 - ) - - def test_build_custom_epoch_negative_success(self): - self.assertEqual( - construct_extras.Timestamp(construct.Int32sl, epoch=_NEW_EPOCH).build( - _TEST_DATE1 - ), - b"\x00\x1e\x20\xfe", - ) - - def test_build_varint(self): - self.assertEqual( - construct_extras.Timestamp(construct.VarInt).build(_TEST_DATE3), b"\x00" - ) - - def test_invalid_value(self): - with self.assertRaises(AssertionError): - construct_extras.Timestamp(construct.Int32ul).build("foo") diff --git a/test/test_contourusb.py b/test/test_contourusb.py deleted file mode 100644 index 3b8b547..0000000 --- a/test/test_contourusb.py +++ /dev/null @@ -1,114 +0,0 @@ -# -*- coding: utf-8 -*- -# -# SPDX-License-Identifier: MIT -"""Tests for the common ContourUSB functions..""" - -# pylint: disable=protected-access,missing-docstring - -from unittest.mock import Mock - -from absl.testing import absltest -from glucometerutils.support import contourusb - - -class TestContourUSB(absltest.TestCase): - - header_record = b"\x04\x021H|\\^&||7w3LBL|Bayer7390^01.24\\01.04\\09.02.20^7390-2336773^7403-|A=1^C=63^G=1^I=0200^R=0^S=1^U=0^V=10600^X=070070070070180130150250^Y=360126090050099050300089^Z=1|1714||||||1|201909221304\r\x17D7\r\n\x05" - - mock_dev = Mock() - - def test_get_datetime(self): - import datetime - - self.datetime = "201908071315" # returned by - self.assertEqual( - datetime.datetime(2019, 8, 7, 13, 15), - contourusb.ContourHidDevice.get_datetime(self), - ) - - def test_RECORD_FORMAT_match(self): - # first decode the header record frame - header_record_decoded = self.header_record.decode() - stx = header_record_decoded.find("\x02") - - _RECORD_FORMAT = contourusb._RECORD_FORMAT - result = _RECORD_FORMAT.match(header_record_decoded[stx:]).group("text") - - self.assertEqual( - "H|\\^&||7w3LBL|Bayer7390^01.24\\01.04\\09.02.20^7390-2336773^7403-|A=1^C=63^G=1^I=0200^R=0^S=1^U=0^V=10600^X=070070070070180130150250^Y=360126090050099050300089^Z=1|1714||||||1|201909221304", - result, - ) - - def test_parse_header_record(self): - - _HEADER_RECORD_RE = contourusb._HEADER_RECORD_RE - _RECORD_FORMAT = contourusb._RECORD_FORMAT - - header_record_decoded = self.header_record.decode() - stx = header_record_decoded.find("\x02") - - result = _RECORD_FORMAT.match(header_record_decoded[stx:]).group("text") - contourusb.ContourHidDevice.parse_header_record(self.mock_dev, result) - - self.assertEqual(self.mock_dev.field_del, "\\") - self.assertEqual(self.mock_dev.repeat_del, "^") - self.assertEqual(self.mock_dev.component_del, "&") - self.assertEqual(self.mock_dev.escape_del, "|") - - self.assertEqual(self.mock_dev.product_code, "Bayer7390") - - self.assertEqual(self.mock_dev.dig_ver, "01.24") - self.assertEqual(self.mock_dev.anlg_ver, "01.04") - self.assertEqual(self.mock_dev.agp_ver, "09.02.20") - self.assertEqual(self.mock_dev.serial_num, "7390-2336773") - self.assertEqual(self.mock_dev.sku_id, "7403-") - self.assertEqual(self.mock_dev.res_marking, "1") - self.assertEqual(self.mock_dev.config_bits, "63") - self.assertEqual(self.mock_dev.lang, "1") - self.assertEqual(self.mock_dev.interv, "0200") - self.assertEqual(self.mock_dev.ref_method, "0") - self.assertEqual(self.mock_dev.internal, "1") - self.assertEqual(self.mock_dev.unit, "0") - self.assertEqual(self.mock_dev.lo_bound, "10") - self.assertEqual(self.mock_dev.hi_bound, "600") - - self.assertEqual(self.mock_dev.hypo_limit, "070") - self.assertEqual(self.mock_dev.overall_low, "070") - self.assertEqual(self.mock_dev.pre_food_low, "070") - self.assertEqual(self.mock_dev.post_food_low, "070") - self.assertEqual(self.mock_dev.overall_high, "180") - self.assertEqual(self.mock_dev.pre_food_high, "130") - self.assertEqual(self.mock_dev.post_food_high, "150") - self.assertEqual(self.mock_dev.hyper_limit, "250") - - self.assertEqual(self.mock_dev.upp_hyper, "360") - self.assertEqual(self.mock_dev.low_hyper, "126") - self.assertEqual(self.mock_dev.upp_hypo, "090") - self.assertEqual(self.mock_dev.low_hypo, "050") - self.assertEqual(self.mock_dev.upp_low_target, "099") - self.assertEqual(self.mock_dev.low_low_target, "050") - self.assertEqual(self.mock_dev.upp_hi_target, "300") - self.assertEqual(self.mock_dev.low_hi_target, "089") - self.assertEqual(self.mock_dev.trends, "1") - self.assertEqual(self.mock_dev.total, "1714") - self.assertEqual(self.mock_dev.spec_ver, "1") - - self.assertEqual(self.mock_dev.datetime, "201909221304") - - # TO-DO checksum and checkframe unit tests - - def test_parse_result_record(self): - # first decode the header record frame - result_record = "R|8|^^^Glucose|133|mg/dL^P||B/X||201202052034" - result_dict = contourusb.ContourHidDevice.parse_result_record( - self.mock_dev, result_record - ) - - self.assertEqual(result_dict["record_type"], "R") - self.assertEqual(result_dict["seq_num"], "8") - self.assertEqual(result_dict["test_id"], "Glucose") - self.assertEqual(result_dict["value"], "133") - self.assertEqual(result_dict["unit"], "mg/dL") - self.assertEqual(result_dict["ref_method"], "P") - self.assertEqual(result_dict["markers"], "B/X") - self.assertEqual(result_dict["datetime"], "201202052034") diff --git a/test/test_freestyle.py b/test/test_freestyle.py deleted file mode 100644 index fb3f3b9..0000000 --- a/test/test_freestyle.py +++ /dev/null @@ -1,22 +0,0 @@ -# -*- coding: utf-8 -*- -# -# SPDX-License-Identifier: MIT -"""Tests for the common FreeStyle functions..""" - -# pylint: disable=protected-access,missing-docstring - -from absl.testing import absltest -from glucometerutils.support import freestyle - - -class TestFreeStyle(absltest.TestCase): - def test_outgoing_command(self): - """Test the generation of a new outgoing message.""" - - self.assertEqual( - b"\0\x17\7command\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", - freestyle._FREESTYLE_MESSAGE.build( - {"message_type": 23, "command": b"command"} - ), - ) diff --git a/test/test_fsoptium.py b/test/test_fsoptium.py deleted file mode 100644 index bdc76f8..0000000 --- a/test/test_fsoptium.py +++ /dev/null @@ -1,32 +0,0 @@ -# -*- coding: utf-8 -*- -# -# SPDX-License-Identifier: MIT -"""Tests for the FreeStyle Optium driver.""" - -# pylint: disable=protected-access,missing-docstring - -import datetime - -from absl.testing import parameterized -from glucometerutils import exceptions -from glucometerutils.drivers import fsoptium - - -class TestFreeStyleOptium(parameterized.TestCase): - @parameterized.parameters( - ("Clock:\tApr 22 2014\t02:14:37", datetime.datetime(2014, 4, 22, 2, 14, 37)), - ("Clock:\tJul 10 2013\t14:26:44", datetime.datetime(2013, 7, 10, 14, 26, 44)), - ("Clock:\tSep 29 2013\t17:35:34", datetime.datetime(2013, 9, 29, 17, 35, 34)), - ) - def test_parse_clock(self, datestr, datevalue): - self.assertEqual(fsoptium._parse_clock(datestr), datevalue) - - @parameterized.parameters( - ("Apr 22 2014 02:14:37",), - ("Clock:\tXxx 10 2013\t14:26",), - ("Clock:\tSep 29 2013\t17:35:22.34",), - ("Foo",), - ) - def test_parse_clock_invalid(self, datestr): - with self.assertRaises(exceptions.InvalidResponse): - fsoptium._parse_clock(datestr) diff --git a/test/test_lifescan.py b/test/test_lifescan.py deleted file mode 100755 index b50b5d6..0000000 --- a/test/test_lifescan.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# -# SPDX-License-Identifier: MIT -"""Tests for the LifeScan OneTouch Ultra Mini driver.""" - -# pylint: disable=protected-access,missing-docstring - -import array - -from absl.testing import absltest -from glucometerutils.support import lifescan - - -class TestChecksum(absltest.TestCase): - def test_crc(self): - self.assertEqual(0x41CD, lifescan.crc_ccitt(b"\x02\x06\x06\x03")) - - def test_crc_array(self): - cmd_array = array.array("B", b"\x02\x06\x08\x03") - self.assertEqual(0x62C2, lifescan.crc_ccitt(cmd_array)) diff --git a/test/test_otultra2.py b/test/test_otultra2.py deleted file mode 100644 index 6b36602..0000000 --- a/test/test_otultra2.py +++ /dev/null @@ -1,43 +0,0 @@ -# -*- coding: utf-8 -*- -# -# SPDX-License-Identifier: MIT -"""Tests for the LifeScan OneTouch Ultra 2 driver.""" - -# pylint: disable=protected-access,missing-docstring - -from unittest import mock - -from absl.testing import parameterized -from glucometerutils import exceptions -from glucometerutils.drivers import otultra2 -from glucometerutils.support import lifescan - - -class TestOTUltra2(parameterized.TestCase): - def test_checksum(self): - checksum = otultra2._calculate_checksum(b"T") - self.assertEqual(0x0054, checksum) - - def test_checksum_full(self): - checksum = otultra2._calculate_checksum(b'T "SAT","08/03/13","22:12:00 "') - self.assertEqual(0x0608, checksum) - - @parameterized.named_parameters( - ("_missing_checksum", b"INVALID", lifescan.MissingChecksum), - ("_short", b".\r", exceptions.InvalidResponse), - ("_generic", b"% 2500\r", exceptions.InvalidResponse), - ( - "_invalid_serial_number", - b'@ "12345678O" 0297\r', - lifescan.InvalidSerialNumber, - ), - ("_invalid_checksum", b"% 1337\r", exceptions.InvalidChecksum), - ("_broken_checksum", b"% 13AZ\r", lifescan.MissingChecksum), - ) - def test_invalid_response(self, returned_string, expected_exception): - with mock.patch("serial.Serial") as mock_serial: - mock_serial.return_value.readline.return_value = returned_string - - device = otultra2.Device("mockdevice") - with self.assertRaises(expected_exception): - device.get_serial_number() diff --git a/test/test_otultraeasy.py b/test/test_otultraeasy.py deleted file mode 100644 index c6fce83..0000000 --- a/test/test_otultraeasy.py +++ /dev/null @@ -1,23 +0,0 @@ -# -*- coding: utf-8 -*- -# -# SPDX-License-Identifier: MIT -"""Tests for the LifeScan OneTouch Ultra Easy driver.""" - -# pylint: disable=protected-access,missing-docstring - -from absl.testing import absltest -from glucometerutils.drivers import otultraeasy - - -class ConstructTest(absltest.TestCase): - def test_make_packet_ack(self): - self.assertEqual( - b"\x02\x06\x08\x03\xc2\x62", - otultraeasy._make_packet(b"", False, False, False, True), - ) - - def test_make_packet_version_request(self): - self.assertEqual( - b"\x02\x09\x03\x05\x0d\x02\x03\x08\x9f", - otultraeasy._make_packet(b"\x05\x0d\x02", True, True, False, False), - ) diff --git a/test/test_td4277.py b/test/test_td4277.py deleted file mode 100644 index fbd4aa2..0000000 --- a/test/test_td4277.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8 -*- -# -# SPDX-License-Identifier: MIT -"""Tests for the TD-4277 driver.""" - -# pylint: disable=protected-access,missing-docstring - -import datetime - -from absl.testing import parameterized -from glucometerutils import exceptions -from glucometerutils.drivers import td4277 -from glucometerutils.support import lifescan - - -class TestTD4277Nexus(parameterized.TestCase): - @parameterized.parameters( - (b"\x21\x24\x0e\x15", datetime.datetime(2018, 1, 1, 21, 14)), - (b"\x21\x26\x0e\x15", datetime.datetime(2019, 1, 1, 21, 14)), - (b"\x04\x27\x25\x0d", datetime.datetime(2019, 8, 4, 13, 37)), - ) - def test_parse_datetime(self, message, date): - self.assertEqual(td4277._parse_datetime(message), date) - - def test_making_message(self): - self.assertEqual( - td4277._make_packet(0x22, 0), b"\x51\x22\x00\x00\x00\x00\xa3\x16" - ) -- cgit v1.2.3