|
| 1 | +import numpy as np |
| 2 | +from nitypes.xy_data import XYData |
| 3 | + |
| 4 | +import ni.protobuf.types.xydata_pb2 as xydata_pb2 |
| 5 | +from ni.protobuf.types.attribute_value_pb2 import AttributeValue |
| 6 | +from ni.protobuf.types.xydata_conversion import ( |
| 7 | + float64_xydata_from_protobuf, |
| 8 | + float64_xydata_to_protobuf, |
| 9 | +) |
| 10 | + |
| 11 | + |
| 12 | +# ======================================================== |
| 13 | +# XYData: Protobuf to Python |
| 14 | +# ======================================================== |
| 15 | +def test___doublexydata_protobuf___convert___valid_xydata_default_units() -> None: |
| 16 | + expected_x_data = [1.0, 2.0, 3.0] |
| 17 | + expected_y_data = [4.0, 5.0, 6.0] |
| 18 | + protobuf_value = xydata_pb2.DoubleXYData(x_data=expected_x_data, y_data=expected_y_data) |
| 19 | + |
| 20 | + python_value = float64_xydata_from_protobuf(protobuf_value) |
| 21 | + assert isinstance(python_value, XYData) |
| 22 | + assert python_value.dtype == np.float64 |
| 23 | + assert list(python_value.x_data) == expected_x_data |
| 24 | + assert list(python_value.y_data) == expected_y_data |
| 25 | + assert python_value.x_units == "" |
| 26 | + assert python_value.y_units == "" |
| 27 | + |
| 28 | + |
| 29 | +def test___doublexydata_protobuf_with_units___convert___valid_xydata() -> None: |
| 30 | + attributes = { |
| 31 | + "NI_UnitDescription_X": AttributeValue(string_value="Volts"), |
| 32 | + "NI_UnitDescription_Y": AttributeValue(string_value="Seconds"), |
| 33 | + } |
| 34 | + expected_x_data = [1.0, 2.0, 3.0] |
| 35 | + expected_y_data = [4.0, 5.0, 6.0] |
| 36 | + protobuf_value = xydata_pb2.DoubleXYData( |
| 37 | + x_data=expected_x_data, |
| 38 | + y_data=expected_y_data, |
| 39 | + attributes=attributes, |
| 40 | + ) |
| 41 | + |
| 42 | + python_value = float64_xydata_from_protobuf(protobuf_value) |
| 43 | + |
| 44 | + assert isinstance(python_value, XYData) |
| 45 | + assert python_value.dtype == np.float64 |
| 46 | + assert list(python_value.x_data) == expected_x_data |
| 47 | + assert list(python_value.y_data) == expected_y_data |
| 48 | + assert python_value.x_units == "Volts" |
| 49 | + assert python_value.y_units == "Seconds" |
| 50 | + |
| 51 | + |
| 52 | +def test___doublexydata_protobuf_with_other_attrs___convert___attrs_converted() -> None: |
| 53 | + attributes = { |
| 54 | + "NI_UnitDescription_X": AttributeValue(string_value="Volts"), |
| 55 | + "NI_UnitDescription_Y": AttributeValue(string_value="Seconds"), |
| 56 | + "Non_Units_Attribute": AttributeValue(double_value=1.1), |
| 57 | + } |
| 58 | + protobuf_value = xydata_pb2.DoubleXYData( |
| 59 | + x_data=[1.0], |
| 60 | + y_data=[2.0], |
| 61 | + attributes=attributes, |
| 62 | + ) |
| 63 | + |
| 64 | + python_value = float64_xydata_from_protobuf(protobuf_value) |
| 65 | + |
| 66 | + assert isinstance(python_value, XYData) |
| 67 | + assert python_value.x_units == "Volts" |
| 68 | + assert python_value.y_units == "Seconds" |
| 69 | + assert python_value.extended_properties.get("Non_Units_Attribute") == 1.1 |
| 70 | + |
| 71 | + |
| 72 | +# ======================================================== |
| 73 | +# XYData: Python to Protobuf |
| 74 | +# ======================================================== |
| 75 | +def test___float64_xydata___convert___valid_doublexydata_protobuf() -> None: |
| 76 | + expected_x_data = [1.0, 2.0, 3.0] |
| 77 | + expected_y_data = [4.0, 5.0, 6.0] |
| 78 | + python_value = XYData.from_arrays_1d( |
| 79 | + x_array=expected_x_data, |
| 80 | + y_array=expected_y_data, |
| 81 | + dtype=np.float64, |
| 82 | + ) |
| 83 | + |
| 84 | + protobuf_value = float64_xydata_to_protobuf(python_value) |
| 85 | + |
| 86 | + assert isinstance(protobuf_value, xydata_pb2.DoubleXYData) |
| 87 | + assert list(protobuf_value.x_data) == expected_x_data |
| 88 | + assert list(protobuf_value.y_data) == expected_y_data |
| 89 | + |
| 90 | + |
| 91 | +def test___int16_xydata___convert___causes_mypy_error() -> None: |
| 92 | + python_value = XYData.from_arrays_1d( |
| 93 | + x_array=[1, 2, 3], |
| 94 | + y_array=[4, 5, 6], |
| 95 | + dtype=np.int16, |
| 96 | + ) |
| 97 | + |
| 98 | + # The next line should generate a mypy error. If it doesn't, we'll get an 'unused |
| 99 | + # ignore' mypy error. |
| 100 | + protobuf_value = float64_xydata_to_protobuf(python_value) # type: ignore[arg-type] |
| 101 | + |
| 102 | + # This conversion still works, so we might as well check it. Int values are converted to float. |
| 103 | + assert isinstance(protobuf_value, xydata_pb2.DoubleXYData) |
| 104 | + assert list(protobuf_value.x_data) == [1.0, 2.0, 3.0] |
| 105 | + assert list(protobuf_value.y_data) == [4.0, 5.0, 6.0] |
| 106 | + |
| 107 | + |
| 108 | +def test___xydata_with_extended_properties___convert___valid_doublexydata_protobuf() -> None: |
| 109 | + expected_x_data = [1.0] |
| 110 | + expected_y_data = [2.0] |
| 111 | + python_value = XYData.from_arrays_1d( |
| 112 | + x_array=expected_x_data, |
| 113 | + y_array=expected_y_data, |
| 114 | + dtype=np.float64, |
| 115 | + extended_properties={ |
| 116 | + "true": True, |
| 117 | + "1": 1, |
| 118 | + "1.0": 1.0, |
| 119 | + "str": "str", |
| 120 | + }, |
| 121 | + ) |
| 122 | + |
| 123 | + protobuf_value = float64_xydata_to_protobuf(python_value) |
| 124 | + |
| 125 | + assert isinstance(protobuf_value, xydata_pb2.DoubleXYData) |
| 126 | + assert list(protobuf_value.x_data) == expected_x_data |
| 127 | + assert list(protobuf_value.y_data) == expected_y_data |
| 128 | + assert protobuf_value.attributes["true"].bool_value is True |
| 129 | + assert protobuf_value.attributes["1"].integer_value == 1 |
| 130 | + assert protobuf_value.attributes["1.0"].double_value == 1.0 |
| 131 | + assert protobuf_value.attributes["str"].string_value == "str" |
0 commit comments