11from __future__ import annotations
22
33from collections .abc import Iterator
4+ from datetime import datetime
45from typing import NamedTuple
56
67import pytest
@@ -78,24 +79,25 @@ def loop_forever(self, timeout=1, retry_first_connection=False):
7879 monkeypatch .setattr ("pms.extra.mqtt.Client" , MockClient )
7980
8081
81- class PointValue (NamedTuple ):
82+ class DataPoint (NamedTuple ):
83+ time : int
8284 name : str
8385 value : str | int | float
8486
8587 def __str__ (self ):
8688 return f"{ self .name } = { self .value } "
8789
8890 @classmethod
89- def from_obs (cls , obs_iter : Iterator [ObsData ]) -> Iterator [PointValue ]:
91+ def from_obs (cls , obs_iter : Iterator [ObsData ]) -> Iterator [DataPoint ]:
9092 for obs in obs_iter :
9193 for name , value in db_measurements (obs ):
92- yield cls (name , value )
94+ yield cls (obs . time , name , value )
9395
9496
9597@pytest .fixture ()
9698def mock_influxdb_client (captured_data , monkeypatch : pytest .MonkeyPatch ):
9799 class MockClient :
98- point_value = PointValue .from_obs (captured_data .obs )
100+ data_point = DataPoint .from_obs (captured_data .obs )
99101
100102 def __init__ (
101103 self , host = "localhost" , port = 8086 , username = "root" , password = "root" , database = None
@@ -122,13 +124,32 @@ def write_points(self, points, time_precision=None, database=None):
122124 assert point .keys () == {"measurement" , "tags" , "time" , "fields" }
123125 assert isinstance (point ["fields" ], dict )
124126 assert point ["fields" ].keys () == {"value" }
125- assert PointValue ( point [ "measurement" ], point [ "fields" ][ "value" ]) == next (
126- self . point_value
127- )
127+ assert DataPoint (
128+ point [ "time" ], point [ "measurement" ], point [ "fields" ][ "value" ]
129+ ) == next ( self . data_point )
128130
129131 monkeypatch .setattr ("pms.extra.influxdb.Client" , MockClient )
130132
131133
134+ @pytest .fixture
135+ def mock_mqtt_datetime (captured_data , monkeypatch : pytest .MonkeyPatch ) -> None :
136+ """mock datetime at `pms.core.sensor` and `pms.sensors.base`"""
137+
138+ class mock_datetime (datetime ):
139+ _timestamp = (p .time for p in DataPoint .from_obs (captured_data .obs ))
140+
141+ @classmethod
142+ def fromtimestamp (cls , t , tz = captured_data .tzinfo ):
143+ assert tz == captured_data .tzinfo
144+ return datetime .fromtimestamp (t , tz )
145+
146+ @classmethod
147+ def now (cls , tz = captured_data .tzinfo ):
148+ return cls .fromtimestamp (next (cls ._timestamp ), tz )
149+
150+ monkeypatch .setattr ("pms.extra.mqtt.datetime" , mock_datetime )
151+
152+
132153@pytest .mark .usefixtures ("mock_mqtt_client" )
133154def test_mqtt (capture ):
134155 result = runner .invoke (main , capture .options ("mqtt" ))
@@ -141,7 +162,7 @@ def test_influxdb(capture):
141162 assert result .exit_code == 0
142163
143164
144- @pytest .mark .usefixtures ("mock_influxdb_client" , "mock_mqtt_client" )
165+ @pytest .mark .usefixtures ("mock_influxdb_client" , "mock_mqtt_client" , "mock_mqtt_datetime" )
145166def test_bridge (capture ):
146167 result = runner .invoke (main , capture .options ("bridge" ))
147168 assert result .exit_code == 0
0 commit comments