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