IRC parsing, tokenization, and state handling in C#
at ircrobotsv2 123 lines 3.5 kB view raw
1namespace IRCSharp.Tests.Tokenization; 2 3public class Tokenization 4{ 5 [Test] 6 public async Task TagsMissing() 7 { 8 var line = new Line("PRIVMSG #channel"); 9 await Assert.That(line.Tags).IsNull(); 10 } 11 12 [Test] 13 public async Task TagsMissingValue() 14 { 15 var line = new Line("@id= PRIVMSG #channel"); 16 await Assert.That(line.Tags["id"]).IsEmpty(); 17 } 18 19 [Test] 20 public async Task TagsMissingEqual() 21 { 22 var line = new Line("@id PRIVMSG #channel"); 23 await Assert.That(line.Tags["id"]).IsNull(); 24 } 25 26 [Test] 27 public async Task TagsUnescape() 28 { 29 var line = new Line(@"@id=1\\\:\r\n\s2 PRIVMSG #channel"); 30 await Assert.That(line.Tags["id"]).IsEqualTo("1\\;\r\n 2"); 31 } 32 33 [Test] 34 public async Task TagsOverlap() 35 { 36 var line = new Line(@"@id=1\\\s\\s PRIVMSG #channel"); 37 await Assert.That(line.Tags["id"]).IsEqualTo(@"1\ \s"); 38 } 39 40 [Test] 41 public async Task TagsLoneEndSlash() 42 { 43 var line = new Line("@id=1\\ PRIVMSG #channel"); 44 await Assert.That(line.Tags["id"]).IsEqualTo("1"); 45 } 46 47 [Test] 48 public async Task SourceWithoutTags() 49 { 50 var line = new Line(":nick!user@host PRIVMSG #channel"); 51 await Assert.That(line.Source).IsEqualTo("nick!user@host"); 52 } 53 54 [Test] 55 public async Task SourceWithTags() 56 { 57 var line = new Line("@id=123 :nick!user@host PRIVMSG #channel"); 58 await Assert.That(line.Source).IsEqualTo("nick!user@host"); 59 } 60 61 [Test] 62 public async Task SourceMissingWithoutTags() 63 { 64 var line = new Line("PRIVMSG #channel"); 65 await Assert.That(line.Source).IsNull(); 66 } 67 68 [Test] 69 public async Task SourceMissingWithTags() 70 { 71 var line = new Line("@id=123 PRIVMSG #channel"); 72 await Assert.That(line.Source).IsNull(); 73 } 74 75 [Test] 76 public async Task Command() 77 { 78 var line = new Line("privmsg #channel"); 79 await Assert.That(line.Command).IsEqualTo("PRIVMSG"); 80 } 81 82 [Test] 83 public async Task ParamsTrailing() 84 { 85 var line = new Line("PRIVMSG #channel :hello world"); 86 await Assert.That(line.Params).IsEquivalentTo(["#channel", "hello world"]); 87 } 88 89 [Test] 90 public async Task ParamsOnlyTrailing() 91 { 92 var line = new Line("PRIVMSG :hello world"); 93 await Assert.That(line.Params).IsEquivalentTo(["hello world"]); 94 } 95 96 [Test] 97 public async Task ParamsMissing() 98 { 99 var line = new Line("PRIVMSG"); 100 await Assert.That(line.Command).IsEqualTo("PRIVMSG"); 101 await Assert.That(line.Params).IsEmpty(); 102 } 103 104 [Test] 105 public async Task AllTokens() 106 { 107 var line = new Line("@id=123 :nick!user@host PRIVMSG #channel :hello world"); 108 await Assert.That(line.Tags).IsEquivalentTo(new Dictionary<string, string> { { "id", "123" } }); 109 await Assert.That(line.Source).IsEqualTo("nick!user@host"); 110 await Assert.That(line.Command).IsEqualTo("PRIVMSG"); 111 await Assert.That(line.Params).IsEquivalentTo(["#channel", "hello world"]); 112 } 113 114 [Test] 115 public async Task NulByte() 116 { 117 var decoder = new IRCTokens.StatefulDecoder(); 118 var bytes = ":nick!user@host PRIVMSG #channel :hello\0world"u8; 119 var line = decoder.Push(bytes.ToArray(), bytes.Length).First(); 120 121 await Assert.That(line.Params).IsEquivalentTo(["#channel", "hello"]); 122 } 123}