using System.Buffers; using System.Text; using NATS.Server.Protocol; namespace NATS.Server.Core.Tests.ProtocolParity; public class ProtocolParserSnippetGapParityTests { [Fact] public void ProtoSnippet_returns_empty_quotes_when_start_is_out_of_range() { var bytes = "PING"u8.ToArray(); var snippet = NatsParser.ProtoSnippet(bytes.Length, 2, bytes); snippet.ShouldBe("\"\""); } [Fact] public void ProtoSnippet_limits_to_requested_window_and_quotes_output() { var bytes = "ABCDEFGHIJ"u8.ToArray(); var snippet = NatsParser.ProtoSnippet(2, 4, bytes); snippet.ShouldBe("\"CDEF\""); } [Fact] public void ProtoSnippet_matches_go_behavior_when_max_runs_past_buffer_end() { var bytes = "ABCDE"u8.ToArray(); var snippet = NatsParser.ProtoSnippet(0, 32, bytes); snippet.ShouldBe("\"ABCD\""); } [Fact] public void Parse_exceeding_max_control_line_includes_snippet_context_in_error() { var parser = new NatsParser(); var longSubject = new string('a', NatsProtocol.MaxControlLineSize + 1); var input = Encoding.ASCII.GetBytes($"PUB {longSubject} 0\r\n\r\n"); ReadOnlySequence buffer = new(input); var ex = Should.Throw(() => parser.TryParse(ref buffer, out _)); ex.Message.ShouldContain("Maximum control line exceeded"); ex.Message.ShouldContain("snip="); } [Fact] public void Parse_invalid_payload_trailer_preserves_existing_error_message() { var parser = new NatsParser(); var input = Encoding.ASCII.GetBytes("PUB foo 5\r\nHelloXX"); ReadOnlySequence buffer = new(input); var ex = Should.Throw(() => parser.TryParse(ref buffer, out _)); ex.Message.ShouldBe("Expected \\r\\n after payload"); } }