33import json
44from pathlib import Path
55import re
6- from unittest .mock import MagicMock , patch
76
7+ from unittest .mock import MagicMock
88import pytest
99
1010import meshtastic
11- import meshtastic .formatter
12- from meshtastic .formatter import FormatterFactory , AbstractFormatter , InfoFormatter
11+ # from meshtastic.formatter import FormatterFactory, AbstractFormatter, InfoFormatter
12+ from ..protobuf import config_pb2
13+ from ..formatter import FormatterFactory , AbstractFormatter , InfoFormatter
14+ from ..mesh_interface import MeshInterface
15+ try :
16+ # Depends upon the powermon group, not installed by default
17+ from ..slog import LogSet
18+ from ..powermon import SimPowerSupply
19+ except ImportError :
20+ pytest .skip ("Can't import LogSet or SimPowerSupply" , allow_module_level = True )
1321
1422
15- # from ..formatter import FormatterFactory, FormatAsText
16-
1723def pskBytes (d ):
1824 """Implement a hook to decode psk to byte as needed for the test"""
1925 if '__psk__' in d :
@@ -23,7 +29,7 @@ def pskBytes(d):
2329
2430@pytest .mark .unit
2531def test_factory ():
26- ff = meshtastic . formatter . FormatterFactory ()
32+ ff = FormatterFactory ()
2733 assert len (ff .infoFormatters ) > 0
2834
2935 # test for at least default formatter which should be returned when passed an empty string
@@ -47,24 +53,24 @@ def test_factory():
4753@pytest .mark .unit
4854@pytest .mark .parametrize ("inFile, expected" , [
4955 ("cfg1.json" , {
50- "len" : 4161 ,
51- "keys" : ["Owner" , "My Info " , "Metadata" , "Nodes" , "Preferences" , "Module preferences " , "Channels" , "publicURL" ]
56+ "len" : 4159 ,
57+ "keys" : ["Owner" , "MyInfo " , "Metadata" , "Nodes" , "Preferences" , "ModulePreferences " , "Channels" , "publicURL" ]
5258 }),
5359 ("cfg2-OwnerOnly.json" , {
54- "len" : 169 ,
55- "keys" : ["Owner" , "My Info " , "Metadata" , "Nodes" , "Preferences" , "Module preferences " , "Channels" ]
60+ "len" : 167 ,
61+ "keys" : ["Owner" , "MyInfo " , "Metadata" , "Nodes" , "Preferences" , "ModulePreferences " , "Channels" ]
5662 }),
5763 ("cfg3-NoNodes.json" , {
58- "len" : 3413 ,
59- "keys" : ["Owner" , "My Info " , "Metadata" , "Preferences" , "Module preferences " , "Channels" , "publicURL" ]
64+ "len" : 3411 ,
65+ "keys" : ["Owner" , "MyInfo " , "Metadata" , "Preferences" , "ModulePreferences " , "Channels" , "publicURL" ]
6066 }),
6167 ("cfg4-NoPrefs.json" , {
62- "len" : 2354 ,
63- "keys" : ["Owner" , "My Info " , "Metadata" , "Channels" , "publicURL" ]
68+ "len" : 2353 ,
69+ "keys" : ["Owner" , "MyInfo " , "Metadata" , "Channels" , "publicURL" ]
6470 }),
6571 ("cfg5-NoChannels.json" , {
66- "len" : 597 ,
67- "keys" : ["Owner" , "My Info " , "Metadata" , "publicURL" ]
72+ "len" : 596 ,
73+ "keys" : ["Owner" , "MyInfo " , "Metadata" , "publicURL" ]
6874 })
6975])
7076def test_jsonFormatter (inFile , expected ):
@@ -132,7 +138,7 @@ def test_ExceptionAbstractClass():
132138
133139@pytest .mark .unit
134140@pytest .mark .parametrize ("inCfg, expected" , [
135- (("cfg1.json" , 'json' ), {"len" : 4162 }),
141+ (("cfg1.json" , 'json' ), {"len" : 4160 }),
136142 (("cfg1.json" , 'txt' ), {"len" : 2390 }),
137143 (("cfg1.json" , None ), {"len" : 2390 })
138144 ])
@@ -145,3 +151,52 @@ def test_InfoFormatter(capsys, inCfg, expected):
145151
146152 out , _ = capsys .readouterr ()
147153 assert len (out ) == expected ['len' ]
154+
155+ @pytest .mark .unit
156+ @pytest .mark .usefixtures ("reset_mt_config" )
157+ @pytest .mark .parametrize ("inFmt, expected" , [
158+ ('json' , {"len" : 556 , "keys" : ["!9388f81c" , "Unknown f81c" , "44:17:93:88:f8:1c" , "https://meshtastic.org/e/#EgA" ]}),
159+ ('txt' , {"len" : 539 , "keys" : ["!9388f81c" , "Unknown f81c" , "44:17:93:88:f8:1c" , "https://meshtastic.org/e/#EgA" ]}),
160+ (None , {"len" : 539 , "keys" : ["!9388f81c" , "Unknown f81c" , "44:17:93:88:f8:1c" , "https://meshtastic.org/e/#EgA" ]})
161+ ])
162+ def test_fullSequenceTest (capsys , inFmt , expected ):
163+ """Test formatter when exporting data from an instantiated mesh interface
164+ --> close the loop of data"""
165+ iface = MeshInterface (noProto = True )
166+
167+ NODE_ID = "!9388f81c"
168+ NODE_NUM = 2475227164
169+ node = {
170+ "num" : NODE_NUM ,
171+ "user" : {
172+ "id" : NODE_ID ,
173+ "longName" : "Unknown f81c" ,
174+ "shortName" : "?1C" ,
175+ "macaddr" : "RBeTiPgc" ,
176+ "hwModel" : "TBEAM" ,
177+ },
178+ "position" : {},
179+ "lastHeard" : 1640204888 ,
180+ }
181+
182+ iface .nodes = {NODE_ID : node }
183+ iface .nodesByNum = {NODE_NUM : node }
184+
185+ myInfo = MagicMock ()
186+ iface .myInfo = myInfo
187+
188+ iface .localNode .localConfig .lora .CopyFrom (config_pb2 .Config .LoRaConfig ())
189+
190+ # Also get some coverage of the structured logging/power meter stuff by turning it on as well
191+ log_set = LogSet (iface , None , SimPowerSupply ())
192+
193+ ifData = iface .getInfo ()
194+ ifData .update (iface .localNode .getInfo ())
195+ iface .close ()
196+ log_set .close ()
197+
198+ InfoFormatter ().format (ifData , inFmt )
199+
200+ out , _ = capsys .readouterr ()
201+ print (out )
202+ assert len (out ) == expected ['len' ]
0 commit comments