IRC parsing, tokenization, and state handling in C#

Start to port some ircstates tests

+206 -13
+18 -1
IrcStates/Emit.cs
··· 1 - namespace IrcStates 1 + using System.Collections.Generic; 2 + 3 + namespace IrcStates 2 4 { 3 5 public class Emit 4 6 { 7 + public string Command { get; set; } 8 + public string Subcommand { get; set; } 9 + public string Text { get; set; } 10 + public List<string> Tokens { get; set; } 11 + public bool Finished { get; set; } 12 + public bool SelfSource { get; set; } 13 + public bool SelfTarget { get; set; } 14 + public Tests.User User { get; set; } 15 + public Tests.User UserSource { get; set; } 16 + public Tests.User UserTarget { get; set; } 17 + public List<Tests.User> Users { get; set; } 18 + public Tests.Channel Channel { get; set; } 19 + public Tests.Channel ChannelSource { get; set; } 20 + public Tests.Channel ChannelTarget { get; set; } 21 + public string Target { get; set; } 5 22 } 6 23 }
+14 -8
IrcStates/Server.cs
··· 64 64 return null; 65 65 } 66 66 67 - private Emit ParseTokens(Line line) 67 + public Emit ParseTokens(Line line) 68 68 { 69 - Emit ret; 70 - if (LineHandlers.ContainsKey(line.Command)) 71 - foreach (var callback in LineHandlers[line.Command]) 72 - { 73 - var emit = callback(line.Command, line); 74 - } 69 + if (line != null && !LineHandlers.ContainsKey(line.Command)) return null; 70 + var ret = new Emit(); 75 71 76 - throw new NotImplementedException(); 72 + var handlers = LineHandlers[line.Command] 73 + .Select(callback => callback(line.Command, line)) 74 + .Where(emit => emit != null); 75 + 76 + foreach (var emit in handlers) 77 + { 78 + emit.Command = line.Command; 79 + ret = emit; 80 + } 81 + 82 + return ret; 77 83 } 78 84 } 79 85 }
+122 -1
IrcStates/Tests/Cap.cs
··· 1 - using Microsoft.VisualStudio.TestTools.UnitTesting; 1 + using System.Collections.Generic; 2 + using IrcTokens; 3 + using Microsoft.VisualStudio.TestTools.UnitTesting; 2 4 3 5 namespace IrcStates.Tests 4 6 { 5 7 [TestClass] 6 8 public class Cap 7 9 { 10 + private Server _server; 11 + 12 + [TestInitialize] 13 + public void TestInitialize() 14 + { 15 + _server = new Server("test"); 16 + } 17 + 18 + [TestMethod] 19 + public void LSOneLine() 20 + { 21 + Assert.IsFalse(_server.HasCap); 22 + CollectionAssert.AreEqual(new Dictionary<string, string>(), _server.AvailableCaps); 23 + _server.ParseTokens(new Line("CAP * LS :a b")); 24 + CollectionAssert.AreEqual(new Dictionary<string, string> {{"a", ""}, {"b", ""}}, _server.AvailableCaps); 25 + } 26 + 27 + [TestMethod] 28 + public void LSTwoLines() 29 + { 30 + _server.ParseTokens(new Line("CAP * LS * :a b")); 31 + CollectionAssert.AreEqual(new Dictionary<string, string>(), _server.AvailableCaps); 32 + _server.ParseTokens(new Line("CAP * LS :c")); 33 + CollectionAssert.AreEqual(new Dictionary<string, string> {{"a", ""}, {"b", ""}, {"c", ""}}, 34 + _server.AvailableCaps); 35 + } 36 + 37 + [TestMethod] 38 + public void LSValues() 39 + { 40 + _server.ParseTokens(new Line("CAP * LS :a b= c=1")); 41 + CollectionAssert.AreEqual(new Dictionary<string, string> {{"a", ""}, {"b", ""}, {"c", "1"}}, 42 + _server.AvailableCaps); 43 + } 44 + 45 + [TestMethod] 46 + public void ACKOneLine() 47 + { 48 + _server.ParseTokens(new Line("CAP * LS :a b")); 49 + _server.ParseTokens(new Line("CAP * ACK :a b")); 50 + CollectionAssert.AreEqual(new List<string> {"a", "b"}, _server.AgreedCaps); 51 + } 52 + 53 + [TestMethod] 54 + public void ACKTwoLines() 55 + { 56 + _server.ParseTokens(new Line("CAP * LS :a b c")); 57 + _server.ParseTokens(new Line("CAP * ACK * :a b")); 58 + _server.ParseTokens(new Line("CAP * ACK :c")); 59 + CollectionAssert.AreEqual(new List<string> {"a", "b", "c"}, _server.AgreedCaps); 60 + } 61 + 62 + [TestMethod] 63 + public void ACKNotLS() 64 + { 65 + _server.ParseTokens(new Line("CAP * LS a")); 66 + _server.ParseTokens(new Line("CAP * ACK b")); 67 + CollectionAssert.AreEqual(new List<string>(), _server.AgreedCaps); 68 + } 69 + 70 + [TestMethod] 71 + public void NEWNoLS() 72 + { 73 + _server.ParseTokens(new Line("CAP * NEW :a")); 74 + CollectionAssert.AreEqual(new Dictionary<string, string> {{"a", ""}}, _server.AvailableCaps); 75 + } 76 + 77 + [TestMethod] 78 + public void NEWOneLine() 79 + { 80 + _server.ParseTokens(new Line("CAP * LS :a")); 81 + _server.ParseTokens(new Line("CAP * NEW :b")); 82 + CollectionAssert.AreEqual(new Dictionary<string, string> {{"a", ""}, {"b", ""}}, _server.AvailableCaps); 83 + } 84 + 85 + [TestMethod] 86 + public void NEWTwoLines() 87 + { 88 + _server.ParseTokens(new Line("CAP * LS :a")); 89 + _server.ParseTokens(new Line("CAP * NEW :b c")); 90 + CollectionAssert.AreEqual(new Dictionary<string, string> {{"a", ""}, {"b", ""}, {"c", ""}}, 91 + _server.AvailableCaps); 92 + } 93 + 94 + [TestMethod] 95 + public void DELNotAcked() 96 + { 97 + _server.ParseTokens(new Line("CAP * DEL a")); 98 + } 99 + 100 + [TestMethod] 101 + public void DELOneLS() 102 + { 103 + _server.ParseTokens(new Line("CAP * LS :a")); 104 + _server.ParseTokens(new Line("CAP * ACK :a")); 105 + _server.ParseTokens(new Line("CAP * DEL :a")); 106 + CollectionAssert.AreEqual(new Dictionary<string, string>(), _server.AvailableCaps); 107 + CollectionAssert.AreEqual(new List<string>(), _server.AgreedCaps); 108 + } 109 + 110 + [TestMethod] 111 + public void DELTwoLS() 112 + { 113 + _server.ParseTokens(new Line("CAP * LS :a b")); 114 + _server.ParseTokens(new Line("CAP * ACK :a b")); 115 + _server.ParseTokens(new Line("CAP * DEL :a")); 116 + CollectionAssert.AreEqual(new Dictionary<string, string> {{"b", ""}}, _server.AvailableCaps); 117 + CollectionAssert.AreEqual(new List<string> {"b"}, _server.AgreedCaps); 118 + } 119 + 120 + [TestMethod] 121 + public void DELTwoDEL() 122 + { 123 + _server.ParseTokens(new Line("CAP * LS :a b")); 124 + _server.ParseTokens(new Line("CAP * ACK :a b")); 125 + _server.ParseTokens(new Line("CAP * DEL :a b")); 126 + CollectionAssert.AreEqual(new Dictionary<string, string>(), _server.AvailableCaps); 127 + CollectionAssert.AreEqual(new List<string>(), _server.AgreedCaps); 128 + } 8 129 } 9 130 }
+50 -1
IrcStates/Tests/Casemap.cs
··· 1 - using Microsoft.VisualStudio.TestTools.UnitTesting; 1 + using IrcTokens; 2 + using Microsoft.VisualStudio.TestTools.UnitTesting; 2 3 3 4 namespace IrcStates.Tests 4 5 { 5 6 [TestClass] 6 7 public class Casemap 7 8 { 9 + [TestMethod] 10 + public void Rfc1459() 11 + { 12 + var lower = IrcStates.Casemap.CaseFold(IrcStates.Casemap.CaseMapping.Rfc1459, @"ÀTEST[]~\"); 13 + Assert.AreEqual("Àtest{}^|", lower); 14 + } 15 + 16 + [TestMethod] 17 + public void Ascii() 18 + { 19 + var lower = IrcStates.Casemap.CaseFold(IrcStates.Casemap.CaseMapping.Ascii, @"ÀTEST[]~\"); 20 + Assert.AreEqual(@"Àtest[]~\", lower); 21 + } 22 + 23 + [TestMethod] 24 + public void CommandJoin() 25 + { 26 + var server = new Server("test"); 27 + server.ParseTokens(new Line("001 nickname")); 28 + server.ParseTokens(new Line(":Nickname JOIN #Chan")); 29 + server.ParseTokens(new Line(":Other JOIN #Chan")); 30 + 31 + Assert.IsTrue(server.Users.ContainsKey("nickname")); 32 + Assert.IsFalse(server.Users.ContainsKey("Nickname")); 33 + Assert.IsTrue(server.Users.ContainsKey("other")); 34 + Assert.IsFalse(server.Users.ContainsKey("Other")); 35 + Assert.IsTrue(server.Channels.ContainsKey("#chan")); 36 + Assert.IsFalse(server.Channels.ContainsKey("#Chan")); 37 + 38 + var channel = server.Channels["#chan"]; 39 + Assert.AreEqual("#Chan", channel.Name); 40 + } 41 + 42 + [TestMethod] 43 + public void CommandNick() 44 + { 45 + var server = new Server("test"); 46 + server.ParseTokens(new Line("001 nickname")); 47 + server.ParseTokens(new Line(":nickname JOIN #chan")); 48 + var user = server.Users["nickname"]; 49 + server.ParseTokens(new Line(":nickname NICK NewNickname")); 50 + Assert.AreEqual(1, server.Users.Count); 51 + Assert.IsTrue(server.Users.ContainsKey("newnickname")); 52 + Assert.AreEqual("NewNickname", user.NickName); 53 + Assert.AreEqual("newnickname", user.NickNameLower); 54 + Assert.AreEqual("NewNickName", server.NickName); 55 + Assert.AreEqual("newnickname", server.NickNameLower); 56 + } 8 57 } 9 58 }
+2 -2
IrcStates/User.cs
··· 4 4 { 5 5 public class User 6 6 { 7 - private string NickName; 8 - private string NickNameLower; 7 + public string NickName { get; set; } 8 + public string NickNameLower { get; set; } 9 9 10 10 public string UserName { get; set; } 11 11 public string HostName { get; set; }