"""测试逻辑分析仪 CSV/BIN 波形解析。""" from __future__ import annotations import struct import tempfile import unittest from pathlib import Path from logic_waveform import ( WaveformChannel, build_frequency_curve, load_bin_waveform, load_csv_waveform, parse_channel_selection, parse_marker_times_ms, ) from parse_logic_csv import CsvParseError class LogicWaveformTest(unittest.TestCase): """验证两种导出格式的关键解析结果。""" def test_load_csv_waveform(self) -> None: """CSV 应识别采样信息、数字时间列和通道跳变。""" content = """; Sample rate: 20 MHz ; Sample count: 10 SystemTime,Time(s),Channel 0,Channel 1 '2026-08-14 10:00:00,0.0,0,1 '2026-08-14 10:00:00,0.1,1,1 '2026-08-14 10:00:00,0.2,1,0 """ with tempfile.TemporaryDirectory() as directory: path = Path(directory) / "wave.csv" path.write_text(content, encoding="utf-8") data = load_csv_waveform(path) self.assertEqual(data.sample_rate, 20_000_000) self.assertEqual(data.sample_count, 10) self.assertEqual(data.record_count, 3) self.assertEqual(data.start_time, 0.0) self.assertEqual(data.end_time, 0.2) self.assertEqual(data.channels[0].times, [0.0, 0.1]) self.assertEqual(data.channels[0].levels, [0, 1]) self.assertEqual(data.channels[1].times, [0.0, 0.2]) self.assertEqual(data.channels[1].levels, [1, 0]) def test_load_16_channel_bin_waveform(self) -> None: """16 通道 BIN 应按小端 16 位采样点读取。""" samples = (0x0000, 0x0010, 0x0010, 0x0000) with tempfile.TemporaryDirectory() as directory: path = Path(directory) / "wave.bin" path.write_bytes(struct.pack("<4H", *samples)) data = load_bin_waveform(path, 10.0, 16, [4]) channel = data.channels[0] self.assertEqual(data.sample_count, 4) self.assertAlmostEqual(data.duration, 0.3) self.assertEqual(channel.index, 4) self.assertEqual(channel.times, [0.0, 0.1, 0.3]) self.assertEqual(channel.levels, [0, 1, 0]) def test_parse_channel_selection(self) -> None: """通道输入应支持单个、列表和范围。""" self.assertIsNone(parse_channel_selection("自动", 16)) self.assertEqual(parse_channel_selection("4", 16), [4]) self.assertEqual(parse_channel_selection("0,2,4-6", 16), [0, 2, 4, 5, 6]) def test_build_frequency_curve_with_automatic_falling_edge(self) -> None: """负逻辑脉冲应自动使用第一个真实下降沿计算频率。""" channel = WaveformChannel( index=4, name="Channel 4", times=[0.0, 0.1, 0.11, 0.2, 0.21, 0.3, 0.31], levels=[1, 0, 1, 0, 1, 0, 1], ) curve = build_frequency_curve(channel, "auto") self.assertEqual(curve.edge_name, "下降沿") self.assertEqual(curve.times, [0.1, 0.2, 0.3]) for frequency in curve.frequencies: self.assertAlmostEqual(frequency, 10.0) measured_time, frequency = curve.frequency_at(0.2) self.assertEqual(measured_time, 0.2) self.assertEqual(frequency, 10.0) def test_build_frequency_curve_with_rising_edge(self) -> None: """指定上升沿时应按相邻上升沿周期换算频率。""" channel = WaveformChannel( index=0, name="Channel 0", times=[0.0, 0.01, 0.015, 0.02, 0.0225, 0.025, 0.0275], levels=[0, 1, 0, 1, 0, 1, 0], ) curve = build_frequency_curve(channel, "rising") self.assertEqual(curve.edge_name, "上升沿") self.assertAlmostEqual(curve.frequencies[0], 100.0) self.assertAlmostEqual(curve.frequencies[-1], 200.0) def test_parse_marker_times_ms(self) -> None: """关键时间应支持多个毫秒数值。""" self.assertEqual(parse_marker_times_ms("100, 200,500"), [0.1, 0.2, 0.5]) def test_parse_marker_times_ms_rejects_more_than_ten_unique_values(self) -> None: """关键时间超过十个时应给出明确错误。""" with self.assertRaisesRegex(CsvParseError, "最多设置 10 个"): parse_marker_times_ms(",".join(str(value) for value in range(11))) if __name__ == "__main__": unittest.main()