Adds GuangdongFcEndToEndTest covering the full vendor extension pipeline:
build a synthetic V2016 realtime frame containing standard blocks
(0x01/0x05/0x07/0x08/0x09) plus the Guangdong-specific 0x30 stack (with
4 sample cell voltages), 0x32 DC/DC, 0x33 air conditioner, 0x34 vehicle
info, and 0x80 demo extension. Decodes it through Gb32960MessageDecoder
with a hand-wired BodyParser whose Gb32960ProfileRegistry knows about
the guangdong-fc catalog entry and a RuleBasedVendorExtensionSelector
matching platformAccount=lingniu.
Two cases:
- parsesRealtimeFrameWithGuangdongFcExtensions: passes "lingniu" as the
platform account, asserts each GuangdongFc.* record is present and
field values match the synthesized bytes, and that no Raw fallback
is produced.
- unmatchedAccountFallsBackToDefaultAndProducesRawForVendorBlocks: passes
null as the account, asserts standard blocks still parse but the
vendor 0x30 segment now lands in InfoBlock.Raw via the default-profile
unknown-typeCode path. This pins down the selector's gate behavior.
Test count: 30 -> 32. All green.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>