Added review.
Tests / Python ${{ matrix.python-version }} (3.12) (push) Waiting to run
Tests / Python ${{ matrix.python-version }} (3.7) (push) Waiting to run
Tests / Python ${{ matrix.python-version }} (3.8) (push) Waiting to run
Tests / Python ${{ matrix.python-version }} (3.9) (push) Waiting to run
Tests / Python ${{ matrix.python-version }} (3.10) (push) Has been cancelled
Tests / Python ${{ matrix.python-version }} (3.11) (push) Has been cancelled

This commit is contained in:
2024-12-29 20:47:35 +01:00
parent 99ad21c896
commit 0ef1b057a6
70 changed files with 1157 additions and 0 deletions
@@ -0,0 +1,11 @@
{
"extension": ".py",
"source": "from decimal import Decimal\n\nimport json\nimport unittest\n\nfrom dsmr_parser import telegram_specifications, obis_references\nfrom dsmr_parser.objects import MbusDevice\n\n\nclass MbusDeviceTest(unittest.TestCase):\n\n def setUp(self):\n v5_objects = telegram_specifications.V5['objects']\n\n device_type_parser = [\n object[\"value_parser\"]\n for object in v5_objects\n if object[\"obis_reference\"] == obis_references.MBUS_DEVICE_TYPE\n ][0]\n device_type = device_type_parser.parse('0-2:24.1.0(003)\\r\\n')\n\n equipment_parser = [\n object[\"value_parser\"]\n for object in v5_objects\n if object[\"obis_reference\"] == obis_references.MBUS_EQUIPMENT_IDENTIFIER\n ][0]\n equipment = equipment_parser.parse('0-2:96.1.0(4730303339303031393336393930363139)\\r\\n')\n\n gas_reading_parser = [\n object[\"value_parser\"]\n for object in v5_objects\n if object[\"obis_reference\"] == obis_references.MBUS_METER_READING\n ][0]\n gas_reading = gas_reading_parser.parse('0-2:24.2.1(200426223001S)(00246.138*m3)\\r\\n')\n\n mbus_device = MbusDevice(channel_id=2)\n mbus_device.add(obis_references.MBUS_DEVICE_TYPE, device_type, \"MBUS_DEVICE_TYPE\")\n mbus_device.add(obis_references.MBUS_EQUIPMENT_IDENTIFIER, equipment, \"MBUS_EQUIPMENT_IDENTIFIER\")\n mbus_device.add(obis_references.MBUS_METER_READING, gas_reading, \"MBUS_METER_READING\")\n\n self.mbus_device = mbus_device\n\n def test_attributes(self):\n self.assertEqual(self.mbus_device.MBUS_DEVICE_TYPE.value, 3)\n self.assertEqual(self.mbus_device.MBUS_DEVICE_TYPE.unit, None)\n\n self.assertEqual(self.mbus_device.MBUS_EQUIPMENT_IDENTIFIER.value,\n '4730303339303031393336393930363139')\n self.assertEqual(self.mbus_device.MBUS_EQUIPMENT_IDENTIFIER.unit, None)\n\n self.assertEqual(self.mbus_device.MBUS_METER_READING.value, Decimal('246.138'))\n self.assertEqual(self.mbus_device.MBUS_METER_READING.unit, 'm3')\n\n def test_to_json(self):\n self.assertEqual(\n json.loads(self.mbus_device.to_json()),\n {\n 'CHANNEL_ID': 2,\n 'MBUS_DEVICE_TYPE': {'value': 3, 'unit': None},\n 'MBUS_EQUIPMENT_IDENTIFIER': {'value': '4730303339303031393336393930363139', 'unit': None},\n 'MBUS_METER_READING': {'datetime': '2020-04-26T20:30:01+00:00', 'value': 246.138, 'unit': 'm3'}}\n )\n\n def test_str(self):\n self.assertEqual(\n str(self.mbus_device),\n (\n 'MBUS DEVICE (channel 2)\\n'\n '\\tMBUS_DEVICE_TYPE: \t 3\t[None]\\n'\n '\\tMBUS_EQUIPMENT_IDENTIFIER: \t 4730303339303031393336393930363139\t[None]\\n'\n '\\tMBUS_METER_READING: \t 246.138\t[m3] at 2020-04-26T20:30:01+00:00\\n'\n )\n )\n",
"review": "# 8\n\n## Bugs\n- No explicit bug was detected in this segment of the code.\n\n## Optimizations\n- Include error handling for parsing functions to manage unexpected inputs more gracefully.\n- Consider using constants or an enum for repeated string literals to improve maintainability.\n- The parsing of date from the MBUS_METER_READING should ensure timezone consistency.\n\n## Good points\n- Makes effective use of unit tests to validate the functionality of the `MbusDevice` class.\n- Uses `unittest` which is a standard Python module for testing, showing good practice.\n- Demonstrates clarity in structuring tests into distinct methods.\n- Code adheres to PEP 8 style guidelines making it readable.\n\n## Summary\nThe code presents a unit test suite for an `MbusDevice` class, verifying its parsing and JSON serialization functionalities. The tests are well-organized, covering attributes and different string representations of the device. While the code is generally well-written and free from apparent bugs, improvements can be made in terms of error handling and simplifying repetitive structures.\n\n## Open source alternatives\n- [Home Assistant](https://www.home-assistant.io/): An open-source platform that can receive and decode DSMR data from smart meters.\n- [DSMR Reader](https://github.com/dsmrreader/dsmr-reader): An open-source application for monitoring and visualizing Dutch Smart Meter data.",
"filename": "test_mbusdevice.py",
"path": "test/objects/test_mbusdevice.py",
"directory": "objects",
"grade": 8,
"size": 2920,
"line_count": 74
}
@@ -0,0 +1,22 @@
# 8
## Bugs
- No explicit bug was detected in this segment of the code.
## Optimizations
- Include error handling for parsing functions to manage unexpected inputs more gracefully.
- Consider using constants or an enum for repeated string literals to improve maintainability.
- The parsing of date from the MBUS_METER_READING should ensure timezone consistency.
## Good points
- Makes effective use of unit tests to validate the functionality of the `MbusDevice` class.
- Uses `unittest` which is a standard Python module for testing, showing good practice.
- Demonstrates clarity in structuring tests into distinct methods.
- Code adheres to PEP 8 style guidelines making it readable.
## Summary
The code presents a unit test suite for an `MbusDevice` class, verifying its parsing and JSON serialization functionalities. The tests are well-organized, covering attributes and different string representations of the device. While the code is generally well-written and free from apparent bugs, improvements can be made in terms of error handling and simplifying repetitive structures.
## Open source alternatives
- [Home Assistant](https://www.home-assistant.io/): An open-source platform that can receive and decode DSMR data from smart meters.
- [DSMR Reader](https://github.com/dsmrreader/dsmr-reader): An open-source application for monitoring and visualizing Dutch Smart Meter data.
@@ -0,0 +1,11 @@
{
"extension": ".py",
"source": "import unittest\n\nfrom dsmr_parser import telegram_specifications\n\nfrom dsmr_parser.objects import ProfileGenericObject\nfrom dsmr_parser.parsers import TelegramParser\nfrom dsmr_parser.parsers import ProfileGenericParser\nfrom dsmr_parser.profile_generic_specifications import BUFFER_TYPES\nfrom dsmr_parser.profile_generic_specifications import PG_HEAD_PARSERS\nfrom dsmr_parser.profile_generic_specifications import PG_UNIDENTIFIED_BUFFERTYPE_PARSERS\nfrom test.example_telegrams import TELEGRAM_V5\n\n\nclass TestParserCornerCases(unittest.TestCase):\n \"\"\" Test instantiation of Telegram object \"\"\"\n\n def test_power_event_log_empty_1(self):\n # POWER_EVENT_FAILURE_LOG (1-0:99.97.0)\n parser = TelegramParser(telegram_specifications.V5)\n telegram = parser.parse(TELEGRAM_V5)\n\n object_type = ProfileGenericObject\n testitem = telegram.POWER_EVENT_FAILURE_LOG\n assert isinstance(testitem, object_type)\n assert testitem.buffer_length == 0\n assert testitem.buffer_type == '0-0:96.7.19'\n buffer = testitem.buffer\n assert isinstance(testitem.buffer, list)\n assert len(buffer) == 0\n\n def test_power_event_log_empty_2(self):\n pef_parser = ProfileGenericParser(BUFFER_TYPES, PG_HEAD_PARSERS, PG_UNIDENTIFIED_BUFFERTYPE_PARSERS)\n object_type = ProfileGenericObject\n\n # Power Event Log with 0 items and no object type\n pefl_line = r'1-0:99.97.0(0)()\\r\\n'\n testitem = pef_parser.parse(pefl_line)\n\n assert isinstance(testitem, object_type)\n assert testitem.buffer_length == 0\n assert testitem.buffer_type is None\n buffer = testitem.buffer\n assert isinstance(testitem.buffer, list)\n assert len(buffer) == 0\n assert testitem.values == [{'value': 0, 'unit': None}, {'value': None, 'unit': None}]\n json = testitem.to_json()\n assert json == '{\"buffer_length\": 0, \"buffer_type\": null, \"buffer\": []}'\n\n def test_power_event_log_null_values(self):\n pef_parser = ProfileGenericParser(BUFFER_TYPES, PG_HEAD_PARSERS, PG_UNIDENTIFIED_BUFFERTYPE_PARSERS)\n object_type = ProfileGenericObject\n\n # Power Event Log with 1 item and no object type and nno values for the item\n pefl_line = r'1-0:99.97.0(1)()()()\\r\\n'\n testitem = pef_parser.parse(pefl_line)\n\n assert isinstance(testitem, object_type)\n assert testitem.buffer_length == 1\n assert testitem.buffer_type is None\n buffer = testitem.buffer\n assert isinstance(testitem.buffer, list)\n assert len(buffer) == 1\n assert testitem.values == [{'value': 1, 'unit': None}, {'value': None, 'unit': None},\n {'value': None, 'unit': None}, {'value': None, 'unit': None}]\n json = testitem.to_json()\n assert json == \\\n '{\"buffer_length\": 1, \"buffer_type\": null, \"buffer\": [{\"datetime\": null, \"value\": null, \"unit\": null}]}'\n\n def test_power_event_log_brackets_only(self):\n # POWER_EVENT_FAILURE_LOG (1-0:99.97.0)\n # Issue 57\n # Test of an ill formatted empty POWER_EVENT_FAILURE_LOG, observed on some smartmeters\n # The idea is that instead of failing, the parser converts it to an empty POWER_EVENT_FAILURE_LOG\n pef_parser = ProfileGenericParser(BUFFER_TYPES, PG_HEAD_PARSERS, PG_UNIDENTIFIED_BUFFERTYPE_PARSERS)\n object_type = ProfileGenericObject\n\n pefl_line = r'1-0:99.97.0()\\r\\n'\n testitem = pef_parser.parse(pefl_line)\n\n assert isinstance(testitem, object_type)\n assert testitem.buffer_length == 0\n assert testitem.buffer_type is None\n buffer = testitem.buffer\n assert isinstance(testitem.buffer, list)\n assert len(buffer) == 0\n assert testitem.values == [{'value': 0, 'unit': None}, {'value': None, 'unit': None}]\n json = testitem.to_json()\n assert json == '{\"buffer_length\": 0, \"buffer_type\": null, \"buffer\": []}'\n",
"review": "# 7\n\n## Bugs\n- No evident bugs found in the code provided. However, potential issues might arise if expected libraries or modules (`dsmr_parser`, `test.example_telegrams`) are missing or not compatible.\n\n## Optimizations\n- The use of hard-coded assert statements can be improved. Instead, using `self.assertEqual`, `self.assertIsInstance`, etc., would provide more robust and informative test outcomes.\n- There is a repeated pattern in obtaining the `ProfileGenericObject`; consider refactoring this into a setup method for reuse.\n- Consider improving the handling of test names to reflect the specific conditions being tested more clearly.\n\n## Good points\n- The tests cover various edge cases such as empty buffers and incorrect formatting, showing a good consideration of potential issues.\n- Usage of regular expression-like syntax to simulate data which suggests potential extensibility.\n- Converts issue-specific scenarios into actionable test cases that prevent regressions.\n\n## Summary\nThe code is a solid test suite for handling edge cases of DSMR (Dutch Smart Meter Requirements) telegram parsing. It focuses on ensuring the parser's robustness against incorrectly formatted or empty logs, and it is clear about the data format expectations. Some improvements might include refactoring to reduce repetition and improve test clarity, but overall, it provides a thorough coverage of corner cases.\n\n## Open source alternatives\n- `PyDSMR`: A Python library to parse DSMR telemetry data, which might include similar parsing and testing utilities.\n- `dsmr-reader`: An open-source project that reads DSMR data and stores it in a database, potentially including parsing capabilities.",
"filename": "test_parser_corner_cases.py",
"path": "test/objects/test_parser_corner_cases.py",
"directory": "objects",
"grade": 7,
"size": 3978,
"line_count": 89
}
@@ -0,0 +1,21 @@
# 7
## Bugs
- No evident bugs found in the code provided. However, potential issues might arise if expected libraries or modules (`dsmr_parser`, `test.example_telegrams`) are missing or not compatible.
## Optimizations
- The use of hard-coded assert statements can be improved. Instead, using `self.assertEqual`, `self.assertIsInstance`, etc., would provide more robust and informative test outcomes.
- There is a repeated pattern in obtaining the `ProfileGenericObject`; consider refactoring this into a setup method for reuse.
- Consider improving the handling of test names to reflect the specific conditions being tested more clearly.
## Good points
- The tests cover various edge cases such as empty buffers and incorrect formatting, showing a good consideration of potential issues.
- Usage of regular expression-like syntax to simulate data which suggests potential extensibility.
- Converts issue-specific scenarios into actionable test cases that prevent regressions.
## Summary
The code is a solid test suite for handling edge cases of DSMR (Dutch Smart Meter Requirements) telegram parsing. It focuses on ensuring the parser's robustness against incorrectly formatted or empty logs, and it is clear about the data format expectations. Some improvements might include refactoring to reduce repetition and improve test clarity, but overall, it provides a thorough coverage of corner cases.
## Open source alternatives
- `PyDSMR`: A Python library to parse DSMR telemetry data, which might include similar parsing and testing utilities.
- `dsmr-reader`: An open-source project that reads DSMR data and stores it in a database, potentially including parsing capabilities.
File diff suppressed because one or more lines are too long
+22
View File
@@ -0,0 +1,22 @@
**7**
### Bugs
- No specific bugs found in the code.
### Optimizations
- Consider replacing `eval()` with a safer alternative to access object attributes to avoid potential security issues.
- Instead of using manual assertions, consider using unittest's built-in methods such as `assertIsInstance()`, `assertEqual()`, etc., which provide better readability and error messages.
### Good points
- Extensive use of unit tests covering various scenarios to ensure the correctness of the parser.
- Use of helper function `verify_telegram_item` reduces code duplication and enhances readability.
- The code follows a consistent pattern in its testing methods, making it easy to follow.
- The use of descriptive variable names aids in understanding the purpose of the tests.
- The tests ensure that the data is correctly parsed and transformed into the expected output formats, including JSON and string representations.
### Summary
The code presented is a test suite for a DSMR (Dutch Smart Meter Requirements) telegram parser. The suite thoroughly tests the parsing of V4 and V5 telegram data into expected object structures, values, and types. It covers a wide range of test cases to ensure the parser accurately processes DSMR telegrams into both object attributes and JSON outputs. Although the test suite is well-structured and effective, using `eval()` can pose a security risk, and employing unittest's built-in assertion methods could improve the code's clarity and maintainability.
### Open source alternatives
- **PyDSMR**: An open-source library to parse DSMR data, focusing on extensibility and Pythonic conventions.
- **dsmr-parser**: A simple DSMR parser library for extracting information from DSMR telegrams.