Coverage for tests/test_scpi.py: 100%

80 statements  

« prev     ^ index     » next       coverage.py v7.10.6, created at 2025-09-04 11:16 +0200

1import pytest 

2 

3from cgse_dummy.scpi import COMMANDS 

4from cgse_dummy.scpi import Commands 

5from cgse_dummy.scpi import FloatCmdR 

6from cgse_dummy.scpi import Request 

7from cgse_dummy.scpi import cmd_expr_to_reg_expr 

8from cgse_dummy.scpi import min_max_cmd 

9from cgse_dummy.scpi import sanitize_msgs 

10from cgse_dummy.scpi import split_line 

11 

12 

13def test_sanitize_msgs(): 

14 r = sanitize_msgs("*rst", "*idn?;*cls") 

15 assert r == (["*rst", "*idn?", "*cls"], ["*idn?"], "*rst\n*idn?\n*cls\n") 

16 

17 r = sanitize_msgs("*rst", "*idn?;*cls", eol="\r\n") 

18 assert r == (["*rst", "*idn?", "*cls"], ["*idn?"], "*rst\r\n*idn?\r\n*cls\r\n") 

19 

20 r = sanitize_msgs("*rst", "*idn?;*cls", strict_query=False) 

21 assert r == (["*rst", "*idn?", "*cls"], ["*idn?"], "*rst\n*idn?;*cls\n") 

22 

23 r = sanitize_msgs("*rst", "*idn?;*cls", strict_query=False) 

24 assert r == (["*rst", "*idn?", "*cls"], ["*idn?"], "*rst\n*idn?;*cls\n") 

25 

26 

27def test_min_max_cmd(): 

28 assert min_max_cmd("*OPC") == ("*OPC", "*OPC") 

29 assert min_max_cmd(":*OPC") == ("*OPC", "*OPC") 

30 assert min_max_cmd("SYSTem:ERRor[:NEXT]") == ("SYST:ERR", "SYSTEM:ERROR:NEXT") 

31 assert min_max_cmd("MEASure[:CURRent[:DC]]") == ("MEAS", "MEASURE:CURRENT:DC") 

32 assert min_max_cmd("[SENSe[1]:]CURRent[:DC]:RANGe[:UPPer]") == ( 

33 "CURR:RANG", 

34 "SENSE1:CURRENT:DC:RANGE:UPPER", 

35 ) 

36 

37 

38def test_cmd_expr_to_reg_expr(): 

39 cmd_exprs = { 

40 "idn": ("*IDN", "\\:?\\*IDN$"), 

41 "err": ("SYSTem:ERRor[:NEXT]", "\\:?SYST(EM)?\\:ERR(OR)?(\\:NEXT)?$"), 

42 "meas": ("MEASure[:CURRent[:DC]]", "\\:?MEAS(URE)?(\\:CURR(ENT)?(\\:DC)?)?$"), 

43 "rupper": ( 

44 "[SENSe[1]:]CURRent[:DC]:RANGe[:UPPer]", 

45 "\\:?(SENS(E)?(1)?\\:)?CURR(ENT)?(\\:DC)?\\:RANG(E)?(\\:UPP(ER)?)?$", 

46 ), 

47 } 

48 

49 for _, (expr, reg_expr) in list(cmd_exprs.items()): 

50 assert cmd_expr_to_reg_expr(expr).pattern == reg_expr 

51 

52 cmd_re = dict( 

53 [(k, cmd_expr_to_reg_expr(expr)) for k, (expr, _) in list(cmd_exprs.items())] 

54 ) 

55 

56 idn_re = cmd_re["idn"] 

57 assert idn_re.match("*IDN") 

58 assert idn_re.match("*idn") 

59 assert not idn_re.match("IDN") 

60 

61 def test_cmd(name, match, no_match): 

62 reg_expr = cmd_re[name] 

63 for m in match: 

64 assert reg_expr.match(m), "{0}: {1} does not match {2}".format( 

65 name, m, cmd_exprs[name][0] 

66 ) 

67 for m in no_match: 

68 assert not reg_expr.match(m), "{0}: {1} matches {2}".format( 

69 name, m, cmd_exprs[name][0] 

70 ) 

71 

72 test_cmd("idn", ("*IDN", "*idn", "*IdN"), ("IDN", " *IDN", "**IDN", "*IDN ")) 

73 

74 test_cmd( 

75 "err", 

76 ("SYST:ERR", "SYSTEM:ERROR:NEXT", "syst:error", "system:err:next"), 

77 ("sys", "syst:erro", "system:next"), 

78 ) 

79 

80 test_cmd( 

81 "err", 

82 ("SYST:ERR", "SYSTEM:ERROR:NEXT", "syst:error", "system:err:next"), 

83 ("sys", "syst:erro", "system:next"), 

84 ) 

85 

86 test_cmd( 

87 "rupper", 

88 ("CURR:RANG", "SENS:CURR:RANG:UPP", "SENSE1:CURRENT:DC:RANGE:UPPER"), 

89 ("sense:curren:rang", "sens1:range:upp"), 

90 ) 

91 

92 

93def test_commands(): 

94 commands = Commands(COMMANDS.deepcopy()) 

95 

96 # Add a new command 

97 

98 commands["MEASure[:CURRent[:DC]]"] = FloatCmdR(get=lambda x: float(x[:-1])) 

99 

100 keys = set(COMMANDS).union({"MEASure[:CURRent[:DC]]"}) 

101 

102 assert "*idn" in commands 

103 assert commands["*idn"] is commands["*IDN"] 

104 assert commands.get("idn") is None 

105 assert "SYST:ERR" in commands 

106 assert "SYSTEM:ERROR:NEXT" in commands 

107 assert "syst:error" in commands 

108 assert commands["SYST:ERR"] is commands["system:error:next"] 

109 assert commands["MEAS"] is commands["measure:current:dc"] 

110 assert len(commands) == len(COMMANDS) + 1 

111 assert set(commands.keys()) == keys 

112 assert len(commands.values()) == len(COMMANDS) + 1 

113 

114 assert commands.get_command(":*idn")["min_command"] == "*IDN" 

115 assert commands.get_command("system:error:next")["min_command"] == "SYST:ERR" 

116 

117 with pytest.raises(KeyError) as err: 

118 _ = commands["IDN"] 

119 assert "IDN" in str(err.value) 

120 

121 assert "*WAI" in commands 

122 del commands["*WAI"] 

123 assert "*WAI" not in commands 

124 assert len(commands) == len(COMMANDS) + 1 - 1 

125 

126 commands.clear() 

127 assert len(commands) == 0 

128 

129 with pytest.raises(KeyError) as err: 

130 del commands["toto"] 

131 

132 

133def test_split_line(): 

134 

135 assert split_line('') == [] 

136 assert split_line(';:CONTROL?') == [Request(":CONTROL", "", True)] 

137 assert split_line('CONTROL?') == [Request("CONTROL", "", True)] 

138 assert split_line('CONTROL ON') == [Request("CONTROL", "ON", False)] 

139 assert split_line(';;;CONTROL ON;;') == [Request("CONTROL", "ON", False)] 

140 

141 line = ";:CONTROL?;:INPUT A:TEMP?;:INPUT B:TEMP?;:CONTROL C1-ON C2-OFF;\n" 

142 result = [ 

143 Request(":CONTROL", "", True), 

144 Request(":INPUT", "A:TEMP", True), 

145 Request(":INPUT", "B:TEMP", True), 

146 Request(":CONTROL", "C1-ON C2-OFF", False) 

147 ] 

148 assert split_line(line) == result