From 35bbd30c2506b3d0b18397ef1443fb18c0d893d6 Mon Sep 17 00:00:00 2001 From: Ben Harris Date: Tue, 10 Nov 2020 18:35:21 -0500 Subject: Move tests to a separate project --- IRCSharp.Tests/IRCSharp.Tests.csproj | 31 +++ IRCSharp.Tests/State/Cap.cs | 131 +++++++++ IRCSharp.Tests/State/Casemap.cs | 58 ++++ IRCSharp.Tests/State/Channel.cs | 202 ++++++++++++++ IRCSharp.Tests/State/Emit.cs | 117 ++++++++ IRCSharp.Tests/State/ISupport.cs | 210 +++++++++++++++ IRCSharp.Tests/State/Mode.cs | 179 +++++++++++++ IRCSharp.Tests/State/Motd.cs | 23 ++ IRCSharp.Tests/State/Sasl.cs | 38 +++ IRCSharp.Tests/State/User.cs | 298 ++++++++++++++++++++ IRCSharp.Tests/State/Who.cs | 61 +++++ IRCSharp.Tests/Tokenization/Data/JoinModel.cs | 30 +++ IRCSharp.Tests/Tokenization/Data/SplitModel.cs | 15 ++ IRCSharp.Tests/Tokenization/Data/msg-join.yaml | 221 +++++++++++++++ IRCSharp.Tests/Tokenization/Data/msg-split.yaml | 343 ++++++++++++++++++++++++ IRCSharp.Tests/Tokenization/Format.cs | 105 ++++++++ IRCSharp.Tests/Tokenization/Hostmask.cs | 64 +++++ IRCSharp.Tests/Tokenization/Parser.cs | 55 ++++ IRCSharp.Tests/Tokenization/StatefulDecoder.cs | 88 ++++++ IRCSharp.Tests/Tokenization/StatefulEncoder.cs | 84 ++++++ IRCSharp.Tests/Tokenization/Tokenization.cs | 133 +++++++++ IRCSharp.sln | 14 +- IRCStates/IRCStates.csproj | 7 +- IRCStates/Tests/Cap.cs | 131 --------- IRCStates/Tests/Casemap.cs | 58 ---- IRCStates/Tests/Channel.cs | 202 -------------- IRCStates/Tests/Emit.cs | 117 -------- IRCStates/Tests/ISupport.cs | 210 --------------- IRCStates/Tests/Mode.cs | 179 ------------- IRCStates/Tests/Motd.cs | 23 -- IRCStates/Tests/Sasl.cs | 38 --- IRCStates/Tests/User.cs | 298 -------------------- IRCStates/Tests/Who.cs | 61 ----- IRCTokens/IRCTokens.csproj | 17 +- IRCTokens/Tests/Data/JoinModel.cs | 30 --- IRCTokens/Tests/Data/SplitModel.cs | 15 -- IRCTokens/Tests/Data/msg-join.yaml | 221 --------------- IRCTokens/Tests/Data/msg-split.yaml | 343 ------------------------ IRCTokens/Tests/Format.cs | 105 -------- IRCTokens/Tests/Hostmask.cs | 64 ----- IRCTokens/Tests/Parser.cs | 55 ---- IRCTokens/Tests/StatefulDecoder.cs | 88 ------ IRCTokens/Tests/StatefulEncoder.cs | 84 ------ IRCTokens/Tests/Tokenization.cs | 133 --------- 44 files changed, 2503 insertions(+), 2476 deletions(-) create mode 100644 IRCSharp.Tests/IRCSharp.Tests.csproj create mode 100644 IRCSharp.Tests/State/Cap.cs create mode 100644 IRCSharp.Tests/State/Casemap.cs create mode 100644 IRCSharp.Tests/State/Channel.cs create mode 100644 IRCSharp.Tests/State/Emit.cs create mode 100644 IRCSharp.Tests/State/ISupport.cs create mode 100644 IRCSharp.Tests/State/Mode.cs create mode 100644 IRCSharp.Tests/State/Motd.cs create mode 100644 IRCSharp.Tests/State/Sasl.cs create mode 100644 IRCSharp.Tests/State/User.cs create mode 100644 IRCSharp.Tests/State/Who.cs create mode 100644 IRCSharp.Tests/Tokenization/Data/JoinModel.cs create mode 100644 IRCSharp.Tests/Tokenization/Data/SplitModel.cs create mode 100644 IRCSharp.Tests/Tokenization/Data/msg-join.yaml create mode 100644 IRCSharp.Tests/Tokenization/Data/msg-split.yaml create mode 100644 IRCSharp.Tests/Tokenization/Format.cs create mode 100644 IRCSharp.Tests/Tokenization/Hostmask.cs create mode 100644 IRCSharp.Tests/Tokenization/Parser.cs create mode 100644 IRCSharp.Tests/Tokenization/StatefulDecoder.cs create mode 100644 IRCSharp.Tests/Tokenization/StatefulEncoder.cs create mode 100644 IRCSharp.Tests/Tokenization/Tokenization.cs delete mode 100644 IRCStates/Tests/Cap.cs delete mode 100644 IRCStates/Tests/Casemap.cs delete mode 100644 IRCStates/Tests/Channel.cs delete mode 100644 IRCStates/Tests/Emit.cs delete mode 100644 IRCStates/Tests/ISupport.cs delete mode 100644 IRCStates/Tests/Mode.cs delete mode 100644 IRCStates/Tests/Motd.cs delete mode 100644 IRCStates/Tests/Sasl.cs delete mode 100644 IRCStates/Tests/User.cs delete mode 100644 IRCStates/Tests/Who.cs delete mode 100644 IRCTokens/Tests/Data/JoinModel.cs delete mode 100644 IRCTokens/Tests/Data/SplitModel.cs delete mode 100644 IRCTokens/Tests/Data/msg-join.yaml delete mode 100644 IRCTokens/Tests/Data/msg-split.yaml delete mode 100644 IRCTokens/Tests/Format.cs delete mode 100644 IRCTokens/Tests/Hostmask.cs delete mode 100644 IRCTokens/Tests/Parser.cs delete mode 100644 IRCTokens/Tests/StatefulDecoder.cs delete mode 100644 IRCTokens/Tests/StatefulEncoder.cs delete mode 100644 IRCTokens/Tests/Tokenization.cs diff --git a/IRCSharp.Tests/IRCSharp.Tests.csproj b/IRCSharp.Tests/IRCSharp.Tests.csproj new file mode 100644 index 0000000..e068b60 --- /dev/null +++ b/IRCSharp.Tests/IRCSharp.Tests.csproj @@ -0,0 +1,31 @@ + + + + net5.0 + + false + + + + + + + + + + + + + + + + + + PreserveNewest + + + PreserveNewest + + + + diff --git a/IRCSharp.Tests/State/Cap.cs b/IRCSharp.Tests/State/Cap.cs new file mode 100644 index 0000000..3c0faba --- /dev/null +++ b/IRCSharp.Tests/State/Cap.cs @@ -0,0 +1,131 @@ +using System.Collections.Generic; +using IRCTokens; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace IRCStates.Tests +{ + [TestClass] + public class Cap + { + private Server _server; + + [TestInitialize] + public void TestInitialize() + { + _server = new Server("test"); + } + + [TestMethod] + public void LSOneLine() + { + Assert.IsFalse(_server.HasCap); + CollectionAssert.AreEqual(new Dictionary(), _server.AvailableCaps); + _server.Parse(new Line("CAP * LS :a b")); + CollectionAssert.AreEqual(new Dictionary {{"a", ""}, {"b", ""}}, _server.AvailableCaps); + } + + [TestMethod] + public void LSTwoLines() + { + _server.Parse(new Line("CAP * LS * :a b")); + CollectionAssert.AreEqual(new Dictionary(), _server.AvailableCaps); + _server.Parse(new Line("CAP * LS :c")); + Assert.IsTrue(_server.AvailableCaps.ContainsKey("a")); + Assert.IsTrue(_server.AvailableCaps.ContainsKey("b")); + Assert.IsTrue(_server.AvailableCaps.ContainsKey("c")); + } + + [TestMethod] + public void LSValues() + { + _server.Parse(new Line("CAP * LS :a b= c=1")); + CollectionAssert.AreEqual(new Dictionary {{"a", ""}, {"b", ""}, {"c", "1"}}, + _server.AvailableCaps); + } + + [TestMethod] + public void ACKOneLine() + { + _server.Parse(new Line("CAP * LS :a b")); + _server.Parse(new Line("CAP * ACK :a b")); + CollectionAssert.AreEqual(new List {"a", "b"}, _server.AgreedCaps); + } + + [TestMethod] + public void ACKTwoLines() + { + _server.Parse(new Line("CAP * LS :a b c")); + _server.Parse(new Line("CAP * ACK * :a b")); + _server.Parse(new Line("CAP * ACK :c")); + CollectionAssert.AreEqual(new List {"a", "b", "c"}, _server.AgreedCaps); + } + + [TestMethod] + public void ACKNotLS() + { + _server.Parse(new Line("CAP * LS a")); + _server.Parse(new Line("CAP * ACK b")); + CollectionAssert.AreEqual(new List(), _server.AgreedCaps); + } + + [TestMethod] + public void NEWNoLS() + { + _server.Parse(new Line("CAP * NEW :a")); + CollectionAssert.AreEqual(new Dictionary {{"a", ""}}, _server.AvailableCaps); + } + + [TestMethod] + public void NEWOneLine() + { + _server.Parse(new Line("CAP * LS :a")); + _server.Parse(new Line("CAP * NEW :b")); + CollectionAssert.AreEqual(new Dictionary {{"a", ""}, {"b", ""}}, _server.AvailableCaps); + } + + [TestMethod] + public void NEWTwoLines() + { + _server.Parse(new Line("CAP * LS :a")); + _server.Parse(new Line("CAP * NEW :b c")); + CollectionAssert.AreEqual(new Dictionary {{"a", ""}, {"b", ""}, {"c", ""}}, + _server.AvailableCaps); + } + + [TestMethod] + public void DELNotAcked() + { + _server.Parse(new Line("CAP * DEL a")); + } + + [TestMethod] + public void DELOneLS() + { + _server.Parse(new Line("CAP * LS :a")); + _server.Parse(new Line("CAP * ACK :a")); + _server.Parse(new Line("CAP * DEL :a")); + CollectionAssert.AreEqual(new Dictionary(), _server.AvailableCaps); + CollectionAssert.AreEqual(new List(), _server.AgreedCaps); + } + + [TestMethod] + public void DELTwoLS() + { + _server.Parse(new Line("CAP * LS :a b")); + _server.Parse(new Line("CAP * ACK :a b")); + _server.Parse(new Line("CAP * DEL :a")); + CollectionAssert.AreEqual(new Dictionary {{"b", ""}}, _server.AvailableCaps); + CollectionAssert.AreEqual(new List {"b"}, _server.AgreedCaps); + } + + [TestMethod] + public void DELTwoDEL() + { + _server.Parse(new Line("CAP * LS :a b")); + _server.Parse(new Line("CAP * ACK :a b")); + _server.Parse(new Line("CAP * DEL :a b")); + CollectionAssert.AreEqual(new Dictionary(), _server.AvailableCaps); + CollectionAssert.AreEqual(new List(), _server.AgreedCaps); + } + } +} diff --git a/IRCSharp.Tests/State/Casemap.cs b/IRCSharp.Tests/State/Casemap.cs new file mode 100644 index 0000000..4a02444 --- /dev/null +++ b/IRCSharp.Tests/State/Casemap.cs @@ -0,0 +1,58 @@ +using IRCTokens; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace IRCStates.Tests +{ + [TestClass] + public class Casemap + { + [TestMethod] + public void Rfc1459() + { + var lower = IRCStates.Casemap.CaseFold(IRCStates.Casemap.CaseMapping.Rfc1459, @"ÀTEST[]~\"); + Assert.AreEqual("Àtest{}^|", lower); + } + + [TestMethod] + public void Ascii() + { + var lower = IRCStates.Casemap.CaseFold(IRCStates.Casemap.CaseMapping.Ascii, @"ÀTEST[]~\"); + Assert.AreEqual(@"Àtest[]~\", lower); + } + + [TestMethod] + public void CommandJoin() + { + var server = new Server("test"); + server.Parse(new Line("001 nickname")); + server.Parse(new Line(":Nickname JOIN #Chan")); + server.Parse(new Line(":Other JOIN #Chan")); + + Assert.IsTrue(server.Users.ContainsKey("nickname")); + Assert.IsFalse(server.Users.ContainsKey("Nickname")); + Assert.IsTrue(server.Users.ContainsKey("other")); + Assert.IsFalse(server.Users.ContainsKey("Other")); + Assert.IsTrue(server.Channels.ContainsKey("#chan")); + Assert.IsFalse(server.Channels.ContainsKey("#Chan")); + + var channel = server.Channels["#chan"]; + Assert.AreEqual("#Chan", channel.Name); + } + + [TestMethod] + public void CommandNick() + { + var server = new Server("test"); + server.Parse(new Line("001 nickname")); + server.Parse(new Line(":nickname JOIN #chan")); + var user = server.Users["nickname"]; + server.Parse(new Line(":nickname NICK NewNickname")); + Assert.AreEqual(1, server.Users.Count); + Assert.IsTrue(server.Users.ContainsKey("newnickname")); + Assert.AreEqual("NewNickname", user.NickName); + Assert.AreEqual("newnickname", user.NickNameLower); + Assert.AreEqual("NewNickname", server.NickName); + Assert.AreEqual("newnickname", server.NickNameLower); + } + } +} diff --git a/IRCSharp.Tests/State/Channel.cs b/IRCSharp.Tests/State/Channel.cs new file mode 100644 index 0000000..6868e0f --- /dev/null +++ b/IRCSharp.Tests/State/Channel.cs @@ -0,0 +1,202 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using IRCTokens; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace IRCStates.Tests +{ + [TestClass] + public class Channel + { + private Server _server; + + [TestInitialize] + public void TestInitialize() + { + _server = new Server("test"); + _server.Parse(new Line("001 nickname")); + _server.Parse(new Line(":nickname JOIN #chan")); + } + + [TestMethod] + public void JoinSelf() + { + Assert.IsTrue(_server.Channels.ContainsKey("#chan")); + Assert.IsTrue(_server.Users.ContainsKey("nickname")); + Assert.AreEqual(1, _server.Channels.Count); + Assert.AreEqual(1, _server.Users.Count); + + var user = _server.Users["nickname"]; + var chan = _server.Channels["#chan"]; + Assert.IsTrue(chan.Users.ContainsKey(user.NickNameLower)); + var chanUser = chan.Users[user.NickNameLower]; + CollectionAssert.AreEqual(new List {chan.NameLower}, user.Channels.ToList()); + } + + [TestMethod] + public void JoinOther() + { + _server.Parse(new Line(":other JOIN #chan")); + + Assert.AreEqual(2, _server.Users.Count); + Assert.IsTrue(_server.Users.ContainsKey("other")); + + var channel = _server.Channels["#chan"]; + Assert.AreEqual(2, channel.Users.Count); + + var user = _server.Users["other"]; + CollectionAssert.AreEqual(new List {channel.NameLower}, user.Channels.ToList()); + } + + [TestMethod] + public void PartSelf() + { + _server.Parse(new Line(":nickname PART #chan")); + + Assert.AreEqual(0, _server.Users.Count); + Assert.AreEqual(0, _server.Channels.Count); + } + + [TestMethod] + public void PartOther() + { + _server.Parse(new Line(":other JOIN #chan")); + _server.Parse(new Line(":other PART #chan")); + + var user = _server.Users["nickname"]; + var channel = _server.Channels["#chan"]; + var chanUser = channel.Users[user.NickNameLower]; + + Assert.AreEqual(channel.NameLower, user.Channels.Single()); + CollectionAssert.AreEqual(new Dictionary {{"nickname", user}}, _server.Users); + CollectionAssert.AreEqual(new Dictionary {{"#chan", channel}}, _server.Channels); + CollectionAssert.AreEqual(new Dictionary {{"nickname", chanUser}}, channel.Users); + } + + [TestMethod] + public void KickSelf() + { + _server.Parse(new Line(":nickname KICK #chan nickname")); + + Assert.AreEqual(0, _server.Users.Count); + Assert.AreEqual(0, _server.Channels.Count); + } + + [TestMethod] + public void KickOther() + { + _server.Parse(new Line(":other JOIN #chan")); + _server.Parse(new Line(":nickname KICK #chan other")); + + var user = _server.Users["nickname"]; + var channel = _server.Channels["#chan"]; + var chanUser = channel.Users[user.NickNameLower]; + + Assert.AreEqual(1, _server.Users.Count); + Assert.AreEqual(1, _server.Channels.Count); + Assert.AreEqual(channel.NameLower, user.Channels.Single()); + CollectionAssert.AreEqual(new Dictionary {{user.NickNameLower, chanUser}}, + channel.Users); + } + + [TestMethod] + public void QuitSelf() + { + _server.Parse(new Line("QUIT :i'm outta here")); + Assert.IsFalse(_server.Users.Any()); + Assert.IsFalse(_server.Channels.Any()); + } + + [TestMethod] + public void QuitSelfWithSource() + { + _server.Parse(new Line(":nickname QUIT :i'm outta here")); + Assert.IsFalse(_server.Users.Any()); + Assert.IsFalse(_server.Channels.Any()); + } + + [TestMethod] + public void QuitOther() + { + _server.Parse(new Line(":other JOIN #chan")); + _server.Parse(new Line(":other QUIT :see ya")); + Assert.IsFalse(_server.Users.ContainsKey("other")); + } + + [TestMethod] + public void TopicText() + { + _server.Parse(new Line("332 * #chan :test")); + Assert.AreEqual("test", _server.Channels["#chan"].Topic); + } + + [TestMethod] + public void TopicSetByAt() + { + var dt = DateTimeOffset.FromUnixTimeSeconds(1584023277).DateTime; + _server.Parse(new Line("333 * #chan other 1584023277")); + + var channel = _server.Channels["#chan"]; + + Assert.AreEqual("other", channel.TopicSetter); + Assert.AreEqual(dt, channel.TopicTime); + } + + [TestMethod] + public void TopicCommand() + { + _server.Parse(new Line("TOPIC #chan :hello there")); + Assert.AreEqual("hello there", _server.Channels["#chan"].Topic); + } + + [TestMethod] + public void CreationDate() + { + _server.Parse(new Line("329 * #chan 1584041889")); + Assert.AreEqual(DateTimeOffset.FromUnixTimeSeconds(1584041889).DateTime, _server.Channels["#chan"].Created); + } + + [TestMethod] + public void NamesCommand() + { + _server.Parse(new Line("353 * * #chan :nickname @+other")); + Assert.IsTrue(_server.Users.ContainsKey("nickname")); + Assert.IsTrue(_server.Users.ContainsKey("other")); + + var user = _server.Users["other"]; + var channel = _server.Channels["#chan"]; + var chanUser1 = channel.Users[user.NickNameLower]; + var chanUser2 = channel.Users[_server.NickNameLower]; + + Assert.AreEqual(2, channel.Users.Count); + CollectionAssert.AreEqual(chanUser1.Modes, channel.Users[user.NickNameLower].Modes); + CollectionAssert.AreEqual(chanUser2.Modes, channel.Users[_server.NickNameLower].Modes); + CollectionAssert.AreEqual(new List {"o", "v"}, chanUser1.Modes); + Assert.AreEqual(channel.NameLower, user.Channels.Single()); + } + + [TestMethod] + public void UserhostInNames() + { + _server.Parse(new Line("353 * * #chan :nickname!user@host other!user2@host2")); + Assert.AreEqual("user", _server.UserName); + Assert.AreEqual("host", _server.HostName); + + var user = _server.Users["other"]; + Assert.AreEqual("user2", user.UserName); + Assert.AreEqual("host2", user.HostName); + } + + [TestMethod] + public void NickAfterJoin() + { + var user = _server.Users["nickname"]; + var channel = _server.Channels["#chan"]; + var chanUser = channel.Users[user.NickNameLower]; + _server.Parse(new Line(":nickname NICK nickname2")); + CollectionAssert.AreEqual(new Dictionary {{user.NickNameLower, chanUser}}, + channel.Users); + } + } +} diff --git a/IRCSharp.Tests/State/Emit.cs b/IRCSharp.Tests/State/Emit.cs new file mode 100644 index 0000000..07fea8c --- /dev/null +++ b/IRCSharp.Tests/State/Emit.cs @@ -0,0 +1,117 @@ +using System.Collections.Generic; +using IRCTokens; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace IRCStates.Tests +{ + [TestClass] + public class Emit + { + private Server _server; + + [TestInitialize] + public void TestInitialize() + { + _server = new Server("test"); + _server.Parse(new Line("001 nickname")); + } + + [TestMethod] + public void EmitJoin() + { + var emit = _server.Parse(new Line(":nickname JOIN #chan")); + + Assert.AreEqual("JOIN", emit.Command); + Assert.IsTrue(emit.Self); + Assert.AreEqual(_server.Users["nickname"], emit.User); + Assert.AreEqual(_server.Channels["#chan"], emit.Channel); + + emit = _server.Parse(new Line(":other JOIN #chan")); + Assert.IsNotNull(emit); + Assert.AreEqual("JOIN", emit.Command); + Assert.IsFalse(emit.Self); + Assert.AreEqual(_server.Users["other"], emit.User); + Assert.AreEqual(_server.Channels["#chan"], emit.Channel); + } + + [TestMethod] + public void EmitPrivmsg() + { + _server.Parse(new Line(":nickname JOIN #chan")); + var emit = _server.Parse(new Line(":nickname PRIVMSG #chan :hello")); + + Assert.IsNotNull(emit); + Assert.AreEqual("PRIVMSG", emit.Command); + Assert.AreEqual("hello", emit.Text); + Assert.IsTrue(emit.SelfSource); + Assert.AreEqual(_server.Users["nickname"], emit.User); + Assert.AreEqual(_server.Channels["#chan"], emit.Channel); + + _server.Parse(new Line(":other JOIN #chan")); + emit = _server.Parse(new Line(":other PRIVMSG #chan :hello2")); + + Assert.IsNotNull(emit); + Assert.AreEqual("PRIVMSG", emit.Command); + Assert.AreEqual("hello2", emit.Text); + Assert.IsFalse(emit.SelfSource); + Assert.AreEqual(_server.Users["other"], emit.User); + Assert.AreEqual(_server.Channels["#chan"], emit.Channel); + } + + [TestMethod] + public void EmitPrivmsgNoJoin() + { + _server.Parse(new Line(":nickname JOIN #chan")); + var emit = _server.Parse(new Line(":other PRIVMSG #chan :hello")); + + Assert.IsNotNull(emit); + Assert.AreEqual("PRIVMSG", emit.Command); + Assert.AreEqual("hello", emit.Text); + Assert.IsFalse(emit.SelfSource); + Assert.IsNotNull(emit.User); + + var channel = _server.Channels["#chan"]; + Assert.AreEqual(channel, emit.Channel); + } + + [TestMethod] + public void EmitKick() + { + _server.Parse(new Line(":nickname JOIN #chan")); + + var user = _server.Users["nickname"]; + var channel = _server.Channels["#chan"]; + _server.Parse(new Line(":other JOIN #chan")); + var userOther = _server.Users["other"]; + var emit = _server.Parse(new Line(":nickname KICK #chan other :reason")); + + Assert.IsNotNull(emit); + Assert.AreEqual("KICK", emit.Command); + Assert.AreEqual("reason", emit.Text); + Assert.IsTrue(emit.SelfSource); + Assert.AreEqual(user, emit.UserSource); + Assert.AreEqual(userOther, emit.UserTarget); + Assert.AreEqual(channel, emit.Channel); + } + + [TestMethod] + public void EmitMode() + { + var emit = _server.Parse(new Line("MODE nickname x+i-i+wi-wi")); + + Assert.IsNotNull(emit); + Assert.AreEqual("MODE", emit.Command); + Assert.IsTrue(emit.SelfTarget); + CollectionAssert.AreEqual(new List + { + "+x", + "+i", + "-i", + "+w", + "+i", + "-w", + "-i" + }, emit.Tokens); + } + } +} diff --git a/IRCSharp.Tests/State/ISupport.cs b/IRCSharp.Tests/State/ISupport.cs new file mode 100644 index 0000000..5cdcc61 --- /dev/null +++ b/IRCSharp.Tests/State/ISupport.cs @@ -0,0 +1,210 @@ +using System.Collections.Generic; +using IRCTokens; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +// ReSharper disable InconsistentNaming + +namespace IRCStates.Tests +{ + [TestClass] + public class ISupport + { + private Server _server; + + [TestInitialize] + public void TestInitialize() + { + _server = new Server("test"); + _server.Parse(new Line("001 nickname")); + } + + [TestMethod] + public void ChanModes() + { + CollectionAssert.AreEqual(new List {"b"}, _server.ISupport.ChanModes.ListModes); + CollectionAssert.AreEqual(new List {"k"}, _server.ISupport.ChanModes.SettingBModes); + CollectionAssert.AreEqual(new List {"l"}, _server.ISupport.ChanModes.SettingCModes); + CollectionAssert.AreEqual(new List + { + "i", + "m", + "n", + "p", + "s", + "t" + }, _server.ISupport.ChanModes.SettingDModes); + + _server.Parse(new Line("005 * CHANMODES=a,b,c,d *")); + + CollectionAssert.AreEqual(new List {"a"}, _server.ISupport.ChanModes.ListModes); + CollectionAssert.AreEqual(new List {"b"}, _server.ISupport.ChanModes.SettingBModes); + CollectionAssert.AreEqual(new List {"c"}, _server.ISupport.ChanModes.SettingCModes); + CollectionAssert.AreEqual(new List {"d"}, _server.ISupport.ChanModes.SettingDModes); + } + + [TestMethod] + public void Prefix() + { + CollectionAssert.AreEqual(new List {"o", "v"}, _server.ISupport.Prefix.Modes); + CollectionAssert.AreEqual(new List {"@", "+"}, _server.ISupport.Prefix.Prefixes); + + Assert.AreEqual("@", _server.ISupport.Prefix.FromMode("o")); + Assert.IsNull(_server.ISupport.Prefix.FromMode("a")); + Assert.AreEqual("o", _server.ISupport.Prefix.FromPrefix("@")); + Assert.IsNull(_server.ISupport.Prefix.FromPrefix("&")); + + _server.Parse(new Line("005 * PREFIX=(qaohv)~&@%+ *")); + CollectionAssert.AreEqual(new List + { + "q", + "a", + "o", + "h", + "v" + }, _server.ISupport.Prefix.Modes); + CollectionAssert.AreEqual(new List + { + "~", + "&", + "@", + "%", + "+" + }, _server.ISupport.Prefix.Prefixes); + Assert.AreEqual("&", _server.ISupport.Prefix.FromMode("a")); + Assert.AreEqual("a", _server.ISupport.Prefix.FromPrefix("&")); + } + + [TestMethod] + public void ChanTypes() + { + CollectionAssert.AreEqual(new List {"#"}, _server.ISupport.ChanTypes); + _server.Parse(new Line("005 * CHANTYPES=#& *")); + CollectionAssert.AreEqual(new List {"#", "&"}, _server.ISupport.ChanTypes); + } + + [TestMethod] + public void Modes() + { + Assert.AreEqual(3, _server.ISupport.Modes); + + _server.Parse(new Line("005 * MODES *")); + Assert.AreEqual(-1, _server.ISupport.Modes); + + _server.Parse(new Line("005 * MODES=5 *")); + Assert.AreEqual(5, _server.ISupport.Modes); + } + + [TestMethod] + public void Rfc1459() + { + Assert.AreEqual(IRCStates.Casemap.CaseMapping.Rfc1459, _server.ISupport.CaseMapping); + _server.Parse(new Line("005 * CASEMAPPING=rfc1459 *")); + Assert.AreEqual(IRCStates.Casemap.CaseMapping.Rfc1459, _server.ISupport.CaseMapping); + var lower = _server.CaseFold(@"ÀTEST[]~\"); + Assert.AreEqual("Àtest{}^|", lower); + } + + [TestMethod] + public void Ascii() + { + _server.Parse(new Line("005 * CASEMAPPING=ascii *")); + Assert.AreEqual(IRCStates.Casemap.CaseMapping.Ascii, _server.ISupport.CaseMapping); + var lower = _server.CaseFold(@"ÀTEST[]~\"); + Assert.AreEqual(@"Àtest[]~\", lower); + } + + [TestMethod] + public void FallbackToRfc1459() + { + _server.Parse(new Line("005 * CASEMAPPING=nonexistent *")); + Assert.AreEqual(IRCStates.Casemap.CaseMapping.Rfc1459, _server.ISupport.CaseMapping); + var lower = _server.CaseFold(@"ÀTEST[]~\"); + Assert.AreEqual("Àtest{}^|", lower); + } + + [TestMethod] + public void Network() + { + Assert.IsNull(_server.ISupport.Network); + _server.Parse(new Line("005 * NETWORK=testnet *")); + Assert.AreEqual("testnet", _server.ISupport.Network); + } + + [TestMethod] + public void StatusMsg() + { + CollectionAssert.AreEqual(new List(), _server.ISupport.StatusMsg); + _server.Parse(new Line("005 * STATUSMSG=&@ *")); + CollectionAssert.AreEqual(new List {"&", "@"}, _server.ISupport.StatusMsg); + } + + [TestMethod] + public void CallerId() + { + Assert.IsNull(_server.ISupport.CallerId); + + _server.Parse(new Line("005 * CALLERID=U *")); + Assert.AreEqual("U", _server.ISupport.CallerId); + + _server.Parse(new Line("005 * CALLERID *")); + Assert.AreEqual("g", _server.ISupport.CallerId); + } + + [TestMethod] + public void Excepts() + { + Assert.IsNull(_server.ISupport.Excepts); + + _server.Parse(new Line("005 * EXCEPTS=U *")); + Assert.AreEqual("U", _server.ISupport.Excepts); + + _server.Parse(new Line("005 * EXCEPTS *")); + Assert.AreEqual("e", _server.ISupport.Excepts); + } + + [TestMethod] + public void Invex() + { + Assert.IsNull(_server.ISupport.Invex); + + _server.Parse(new Line("005 * INVEX=U *")); + Assert.AreEqual("U", _server.ISupport.Invex); + + _server.Parse(new Line("005 * INVEX *")); + Assert.AreEqual("I", _server.ISupport.Invex); + } + + [TestMethod] + public void Whox() + { + Assert.IsFalse(_server.ISupport.Whox); + + _server.Parse(new Line("005 * WHOX *")); + Assert.IsTrue(_server.ISupport.Whox); + } + + [TestMethod] + public void Monitor() + { + Assert.IsNull(_server.ISupport.Monitor); + + _server.Parse(new Line("005 * MONITOR=123 *")); + Assert.AreEqual(123, _server.ISupport.Monitor); + + _server.Parse(new Line("005 * MONITOR *")); + Assert.AreEqual(-1, _server.ISupport.Monitor); + } + + [TestMethod] + public void Watch() + { + Assert.IsNull(_server.ISupport.Watch); + + _server.Parse(new Line("005 * WATCH=123 *")); + Assert.AreEqual(123, _server.ISupport.Watch); + + _server.Parse(new Line("005 * WATCH *")); + Assert.AreEqual(-1, _server.ISupport.Watch); + } + } +} diff --git a/IRCSharp.Tests/State/Mode.cs b/IRCSharp.Tests/State/Mode.cs new file mode 100644 index 0000000..90763fa --- /dev/null +++ b/IRCSharp.Tests/State/Mode.cs @@ -0,0 +1,179 @@ +using System.Collections.Generic; +using IRCTokens; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace IRCStates.Tests +{ + [TestClass] + public class Mode + { + private Server _server; + + [TestInitialize] + public void TestInitialize() + { + _server = new Server("test"); + _server.Parse(new Line("001 nickname")); + } + + [TestMethod] + public void UModeAdd() + { + _server.Parse(new Line("MODE nickname +i")); + CollectionAssert.AreEqual(new List {"i"}, _server.Modes); + } + + [TestMethod] + public void UModeRemove() + { + _server.Parse(new Line("MODE nickname +i")); + _server.Parse(new Line("MODE nickname -i")); + CollectionAssert.AreEqual(new List(), _server.Modes); + } + + [TestMethod] + public void PrefixAdd() + { + _server.Parse(new Line(":nickname JOIN #chan")); + _server.Parse(new Line("MODE #chan +ov nickname nickname")); + + var user = _server.Users["nickname"]; + var channel = _server.Channels["#chan"]; + var channelUser = channel.Users[user.NickNameLower]; + CollectionAssert.AreEqual(new List {"o", "v"}, channelUser.Modes); + } + + [TestMethod] + public void PrefixRemove() + { + _server.Parse(new Line(":nickname JOIN #chan")); + _server.Parse(new Line("MODE #chan +ov nickname nickname")); + _server.Parse(new Line("MODE #chan -ov nickname nickname")); + + var user = _server.Users["nickname"]; + var channel = _server.Channels["#chan"]; + var channelUser = channel.Users[user.NickNameLower]; + CollectionAssert.AreEqual(new List(), channelUser.Modes); + } + + [TestMethod] + public void ChannelListAdd() + { + _server.Parse(new Line(":nickname JOIN #chan")); + _server.Parse(new Line("MODE #chan +b asd!*@*")); + + var channel = _server.Channels["#chan"]; + CollectionAssert.AreEqual(new List {"asd!*@*"}, channel.ListModes["b"]); + } + + [TestMethod] + public void ChannelListRemove() + { + _server.Parse(new Line(":nickname JOIN #chan")); + _server.Parse(new Line("MODE #chan +b asd!*@*")); + _server.Parse(new Line("MODE #chan -b asd!*@*")); + + var channel = _server.Channels["#chan"]; + CollectionAssert.AreEqual(new Dictionary>(), channel.ListModes); + } + + [TestMethod] + public void ChannelTypeBAdd() + { + _server.Parse(new Line(":nickname JOIN #chan")); + _server.Parse(new Line("MODE #chan +k password")); + + var channel = _server.Channels["#chan"]; + CollectionAssert.AreEqual(new Dictionary {{"k", "password"}}, channel.Modes); + } + + [TestMethod] + public void ChannelTypeBRemove() + { + _server.Parse(new Line(":nickname JOIN #chan")); + _server.Parse(new Line("MODE #chan +k password")); + _server.Parse(new Line("MODE #chan -k *")); + + var channel = _server.Channels["#chan"]; + CollectionAssert.AreEqual(new Dictionary(), channel.Modes); + } + + [TestMethod] + public void ChannelTypeCAdd() + { + _server.Parse(new Line(":nickname JOIN #chan")); + _server.Parse(new Line("MODE #chan +l 100")); + + var channel = _server.Channels["#chan"]; + CollectionAssert.AreEqual(new Dictionary {{"l", "100"}}, channel.Modes); + } + + [TestMethod] + public void ChannelTypeCRemove() + { + _server.Parse(new Line(":nickname JOIN #chan")); + _server.Parse(new Line("MODE #chan +l 100")); + _server.Parse(new Line("MODE #chan -l")); + + var channel = _server.Channels["#chan"]; + CollectionAssert.AreEqual(new Dictionary(), channel.Modes); + } + + [TestMethod] + public void ChannelTypeDAdd() + { + _server.Parse(new Line(":nickname JOIN #chan")); + _server.Parse(new Line("MODE #chan +i")); + + var channel = _server.Channels["#chan"]; + CollectionAssert.AreEqual(new Dictionary {{"i", null}}, channel.Modes); + } + + [TestMethod] + public void ChannelTypeDRemove() + { + _server.Parse(new Line(":nickname JOIN #chan")); + _server.Parse(new Line("MODE #chan +i")); + _server.Parse(new Line("MODE #chan -i")); + + var channel = _server.Channels["#chan"]; + CollectionAssert.AreEqual(new Dictionary(), channel.Modes); + } + + [TestMethod] + public void ChannelNumeric() + { + _server.Parse(new Line(":nickname JOIN #chan")); + _server.Parse(new Line("324 * #chan +bkli *!*@* pass 10")); + + var channel = _server.Channels["#chan"]; + CollectionAssert.AreEqual(new Dictionary {{"k", "pass"}, {"l", "10"}, {"i", null}}, + channel.Modes); + CollectionAssert.AreEqual(new List {"*!*@*"}, channel.ListModes["b"]); + } + + [TestMethod] + public void ChannelNumericWithoutPlus() + { + _server.Parse(new Line(":nickname JOIN #chan")); + _server.Parse(new Line("324 * #chan il 10")); + + var channel = _server.Channels["#chan"]; + CollectionAssert.AreEqual(new Dictionary {{"i", null}, {"l", "10"}}, channel.Modes); + } + + [TestMethod] + public void UserNumeric() + { + _server.Parse(new Line("221 * +iw")); + CollectionAssert.AreEqual(new List {"i", "w"}, _server.Modes); + } + + [TestMethod] + public void UserNumericWithoutPlus() + { + _server.Parse(new Line("221 * iw")); + CollectionAssert.AreEqual(new List {"i", "w"}, _server.Modes); + } + } +} diff --git a/IRCSharp.Tests/State/Motd.cs b/IRCSharp.Tests/State/Motd.cs new file mode 100644 index 0000000..2d75982 --- /dev/null +++ b/IRCSharp.Tests/State/Motd.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using IRCTokens; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace IRCStates.Tests +{ + [TestClass] + public class Motd + { + [TestMethod] + public void MessageOfTheDay() + { + var server = new Server("test"); + server.Parse(new Line("001 nickname")); + server.Parse(new Line("375 * :start of motd")); + server.Parse(new Line("372 * :first line of motd")); + server.Parse(new Line("372 * :second line of motd")); + + CollectionAssert.AreEqual(new List {"start of motd", "first line of motd", "second line of motd"}, + server.Motd); + } + } +} diff --git a/IRCSharp.Tests/State/Sasl.cs b/IRCSharp.Tests/State/Sasl.cs new file mode 100644 index 0000000..151ccdf --- /dev/null +++ b/IRCSharp.Tests/State/Sasl.cs @@ -0,0 +1,38 @@ +using IRCTokens; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace IRCStates.Tests +{ + [TestClass] + public class Sasl + { + private Server _server; + + [TestInitialize] + public void TestInitialize() + { + _server = new Server("test"); + _server.Parse(new Line("900 * nick!user@host account")); + } + + [TestMethod] + public void LoggedIn() + { + Assert.AreEqual("nick", _server.NickName); + Assert.AreEqual("user", _server.UserName); + Assert.AreEqual("host", _server.HostName); + Assert.AreEqual("account", _server.Account); + } + + [TestMethod] + public void LoggedOut() + { + _server.Parse(new Line("901 * nick1!user1@host1")); + + Assert.AreEqual("nick1", _server.NickName); + Assert.AreEqual("user1", _server.UserName); + Assert.AreEqual("host1", _server.HostName); + Assert.IsTrue(string.IsNullOrEmpty(_server.Account)); + } + } +} diff --git a/IRCSharp.Tests/State/User.cs b/IRCSharp.Tests/State/User.cs new file mode 100644 index 0000000..61d7157 --- /dev/null +++ b/IRCSharp.Tests/State/User.cs @@ -0,0 +1,298 @@ +using IRCTokens; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace IRCStates.Tests +{ + [TestClass] + public class User + { + private Server _server; + + [TestInitialize] + public void TestInitialize() + { + _server = new Server("test"); + _server.Parse(new Line("001 nickname")); + } + + [TestMethod] + public void Welcome() + { + Assert.AreEqual("test", _server.Name); + Assert.AreEqual("nickname", _server.NickName); + } + + [TestMethod] + public void NicknameChange() + { + _server.Parse(new Line(":nickname NICK nickname2")); + Assert.AreEqual("nickname2", _server.NickName); + + _server.Parse(new Line(":nickname2 JOIN #chan")); + _server.Parse(new Line(":other JOIN #chan")); + Assert.IsTrue(_server.Users.ContainsKey("other")); + + _server.Parse(new Line(":other NICK other2")); + Assert.IsFalse(_server.Users.ContainsKey("other")); + Assert.IsTrue(_server.Users.ContainsKey("other2")); + } + + [TestMethod] + public void HostmaskJoinBoth() + { + _server.Parse(new Line(":nickname!user@host JOIN #chan")); + Assert.AreEqual("user", _server.UserName); + Assert.AreEqual("host", _server.HostName); + + _server.Parse(new Line(":other!user@host JOIN #chan")); + var user = _server.Users["other"]; + Assert.AreEqual("user", user.UserName); + Assert.AreEqual("host", user.HostName); + } + + [TestMethod] + public void HostmaskJoinUser() + { + _server.Parse(new Line(":nickname!user JOIN #chan")); + Assert.AreEqual("user", _server.UserName); + Assert.IsNull(_server.HostName); + + _server.Parse(new Line(":other!user JOIN #chan")); + var user = _server.Users["other"]; + Assert.AreEqual("user", user.UserName); + Assert.IsNull(user.HostName); + } + + [TestMethod] + public void HostmaskJoinHost() + { + _server.Parse(new Line(":nickname@host JOIN #chan")); + Assert.IsNull(_server.UserName); + Assert.AreEqual("host", _server.HostName); + + _server.Parse(new Line(":other@host JOIN #chan")); + var user = _server.Users["other"]; + Assert.IsNull(user.UserName); + Assert.AreEqual("host", user.HostName); + } + + [TestMethod] + public void ExtendedJoinWithoutExtendedJoin() + { + _server.Parse(new Line(":nickname JOIN #chan")); + Assert.IsNull(_server.Account); + Assert.IsNull(_server.RealName); + + _server.Parse(new Line(":other JOIN #chan")); + var user = _server.Users["other"]; + Assert.IsNull(user.Account); + Assert.IsNull(user.RealName); + } + + [TestMethod] + public void ExtendedJoinWithAccount() + { + _server.Parse(new Line(":nickname JOIN #chan acc :realname")); + Assert.AreEqual("acc", _server.Account); + Assert.AreEqual("realname", _server.RealName); + + _server.Parse(new Line(":other JOIN #chan acc2 :realname2")); + var user = _server.Users["other"]; + Assert.AreEqual("acc2", user.Account); + Assert.AreEqual("realname2", user.RealName); + } + + [TestMethod] + public void ExtendedJoinWithoutAccount() + { + _server.Parse(new Line(":nickname JOIN #chan * :realname")); + Assert.AreEqual("", _server.Account); + Assert.AreEqual("realname", _server.RealName); + + _server.Parse(new Line(":other JOIN #chan * :realname2")); + var user = _server.Users["other"]; + Assert.AreEqual("", user.Account); + Assert.AreEqual("realname2", user.RealName); + } + + [TestMethod] + public void AccountNotifyWithAccount() + { + _server.Parse(new Line(":nickname JOIN #chan")); + _server.Parse(new Line(":nickname ACCOUNT acc")); + Assert.AreEqual("acc", _server.Account); + + _server.Parse(new Line(":other JOIN #chan")); + _server.Parse(new Line(":other ACCOUNT acc2")); + var user = _server.Users["other"]; + Assert.AreEqual("acc2", user.Account); + } + + [TestMethod] + public void AccountNotifyWithoutAccount() + { + _server.Parse(new Line(":nickname JOIN #chan")); + _server.Parse(new Line(":nickname ACCOUNT *")); + Assert.AreEqual("", _server.Account); + + _server.Parse(new Line(":other JOIN #chan")); + _server.Parse(new Line(":other ACCOUNT *")); + var user = _server.Users["other"]; + Assert.AreEqual("", user.Account); + } + + [TestMethod] + public void HostmaskPrivmsgBoth() + { + _server.Parse(new Line(":nickname JOIN #chan")); + _server.Parse(new Line(":nickname!user@host PRIVMSG #chan :hi")); + Assert.AreEqual("user", _server.UserName); + Assert.AreEqual("host", _server.HostName); + + _server.Parse(new Line(":other!user@host PRIVMSG #chan :hi")); + var user = _server.Users["other"]; + Assert.AreEqual("user", user.UserName); + Assert.AreEqual("host", user.HostName); + } + + [TestMethod] + public void HostmaskPrivmsgUser() + { + _server.Parse(new Line(":nickname JOIN #chan")); + _server.Parse(new Line(":nickname!user PRIVMSG #chan :hi")); + Assert.AreEqual("user", _server.UserName); + Assert.IsNull(_server.HostName); + + _server.Parse(new Line(":other!user PRIVMSG #chan :hi")); + var user = _server.Users["other"]; + Assert.AreEqual("user", user.UserName); + Assert.IsNull(user.HostName); + } + + [TestMethod] + public void HostmaskPrivmsgHost() + { + _server.Parse(new Line(":nickname JOIN #chan")); + _server.Parse(new Line(":nickname@host PRIVMSG #chan :hi")); + Assert.IsNull(_server.UserName); + Assert.AreEqual("host", _server.HostName); + + _server.Parse(new Line(":other@host PRIVMSG #chan :hi")); + var user = _server.Users["other"]; + Assert.IsNull(user.UserName); + Assert.AreEqual("host", user.HostName); + } + + [TestMethod] + public void VisibleHostWithoutUsername() + { + _server.Parse(new Line("396 * hostname")); + Assert.IsNull(_server.UserName); + Assert.AreEqual("hostname", _server.HostName); + } + + [TestMethod] + public void VisibleHostWithUsername() + { + _server.Parse(new Line("396 * username@hostname")); + Assert.AreEqual("username", _server.UserName); + Assert.AreEqual("hostname", _server.HostName); + } + + [TestMethod] + public void Who() + { + _server.Parse(new Line(":nickname JOIN #chan")); + _server.Parse(new Line(":other JOIN #chan")); + _server.Parse(new Line("352 * #chan user host * nickname * :0 real")); + _server.Parse(new Line("352 * #chan user2 host2 * other * :0 real2")); + + Assert.AreEqual("user", _server.UserName); + Assert.AreEqual("host", _server.HostName); + Assert.AreEqual("real", _server.RealName); + + var user = _server.Users["other"]; + Assert.AreEqual("user2", user.UserName); + Assert.AreEqual("host2", user.HostName); + Assert.AreEqual("real2", user.RealName); + } + + [TestMethod] + public void Chghost() + { + _server.Parse(new Line(":nickname!user@host JOIN #chan")); + _server.Parse(new Line(":nickname CHGHOST u h")); + Assert.AreEqual("u", _server.UserName); + Assert.AreEqual("h", _server.HostName); + + _server.Parse(new Line(":other!user2@host2 JOIN #chan")); + _server.Parse(new Line(":other CHGHOST u2 h2")); + var user = _server.Users["other"]; + Assert.AreEqual("u2", user.UserName); + Assert.AreEqual("h2", user.HostName); + } + + [TestMethod] + public void Whois() + { + _server.Parse(new Line(":nickname JOIN #chan")); + _server.Parse(new Line("311 * nickname u h * :r")); + Assert.AreEqual("u", _server.UserName); + Assert.AreEqual("h", _server.HostName); + Assert.AreEqual("r", _server.RealName); + + _server.Parse(new Line(":other JOIN #chan")); + _server.Parse(new Line(":other CHGHOST u2 h2")); + _server.Parse(new Line("311 * other u2 h2 * :r2")); + var user = _server.Users["other"]; + Assert.AreEqual("u2", user.UserName); + Assert.AreEqual("h2", user.HostName); + Assert.AreEqual("r2", user.RealName); + } + + [TestMethod] + public void AwaySet() + { + _server.Parse(new Line(":nickname JOIN #chan")); + _server.Parse(new Line(":other JOIN #chan")); + var user = _server.Users["other"]; + Assert.IsNull(_server.Away); + Assert.IsNull(user.Away); + + _server.Parse(new Line(":nickname AWAY :bye bye")); + _server.Parse(new Line(":other AWAY :ich geh weg")); + Assert.AreEqual("bye bye", _server.Away); + Assert.AreEqual("ich geh weg", user.Away); + } + + [TestMethod] + public void AwayUnset() + { + _server.Parse(new Line(":nickname JOIN #chan")); + _server.Parse(new Line(":other JOIN #chan")); + _server.Parse(new Line(":nickname AWAY :bye bye")); + _server.Parse(new Line(":nickname AWAY")); + _server.Parse(new Line(":other AWAY :ich geh weg")); + _server.Parse(new Line(":other AWAY")); + + var user = _server.Users["other"]; + Assert.IsNull(_server.Away); + Assert.IsNull(user.Away); + } + + [TestMethod] + public void Setname() + { + _server.Parse(new Line(":nickname JOIN #chan")); + _server.Parse(new Line(":other JOIN #chan")); + var user = _server.Users["other"]; + Assert.IsNull(user.RealName); + Assert.IsNull(_server.RealName); + + _server.Parse(new Line(":nickname SETNAME :new now know how")); + _server.Parse(new Line(":other SETNAME :tyrannosaurus hex")); + Assert.AreEqual("new now know how", _server.RealName); + Assert.AreEqual("tyrannosaurus hex", user.RealName); + } + } +} diff --git a/IRCSharp.Tests/State/Who.cs b/IRCSharp.Tests/State/Who.cs new file mode 100644 index 0000000..d091785 --- /dev/null +++ b/IRCSharp.Tests/State/Who.cs @@ -0,0 +1,61 @@ +using IRCTokens; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace IRCStates.Tests +{ + [TestClass] + public class Who + { + private Server _server; + + [TestInitialize] + public void TestInitialize() + { + _server = new Server("test"); + _server.Parse(new Line("001 nickname")); + _server.Parse(new Line(":nickname JOIN #chan")); + } + + [TestMethod] + public void WhoResponse() + { + _server.Parse(new Line("352 * #chan user host server nickname * :0 real")); + var user = _server.Users["nickname"]; + + Assert.AreEqual("user", user.UserName); + Assert.AreEqual("host", _server.HostName); + Assert.AreEqual("real", user.RealName); + + Assert.AreEqual(user.UserName, _server.UserName); + Assert.AreEqual(user.HostName, _server.HostName); + Assert.AreEqual(user.RealName, _server.RealName); + } + + [TestMethod] + public void Whox() + { + _server.Parse(new Line($"354 * {Server.WhoType} user realip host nickname account :real")); + var user = _server.Users["nickname"]; + + Assert.AreEqual("user", user.UserName); + Assert.AreEqual("host", user.HostName); + Assert.AreEqual("real", user.RealName); + Assert.AreEqual("account", user.Account); + + Assert.AreEqual(user.UserName, _server.UserName); + Assert.AreEqual(user.HostName, _server.HostName); + Assert.AreEqual(user.RealName, _server.RealName); + Assert.AreEqual(user.Account, _server.Account); + } + + [TestMethod] + public void WhoxNoAccount() + { + _server.Parse(new Line($"354 * {Server.WhoType} user realip host nickname 0 :real")); + var user = _server.Users["nickname"]; + + Assert.IsNull(user.Account); + Assert.AreEqual(user.Account, _server.Account); + } + } +} diff --git a/IRCSharp.Tests/Tokenization/Data/JoinModel.cs b/IRCSharp.Tests/Tokenization/Data/JoinModel.cs new file mode 100644 index 0000000..e54f4cf --- /dev/null +++ b/IRCSharp.Tests/Tokenization/Data/JoinModel.cs @@ -0,0 +1,30 @@ +using System.Collections.Generic; +using YamlDotNet.Serialization; + +namespace IRCTokens.Tests.Data +{ + public class JoinModel + { + public List Tests { get; set; } + + public class Test + { + [YamlMember(Alias = "desc")] public string Description { get; set; } + + public Atoms Atoms { get; set; } + + public List Matches { get; set; } + } + + public class Atoms + { + public Dictionary Tags { get; set; } + + public string Source { get; set; } + + public string Verb { get; set; } + + public List Params { get; set; } + } + } +} diff --git a/IRCSharp.Tests/Tokenization/Data/SplitModel.cs b/IRCSharp.Tests/Tokenization/Data/SplitModel.cs new file mode 100644 index 0000000..5386326 --- /dev/null +++ b/IRCSharp.Tests/Tokenization/Data/SplitModel.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; + +namespace IRCTokens.Tests.Data +{ + public class SplitModel + { + public List Tests { get; set; } + + public class Test + { + public string Input { get; set; } + public JoinModel.Atoms Atoms { get; set; } + } + } +} diff --git a/IRCSharp.Tests/Tokenization/Data/msg-join.yaml b/IRCSharp.Tests/Tokenization/Data/msg-join.yaml new file mode 100644 index 0000000..d1d7429 --- /dev/null +++ b/IRCSharp.Tests/Tokenization/Data/msg-join.yaml @@ -0,0 +1,221 @@ +# IRC parser tests +# joining atoms into sendable messages + +# Written in 2015 by Daniel Oaks +# +# To the extent possible under law, the author(s) have dedicated all copyright +# and related and neighboring rights to this software to the public domain +# worldwide. This software is distributed without any warranty. +# +# You should have received a copy of the CC0 Public Domain Dedication along +# with this software. If not, see +# . + +# some of the tests here originate from grawity's test vectors, which is WTFPL v2 licensed +# https://github.com/grawity/code/tree/master/lib/tests +# some of the tests here originate from Mozilla's test vectors, which is public domain +# https://dxr.mozilla.org/comm-central/source/chat/protocols/irc/test/test_ircMessage.js +# some of the tests here originate from SaberUK's test vectors, which he's indicated I am free to include here +# https://github.com/SaberUK/ircparser/tree/master/test + +tests: + # the desc string holds a description of the test, if it exists + + # the atoms dict has the keys: + # * tags: tags dict + # tags with no value are an empty string + # * source: source string, without single leading colon + # * verb: verb string + # * params: params split up as a list + # if the params key does not exist, assume it is empty + # if any other keys do no exist, assume they are null + # a key that is null does not exist or is not specified with the + # given input string + + # matches is a list of messages that match + + # simple tests + - desc: Simple test with verb and params. + atoms: + verb: "foo" + params: + - "bar" + - "baz" + - "asdf" + matches: + - "foo bar baz asdf" + - "foo bar baz :asdf" + + # with no regular params + - desc: Simple test with source and no params. + atoms: + source: "src" + verb: "AWAY" + matches: + - ":src AWAY" + + - desc: Simple test with source and empty trailing param. + atoms: + source: "src" + verb: "AWAY" + params: + - "" + matches: + - ":src AWAY :" + + # with source + - desc: Simple test with source. + atoms: + source: "coolguy" + verb: "foo" + params: + - "bar" + - "baz" + - "asdf" + matches: + - ":coolguy foo bar baz asdf" + - ":coolguy foo bar baz :asdf" + + # with trailing param + - desc: Simple test with trailing param. + atoms: + verb: "foo" + params: + - "bar" + - "baz" + - "asdf quux" + matches: + - "foo bar baz :asdf quux" + + - desc: Simple test with empty trailing param. + atoms: + verb: "foo" + params: + - "bar" + - "baz" + - "" + matches: + - "foo bar baz :" + + - desc: Simple test with trailing param containing colon. + atoms: + verb: "foo" + params: + - "bar" + - "baz" + - ":asdf" + matches: + - "foo bar baz ::asdf" + + # with source and trailing param + - desc: Test with source and trailing param. + atoms: + source: "coolguy" + verb: "foo" + params: + - "bar" + - "baz" + - "asdf quux" + matches: + - ":coolguy foo bar baz :asdf quux" + + - desc: Test with trailing containing beginning+end whitespace. + atoms: + source: "coolguy" + verb: "foo" + params: + - "bar" + - "baz" + - " asdf quux " + matches: + - ":coolguy foo bar baz : asdf quux " + + - desc: Test with trailing containing what looks like another trailing param. + atoms: + source: "coolguy" + verb: "PRIVMSG" + params: + - "bar" + - "lol :) " + matches: + - ":coolguy PRIVMSG bar :lol :) " + + - desc: Simple test with source and empty trailing. + atoms: + source: "coolguy" + verb: "foo" + params: + - "bar" + - "baz" + - "" + matches: + - ":coolguy foo bar baz :" + + - desc: Trailing contains only spaces. + atoms: + source: "coolguy" + verb: "foo" + params: + - "bar" + - "baz" + - " " + matches: + - ":coolguy foo bar baz : " + + - desc: Param containing tab (tab is not considered SPACE for message splitting). + atoms: + source: "coolguy" + verb: "foo" + params: + - "b\tar" + - "baz" + matches: + - ":coolguy foo b\tar baz" + - ":coolguy foo b\tar :baz" + + # with tags + - desc: Tag with no value and space-filled trailing. + atoms: + tags: + "asd": "" + source: "coolguy" + verb: "foo" + params: + - "bar" + - "baz" + - " " + matches: + - "@asd :coolguy foo bar baz : " + + - desc: Tags with escaped values. + atoms: + verb: "foo" + tags: + "a": "b\\and\nk" + "d": "gh;764" + matches: + - "@a=b\\\\and\\nk;d=gh\\:764 foo" + - "@d=gh\\:764;a=b\\\\and\\nk foo" + + - desc: Tags with escaped values and params. + atoms: + verb: "foo" + tags: + "a": "b\\and\nk" + "d": "gh;764" + params: + - "par1" + - "par2" + matches: + - "@a=b\\\\and\\nk;d=gh\\:764 foo par1 par2" + - "@a=b\\\\and\\nk;d=gh\\:764 foo par1 :par2" + - "@d=gh\\:764;a=b\\\\and\\nk foo par1 par2" + - "@d=gh\\:764;a=b\\\\and\\nk foo par1 :par2" + + - desc: Tag with long, strange values (including LF and newline). + atoms: + tags: + foo: "\\\\;\\s \r\n" + verb: "COMMAND" + matches: + - "@foo=\\\\\\\\\\:\\\\s\\s\\r\\n COMMAND" diff --git a/IRCSharp.Tests/Tokenization/Data/msg-split.yaml b/IRCSharp.Tests/Tokenization/Data/msg-split.yaml new file mode 100644 index 0000000..fa3f4aa --- /dev/null +++ b/IRCSharp.Tests/Tokenization/Data/msg-split.yaml @@ -0,0 +1,343 @@ +# IRC parser tests +# splitting messages into usable atoms + +# Written in 2015 by Daniel Oaks +# +# To the extent possible under law, the author(s) have dedicated all copyright +# and related and neighboring rights to this software to the public domain +# worldwide. This software is distributed without any warranty. +# +# You should have received a copy of the CC0 Public Domain Dedication along +# with this software. If not, see +# . + +# some of the tests here originate from grawity's test vectors, which is WTFPL v2 licensed +# https://github.com/grawity/code/tree/master/lib/tests +# some of the tests here originate from Mozilla's test vectors, which is public domain +# https://dxr.mozilla.org/comm-central/source/chat/protocols/irc/test/test_ircMessage.js +# some of the tests here originate from SaberUK's test vectors, which he's indicated I am free to include here +# https://github.com/SaberUK/ircparser/tree/master/test + +# we follow RFC1459 with regards to multiple ascii spaces splitting atoms: +# The prefix, command, and all parameters are +# separated by one (or more) ASCII space character(s) (0x20). +# because doing it as RFC2812 says (strictly as a single ascii space) isn't sane + +tests: + # input is the string coming directly from the server to parse + + # the atoms dict has the keys: + # * tags: tags dict + # tags with no value are an empty string + # * source: source string, without single leading colon + # * verb: verb string + # * params: params split up as a list + # if the params key does not exist, assume it is empty + # if any other keys do no exist, assume they are null + # a key that is null does not exist or is not specified with the + # given input string + + # simple + - input: "foo bar baz asdf" + atoms: + verb: "foo" + params: + - "bar" + - "baz" + - "asdf" + + # with source + - input: ":coolguy foo bar baz asdf" + atoms: + source: "coolguy" + verb: "foo" + params: + - "bar" + - "baz" + - "asdf" + + # with trailing param + - input: "foo bar baz :asdf quux" + atoms: + verb: "foo" + params: + - "bar" + - "baz" + - "asdf quux" + + - input: "foo bar baz :" + atoms: + verb: "foo" + params: + - "bar" + - "baz" + - "" + + - input: "foo bar baz ::asdf" + atoms: + verb: "foo" + params: + - "bar" + - "baz" + - ":asdf" + + # with source and trailing param + - input: ":coolguy foo bar baz :asdf quux" + atoms: + source: "coolguy" + verb: "foo" + params: + - "bar" + - "baz" + - "asdf quux" + + - input: ":coolguy foo bar baz : asdf quux " + atoms: + source: "coolguy" + verb: "foo" + params: + - "bar" + - "baz" + - " asdf quux " + + - input: ":coolguy PRIVMSG bar :lol :) " + atoms: + source: "coolguy" + verb: "PRIVMSG" + params: + - "bar" + - "lol :) " + + - input: ":coolguy foo bar baz :" + atoms: + source: "coolguy" + verb: "foo" + params: + - "bar" + - "baz" + - "" + + - input: ":coolguy foo bar baz : " + atoms: + source: "coolguy" + verb: "foo" + params: + - "bar" + - "baz" + - " " + + # with tags + - input: "@a=b;c=32;k;rt=ql7 foo" + atoms: + verb: "foo" + tags: + "a": "b" + "c": "32" + "k": "" + "rt": "ql7" + + # with escaped tags + - input: "@a=b\\\\and\\nk;c=72\\s45;d=gh\\:764 foo" + atoms: + verb: "foo" + tags: + "a": "b\\and\nk" + "c": "72 45" + "d": "gh;764" + + # with tags and source + - input: "@c;h=;a=b :quux ab cd" + atoms: + tags: + "c": "" + "h": "" + "a": "b" + source: "quux" + verb: "ab" + params: + - "cd" + + # different forms of last param + - input: ":src JOIN #chan" + atoms: + source: "src" + verb: "JOIN" + params: + - "#chan" + + - input: ":src JOIN :#chan" + atoms: + source: "src" + verb: "JOIN" + params: + - "#chan" + + # with and without last param + - input: ":src AWAY" + atoms: + source: "src" + verb: "AWAY" + + - input: ":src AWAY " + atoms: + source: "src" + verb: "AWAY" + + # tab is not considered + - input: ":cool\tguy foo bar baz" + atoms: + source: "cool\tguy" + verb: "foo" + params: + - "bar" + - "baz" + + # with weird control codes in the source + - input: ":coolguy!ag@net\x035w\x03ork.admin PRIVMSG foo :bar baz" + atoms: + source: "coolguy!ag@net\x035w\x03ork.admin" + verb: "PRIVMSG" + params: + - "foo" + - "bar baz" + + - input: ":coolguy!~ag@n\x02et\x0305w\x0fork.admin PRIVMSG foo :bar baz" + atoms: + source: "coolguy!~ag@n\x02et\x0305w\x0fork.admin" + verb: "PRIVMSG" + params: + - "foo" + - "bar baz" + + - input: "@tag1=value1;tag2;vendor1/tag3=value2;vendor2/tag4= :irc.example.com COMMAND param1 param2 :param3 param3" + atoms: + tags: + tag1: "value1" + tag2: "" + vendor1/tag3: "value2" + vendor2/tag4: "" + source: "irc.example.com" + verb: "COMMAND" + params: + - "param1" + - "param2" + - "param3 param3" + + - input: ":irc.example.com COMMAND param1 param2 :param3 param3" + atoms: + source: "irc.example.com" + verb: "COMMAND" + params: + - "param1" + - "param2" + - "param3 param3" + + - input: "@tag1=value1;tag2;vendor1/tag3=value2;vendor2/tag4 COMMAND param1 param2 :param3 param3" + atoms: + tags: + tag1: "value1" + tag2: "" + vendor1/tag3: "value2" + vendor2/tag4: "" + verb: "COMMAND" + params: + - "param1" + - "param2" + - "param3 param3" + + - input: "COMMAND" + atoms: + verb: "COMMAND" + + # yaml encoding + slashes is fun + - input: "@foo=\\\\\\\\\\:\\\\s\\s\\r\\n COMMAND" + atoms: + tags: + foo: "\\\\;\\s \r\n" + verb: "COMMAND" + + # broken messages from unreal + - input: ":gravel.mozilla.org 432 #momo :Erroneous Nickname: Illegal characters" + atoms: + source: "gravel.mozilla.org" + verb: "432" + params: + - "#momo" + - "Erroneous Nickname: Illegal characters" + + - input: ":gravel.mozilla.org MODE #tckk +n " + atoms: + source: "gravel.mozilla.org" + verb: "MODE" + params: + - "#tckk" + - "+n" + + - input: ":services.esper.net MODE #foo-bar +o foobar " + atoms: + source: "services.esper.net" + verb: "MODE" + params: + - "#foo-bar" + - "+o" + - "foobar" + + # tag values should be parsed char-at-a-time to prevent wayward replacements. + - input: "@tag1=value\\\\ntest COMMAND" + atoms: + tags: + tag1: "value\\ntest" + verb: "COMMAND" + + # If a tag value has a slash followed by a character which doesn't need + # to be escaped, the slash should be dropped. + - input: "@tag1=value\\1 COMMAND" + atoms: + tags: + tag1: "value1" + verb: "COMMAND" + + # A slash at the end of a tag value should be dropped + - input: "@tag1=value1\\ COMMAND" + atoms: + tags: + tag1: "value1" + verb: "COMMAND" + + # Duplicate tags: Parsers SHOULD disregard all but the final occurence + - input: "@tag1=1;tag2=3;tag3=4;tag1=5 COMMAND" + atoms: + tags: + tag1: "5" + tag2: "3" + tag3: "4" + verb: "COMMAND" + + # vendored tags can have the same name as a non-vendored tag + - input: "@tag1=1;tag2=3;tag3=4;tag1=5;vendor/tag2=8 COMMAND" + atoms: + tags: + tag1: "5" + tag2: "3" + tag3: "4" + vendor/tag2: "8" + verb: "COMMAND" + + # Some parsers handle /MODE in a special way, make sure they do it right + - input: ":SomeOp MODE #channel :+i" + atoms: + source: "SomeOp" + verb: "MODE" + params: + - "#channel" + - "+i" + + - input: ":SomeOp MODE #channel +oo SomeUser :AnotherUser" + atoms: + source: "SomeOp" + verb: "MODE" + params: + - "#channel" + - "+oo" + - "SomeUser" + - "AnotherUser" diff --git a/IRCSharp.Tests/Tokenization/Format.cs b/IRCSharp.Tests/Tokenization/Format.cs new file mode 100644 index 0000000..7224f97 --- /dev/null +++ b/IRCSharp.Tests/Tokenization/Format.cs @@ -0,0 +1,105 @@ +using System; +using System.Collections.Generic; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace IRCTokens.Tests +{ + [TestClass] + public class Format + { + [TestMethod] + public void Tags() + { + var line = new Line("PRIVMSG", "#channel", "hello") + { + Tags = new Dictionary {{"id", "\\" + " " + ";" + "\r\n"}} + }.Format(); + + Assert.AreEqual("@id=\\\\\\s\\:\\r\\n PRIVMSG #channel hello", line); + } + + [TestMethod] + public void MissingTag() + { + var line = new Line("PRIVMSG", "#channel", "hello").Format(); + + Assert.AreEqual("PRIVMSG #channel hello", line); + } + + [TestMethod] + public void NullTag() + { + var line = new Line("PRIVMSG", "#channel", "hello") {Tags = new Dictionary {{"a", null}}} + .Format(); + + Assert.AreEqual("@a PRIVMSG #channel hello", line); + } + + [TestMethod] + public void EmptyTag() + { + var line = new Line("PRIVMSG", "#channel", "hello") {Tags = new Dictionary {{"a", ""}}} + .Format(); + + Assert.AreEqual("@a PRIVMSG #channel hello", line); + } + + [TestMethod] + public void Source() + { + var line = new Line("PRIVMSG", "#channel", "hello") {Source = "nick!user@host"}.Format(); + + Assert.AreEqual(":nick!user@host PRIVMSG #channel hello", line); + } + + [TestMethod] + public void CommandLowercase() + { + var line = new Line {Command = "privmsg"}.Format(); + Assert.AreEqual("privmsg", line); + } + + [TestMethod] + public void CommandUppercase() + { + var line = new Line {Command = "PRIVMSG"}.Format(); + Assert.AreEqual("PRIVMSG", line); + } + + [TestMethod] + public void TrailingSpace() + { + var line = new Line("PRIVMSG", "#channel", "hello world").Format(); + + Assert.AreEqual("PRIVMSG #channel :hello world", line); + } + + [TestMethod] + public void TrailingNoSpace() + { + var line = new Line("PRIVMSG", "#channel", "helloworld").Format(); + + Assert.AreEqual("PRIVMSG #channel helloworld", line); + } + + [TestMethod] + public void TrailingDoubleColon() + { + var line = new Line("PRIVMSG", "#channel", ":helloworld").Format(); + + Assert.AreEqual("PRIVMSG #channel ::helloworld", line); + } + + [TestMethod] + public void InvalidNonLastSpace() + { + Assert.ThrowsException(() => { new Line("USER", "user", "0 *", "real name").Format(); }); + } + + [TestMethod] + public void InvalidNonLastColon() + { + Assert.ThrowsException(() => { new Line("PRIVMSG", ":#channel", "hello").Format(); }); + } + } +} diff --git a/IRCSharp.Tests/Tokenization/Hostmask.cs b/IRCSharp.Tests/Tokenization/Hostmask.cs new file mode 100644 index 0000000..17c5ad7 --- /dev/null +++ b/IRCSharp.Tests/Tokenization/Hostmask.cs @@ -0,0 +1,64 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace IRCTokens.Tests +{ + [TestClass] + public class Hostmask + { + [TestMethod] + public void FullHostmask() + { + var hostmask = new IRCTokens.Hostmask("nick!user@host"); + Assert.AreEqual("nick", hostmask.NickName); + Assert.AreEqual("user", hostmask.UserName); + Assert.AreEqual("host", hostmask.HostName); + } + + [TestMethod] + public void NoHostName() + { + var hostmask = new IRCTokens.Hostmask("nick!user"); + Assert.AreEqual("nick", hostmask.NickName); + Assert.AreEqual("user", hostmask.UserName); + Assert.IsNull(hostmask.HostName); + } + + [TestMethod] + public void NoUserName() + { + var hostmask = new IRCTokens.Hostmask("nick@host"); + Assert.AreEqual("nick", hostmask.NickName); + Assert.IsNull(hostmask.UserName); + Assert.AreEqual("host", hostmask.HostName); + } + + [TestMethod] + public void OnlyNickName() + { + var hostmask = new IRCTokens.Hostmask("nick"); + Assert.AreEqual("nick", hostmask.NickName); + Assert.IsNull(hostmask.UserName); + Assert.IsNull(hostmask.HostName); + } + + [TestMethod] + public void HostmaskFromLine() + { + var line = new Line(":nick!user@host PRIVMSG #channel hello"); + var hostmask = new IRCTokens.Hostmask("nick!user@host"); + Assert.AreEqual(hostmask.ToString(), line.Hostmask.ToString()); + Assert.AreEqual("nick", line.Hostmask.NickName); + Assert.AreEqual("user", line.Hostmask.UserName); + Assert.AreEqual("host", line.Hostmask.HostName); + } + + [TestMethod] + public void EmptyHostmaskFromLine() + { + var line = new Line("PRIVMSG #channel hello"); + Assert.IsNull(line.Hostmask.HostName); + Assert.IsNull(line.Hostmask.UserName); + Assert.IsNull(line.Hostmask.NickName); + } + } +} diff --git a/IRCSharp.Tests/Tokenization/Parser.cs b/IRCSharp.Tests/Tokenization/Parser.cs new file mode 100644 index 0000000..40ff803 --- /dev/null +++ b/IRCSharp.Tests/Tokenization/Parser.cs @@ -0,0 +1,55 @@ +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using IRCTokens.Tests.Data; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using YamlDotNet.Serialization; +using YamlDotNet.Serialization.NamingConventions; + +namespace IRCTokens.Tests +{ + [TestClass] + public class Parser + { + private static T LoadYaml(string path) + { + var deserializer = new DeserializerBuilder() + .WithNamingConvention(CamelCaseNamingConvention.Instance) + .Build(); + + return deserializer.Deserialize(File.ReadAllText(path)); + } + + [TestMethod] + public void Split() + { + foreach (var test in LoadYaml("Tokenization/Data/msg-split.yaml").Tests) + { + var tokens = new Line(test.Input); + var atoms = test.Atoms; + + Assert.AreEqual(atoms.Verb.ToUpper(CultureInfo.InvariantCulture), tokens.Command, + $"command failed on: '{test.Input}'"); + Assert.AreEqual(atoms.Source, tokens.Source, $"source failed on: '{test.Input}'"); + CollectionAssert.AreEqual(atoms.Tags, tokens.Tags, $"tags failed on: '{test.Input}'"); + CollectionAssert.AreEqual(atoms.Params ?? new List(), tokens.Params, + $"params failed on: '{test.Input}'"); + } + } + + [TestMethod] + public void Join() + { + foreach (var test in LoadYaml("Tokenization/Data/msg-join.yaml").Tests) + { + var atoms = test.Atoms; + var line = new Line + { + Command = atoms.Verb, Params = atoms.Params, Source = atoms.Source, Tags = atoms.Tags + }.Format(); + + Assert.IsTrue(test.Matches.Contains(line), test.Description); + } + } + } +} diff --git a/IRCSharp.Tests/Tokenization/StatefulDecoder.cs b/IRCSharp.Tests/Tokenization/StatefulDecoder.cs new file mode 100644 index 0000000..4da7690 --- /dev/null +++ b/IRCSharp.Tests/Tokenization/StatefulDecoder.cs @@ -0,0 +1,88 @@ +using System.Collections.Generic; +using System.Text; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace IRCTokens.Tests +{ + [TestClass] + public class StatefulDecoder + { + private IRCTokens.StatefulDecoder _decoder; + + [TestInitialize] + public void Initialize() + { + _decoder = new IRCTokens.StatefulDecoder(); + } + + [TestMethod] + public void Partial() + { + var lines = _decoder.Push("PRIVMSG "); + Assert.AreEqual(0, lines.Count); + + lines = _decoder.Push("#channel hello\r\n"); + Assert.AreEqual(1, lines.Count); + + var line = new Line("PRIVMSG #channel hello"); + CollectionAssert.AreEqual(new List {line}, lines); + } + + [TestMethod] + public void Multiple() + { + var lines = _decoder.Push("PRIVMSG #channel1 hello\r\nPRIVMSG #channel2 hello\r\n"); + Assert.AreEqual(2, lines.Count); + + var line1 = new Line("PRIVMSG #channel1 hello"); + var line2 = new Line("PRIVMSG #channel2 hello"); + Assert.AreEqual(line1, lines[0]); + Assert.AreEqual(line2, lines[1]); + } + + [TestMethod] + public void EncodingIso8859() + { + var iso8859 = Encoding.GetEncoding("iso-8859-1"); + _decoder = new IRCTokens.StatefulDecoder {Encoding = iso8859}; + var bytes = iso8859.GetBytes("PRIVMSG #channel :hello Ç\r\n"); + var lines = _decoder.Push(bytes, bytes.Length); + var line = new Line("PRIVMSG #channel :hello Ç"); + Assert.IsTrue(line.Equals(lines[0])); + } + + [TestMethod] + public void EncodingFallback() + { + var latin1 = Encoding.GetEncoding("iso-8859-1"); + _decoder = new IRCTokens.StatefulDecoder {Encoding = null, Fallback = latin1}; + var bytes = latin1.GetBytes("PRIVMSG #channel hélló\r\n"); + var lines = _decoder.Push(bytes, bytes.Length); + Assert.AreEqual(1, lines.Count); + Assert.IsTrue(new Line("PRIVMSG #channel hélló").Equals(lines[0])); + } + + [TestMethod] + public void Empty() + { + var lines = _decoder.Push(string.Empty); + Assert.AreEqual(0, lines.Count); + } + + [TestMethod] + public void BufferUnfinished() + { + _decoder.Push("PRIVMSG #channel hello"); + var lines = _decoder.Push(string.Empty); + Assert.AreEqual(0, lines.Count); + } + + [TestMethod] + public void Clear() + { + _decoder.Push("PRIVMSG "); + _decoder.Clear(); + Assert.AreEqual(string.Empty, _decoder.Pending); + } + } +} diff --git a/IRCSharp.Tests/Tokenization/StatefulEncoder.cs b/IRCSharp.Tests/Tokenization/StatefulEncoder.cs new file mode 100644 index 0000000..d1e1e3e --- /dev/null +++ b/IRCSharp.Tests/Tokenization/StatefulEncoder.cs @@ -0,0 +1,84 @@ +using System.Text; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace IRCTokens.Tests +{ + [TestClass] + public class StatefulEncoder + { + private IRCTokens.StatefulEncoder _encoder; + + [TestInitialize] + public void Initialize() + { + _encoder = new IRCTokens.StatefulEncoder(); + } + + [TestMethod] + public void Push() + { + var line = new Line("PRIVMSG #channel hello"); + _encoder.Push(line); + Assert.AreEqual("PRIVMSG #channel hello\r\n", _encoder.Pending()); + } + + [TestMethod] + public void PopPartial() + { + var line = new Line("PRIVMSG #channel hello"); + _encoder.Push(line); + _encoder.Pop("PRIVMSG #channel hello".Length); + Assert.AreEqual("\r\n", _encoder.Pending()); + } + + [TestMethod] + public void TestPopReturned() + { + var line = new Line("PRIVMSG #channel hello"); + _encoder.Push(line); + _encoder.Push(line); + var lines = _encoder.Pop("PRIVMSG #channel hello\r\n".Length); + Assert.AreEqual(1, lines.Count); + Assert.AreEqual(line, lines[0]); + } + + [TestMethod] + public void PopNoneReturned() + { + var line = new Line("PRIVMSG #channel hello"); + _encoder.Push(line); + var lines = _encoder.Pop(1); + Assert.AreEqual(0, lines.Count); + } + + [TestMethod] + public void PopMultipleLines() + { + var line1 = new Line("PRIVMSG #channel1 hello"); + _encoder.Push(line1); + var line2 = new Line("PRIVMSG #channel2 hello"); + _encoder.Push(line2); + + var lines = _encoder.Pop(_encoder.Pending().Length); + Assert.AreEqual(2, lines.Count); + Assert.AreEqual(string.Empty, _encoder.Pending()); + } + + [TestMethod] + public void Clear() + { + _encoder.Push(new Line("PRIVMSG #channel hello")); + _encoder.Clear(); + Assert.AreEqual(string.Empty, _encoder.Pending()); + } + + [TestMethod] + public void EncodingIso8859() + { + var iso8859 = Encoding.GetEncoding("iso-8859-1"); + _encoder = new IRCTokens.StatefulEncoder {Encoding = iso8859}; + _encoder.Push(new Line("PRIVMSG #channel :hello Ç")); + CollectionAssert.AreEqual(iso8859.GetBytes("PRIVMSG #channel :hello Ç\r\n"), _encoder.PendingBytes); + } + } +} diff --git a/IRCSharp.Tests/Tokenization/Tokenization.cs b/IRCSharp.Tests/Tokenization/Tokenization.cs new file mode 100644 index 0000000..c4c5c5a --- /dev/null +++ b/IRCSharp.Tests/Tokenization/Tokenization.cs @@ -0,0 +1,133 @@ +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace IRCTokens.Tests +{ + [TestClass] + public class Tokenization + { + [TestMethod] + public void TagsMissing() + { + var line = new Line("PRIVMSG #channel"); + Assert.IsNull(line.Tags); + } + + [TestMethod] + public void TagsMissingValue() + { + var line = new Line("@id= PRIVMSG #channel"); + Assert.AreEqual(string.Empty, line.Tags["id"]); + } + + [TestMethod] + public void TagsMissingEqual() + { + var line = new Line("@id PRIVMSG #channel"); + Assert.AreEqual(string.Empty, line.Tags["id"]); + } + + [TestMethod] + public void TagsUnescape() + { + var line = new Line(@"@id=1\\\:\r\n\s2 PRIVMSG #channel"); + Assert.AreEqual("1\\;\r\n 2", line.Tags["id"]); + } + + [TestMethod] + public void TagsOverlap() + { + var line = new Line(@"@id=1\\\s\\s PRIVMSG #channel"); + Assert.AreEqual("1\\ \\s", line.Tags["id"]); + } + + [TestMethod] + public void TagsLoneEndSlash() + { + var line = new Line("@id=1\\ PRIVMSG #channel"); + Assert.AreEqual("1", line.Tags["id"]); + } + + [TestMethod] + public void SourceWithoutTags() + { + var line = new Line(":nick!user@host PRIVMSG #channel"); + Assert.AreEqual("nick!user@host", line.Source); + } + + [TestMethod] + public void SourceWithTags() + { + var line = new Line("@id=123 :nick!user@host PRIVMSG #channel"); + Assert.AreEqual("nick!user@host", line.Source); + } + + [TestMethod] + public void SourceMissingWithoutTags() + { + var line = new Line("PRIVMSG #channel"); + Assert.IsNull(line.Source); + } + + [TestMethod] + public void SourceMissingWithTags() + { + var line = new Line("@id=123 PRIVMSG #channel"); + Assert.IsNull(line.Source); + } + + [TestMethod] + public void Command() + { + var line = new Line("privmsg #channel"); + Assert.AreEqual("PRIVMSG", line.Command); + } + + [TestMethod] + public void ParamsTrailing() + { + var line = new Line("PRIVMSG #channel :hello world"); + CollectionAssert.AreEqual(new List {"#channel", "hello world"}, line.Params); + } + + [TestMethod] + public void ParamsOnlyTrailing() + { + var line = new Line("PRIVMSG :hello world"); + CollectionAssert.AreEqual(new List {"hello world"}, line.Params); + } + + [TestMethod] + public void ParamsMissing() + { + var line = new Line("PRIVMSG"); + Assert.AreEqual("PRIVMSG", line.Command); + CollectionAssert.AreEqual(new List(), line.Params); + } + + [TestMethod] + public void AllTokens() + { + var line = new Line("@id=123 :nick!user@host PRIVMSG #channel :hello world"); + CollectionAssert.AreEqual(new Dictionary {{"id", "123"}}, line.Tags); + Assert.AreEqual("nick!user@host", line.Source); + Assert.AreEqual("PRIVMSG", line.Command); + CollectionAssert.AreEqual(new List {"#channel", "hello world"}, line.Params); + } + + [TestMethod] + public void NulByte() + { + var decoder = new IRCTokens.StatefulDecoder(); + var bytes = Encoding.UTF8.GetBytes(":nick!user@host PRIVMSG #channel :hello") + .Concat(Encoding.UTF8.GetBytes("\0")) + .Concat(Encoding.UTF8.GetBytes("world")) + .ToArray(); + var line = decoder.Push(bytes, bytes.Length).First(); + + CollectionAssert.AreEqual(new List {"#channel", "hello"}, line.Params); + } + } +} diff --git a/IRCSharp.sln b/IRCSharp.sln index ff19f5e..1a79759 100644 --- a/IRCSharp.sln +++ b/IRCSharp.sln @@ -9,13 +9,17 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TokensSample", "Examples\To EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IRCStates", "IRCStates\IRCStates.csproj", "{233E3CB4-61F1-4368-9139-7E9F4A58ED2D}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StatesSample", "Examples\States\StatesSample.csproj", "{BC9F6696-9D83-4F7A-9E15-CE4D3626C1AF}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StatesSample", "Examples\States\StatesSample.csproj", "{BC9F6696-9D83-4F7A-9E15-CE4D3626C1AF}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{1A85EB22-D7B4-417F-AC3B-DAFD97DDEA08}" ProjectSection(SolutionItems) = preProject .editorconfig = .editorconfig EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IRCSharp.Tests", "IRCSharp.Tests\IRCSharp.Tests.csproj", "{B420F0F3-1ED0-4FD3-9E91-2E7F96F9FF7F}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Examples", "Examples", "{4260E03C-6E28-4519-8943-5B477841A75A}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -38,10 +42,18 @@ Global {BC9F6696-9D83-4F7A-9E15-CE4D3626C1AF}.Debug|Any CPU.Build.0 = Debug|Any CPU {BC9F6696-9D83-4F7A-9E15-CE4D3626C1AF}.Release|Any CPU.ActiveCfg = Release|Any CPU {BC9F6696-9D83-4F7A-9E15-CE4D3626C1AF}.Release|Any CPU.Build.0 = Release|Any CPU + {B420F0F3-1ED0-4FD3-9E91-2E7F96F9FF7F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B420F0F3-1ED0-4FD3-9E91-2E7F96F9FF7F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B420F0F3-1ED0-4FD3-9E91-2E7F96F9FF7F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B420F0F3-1ED0-4FD3-9E91-2E7F96F9FF7F}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {A45DA39B-6B47-4713-8049-3B36E0235B67} = {4260E03C-6E28-4519-8943-5B477841A75A} + {BC9F6696-9D83-4F7A-9E15-CE4D3626C1AF} = {4260E03C-6E28-4519-8943-5B477841A75A} + EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {0B91F0EA-8564-4318-8EEC-ED0640475141} EndGlobalSection diff --git a/IRCStates/IRCStates.csproj b/IRCStates/IRCStates.csproj index dee711e..891167c 100644 --- a/IRCStates/IRCStates.csproj +++ b/IRCStates/IRCStates.csproj @@ -3,7 +3,7 @@ net5.0 IRCStates - 1.0.2 + 1.1.0 Ben Harris tildeverse.org true @@ -13,7 +13,7 @@ https://tildegit.org/irctokens/ircsharp/src/branch/main/IRCStates git irc - 1.0.2 + 1.1.0 @@ -21,9 +21,6 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - - diff --git a/IRCStates/Tests/Cap.cs b/IRCStates/Tests/Cap.cs deleted file mode 100644 index 3c0faba..0000000 --- a/IRCStates/Tests/Cap.cs +++ /dev/null @@ -1,131 +0,0 @@ -using System.Collections.Generic; -using IRCTokens; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace IRCStates.Tests -{ - [TestClass] - public class Cap - { - private Server _server; - - [TestInitialize] - public void TestInitialize() - { - _server = new Server("test"); - } - - [TestMethod] - public void LSOneLine() - { - Assert.IsFalse(_server.HasCap); - CollectionAssert.AreEqual(new Dictionary(), _server.AvailableCaps); - _server.Parse(new Line("CAP * LS :a b")); - CollectionAssert.AreEqual(new Dictionary {{"a", ""}, {"b", ""}}, _server.AvailableCaps); - } - - [TestMethod] - public void LSTwoLines() - { - _server.Parse(new Line("CAP * LS * :a b")); - CollectionAssert.AreEqual(new Dictionary(), _server.AvailableCaps); - _server.Parse(new Line("CAP * LS :c")); - Assert.IsTrue(_server.AvailableCaps.ContainsKey("a")); - Assert.IsTrue(_server.AvailableCaps.ContainsKey("b")); - Assert.IsTrue(_server.AvailableCaps.ContainsKey("c")); - } - - [TestMethod] - public void LSValues() - { - _server.Parse(new Line("CAP * LS :a b= c=1")); - CollectionAssert.AreEqual(new Dictionary {{"a", ""}, {"b", ""}, {"c", "1"}}, - _server.AvailableCaps); - } - - [TestMethod] - public void ACKOneLine() - { - _server.Parse(new Line("CAP * LS :a b")); - _server.Parse(new Line("CAP * ACK :a b")); - CollectionAssert.AreEqual(new List {"a", "b"}, _server.AgreedCaps); - } - - [TestMethod] - public void ACKTwoLines() - { - _server.Parse(new Line("CAP * LS :a b c")); - _server.Parse(new Line("CAP * ACK * :a b")); - _server.Parse(new Line("CAP * ACK :c")); - CollectionAssert.AreEqual(new List {"a", "b", "c"}, _server.AgreedCaps); - } - - [TestMethod] - public void ACKNotLS() - { - _server.Parse(new Line("CAP * LS a")); - _server.Parse(new Line("CAP * ACK b")); - CollectionAssert.AreEqual(new List(), _server.AgreedCaps); - } - - [TestMethod] - public void NEWNoLS() - { - _server.Parse(new Line("CAP * NEW :a")); - CollectionAssert.AreEqual(new Dictionary {{"a", ""}}, _server.AvailableCaps); - } - - [TestMethod] - public void NEWOneLine() - { - _server.Parse(new Line("CAP * LS :a")); - _server.Parse(new Line("CAP * NEW :b")); - CollectionAssert.AreEqual(new Dictionary {{"a", ""}, {"b", ""}}, _server.AvailableCaps); - } - - [TestMethod] - public void NEWTwoLines() - { - _server.Parse(new Line("CAP * LS :a")); - _server.Parse(new Line("CAP * NEW :b c")); - CollectionAssert.AreEqual(new Dictionary {{"a", ""}, {"b", ""}, {"c", ""}}, - _server.AvailableCaps); - } - - [TestMethod] - public void DELNotAcked() - { - _server.Parse(new Line("CAP * DEL a")); - } - - [TestMethod] - public void DELOneLS() - { - _server.Parse(new Line("CAP * LS :a")); - _server.Parse(new Line("CAP * ACK :a")); - _server.Parse(new Line("CAP * DEL :a")); - CollectionAssert.AreEqual(new Dictionary(), _server.AvailableCaps); - CollectionAssert.AreEqual(new List(), _server.AgreedCaps); - } - - [TestMethod] - public void DELTwoLS() - { - _server.Parse(new Line("CAP * LS :a b")); - _server.Parse(new Line("CAP * ACK :a b")); - _server.Parse(new Line("CAP * DEL :a")); - CollectionAssert.AreEqual(new Dictionary {{"b", ""}}, _server.AvailableCaps); - CollectionAssert.AreEqual(new List {"b"}, _server.AgreedCaps); - } - - [TestMethod] - public void DELTwoDEL() - { - _server.Parse(new Line("CAP * LS :a b")); - _server.Parse(new Line("CAP * ACK :a b")); - _server.Parse(new Line("CAP * DEL :a b")); - CollectionAssert.AreEqual(new Dictionary(), _server.AvailableCaps); - CollectionAssert.AreEqual(new List(), _server.AgreedCaps); - } - } -} diff --git a/IRCStates/Tests/Casemap.cs b/IRCStates/Tests/Casemap.cs deleted file mode 100644 index 4a02444..0000000 --- a/IRCStates/Tests/Casemap.cs +++ /dev/null @@ -1,58 +0,0 @@ -using IRCTokens; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace IRCStates.Tests -{ - [TestClass] - public class Casemap - { - [TestMethod] - public void Rfc1459() - { - var lower = IRCStates.Casemap.CaseFold(IRCStates.Casemap.CaseMapping.Rfc1459, @"ÀTEST[]~\"); - Assert.AreEqual("Àtest{}^|", lower); - } - - [TestMethod] - public void Ascii() - { - var lower = IRCStates.Casemap.CaseFold(IRCStates.Casemap.CaseMapping.Ascii, @"ÀTEST[]~\"); - Assert.AreEqual(@"Àtest[]~\", lower); - } - - [TestMethod] - public void CommandJoin() - { - var server = new Server("test"); - server.Parse(new Line("001 nickname")); - server.Parse(new Line(":Nickname JOIN #Chan")); - server.Parse(new Line(":Other JOIN #Chan")); - - Assert.IsTrue(server.Users.ContainsKey("nickname")); - Assert.IsFalse(server.Users.ContainsKey("Nickname")); - Assert.IsTrue(server.Users.ContainsKey("other")); - Assert.IsFalse(server.Users.ContainsKey("Other")); - Assert.IsTrue(server.Channels.ContainsKey("#chan")); - Assert.IsFalse(server.Channels.ContainsKey("#Chan")); - - var channel = server.Channels["#chan"]; - Assert.AreEqual("#Chan", channel.Name); - } - - [TestMethod] - public void CommandNick() - { - var server = new Server("test"); - server.Parse(new Line("001 nickname")); - server.Parse(new Line(":nickname JOIN #chan")); - var user = server.Users["nickname"]; - server.Parse(new Line(":nickname NICK NewNickname")); - Assert.AreEqual(1, server.Users.Count); - Assert.IsTrue(server.Users.ContainsKey("newnickname")); - Assert.AreEqual("NewNickname", user.NickName); - Assert.AreEqual("newnickname", user.NickNameLower); - Assert.AreEqual("NewNickname", server.NickName); - Assert.AreEqual("newnickname", server.NickNameLower); - } - } -} diff --git a/IRCStates/Tests/Channel.cs b/IRCStates/Tests/Channel.cs deleted file mode 100644 index 6868e0f..0000000 --- a/IRCStates/Tests/Channel.cs +++ /dev/null @@ -1,202 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using IRCTokens; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace IRCStates.Tests -{ - [TestClass] - public class Channel - { - private Server _server; - - [TestInitialize] - public void TestInitialize() - { - _server = new Server("test"); - _server.Parse(new Line("001 nickname")); - _server.Parse(new Line(":nickname JOIN #chan")); - } - - [TestMethod] - public void JoinSelf() - { - Assert.IsTrue(_server.Channels.ContainsKey("#chan")); - Assert.IsTrue(_server.Users.ContainsKey("nickname")); - Assert.AreEqual(1, _server.Channels.Count); - Assert.AreEqual(1, _server.Users.Count); - - var user = _server.Users["nickname"]; - var chan = _server.Channels["#chan"]; - Assert.IsTrue(chan.Users.ContainsKey(user.NickNameLower)); - var chanUser = chan.Users[user.NickNameLower]; - CollectionAssert.AreEqual(new List {chan.NameLower}, user.Channels.ToList()); - } - - [TestMethod] - public void JoinOther() - { - _server.Parse(new Line(":other JOIN #chan")); - - Assert.AreEqual(2, _server.Users.Count); - Assert.IsTrue(_server.Users.ContainsKey("other")); - - var channel = _server.Channels["#chan"]; - Assert.AreEqual(2, channel.Users.Count); - - var user = _server.Users["other"]; - CollectionAssert.AreEqual(new List {channel.NameLower}, user.Channels.ToList()); - } - - [TestMethod] - public void PartSelf() - { - _server.Parse(new Line(":nickname PART #chan")); - - Assert.AreEqual(0, _server.Users.Count); - Assert.AreEqual(0, _server.Channels.Count); - } - - [TestMethod] - public void PartOther() - { - _server.Parse(new Line(":other JOIN #chan")); - _server.Parse(new Line(":other PART #chan")); - - var user = _server.Users["nickname"]; - var channel = _server.Channels["#chan"]; - var chanUser = channel.Users[user.NickNameLower]; - - Assert.AreEqual(channel.NameLower, user.Channels.Single()); - CollectionAssert.AreEqual(new Dictionary {{"nickname", user}}, _server.Users); - CollectionAssert.AreEqual(new Dictionary {{"#chan", channel}}, _server.Channels); - CollectionAssert.AreEqual(new Dictionary {{"nickname", chanUser}}, channel.Users); - } - - [TestMethod] - public void KickSelf() - { - _server.Parse(new Line(":nickname KICK #chan nickname")); - - Assert.AreEqual(0, _server.Users.Count); - Assert.AreEqual(0, _server.Channels.Count); - } - - [TestMethod] - public void KickOther() - { - _server.Parse(new Line(":other JOIN #chan")); - _server.Parse(new Line(":nickname KICK #chan other")); - - var user = _server.Users["nickname"]; - var channel = _server.Channels["#chan"]; - var chanUser = channel.Users[user.NickNameLower]; - - Assert.AreEqual(1, _server.Users.Count); - Assert.AreEqual(1, _server.Channels.Count); - Assert.AreEqual(channel.NameLower, user.Channels.Single()); - CollectionAssert.AreEqual(new Dictionary {{user.NickNameLower, chanUser}}, - channel.Users); - } - - [TestMethod] - public void QuitSelf() - { - _server.Parse(new Line("QUIT :i'm outta here")); - Assert.IsFalse(_server.Users.Any()); - Assert.IsFalse(_server.Channels.Any()); - } - - [TestMethod] - public void QuitSelfWithSource() - { - _server.Parse(new Line(":nickname QUIT :i'm outta here")); - Assert.IsFalse(_server.Users.Any()); - Assert.IsFalse(_server.Channels.Any()); - } - - [TestMethod] - public void QuitOther() - { - _server.Parse(new Line(":other JOIN #chan")); - _server.Parse(new Line(":other QUIT :see ya")); - Assert.IsFalse(_server.Users.ContainsKey("other")); - } - - [TestMethod] - public void TopicText() - { - _server.Parse(new Line("332 * #chan :test")); - Assert.AreEqual("test", _server.Channels["#chan"].Topic); - } - - [TestMethod] - public void TopicSetByAt() - { - var dt = DateTimeOffset.FromUnixTimeSeconds(1584023277).DateTime; - _server.Parse(new Line("333 * #chan other 1584023277")); - - var channel = _server.Channels["#chan"]; - - Assert.AreEqual("other", channel.TopicSetter); - Assert.AreEqual(dt, channel.TopicTime); - } - - [TestMethod] - public void TopicCommand() - { - _server.Parse(new Line("TOPIC #chan :hello there")); - Assert.AreEqual("hello there", _server.Channels["#chan"].Topic); - } - - [TestMethod] - public void CreationDate() - { - _server.Parse(new Line("329 * #chan 1584041889")); - Assert.AreEqual(DateTimeOffset.FromUnixTimeSeconds(1584041889).DateTime, _server.Channels["#chan"].Created); - } - - [TestMethod] - public void NamesCommand() - { - _server.Parse(new Line("353 * * #chan :nickname @+other")); - Assert.IsTrue(_server.Users.ContainsKey("nickname")); - Assert.IsTrue(_server.Users.ContainsKey("other")); - - var user = _server.Users["other"]; - var channel = _server.Channels["#chan"]; - var chanUser1 = channel.Users[user.NickNameLower]; - var chanUser2 = channel.Users[_server.NickNameLower]; - - Assert.AreEqual(2, channel.Users.Count); - CollectionAssert.AreEqual(chanUser1.Modes, channel.Users[user.NickNameLower].Modes); - CollectionAssert.AreEqual(chanUser2.Modes, channel.Users[_server.NickNameLower].Modes); - CollectionAssert.AreEqual(new List {"o", "v"}, chanUser1.Modes); - Assert.AreEqual(channel.NameLower, user.Channels.Single()); - } - - [TestMethod] - public void UserhostInNames() - { - _server.Parse(new Line("353 * * #chan :nickname!user@host other!user2@host2")); - Assert.AreEqual("user", _server.UserName); - Assert.AreEqual("host", _server.HostName); - - var user = _server.Users["other"]; - Assert.AreEqual("user2", user.UserName); - Assert.AreEqual("host2", user.HostName); - } - - [TestMethod] - public void NickAfterJoin() - { - var user = _server.Users["nickname"]; - var channel = _server.Channels["#chan"]; - var chanUser = channel.Users[user.NickNameLower]; - _server.Parse(new Line(":nickname NICK nickname2")); - CollectionAssert.AreEqual(new Dictionary {{user.NickNameLower, chanUser}}, - channel.Users); - } - } -} diff --git a/IRCStates/Tests/Emit.cs b/IRCStates/Tests/Emit.cs deleted file mode 100644 index 07fea8c..0000000 --- a/IRCStates/Tests/Emit.cs +++ /dev/null @@ -1,117 +0,0 @@ -using System.Collections.Generic; -using IRCTokens; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace IRCStates.Tests -{ - [TestClass] - public class Emit - { - private Server _server; - - [TestInitialize] - public void TestInitialize() - { - _server = new Server("test"); - _server.Parse(new Line("001 nickname")); - } - - [TestMethod] - public void EmitJoin() - { - var emit = _server.Parse(new Line(":nickname JOIN #chan")); - - Assert.AreEqual("JOIN", emit.Command); - Assert.IsTrue(emit.Self); - Assert.AreEqual(_server.Users["nickname"], emit.User); - Assert.AreEqual(_server.Channels["#chan"], emit.Channel); - - emit = _server.Parse(new Line(":other JOIN #chan")); - Assert.IsNotNull(emit); - Assert.AreEqual("JOIN", emit.Command); - Assert.IsFalse(emit.Self); - Assert.AreEqual(_server.Users["other"], emit.User); - Assert.AreEqual(_server.Channels["#chan"], emit.Channel); - } - - [TestMethod] - public void EmitPrivmsg() - { - _server.Parse(new Line(":nickname JOIN #chan")); - var emit = _server.Parse(new Line(":nickname PRIVMSG #chan :hello")); - - Assert.IsNotNull(emit); - Assert.AreEqual("PRIVMSG", emit.Command); - Assert.AreEqual("hello", emit.Text); - Assert.IsTrue(emit.SelfSource); - Assert.AreEqual(_server.Users["nickname"], emit.User); - Assert.AreEqual(_server.Channels["#chan"], emit.Channel); - - _server.Parse(new Line(":other JOIN #chan")); - emit = _server.Parse(new Line(":other PRIVMSG #chan :hello2")); - - Assert.IsNotNull(emit); - Assert.AreEqual("PRIVMSG", emit.Command); - Assert.AreEqual("hello2", emit.Text); - Assert.IsFalse(emit.SelfSource); - Assert.AreEqual(_server.Users["other"], emit.User); - Assert.AreEqual(_server.Channels["#chan"], emit.Channel); - } - - [TestMethod] - public void EmitPrivmsgNoJoin() - { - _server.Parse(new Line(":nickname JOIN #chan")); - var emit = _server.Parse(new Line(":other PRIVMSG #chan :hello")); - - Assert.IsNotNull(emit); - Assert.AreEqual("PRIVMSG", emit.Command); - Assert.AreEqual("hello", emit.Text); - Assert.IsFalse(emit.SelfSource); - Assert.IsNotNull(emit.User); - - var channel = _server.Channels["#chan"]; - Assert.AreEqual(channel, emit.Channel); - } - - [TestMethod] - public void EmitKick() - { - _server.Parse(new Line(":nickname JOIN #chan")); - - var user = _server.Users["nickname"]; - var channel = _server.Channels["#chan"]; - _server.Parse(new Line(":other JOIN #chan")); - var userOther = _server.Users["other"]; - var emit = _server.Parse(new Line(":nickname KICK #chan other :reason")); - - Assert.IsNotNull(emit); - Assert.AreEqual("KICK", emit.Command); - Assert.AreEqual("reason", emit.Text); - Assert.IsTrue(emit.SelfSource); - Assert.AreEqual(user, emit.UserSource); - Assert.AreEqual(userOther, emit.UserTarget); - Assert.AreEqual(channel, emit.Channel); - } - - [TestMethod] - public void EmitMode() - { - var emit = _server.Parse(new Line("MODE nickname x+i-i+wi-wi")); - - Assert.IsNotNull(emit); - Assert.AreEqual("MODE", emit.Command); - Assert.IsTrue(emit.SelfTarget); - CollectionAssert.AreEqual(new List - { - "+x", - "+i", - "-i", - "+w", - "+i", - "-w", - "-i" - }, emit.Tokens); - } - } -} diff --git a/IRCStates/Tests/ISupport.cs b/IRCStates/Tests/ISupport.cs deleted file mode 100644 index 5cdcc61..0000000 --- a/IRCStates/Tests/ISupport.cs +++ /dev/null @@ -1,210 +0,0 @@ -using System.Collections.Generic; -using IRCTokens; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -// ReSharper disable InconsistentNaming - -namespace IRCStates.Tests -{ - [TestClass] - public class ISupport - { - private Server _server; - - [TestInitialize] - public void TestInitialize() - { - _server = new Server("test"); - _server.Parse(new Line("001 nickname")); - } - - [TestMethod] - public void ChanModes() - { - CollectionAssert.AreEqual(new List {"b"}, _server.ISupport.ChanModes.ListModes); - CollectionAssert.AreEqual(new List {"k"}, _server.ISupport.ChanModes.SettingBModes); - CollectionAssert.AreEqual(new List {"l"}, _server.ISupport.ChanModes.SettingCModes); - CollectionAssert.AreEqual(new List - { - "i", - "m", - "n", - "p", - "s", - "t" - }, _server.ISupport.ChanModes.SettingDModes); - - _server.Parse(new Line("005 * CHANMODES=a,b,c,d *")); - - CollectionAssert.AreEqual(new List {"a"}, _server.ISupport.ChanModes.ListModes); - CollectionAssert.AreEqual(new List {"b"}, _server.ISupport.ChanModes.SettingBModes); - CollectionAssert.AreEqual(new List {"c"}, _server.ISupport.ChanModes.SettingCModes); - CollectionAssert.AreEqual(new List {"d"}, _server.ISupport.ChanModes.SettingDModes); - } - - [TestMethod] - public void Prefix() - { - CollectionAssert.AreEqual(new List {"o", "v"}, _server.ISupport.Prefix.Modes); - CollectionAssert.AreEqual(new List {"@", "+"}, _server.ISupport.Prefix.Prefixes); - - Assert.AreEqual("@", _server.ISupport.Prefix.FromMode("o")); - Assert.IsNull(_server.ISupport.Prefix.FromMode("a")); - Assert.AreEqual("o", _server.ISupport.Prefix.FromPrefix("@")); - Assert.IsNull(_server.ISupport.Prefix.FromPrefix("&")); - - _server.Parse(new Line("005 * PREFIX=(qaohv)~&@%+ *")); - CollectionAssert.AreEqual(new List - { - "q", - "a", - "o", - "h", - "v" - }, _server.ISupport.Prefix.Modes); - CollectionAssert.AreEqual(new List - { - "~", - "&", - "@", - "%", - "+" - }, _server.ISupport.Prefix.Prefixes); - Assert.AreEqual("&", _server.ISupport.Prefix.FromMode("a")); - Assert.AreEqual("a", _server.ISupport.Prefix.FromPrefix("&")); - } - - [TestMethod] - public void ChanTypes() - { - CollectionAssert.AreEqual(new List {"#"}, _server.ISupport.ChanTypes); - _server.Parse(new Line("005 * CHANTYPES=#& *")); - CollectionAssert.AreEqual(new List {"#", "&"}, _server.ISupport.ChanTypes); - } - - [TestMethod] - public void Modes() - { - Assert.AreEqual(3, _server.ISupport.Modes); - - _server.Parse(new Line("005 * MODES *")); - Assert.AreEqual(-1, _server.ISupport.Modes); - - _server.Parse(new Line("005 * MODES=5 *")); - Assert.AreEqual(5, _server.ISupport.Modes); - } - - [TestMethod] - public void Rfc1459() - { - Assert.AreEqual(IRCStates.Casemap.CaseMapping.Rfc1459, _server.ISupport.CaseMapping); - _server.Parse(new Line("005 * CASEMAPPING=rfc1459 *")); - Assert.AreEqual(IRCStates.Casemap.CaseMapping.Rfc1459, _server.ISupport.CaseMapping); - var lower = _server.CaseFold(@"ÀTEST[]~\"); - Assert.AreEqual("Àtest{}^|", lower); - } - - [TestMethod] - public void Ascii() - { - _server.Parse(new Line("005 * CASEMAPPING=ascii *")); - Assert.AreEqual(IRCStates.Casemap.CaseMapping.Ascii, _server.ISupport.CaseMapping); - var lower = _server.CaseFold(@"ÀTEST[]~\"); - Assert.AreEqual(@"Àtest[]~\", lower); - } - - [TestMethod] - public void FallbackToRfc1459() - { - _server.Parse(new Line("005 * CASEMAPPING=nonexistent *")); - Assert.AreEqual(IRCStates.Casemap.CaseMapping.Rfc1459, _server.ISupport.CaseMapping); - var lower = _server.CaseFold(@"ÀTEST[]~\"); - Assert.AreEqual("Àtest{}^|", lower); - } - - [TestMethod] - public void Network() - { - Assert.IsNull(_server.ISupport.Network); - _server.Parse(new Line("005 * NETWORK=testnet *")); - Assert.AreEqual("testnet", _server.ISupport.Network); - } - - [TestMethod] - public void StatusMsg() - { - CollectionAssert.AreEqual(new List(), _server.ISupport.StatusMsg); - _server.Parse(new Line("005 * STATUSMSG=&@ *")); - CollectionAssert.AreEqual(new List {"&", "@"}, _server.ISupport.StatusMsg); - } - - [TestMethod] - public void CallerId() - { - Assert.IsNull(_server.ISupport.CallerId); - - _server.Parse(new Line("005 * CALLERID=U *")); - Assert.AreEqual("U", _server.ISupport.CallerId); - - _server.Parse(new Line("005 * CALLERID *")); - Assert.AreEqual("g", _server.ISupport.CallerId); - } - - [TestMethod] - public void Excepts() - { - Assert.IsNull(_server.ISupport.Excepts); - - _server.Parse(new Line("005 * EXCEPTS=U *")); - Assert.AreEqual("U", _server.ISupport.Excepts); - - _server.Parse(new Line("005 * EXCEPTS *")); - Assert.AreEqual("e", _server.ISupport.Excepts); - } - - [TestMethod] - public void Invex() - { - Assert.IsNull(_server.ISupport.Invex); - - _server.Parse(new Line("005 * INVEX=U *")); - Assert.AreEqual("U", _server.ISupport.Invex); - - _server.Parse(new Line("005 * INVEX *")); - Assert.AreEqual("I", _server.ISupport.Invex); - } - - [TestMethod] - public void Whox() - { - Assert.IsFalse(_server.ISupport.Whox); - - _server.Parse(new Line("005 * WHOX *")); - Assert.IsTrue(_server.ISupport.Whox); - } - - [TestMethod] - public void Monitor() - { - Assert.IsNull(_server.ISupport.Monitor); - - _server.Parse(new Line("005 * MONITOR=123 *")); - Assert.AreEqual(123, _server.ISupport.Monitor); - - _server.Parse(new Line("005 * MONITOR *")); - Assert.AreEqual(-1, _server.ISupport.Monitor); - } - - [TestMethod] - public void Watch() - { - Assert.IsNull(_server.ISupport.Watch); - - _server.Parse(new Line("005 * WATCH=123 *")); - Assert.AreEqual(123, _server.ISupport.Watch); - - _server.Parse(new Line("005 * WATCH *")); - Assert.AreEqual(-1, _server.ISupport.Watch); - } - } -} diff --git a/IRCStates/Tests/Mode.cs b/IRCStates/Tests/Mode.cs deleted file mode 100644 index 90763fa..0000000 --- a/IRCStates/Tests/Mode.cs +++ /dev/null @@ -1,179 +0,0 @@ -using System.Collections.Generic; -using IRCTokens; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace IRCStates.Tests -{ - [TestClass] - public class Mode - { - private Server _server; - - [TestInitialize] - public void TestInitialize() - { - _server = new Server("test"); - _server.Parse(new Line("001 nickname")); - } - - [TestMethod] - public void UModeAdd() - { - _server.Parse(new Line("MODE nickname +i")); - CollectionAssert.AreEqual(new List {"i"}, _server.Modes); - } - - [TestMethod] - public void UModeRemove() - { - _server.Parse(new Line("MODE nickname +i")); - _server.Parse(new Line("MODE nickname -i")); - CollectionAssert.AreEqual(new List(), _server.Modes); - } - - [TestMethod] - public void PrefixAdd() - { - _server.Parse(new Line(":nickname JOIN #chan")); - _server.Parse(new Line("MODE #chan +ov nickname nickname")); - - var user = _server.Users["nickname"]; - var channel = _server.Channels["#chan"]; - var channelUser = channel.Users[user.NickNameLower]; - CollectionAssert.AreEqual(new List {"o", "v"}, channelUser.Modes); - } - - [TestMethod] - public void PrefixRemove() - { - _server.Parse(new Line(":nickname JOIN #chan")); - _server.Parse(new Line("MODE #chan +ov nickname nickname")); - _server.Parse(new Line("MODE #chan -ov nickname nickname")); - - var user = _server.Users["nickname"]; - var channel = _server.Channels["#chan"]; - var channelUser = channel.Users[user.NickNameLower]; - CollectionAssert.AreEqual(new List(), channelUser.Modes); - } - - [TestMethod] - public void ChannelListAdd() - { - _server.Parse(new Line(":nickname JOIN #chan")); - _server.Parse(new Line("MODE #chan +b asd!*@*")); - - var channel = _server.Channels["#chan"]; - CollectionAssert.AreEqual(new List {"asd!*@*"}, channel.ListModes["b"]); - } - - [TestMethod] - public void ChannelListRemove() - { - _server.Parse(new Line(":nickname JOIN #chan")); - _server.Parse(new Line("MODE #chan +b asd!*@*")); - _server.Parse(new Line("MODE #chan -b asd!*@*")); - - var channel = _server.Channels["#chan"]; - CollectionAssert.AreEqual(new Dictionary>(), channel.ListModes); - } - - [TestMethod] - public void ChannelTypeBAdd() - { - _server.Parse(new Line(":nickname JOIN #chan")); - _server.Parse(new Line("MODE #chan +k password")); - - var channel = _server.Channels["#chan"]; - CollectionAssert.AreEqual(new Dictionary {{"k", "password"}}, channel.Modes); - } - - [TestMethod] - public void ChannelTypeBRemove() - { - _server.Parse(new Line(":nickname JOIN #chan")); - _server.Parse(new Line("MODE #chan +k password")); - _server.Parse(new Line("MODE #chan -k *")); - - var channel = _server.Channels["#chan"]; - CollectionAssert.AreEqual(new Dictionary(), channel.Modes); - } - - [TestMethod] - public void ChannelTypeCAdd() - { - _server.Parse(new Line(":nickname JOIN #chan")); - _server.Parse(new Line("MODE #chan +l 100")); - - var channel = _server.Channels["#chan"]; - CollectionAssert.AreEqual(new Dictionary {{"l", "100"}}, channel.Modes); - } - - [TestMethod] - public void ChannelTypeCRemove() - { - _server.Parse(new Line(":nickname JOIN #chan")); - _server.Parse(new Line("MODE #chan +l 100")); - _server.Parse(new Line("MODE #chan -l")); - - var channel = _server.Channels["#chan"]; - CollectionAssert.AreEqual(new Dictionary(), channel.Modes); - } - - [TestMethod] - public void ChannelTypeDAdd() - { - _server.Parse(new Line(":nickname JOIN #chan")); - _server.Parse(new Line("MODE #chan +i")); - - var channel = _server.Channels["#chan"]; - CollectionAssert.AreEqual(new Dictionary {{"i", null}}, channel.Modes); - } - - [TestMethod] - public void ChannelTypeDRemove() - { - _server.Parse(new Line(":nickname JOIN #chan")); - _server.Parse(new Line("MODE #chan +i")); - _server.Parse(new Line("MODE #chan -i")); - - var channel = _server.Channels["#chan"]; - CollectionAssert.AreEqual(new Dictionary(), channel.Modes); - } - - [TestMethod] - public void ChannelNumeric() - { - _server.Parse(new Line(":nickname JOIN #chan")); - _server.Parse(new Line("324 * #chan +bkli *!*@* pass 10")); - - var channel = _server.Channels["#chan"]; - CollectionAssert.AreEqual(new Dictionary {{"k", "pass"}, {"l", "10"}, {"i", null}}, - channel.Modes); - CollectionAssert.AreEqual(new List {"*!*@*"}, channel.ListModes["b"]); - } - - [TestMethod] - public void ChannelNumericWithoutPlus() - { - _server.Parse(new Line(":nickname JOIN #chan")); - _server.Parse(new Line("324 * #chan il 10")); - - var channel = _server.Channels["#chan"]; - CollectionAssert.AreEqual(new Dictionary {{"i", null}, {"l", "10"}}, channel.Modes); - } - - [TestMethod] - public void UserNumeric() - { - _server.Parse(new Line("221 * +iw")); - CollectionAssert.AreEqual(new List {"i", "w"}, _server.Modes); - } - - [TestMethod] - public void UserNumericWithoutPlus() - { - _server.Parse(new Line("221 * iw")); - CollectionAssert.AreEqual(new List {"i", "w"}, _server.Modes); - } - } -} diff --git a/IRCStates/Tests/Motd.cs b/IRCStates/Tests/Motd.cs deleted file mode 100644 index 2d75982..0000000 --- a/IRCStates/Tests/Motd.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System.Collections.Generic; -using IRCTokens; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace IRCStates.Tests -{ - [TestClass] - public class Motd - { - [TestMethod] - public void MessageOfTheDay() - { - var server = new Server("test"); - server.Parse(new Line("001 nickname")); - server.Parse(new Line("375 * :start of motd")); - server.Parse(new Line("372 * :first line of motd")); - server.Parse(new Line("372 * :second line of motd")); - - CollectionAssert.AreEqual(new List {"start of motd", "first line of motd", "second line of motd"}, - server.Motd); - } - } -} diff --git a/IRCStates/Tests/Sasl.cs b/IRCStates/Tests/Sasl.cs deleted file mode 100644 index 151ccdf..0000000 --- a/IRCStates/Tests/Sasl.cs +++ /dev/null @@ -1,38 +0,0 @@ -using IRCTokens; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace IRCStates.Tests -{ - [TestClass] - public class Sasl - { - private Server _server; - - [TestInitialize] - public void TestInitialize() - { - _server = new Server("test"); - _server.Parse(new Line("900 * nick!user@host account")); - } - - [TestMethod] - public void LoggedIn() - { - Assert.AreEqual("nick", _server.NickName); - Assert.AreEqual("user", _server.UserName); - Assert.AreEqual("host", _server.HostName); - Assert.AreEqual("account", _server.Account); - } - - [TestMethod] - public void LoggedOut() - { - _server.Parse(new Line("901 * nick1!user1@host1")); - - Assert.AreEqual("nick1", _server.NickName); - Assert.AreEqual("user1", _server.UserName); - Assert.AreEqual("host1", _server.HostName); - Assert.IsTrue(string.IsNullOrEmpty(_server.Account)); - } - } -} diff --git a/IRCStates/Tests/User.cs b/IRCStates/Tests/User.cs deleted file mode 100644 index 61d7157..0000000 --- a/IRCStates/Tests/User.cs +++ /dev/null @@ -1,298 +0,0 @@ -using IRCTokens; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace IRCStates.Tests -{ - [TestClass] - public class User - { - private Server _server; - - [TestInitialize] - public void TestInitialize() - { - _server = new Server("test"); - _server.Parse(new Line("001 nickname")); - } - - [TestMethod] - public void Welcome() - { - Assert.AreEqual("test", _server.Name); - Assert.AreEqual("nickname", _server.NickName); - } - - [TestMethod] - public void NicknameChange() - { - _server.Parse(new Line(":nickname NICK nickname2")); - Assert.AreEqual("nickname2", _server.NickName); - - _server.Parse(new Line(":nickname2 JOIN #chan")); - _server.Parse(new Line(":other JOIN #chan")); - Assert.IsTrue(_server.Users.ContainsKey("other")); - - _server.Parse(new Line(":other NICK other2")); - Assert.IsFalse(_server.Users.ContainsKey("other")); - Assert.IsTrue(_server.Users.ContainsKey("other2")); - } - - [TestMethod] - public void HostmaskJoinBoth() - { - _server.Parse(new Line(":nickname!user@host JOIN #chan")); - Assert.AreEqual("user", _server.UserName); - Assert.AreEqual("host", _server.HostName); - - _server.Parse(new Line(":other!user@host JOIN #chan")); - var user = _server.Users["other"]; - Assert.AreEqual("user", user.UserName); - Assert.AreEqual("host", user.HostName); - } - - [TestMethod] - public void HostmaskJoinUser() - { - _server.Parse(new Line(":nickname!user JOIN #chan")); - Assert.AreEqual("user", _server.UserName); - Assert.IsNull(_server.HostName); - - _server.Parse(new Line(":other!user JOIN #chan")); - var user = _server.Users["other"]; - Assert.AreEqual("user", user.UserName); - Assert.IsNull(user.HostName); - } - - [TestMethod] - public void HostmaskJoinHost() - { - _server.Parse(new Line(":nickname@host JOIN #chan")); - Assert.IsNull(_server.UserName); - Assert.AreEqual("host", _server.HostName); - - _server.Parse(new Line(":other@host JOIN #chan")); - var user = _server.Users["other"]; - Assert.IsNull(user.UserName); - Assert.AreEqual("host", user.HostName); - } - - [TestMethod] - public void ExtendedJoinWithoutExtendedJoin() - { - _server.Parse(new Line(":nickname JOIN #chan")); - Assert.IsNull(_server.Account); - Assert.IsNull(_server.RealName); - - _server.Parse(new Line(":other JOIN #chan")); - var user = _server.Users["other"]; - Assert.IsNull(user.Account); - Assert.IsNull(user.RealName); - } - - [TestMethod] - public void ExtendedJoinWithAccount() - { - _server.Parse(new Line(":nickname JOIN #chan acc :realname")); - Assert.AreEqual("acc", _server.Account); - Assert.AreEqual("realname", _server.RealName); - - _server.Parse(new Line(":other JOIN #chan acc2 :realname2")); - var user = _server.Users["other"]; - Assert.AreEqual("acc2", user.Account); - Assert.AreEqual("realname2", user.RealName); - } - - [TestMethod] - public void ExtendedJoinWithoutAccount() - { - _server.Parse(new Line(":nickname JOIN #chan * :realname")); - Assert.AreEqual("", _server.Account); - Assert.AreEqual("realname", _server.RealName); - - _server.Parse(new Line(":other JOIN #chan * :realname2")); - var user = _server.Users["other"]; - Assert.AreEqual("", user.Account); - Assert.AreEqual("realname2", user.RealName); - } - - [TestMethod] - public void AccountNotifyWithAccount() - { - _server.Parse(new Line(":nickname JOIN #chan")); - _server.Parse(new Line(":nickname ACCOUNT acc")); - Assert.AreEqual("acc", _server.Account); - - _server.Parse(new Line(":other JOIN #chan")); - _server.Parse(new Line(":other ACCOUNT acc2")); - var user = _server.Users["other"]; - Assert.AreEqual("acc2", user.Account); - } - - [TestMethod] - public void AccountNotifyWithoutAccount() - { - _server.Parse(new Line(":nickname JOIN #chan")); - _server.Parse(new Line(":nickname ACCOUNT *")); - Assert.AreEqual("", _server.Account); - - _server.Parse(new Line(":other JOIN #chan")); - _server.Parse(new Line(":other ACCOUNT *")); - var user = _server.Users["other"]; - Assert.AreEqual("", user.Account); - } - - [TestMethod] - public void HostmaskPrivmsgBoth() - { - _server.Parse(new Line(":nickname JOIN #chan")); - _server.Parse(new Line(":nickname!user@host PRIVMSG #chan :hi")); - Assert.AreEqual("user", _server.UserName); - Assert.AreEqual("host", _server.HostName); - - _server.Parse(new Line(":other!user@host PRIVMSG #chan :hi")); - var user = _server.Users["other"]; - Assert.AreEqual("user", user.UserName); - Assert.AreEqual("host", user.HostName); - } - - [TestMethod] - public void HostmaskPrivmsgUser() - { - _server.Parse(new Line(":nickname JOIN #chan")); - _server.Parse(new Line(":nickname!user PRIVMSG #chan :hi")); - Assert.AreEqual("user", _server.UserName); - Assert.IsNull(_server.HostName); - - _server.Parse(new Line(":other!user PRIVMSG #chan :hi")); - var user = _server.Users["other"]; - Assert.AreEqual("user", user.UserName); - Assert.IsNull(user.HostName); - } - - [TestMethod] - public void HostmaskPrivmsgHost() - { - _server.Parse(new Line(":nickname JOIN #chan")); - _server.Parse(new Line(":nickname@host PRIVMSG #chan :hi")); - Assert.IsNull(_server.UserName); - Assert.AreEqual("host", _server.HostName); - - _server.Parse(new Line(":other@host PRIVMSG #chan :hi")); - var user = _server.Users["other"]; - Assert.IsNull(user.UserName); - Assert.AreEqual("host", user.HostName); - } - - [TestMethod] - public void VisibleHostWithoutUsername() - { - _server.Parse(new Line("396 * hostname")); - Assert.IsNull(_server.UserName); - Assert.AreEqual("hostname", _server.HostName); - } - - [TestMethod] - public void VisibleHostWithUsername() - { - _server.Parse(new Line("396 * username@hostname")); - Assert.AreEqual("username", _server.UserName); - Assert.AreEqual("hostname", _server.HostName); - } - - [TestMethod] - public void Who() - { - _server.Parse(new Line(":nickname JOIN #chan")); - _server.Parse(new Line(":other JOIN #chan")); - _server.Parse(new Line("352 * #chan user host * nickname * :0 real")); - _server.Parse(new Line("352 * #chan user2 host2 * other * :0 real2")); - - Assert.AreEqual("user", _server.UserName); - Assert.AreEqual("host", _server.HostName); - Assert.AreEqual("real", _server.RealName); - - var user = _server.Users["other"]; - Assert.AreEqual("user2", user.UserName); - Assert.AreEqual("host2", user.HostName); - Assert.AreEqual("real2", user.RealName); - } - - [TestMethod] - public void Chghost() - { - _server.Parse(new Line(":nickname!user@host JOIN #chan")); - _server.Parse(new Line(":nickname CHGHOST u h")); - Assert.AreEqual("u", _server.UserName); - Assert.AreEqual("h", _server.HostName); - - _server.Parse(new Line(":other!user2@host2 JOIN #chan")); - _server.Parse(new Line(":other CHGHOST u2 h2")); - var user = _server.Users["other"]; - Assert.AreEqual("u2", user.UserName); - Assert.AreEqual("h2", user.HostName); - } - - [TestMethod] - public void Whois() - { - _server.Parse(new Line(":nickname JOIN #chan")); - _server.Parse(new Line("311 * nickname u h * :r")); - Assert.AreEqual("u", _server.UserName); - Assert.AreEqual("h", _server.HostName); - Assert.AreEqual("r", _server.RealName); - - _server.Parse(new Line(":other JOIN #chan")); - _server.Parse(new Line(":other CHGHOST u2 h2")); - _server.Parse(new Line("311 * other u2 h2 * :r2")); - var user = _server.Users["other"]; - Assert.AreEqual("u2", user.UserName); - Assert.AreEqual("h2", user.HostName); - Assert.AreEqual("r2", user.RealName); - } - - [TestMethod] - public void AwaySet() - { - _server.Parse(new Line(":nickname JOIN #chan")); - _server.Parse(new Line(":other JOIN #chan")); - var user = _server.Users["other"]; - Assert.IsNull(_server.Away); - Assert.IsNull(user.Away); - - _server.Parse(new Line(":nickname AWAY :bye bye")); - _server.Parse(new Line(":other AWAY :ich geh weg")); - Assert.AreEqual("bye bye", _server.Away); - Assert.AreEqual("ich geh weg", user.Away); - } - - [TestMethod] - public void AwayUnset() - { - _server.Parse(new Line(":nickname JOIN #chan")); - _server.Parse(new Line(":other JOIN #chan")); - _server.Parse(new Line(":nickname AWAY :bye bye")); - _server.Parse(new Line(":nickname AWAY")); - _server.Parse(new Line(":other AWAY :ich geh weg")); - _server.Parse(new Line(":other AWAY")); - - var user = _server.Users["other"]; - Assert.IsNull(_server.Away); - Assert.IsNull(user.Away); - } - - [TestMethod] - public void Setname() - { - _server.Parse(new Line(":nickname JOIN #chan")); - _server.Parse(new Line(":other JOIN #chan")); - var user = _server.Users["other"]; - Assert.IsNull(user.RealName); - Assert.IsNull(_server.RealName); - - _server.Parse(new Line(":nickname SETNAME :new now know how")); - _server.Parse(new Line(":other SETNAME :tyrannosaurus hex")); - Assert.AreEqual("new now know how", _server.RealName); - Assert.AreEqual("tyrannosaurus hex", user.RealName); - } - } -} diff --git a/IRCStates/Tests/Who.cs b/IRCStates/Tests/Who.cs deleted file mode 100644 index d091785..0000000 --- a/IRCStates/Tests/Who.cs +++ /dev/null @@ -1,61 +0,0 @@ -using IRCTokens; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace IRCStates.Tests -{ - [TestClass] - public class Who - { - private Server _server; - - [TestInitialize] - public void TestInitialize() - { - _server = new Server("test"); - _server.Parse(new Line("001 nickname")); - _server.Parse(new Line(":nickname JOIN #chan")); - } - - [TestMethod] - public void WhoResponse() - { - _server.Parse(new Line("352 * #chan user host server nickname * :0 real")); - var user = _server.Users["nickname"]; - - Assert.AreEqual("user", user.UserName); - Assert.AreEqual("host", _server.HostName); - Assert.AreEqual("real", user.RealName); - - Assert.AreEqual(user.UserName, _server.UserName); - Assert.AreEqual(user.HostName, _server.HostName); - Assert.AreEqual(user.RealName, _server.RealName); - } - - [TestMethod] - public void Whox() - { - _server.Parse(new Line($"354 * {Server.WhoType} user realip host nickname account :real")); - var user = _server.Users["nickname"]; - - Assert.AreEqual("user", user.UserName); - Assert.AreEqual("host", user.HostName); - Assert.AreEqual("real", user.RealName); - Assert.AreEqual("account", user.Account); - - Assert.AreEqual(user.UserName, _server.UserName); - Assert.AreEqual(user.HostName, _server.HostName); - Assert.AreEqual(user.RealName, _server.RealName); - Assert.AreEqual(user.Account, _server.Account); - } - - [TestMethod] - public void WhoxNoAccount() - { - _server.Parse(new Line($"354 * {Server.WhoType} user realip host nickname 0 :real")); - var user = _server.Users["nickname"]; - - Assert.IsNull(user.Account); - Assert.AreEqual(user.Account, _server.Account); - } - } -} diff --git a/IRCTokens/IRCTokens.csproj b/IRCTokens/IRCTokens.csproj index 7c927f2..f926041 100644 --- a/IRCTokens/IRCTokens.csproj +++ b/IRCTokens/IRCTokens.csproj @@ -3,7 +3,7 @@ net5.0 IRCTokens - 1.0.2 + 1.1.0 Ben Harris tildeverse.org true @@ -13,7 +13,7 @@ https://tildegit.org/irctokens/ircsharp/src/branch/main/IRCTokens git irc - 1.0.2 + 1.1.0 @@ -21,21 +21,8 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - PreserveNewest - - - PreserveNewest - diff --git a/IRCTokens/Tests/Data/JoinModel.cs b/IRCTokens/Tests/Data/JoinModel.cs deleted file mode 100644 index e54f4cf..0000000 --- a/IRCTokens/Tests/Data/JoinModel.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System.Collections.Generic; -using YamlDotNet.Serialization; - -namespace IRCTokens.Tests.Data -{ - public class JoinModel - { - public List Tests { get; set; } - - public class Test - { - [YamlMember(Alias = "desc")] public string Description { get; set; } - - public Atoms Atoms { get; set; } - - public List Matches { get; set; } - } - - public class Atoms - { - public Dictionary Tags { get; set; } - - public string Source { get; set; } - - public string Verb { get; set; } - - public List Params { get; set; } - } - } -} diff --git a/IRCTokens/Tests/Data/SplitModel.cs b/IRCTokens/Tests/Data/SplitModel.cs deleted file mode 100644 index 5386326..0000000 --- a/IRCTokens/Tests/Data/SplitModel.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.Collections.Generic; - -namespace IRCTokens.Tests.Data -{ - public class SplitModel - { - public List Tests { get; set; } - - public class Test - { - public string Input { get; set; } - public JoinModel.Atoms Atoms { get; set; } - } - } -} diff --git a/IRCTokens/Tests/Data/msg-join.yaml b/IRCTokens/Tests/Data/msg-join.yaml deleted file mode 100644 index d1d7429..0000000 --- a/IRCTokens/Tests/Data/msg-join.yaml +++ /dev/null @@ -1,221 +0,0 @@ -# IRC parser tests -# joining atoms into sendable messages - -# Written in 2015 by Daniel Oaks -# -# To the extent possible under law, the author(s) have dedicated all copyright -# and related and neighboring rights to this software to the public domain -# worldwide. This software is distributed without any warranty. -# -# You should have received a copy of the CC0 Public Domain Dedication along -# with this software. If not, see -# . - -# some of the tests here originate from grawity's test vectors, which is WTFPL v2 licensed -# https://github.com/grawity/code/tree/master/lib/tests -# some of the tests here originate from Mozilla's test vectors, which is public domain -# https://dxr.mozilla.org/comm-central/source/chat/protocols/irc/test/test_ircMessage.js -# some of the tests here originate from SaberUK's test vectors, which he's indicated I am free to include here -# https://github.com/SaberUK/ircparser/tree/master/test - -tests: - # the desc string holds a description of the test, if it exists - - # the atoms dict has the keys: - # * tags: tags dict - # tags with no value are an empty string - # * source: source string, without single leading colon - # * verb: verb string - # * params: params split up as a list - # if the params key does not exist, assume it is empty - # if any other keys do no exist, assume they are null - # a key that is null does not exist or is not specified with the - # given input string - - # matches is a list of messages that match - - # simple tests - - desc: Simple test with verb and params. - atoms: - verb: "foo" - params: - - "bar" - - "baz" - - "asdf" - matches: - - "foo bar baz asdf" - - "foo bar baz :asdf" - - # with no regular params - - desc: Simple test with source and no params. - atoms: - source: "src" - verb: "AWAY" - matches: - - ":src AWAY" - - - desc: Simple test with source and empty trailing param. - atoms: - source: "src" - verb: "AWAY" - params: - - "" - matches: - - ":src AWAY :" - - # with source - - desc: Simple test with source. - atoms: - source: "coolguy" - verb: "foo" - params: - - "bar" - - "baz" - - "asdf" - matches: - - ":coolguy foo bar baz asdf" - - ":coolguy foo bar baz :asdf" - - # with trailing param - - desc: Simple test with trailing param. - atoms: - verb: "foo" - params: - - "bar" - - "baz" - - "asdf quux" - matches: - - "foo bar baz :asdf quux" - - - desc: Simple test with empty trailing param. - atoms: - verb: "foo" - params: - - "bar" - - "baz" - - "" - matches: - - "foo bar baz :" - - - desc: Simple test with trailing param containing colon. - atoms: - verb: "foo" - params: - - "bar" - - "baz" - - ":asdf" - matches: - - "foo bar baz ::asdf" - - # with source and trailing param - - desc: Test with source and trailing param. - atoms: - source: "coolguy" - verb: "foo" - params: - - "bar" - - "baz" - - "asdf quux" - matches: - - ":coolguy foo bar baz :asdf quux" - - - desc: Test with trailing containing beginning+end whitespace. - atoms: - source: "coolguy" - verb: "foo" - params: - - "bar" - - "baz" - - " asdf quux " - matches: - - ":coolguy foo bar baz : asdf quux " - - - desc: Test with trailing containing what looks like another trailing param. - atoms: - source: "coolguy" - verb: "PRIVMSG" - params: - - "bar" - - "lol :) " - matches: - - ":coolguy PRIVMSG bar :lol :) " - - - desc: Simple test with source and empty trailing. - atoms: - source: "coolguy" - verb: "foo" - params: - - "bar" - - "baz" - - "" - matches: - - ":coolguy foo bar baz :" - - - desc: Trailing contains only spaces. - atoms: - source: "coolguy" - verb: "foo" - params: - - "bar" - - "baz" - - " " - matches: - - ":coolguy foo bar baz : " - - - desc: Param containing tab (tab is not considered SPACE for message splitting). - atoms: - source: "coolguy" - verb: "foo" - params: - - "b\tar" - - "baz" - matches: - - ":coolguy foo b\tar baz" - - ":coolguy foo b\tar :baz" - - # with tags - - desc: Tag with no value and space-filled trailing. - atoms: - tags: - "asd": "" - source: "coolguy" - verb: "foo" - params: - - "bar" - - "baz" - - " " - matches: - - "@asd :coolguy foo bar baz : " - - - desc: Tags with escaped values. - atoms: - verb: "foo" - tags: - "a": "b\\and\nk" - "d": "gh;764" - matches: - - "@a=b\\\\and\\nk;d=gh\\:764 foo" - - "@d=gh\\:764;a=b\\\\and\\nk foo" - - - desc: Tags with escaped values and params. - atoms: - verb: "foo" - tags: - "a": "b\\and\nk" - "d": "gh;764" - params: - - "par1" - - "par2" - matches: - - "@a=b\\\\and\\nk;d=gh\\:764 foo par1 par2" - - "@a=b\\\\and\\nk;d=gh\\:764 foo par1 :par2" - - "@d=gh\\:764;a=b\\\\and\\nk foo par1 par2" - - "@d=gh\\:764;a=b\\\\and\\nk foo par1 :par2" - - - desc: Tag with long, strange values (including LF and newline). - atoms: - tags: - foo: "\\\\;\\s \r\n" - verb: "COMMAND" - matches: - - "@foo=\\\\\\\\\\:\\\\s\\s\\r\\n COMMAND" diff --git a/IRCTokens/Tests/Data/msg-split.yaml b/IRCTokens/Tests/Data/msg-split.yaml deleted file mode 100644 index fa3f4aa..0000000 --- a/IRCTokens/Tests/Data/msg-split.yaml +++ /dev/null @@ -1,343 +0,0 @@ -# IRC parser tests -# splitting messages into usable atoms - -# Written in 2015 by Daniel Oaks -# -# To the extent possible under law, the author(s) have dedicated all copyright -# and related and neighboring rights to this software to the public domain -# worldwide. This software is distributed without any warranty. -# -# You should have received a copy of the CC0 Public Domain Dedication along -# with this software. If not, see -# . - -# some of the tests here originate from grawity's test vectors, which is WTFPL v2 licensed -# https://github.com/grawity/code/tree/master/lib/tests -# some of the tests here originate from Mozilla's test vectors, which is public domain -# https://dxr.mozilla.org/comm-central/source/chat/protocols/irc/test/test_ircMessage.js -# some of the tests here originate from SaberUK's test vectors, which he's indicated I am free to include here -# https://github.com/SaberUK/ircparser/tree/master/test - -# we follow RFC1459 with regards to multiple ascii spaces splitting atoms: -# The prefix, command, and all parameters are -# separated by one (or more) ASCII space character(s) (0x20). -# because doing it as RFC2812 says (strictly as a single ascii space) isn't sane - -tests: - # input is the string coming directly from the server to parse - - # the atoms dict has the keys: - # * tags: tags dict - # tags with no value are an empty string - # * source: source string, without single leading colon - # * verb: verb string - # * params: params split up as a list - # if the params key does not exist, assume it is empty - # if any other keys do no exist, assume they are null - # a key that is null does not exist or is not specified with the - # given input string - - # simple - - input: "foo bar baz asdf" - atoms: - verb: "foo" - params: - - "bar" - - "baz" - - "asdf" - - # with source - - input: ":coolguy foo bar baz asdf" - atoms: - source: "coolguy" - verb: "foo" - params: - - "bar" - - "baz" - - "asdf" - - # with trailing param - - input: "foo bar baz :asdf quux" - atoms: - verb: "foo" - params: - - "bar" - - "baz" - - "asdf quux" - - - input: "foo bar baz :" - atoms: - verb: "foo" - params: - - "bar" - - "baz" - - "" - - - input: "foo bar baz ::asdf" - atoms: - verb: "foo" - params: - - "bar" - - "baz" - - ":asdf" - - # with source and trailing param - - input: ":coolguy foo bar baz :asdf quux" - atoms: - source: "coolguy" - verb: "foo" - params: - - "bar" - - "baz" - - "asdf quux" - - - input: ":coolguy foo bar baz : asdf quux " - atoms: - source: "coolguy" - verb: "foo" - params: - - "bar" - - "baz" - - " asdf quux " - - - input: ":coolguy PRIVMSG bar :lol :) " - atoms: - source: "coolguy" - verb: "PRIVMSG" - params: - - "bar" - - "lol :) " - - - input: ":coolguy foo bar baz :" - atoms: - source: "coolguy" - verb: "foo" - params: - - "bar" - - "baz" - - "" - - - input: ":coolguy foo bar baz : " - atoms: - source: "coolguy" - verb: "foo" - params: - - "bar" - - "baz" - - " " - - # with tags - - input: "@a=b;c=32;k;rt=ql7 foo" - atoms: - verb: "foo" - tags: - "a": "b" - "c": "32" - "k": "" - "rt": "ql7" - - # with escaped tags - - input: "@a=b\\\\and\\nk;c=72\\s45;d=gh\\:764 foo" - atoms: - verb: "foo" - tags: - "a": "b\\and\nk" - "c": "72 45" - "d": "gh;764" - - # with tags and source - - input: "@c;h=;a=b :quux ab cd" - atoms: - tags: - "c": "" - "h": "" - "a": "b" - source: "quux" - verb: "ab" - params: - - "cd" - - # different forms of last param - - input: ":src JOIN #chan" - atoms: - source: "src" - verb: "JOIN" - params: - - "#chan" - - - input: ":src JOIN :#chan" - atoms: - source: "src" - verb: "JOIN" - params: - - "#chan" - - # with and without last param - - input: ":src AWAY" - atoms: - source: "src" - verb: "AWAY" - - - input: ":src AWAY " - atoms: - source: "src" - verb: "AWAY" - - # tab is not considered - - input: ":cool\tguy foo bar baz" - atoms: - source: "cool\tguy" - verb: "foo" - params: - - "bar" - - "baz" - - # with weird control codes in the source - - input: ":coolguy!ag@net\x035w\x03ork.admin PRIVMSG foo :bar baz" - atoms: - source: "coolguy!ag@net\x035w\x03ork.admin" - verb: "PRIVMSG" - params: - - "foo" - - "bar baz" - - - input: ":coolguy!~ag@n\x02et\x0305w\x0fork.admin PRIVMSG foo :bar baz" - atoms: - source: "coolguy!~ag@n\x02et\x0305w\x0fork.admin" - verb: "PRIVMSG" - params: - - "foo" - - "bar baz" - - - input: "@tag1=value1;tag2;vendor1/tag3=value2;vendor2/tag4= :irc.example.com COMMAND param1 param2 :param3 param3" - atoms: - tags: - tag1: "value1" - tag2: "" - vendor1/tag3: "value2" - vendor2/tag4: "" - source: "irc.example.com" - verb: "COMMAND" - params: - - "param1" - - "param2" - - "param3 param3" - - - input: ":irc.example.com COMMAND param1 param2 :param3 param3" - atoms: - source: "irc.example.com" - verb: "COMMAND" - params: - - "param1" - - "param2" - - "param3 param3" - - - input: "@tag1=value1;tag2;vendor1/tag3=value2;vendor2/tag4 COMMAND param1 param2 :param3 param3" - atoms: - tags: - tag1: "value1" - tag2: "" - vendor1/tag3: "value2" - vendor2/tag4: "" - verb: "COMMAND" - params: - - "param1" - - "param2" - - "param3 param3" - - - input: "COMMAND" - atoms: - verb: "COMMAND" - - # yaml encoding + slashes is fun - - input: "@foo=\\\\\\\\\\:\\\\s\\s\\r\\n COMMAND" - atoms: - tags: - foo: "\\\\;\\s \r\n" - verb: "COMMAND" - - # broken messages from unreal - - input: ":gravel.mozilla.org 432 #momo :Erroneous Nickname: Illegal characters" - atoms: - source: "gravel.mozilla.org" - verb: "432" - params: - - "#momo" - - "Erroneous Nickname: Illegal characters" - - - input: ":gravel.mozilla.org MODE #tckk +n " - atoms: - source: "gravel.mozilla.org" - verb: "MODE" - params: - - "#tckk" - - "+n" - - - input: ":services.esper.net MODE #foo-bar +o foobar " - atoms: - source: "services.esper.net" - verb: "MODE" - params: - - "#foo-bar" - - "+o" - - "foobar" - - # tag values should be parsed char-at-a-time to prevent wayward replacements. - - input: "@tag1=value\\\\ntest COMMAND" - atoms: - tags: - tag1: "value\\ntest" - verb: "COMMAND" - - # If a tag value has a slash followed by a character which doesn't need - # to be escaped, the slash should be dropped. - - input: "@tag1=value\\1 COMMAND" - atoms: - tags: - tag1: "value1" - verb: "COMMAND" - - # A slash at the end of a tag value should be dropped - - input: "@tag1=value1\\ COMMAND" - atoms: - tags: - tag1: "value1" - verb: "COMMAND" - - # Duplicate tags: Parsers SHOULD disregard all but the final occurence - - input: "@tag1=1;tag2=3;tag3=4;tag1=5 COMMAND" - atoms: - tags: - tag1: "5" - tag2: "3" - tag3: "4" - verb: "COMMAND" - - # vendored tags can have the same name as a non-vendored tag - - input: "@tag1=1;tag2=3;tag3=4;tag1=5;vendor/tag2=8 COMMAND" - atoms: - tags: - tag1: "5" - tag2: "3" - tag3: "4" - vendor/tag2: "8" - verb: "COMMAND" - - # Some parsers handle /MODE in a special way, make sure they do it right - - input: ":SomeOp MODE #channel :+i" - atoms: - source: "SomeOp" - verb: "MODE" - params: - - "#channel" - - "+i" - - - input: ":SomeOp MODE #channel +oo SomeUser :AnotherUser" - atoms: - source: "SomeOp" - verb: "MODE" - params: - - "#channel" - - "+oo" - - "SomeUser" - - "AnotherUser" diff --git a/IRCTokens/Tests/Format.cs b/IRCTokens/Tests/Format.cs deleted file mode 100644 index 7224f97..0000000 --- a/IRCTokens/Tests/Format.cs +++ /dev/null @@ -1,105 +0,0 @@ -using System; -using System.Collections.Generic; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace IRCTokens.Tests -{ - [TestClass] - public class Format - { - [TestMethod] - public void Tags() - { - var line = new Line("PRIVMSG", "#channel", "hello") - { - Tags = new Dictionary {{"id", "\\" + " " + ";" + "\r\n"}} - }.Format(); - - Assert.AreEqual("@id=\\\\\\s\\:\\r\\n PRIVMSG #channel hello", line); - } - - [TestMethod] - public void MissingTag() - { - var line = new Line("PRIVMSG", "#channel", "hello").Format(); - - Assert.AreEqual("PRIVMSG #channel hello", line); - } - - [TestMethod] - public void NullTag() - { - var line = new Line("PRIVMSG", "#channel", "hello") {Tags = new Dictionary {{"a", null}}} - .Format(); - - Assert.AreEqual("@a PRIVMSG #channel hello", line); - } - - [TestMethod] - public void EmptyTag() - { - var line = new Line("PRIVMSG", "#channel", "hello") {Tags = new Dictionary {{"a", ""}}} - .Format(); - - Assert.AreEqual("@a PRIVMSG #channel hello", line); - } - - [TestMethod] - public void Source() - { - var line = new Line("PRIVMSG", "#channel", "hello") {Source = "nick!user@host"}.Format(); - - Assert.AreEqual(":nick!user@host PRIVMSG #channel hello", line); - } - - [TestMethod] - public void CommandLowercase() - { - var line = new Line {Command = "privmsg"}.Format(); - Assert.AreEqual("privmsg", line); - } - - [TestMethod] - public void CommandUppercase() - { - var line = new Line {Command = "PRIVMSG"}.Format(); - Assert.AreEqual("PRIVMSG", line); - } - - [TestMethod] - public void TrailingSpace() - { - var line = new Line("PRIVMSG", "#channel", "hello world").Format(); - - Assert.AreEqual("PRIVMSG #channel :hello world", line); - } - - [TestMethod] - public void TrailingNoSpace() - { - var line = new Line("PRIVMSG", "#channel", "helloworld").Format(); - - Assert.AreEqual("PRIVMSG #channel helloworld", line); - } - - [TestMethod] - public void TrailingDoubleColon() - { - var line = new Line("PRIVMSG", "#channel", ":helloworld").Format(); - - Assert.AreEqual("PRIVMSG #channel ::helloworld", line); - } - - [TestMethod] - public void InvalidNonLastSpace() - { - Assert.ThrowsException(() => { new Line("USER", "user", "0 *", "real name").Format(); }); - } - - [TestMethod] - public void InvalidNonLastColon() - { - Assert.ThrowsException(() => { new Line("PRIVMSG", ":#channel", "hello").Format(); }); - } - } -} diff --git a/IRCTokens/Tests/Hostmask.cs b/IRCTokens/Tests/Hostmask.cs deleted file mode 100644 index 17c5ad7..0000000 --- a/IRCTokens/Tests/Hostmask.cs +++ /dev/null @@ -1,64 +0,0 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace IRCTokens.Tests -{ - [TestClass] - public class Hostmask - { - [TestMethod] - public void FullHostmask() - { - var hostmask = new IRCTokens.Hostmask("nick!user@host"); - Assert.AreEqual("nick", hostmask.NickName); - Assert.AreEqual("user", hostmask.UserName); - Assert.AreEqual("host", hostmask.HostName); - } - - [TestMethod] - public void NoHostName() - { - var hostmask = new IRCTokens.Hostmask("nick!user"); - Assert.AreEqual("nick", hostmask.NickName); - Assert.AreEqual("user", hostmask.UserName); - Assert.IsNull(hostmask.HostName); - } - - [TestMethod] - public void NoUserName() - { - var hostmask = new IRCTokens.Hostmask("nick@host"); - Assert.AreEqual("nick", hostmask.NickName); - Assert.IsNull(hostmask.UserName); - Assert.AreEqual("host", hostmask.HostName); - } - - [TestMethod] - public void OnlyNickName() - { - var hostmask = new IRCTokens.Hostmask("nick"); - Assert.AreEqual("nick", hostmask.NickName); - Assert.IsNull(hostmask.UserName); - Assert.IsNull(hostmask.HostName); - } - - [TestMethod] - public void HostmaskFromLine() - { - var line = new Line(":nick!user@host PRIVMSG #channel hello"); - var hostmask = new IRCTokens.Hostmask("nick!user@host"); - Assert.AreEqual(hostmask.ToString(), line.Hostmask.ToString()); - Assert.AreEqual("nick", line.Hostmask.NickName); - Assert.AreEqual("user", line.Hostmask.UserName); - Assert.AreEqual("host", line.Hostmask.HostName); - } - - [TestMethod] - public void EmptyHostmaskFromLine() - { - var line = new Line("PRIVMSG #channel hello"); - Assert.IsNull(line.Hostmask.HostName); - Assert.IsNull(line.Hostmask.UserName); - Assert.IsNull(line.Hostmask.NickName); - } - } -} diff --git a/IRCTokens/Tests/Parser.cs b/IRCTokens/Tests/Parser.cs deleted file mode 100644 index a560793..0000000 --- a/IRCTokens/Tests/Parser.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using IRCTokens.Tests.Data; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using YamlDotNet.Serialization; -using YamlDotNet.Serialization.NamingConventions; - -namespace IRCTokens.Tests -{ - [TestClass] - public class Parser - { - private static T LoadYaml(string path) - { - var deserializer = new DeserializerBuilder() - .WithNamingConvention(CamelCaseNamingConvention.Instance) - .Build(); - - return deserializer.Deserialize(File.ReadAllText(path)); - } - - [TestMethod] - public void Split() - { - foreach (var test in LoadYaml("Tests/Data/msg-split.yaml").Tests) - { - var tokens = new Line(test.Input); - var atoms = test.Atoms; - - Assert.AreEqual(atoms.Verb.ToUpper(CultureInfo.InvariantCulture), tokens.Command, - $"command failed on: '{test.Input}'"); - Assert.AreEqual(atoms.Source, tokens.Source, $"source failed on: '{test.Input}'"); - CollectionAssert.AreEqual(atoms.Tags, tokens.Tags, $"tags failed on: '{test.Input}'"); - CollectionAssert.AreEqual(atoms.Params ?? new List(), tokens.Params, - $"params failed on: '{test.Input}'"); - } - } - - [TestMethod] - public void Join() - { - foreach (var test in LoadYaml("Tests/Data/msg-join.yaml").Tests) - { - var atoms = test.Atoms; - var line = new Line - { - Command = atoms.Verb, Params = atoms.Params, Source = atoms.Source, Tags = atoms.Tags - }.Format(); - - Assert.IsTrue(test.Matches.Contains(line), test.Description); - } - } - } -} diff --git a/IRCTokens/Tests/StatefulDecoder.cs b/IRCTokens/Tests/StatefulDecoder.cs deleted file mode 100644 index 4da7690..0000000 --- a/IRCTokens/Tests/StatefulDecoder.cs +++ /dev/null @@ -1,88 +0,0 @@ -using System.Collections.Generic; -using System.Text; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace IRCTokens.Tests -{ - [TestClass] - public class StatefulDecoder - { - private IRCTokens.StatefulDecoder _decoder; - - [TestInitialize] - public void Initialize() - { - _decoder = new IRCTokens.StatefulDecoder(); - } - - [TestMethod] - public void Partial() - { - var lines = _decoder.Push("PRIVMSG "); - Assert.AreEqual(0, lines.Count); - - lines = _decoder.Push("#channel hello\r\n"); - Assert.AreEqual(1, lines.Count); - - var line = new Line("PRIVMSG #channel hello"); - CollectionAssert.AreEqual(new List {line}, lines); - } - - [TestMethod] - public void Multiple() - { - var lines = _decoder.Push("PRIVMSG #channel1 hello\r\nPRIVMSG #channel2 hello\r\n"); - Assert.AreEqual(2, lines.Count); - - var line1 = new Line("PRIVMSG #channel1 hello"); - var line2 = new Line("PRIVMSG #channel2 hello"); - Assert.AreEqual(line1, lines[0]); - Assert.AreEqual(line2, lines[1]); - } - - [TestMethod] - public void EncodingIso8859() - { - var iso8859 = Encoding.GetEncoding("iso-8859-1"); - _decoder = new IRCTokens.StatefulDecoder {Encoding = iso8859}; - var bytes = iso8859.GetBytes("PRIVMSG #channel :hello Ç\r\n"); - var lines = _decoder.Push(bytes, bytes.Length); - var line = new Line("PRIVMSG #channel :hello Ç"); - Assert.IsTrue(line.Equals(lines[0])); - } - - [TestMethod] - public void EncodingFallback() - { - var latin1 = Encoding.GetEncoding("iso-8859-1"); - _decoder = new IRCTokens.StatefulDecoder {Encoding = null, Fallback = latin1}; - var bytes = latin1.GetBytes("PRIVMSG #channel hélló\r\n"); - var lines = _decoder.Push(bytes, bytes.Length); - Assert.AreEqual(1, lines.Count); - Assert.IsTrue(new Line("PRIVMSG #channel hélló").Equals(lines[0])); - } - - [TestMethod] - public void Empty() - { - var lines = _decoder.Push(string.Empty); - Assert.AreEqual(0, lines.Count); - } - - [TestMethod] - public void BufferUnfinished() - { - _decoder.Push("PRIVMSG #channel hello"); - var lines = _decoder.Push(string.Empty); - Assert.AreEqual(0, lines.Count); - } - - [TestMethod] - public void Clear() - { - _decoder.Push("PRIVMSG "); - _decoder.Clear(); - Assert.AreEqual(string.Empty, _decoder.Pending); - } - } -} diff --git a/IRCTokens/Tests/StatefulEncoder.cs b/IRCTokens/Tests/StatefulEncoder.cs deleted file mode 100644 index d1e1e3e..0000000 --- a/IRCTokens/Tests/StatefulEncoder.cs +++ /dev/null @@ -1,84 +0,0 @@ -using System.Text; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace IRCTokens.Tests -{ - [TestClass] - public class StatefulEncoder - { - private IRCTokens.StatefulEncoder _encoder; - - [TestInitialize] - public void Initialize() - { - _encoder = new IRCTokens.StatefulEncoder(); - } - - [TestMethod] - public void Push() - { - var line = new Line("PRIVMSG #channel hello"); - _encoder.Push(line); - Assert.AreEqual("PRIVMSG #channel hello\r\n", _encoder.Pending()); - } - - [TestMethod] - public void PopPartial() - { - var line = new Line("PRIVMSG #channel hello"); - _encoder.Push(line); - _encoder.Pop("PRIVMSG #channel hello".Length); - Assert.AreEqual("\r\n", _encoder.Pending()); - } - - [TestMethod] - public void TestPopReturned() - { - var line = new Line("PRIVMSG #channel hello"); - _encoder.Push(line); - _encoder.Push(line); - var lines = _encoder.Pop("PRIVMSG #channel hello\r\n".Length); - Assert.AreEqual(1, lines.Count); - Assert.AreEqual(line, lines[0]); - } - - [TestMethod] - public void PopNoneReturned() - { - var line = new Line("PRIVMSG #channel hello"); - _encoder.Push(line); - var lines = _encoder.Pop(1); - Assert.AreEqual(0, lines.Count); - } - - [TestMethod] - public void PopMultipleLines() - { - var line1 = new Line("PRIVMSG #channel1 hello"); - _encoder.Push(line1); - var line2 = new Line("PRIVMSG #channel2 hello"); - _encoder.Push(line2); - - var lines = _encoder.Pop(_encoder.Pending().Length); - Assert.AreEqual(2, lines.Count); - Assert.AreEqual(string.Empty, _encoder.Pending()); - } - - [TestMethod] - public void Clear() - { - _encoder.Push(new Line("PRIVMSG #channel hello")); - _encoder.Clear(); - Assert.AreEqual(string.Empty, _encoder.Pending()); - } - - [TestMethod] - public void EncodingIso8859() - { - var iso8859 = Encoding.GetEncoding("iso-8859-1"); - _encoder = new IRCTokens.StatefulEncoder {Encoding = iso8859}; - _encoder.Push(new Line("PRIVMSG #channel :hello Ç")); - CollectionAssert.AreEqual(iso8859.GetBytes("PRIVMSG #channel :hello Ç\r\n"), _encoder.PendingBytes); - } - } -} diff --git a/IRCTokens/Tests/Tokenization.cs b/IRCTokens/Tests/Tokenization.cs deleted file mode 100644 index c4c5c5a..0000000 --- a/IRCTokens/Tests/Tokenization.cs +++ /dev/null @@ -1,133 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace IRCTokens.Tests -{ - [TestClass] - public class Tokenization - { - [TestMethod] - public void TagsMissing() - { - var line = new Line("PRIVMSG #channel"); - Assert.IsNull(line.Tags); - } - - [TestMethod] - public void TagsMissingValue() - { - var line = new Line("@id= PRIVMSG #channel"); - Assert.AreEqual(string.Empty, line.Tags["id"]); - } - - [TestMethod] - public void TagsMissingEqual() - { - var line = new Line("@id PRIVMSG #channel"); - Assert.AreEqual(string.Empty, line.Tags["id"]); - } - - [TestMethod] - public void TagsUnescape() - { - var line = new Line(@"@id=1\\\:\r\n\s2 PRIVMSG #channel"); - Assert.AreEqual("1\\;\r\n 2", line.Tags["id"]); - } - - [TestMethod] - public void TagsOverlap() - { - var line = new Line(@"@id=1\\\s\\s PRIVMSG #channel"); - Assert.AreEqual("1\\ \\s", line.Tags["id"]); - } - - [TestMethod] - public void TagsLoneEndSlash() - { - var line = new Line("@id=1\\ PRIVMSG #channel"); - Assert.AreEqual("1", line.Tags["id"]); - } - - [TestMethod] - public void SourceWithoutTags() - { - var line = new Line(":nick!user@host PRIVMSG #channel"); - Assert.AreEqual("nick!user@host", line.Source); - } - - [TestMethod] - public void SourceWithTags() - { - var line = new Line("@id=123 :nick!user@host PRIVMSG #channel"); - Assert.AreEqual("nick!user@host", line.Source); - } - - [TestMethod] - public void SourceMissingWithoutTags() - { - var line = new Line("PRIVMSG #channel"); - Assert.IsNull(line.Source); - } - - [TestMethod] - public void SourceMissingWithTags() - { - var line = new Line("@id=123 PRIVMSG #channel"); - Assert.IsNull(line.Source); - } - - [TestMethod] - public void Command() - { - var line = new Line("privmsg #channel"); - Assert.AreEqual("PRIVMSG", line.Command); - } - - [TestMethod] - public void ParamsTrailing() - { - var line = new Line("PRIVMSG #channel :hello world"); - CollectionAssert.AreEqual(new List {"#channel", "hello world"}, line.Params); - } - - [TestMethod] - public void ParamsOnlyTrailing() - { - var line = new Line("PRIVMSG :hello world"); - CollectionAssert.AreEqual(new List {"hello world"}, line.Params); - } - - [TestMethod] - public void ParamsMissing() - { - var line = new Line("PRIVMSG"); - Assert.AreEqual("PRIVMSG", line.Command); - CollectionAssert.AreEqual(new List(), line.Params); - } - - [TestMethod] - public void AllTokens() - { - var line = new Line("@id=123 :nick!user@host PRIVMSG #channel :hello world"); - CollectionAssert.AreEqual(new Dictionary {{"id", "123"}}, line.Tags); - Assert.AreEqual("nick!user@host", line.Source); - Assert.AreEqual("PRIVMSG", line.Command); - CollectionAssert.AreEqual(new List {"#channel", "hello world"}, line.Params); - } - - [TestMethod] - public void NulByte() - { - var decoder = new IRCTokens.StatefulDecoder(); - var bytes = Encoding.UTF8.GetBytes(":nick!user@host PRIVMSG #channel :hello") - .Concat(Encoding.UTF8.GetBytes("\0")) - .Concat(Encoding.UTF8.GetBytes("world")) - .ToArray(); - var line = decoder.Push(bytes, bytes.Length).First(); - - CollectionAssert.AreEqual(new List {"#channel", "hello"}, line.Params); - } - } -} -- cgit 1.4.1