Killed history

This commit is contained in:
Kwoth
2021-09-06 21:29:22 +02:00
commit 7aca29ae8a
950 changed files with 366651 additions and 0 deletions

View File

@@ -0,0 +1,129 @@
using NUnit.Framework;
using System.Globalization;
using System.Linq;
using System.Reflection;
using AngleSharp.Common;
using Discord.Commands;
using NadekoBot.Common.Attributes;
using NadekoBot.Core.Services;
using NadekoBot.Modules;
using YamlDotNet.Serialization;
namespace Nadeko.Tests
{
public class CommandStringsTests
{
private const string responsesPath = "../../../../src/NadekoBot/data/strings/responses";
private const string commandsPath = "../../../../src/NadekoBot/data/strings/commands";
private const string aliasesPath = "../../../../src/NadekoBot/data/aliases.yml";
[Test]
public void AllCommandNamesHaveStrings()
{
var stringsSource = new LocalFileStringsSource(
responsesPath,
commandsPath);
var strings = new LocalBotStringsProvider(stringsSource);
var culture = new CultureInfo("en-US");
var isSuccess = true;
foreach (var entry in CommandNameLoadHelper.LoadCommandNames(aliasesPath))
{
var commandName = entry.Value[0];
var cmdStrings = strings.GetCommandStrings(culture.Name, commandName);
if (cmdStrings is null)
{
isSuccess = false;
TestContext.Out.WriteLine($"{commandName} doesn't exist in commands.en-US.yml");
}
}
Assert.IsTrue(isSuccess);
}
private static string[] GetCommandMethodNames()
=> typeof(NadekoBot.NadekoBot).Assembly
.GetExportedTypes()
.Where(type => type.IsClass && !type.IsAbstract)
.Where(type => typeof(NadekoModule).IsAssignableFrom(type) // if its a top level module
|| !(type.GetCustomAttribute<GroupAttribute>(true) is null)) // or a submodule
.SelectMany(x => x.GetMethods()
.Where(mi => mi.CustomAttributes
.Any(ca => ca.AttributeType == typeof(NadekoCommandAttribute))))
.Select(x => x.Name.ToLowerInvariant())
.ToArray();
[Test]
public void AllCommandMethodsHaveNames()
{
var allAliases = CommandNameLoadHelper.LoadCommandNames(
aliasesPath);
var methodNames = GetCommandMethodNames();
var isSuccess = true;
foreach (var methodName in methodNames)
{
if (!allAliases.TryGetValue(methodName, out var _))
{
TestContext.Error.WriteLine($"{methodName} is missing an alias.");
isSuccess = false;
}
}
Assert.IsTrue(isSuccess);
}
[Test]
public void NoObsoleteAliases()
{
var allAliases = CommandNameLoadHelper.LoadCommandNames(aliasesPath);
var methodNames = GetCommandMethodNames()
.ToHashSet();
var isSuccess = true;
foreach (var item in allAliases)
{
var methodName = item.Key;
if (!methodNames.Contains(methodName))
{
TestContext.WriteLine($"'{methodName}' from aliases.yml doesn't have a matching command method.");
isSuccess = false;
}
}
Assert.IsTrue(isSuccess);
}
// [Test]
// public void NoObsoleteCommandStrings()
// {
// var stringsSource = new LocalFileStringsSource(responsesPath, commandsPath);
//
// var culture = new CultureInfo("en-US");
//
// var isSuccess = true;
// var allCommandNames = CommandNameLoadHelper.LoadCommandNames(aliasesPath);
// var enUsCommandNames = allCommandNames
// .Select(x => x.Value[0]) // first alias is command name
// .ToHashSet();
// foreach (var entry in stringsSource.GetCommandStrings()[culture.Name])
// {
// // key is command name which should be specified in aliases[0] of any method name
// var cmdName = entry.Key;
//
// if (!enUsCommandNames.Contains(cmdName))
// {
// TestContext.Out.WriteLine($"'{cmdName}' It's either obsolete or missing an alias entry.");
// isSuccess = false;
// }
// }
//
// Assert.IsTrue(isSuccess);
// }
}
}

View File

@@ -0,0 +1,79 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using NadekoBot.Core.Services;
using NUnit.Framework;
namespace Nadeko.Tests
{
public class GroupGreetTests
{
private GreetGrouper<int> _grouper;
[SetUp]
public void Setup()
{
_grouper = new GreetGrouper<int>();
}
[Test]
public void CreateTest()
{
var created = _grouper.CreateOrAdd(0, 5);
Assert.True(created);
}
[Test]
public void CreateClearTest()
{
_grouper.CreateOrAdd(0, 5);
_grouper.ClearGroup(0, 5, out var items);
Assert.AreEqual(0, items.Count());
}
[Test]
public void NotCreatedTest()
{
_grouper.CreateOrAdd(0, 5);
var created = _grouper.CreateOrAdd(0, 4);
Assert.False(created);
}
[Test]
public void ClearAddedTest()
{
_grouper.CreateOrAdd(0, 5);
_grouper.CreateOrAdd(0, 4);
_grouper.ClearGroup(0, 5, out var items);
var list = items.ToList();
Assert.AreEqual(1, list.Count, $"Count was {list.Count}");
Assert.AreEqual(4, list[0]);
}
[Test]
public async Task ClearManyTest()
{
_grouper.CreateOrAdd(0, 5);
// add 15 items
await Task.WhenAll(Enumerable.Range(10, 15)
.Select(x => Task.Run(() => _grouper.CreateOrAdd(0, x))));
// get 5 at most
_grouper.ClearGroup(0, 5, out var items);
var list = items.ToList();
Assert.AreEqual(5, list.Count, $"Count was {list.Count}");
// try to get 15, but there should be 10 left
_grouper.ClearGroup(0, 15, out items);
list = items.ToList();
Assert.AreEqual(10, list.Count, $"Count was {list.Count}");
}
}
}

View File

@@ -0,0 +1,185 @@
using NadekoBot.Common.Collections;
using NadekoBot.Core.Services.Database.Models;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Nadeko.Tests
{
public class IndexedCollectionTests
{
[Test]
public void AddTest()
{
var collection = GetCollectionSample(Enumerable.Empty<ShopEntry>());
// Add the items
for (var counter = 0; counter < 10; counter++)
collection.Add(new ShopEntry());
// Evaluate the items are ordered
CheckIndices(collection);
}
[Test]
public void RemoveTest()
{
var collection = GetCollectionSample<ShopEntry>();
collection.Remove(collection[1]);
collection.Remove(collection[1]);
// Evaluate the indices are ordered
CheckIndices(collection);
Assert.AreEqual(8, collection.Count);
}
[Test]
public void RemoveAtTest()
{
var collection = GetCollectionSample<ShopEntry>();
// Remove items 5 and 7
collection.RemoveAt(5);
collection.RemoveAt(6);
// Evaluate if the items got removed
foreach (var item in collection)
Assert.IsFalse(item.Id == 5 || item.Id == 7, $"Item at index {item.Index} was not removed");
CheckIndices(collection);
// RemoveAt out of range
Assert.Throws<ArgumentOutOfRangeException>(() => collection.RemoveAt(999), $"No exception thrown when removing from index 999 in a collection of size {collection.Count}.");
Assert.Throws<ArgumentOutOfRangeException>(() => collection.RemoveAt(-3), $"No exception thrown when removing from negative index -3.");
}
[Test]
public void ClearTest()
{
var collection = GetCollectionSample<ShopEntry>();
collection.Clear();
Assert.IsTrue(collection.Count == 0, "Collection has not been cleared.");
Assert.Throws<ArgumentOutOfRangeException>(() => collection.Contains(collection[0]), "Collection has not been cleared.");
}
[Test]
public void CopyToTest()
{
var collection = GetCollectionSample<ShopEntry>();
var fullCopy = new ShopEntry[10];
collection.CopyTo(fullCopy, 0);
// Evaluate copy
for (var index = 0; index < fullCopy.Length; index++)
Assert.AreEqual(index, fullCopy[index].Index);
Assert.Throws<ArgumentException>(() => collection.CopyTo(new ShopEntry[10], 4));
Assert.Throws<ArgumentException>(() => collection.CopyTo(new ShopEntry[6], 0));
}
[Test]
public void IndexOfTest()
{
var collection = GetCollectionSample<ShopEntry>();
Assert.AreEqual(4, collection.IndexOf(collection[4]));
Assert.AreEqual(0, collection.IndexOf(collection[0]));
Assert.AreEqual(7, collection.IndexOf(collection[7]));
Assert.AreEqual(9, collection.IndexOf(collection[9]));
}
[Test]
public void InsertTest()
{
var collection = GetCollectionSample<ShopEntry>();
// Insert items at indices 5 and 7
collection.Insert(5, new ShopEntry() { Id = 555 });
collection.Insert(7, new ShopEntry() { Id = 777 });
Assert.AreEqual(12, collection.Count);
Assert.AreEqual(555, collection[5].Id);
Assert.AreEqual(777, collection[7].Id);
CheckIndices(collection);
// Insert out of range
Assert.Throws<ArgumentOutOfRangeException>(() => collection.Insert(999, new ShopEntry() { Id = 999 }), $"No exception thrown when inserting at index 999 in a collection of size {collection.Count}.");
Assert.Throws<ArgumentOutOfRangeException>(() => collection.Insert(-3, new ShopEntry() { Id = -3 }), $"No exception thrown when inserting at negative index -3.");
}
[Test]
public void ContainsTest()
{
var subCol = new ShopEntry[]
{
new ShopEntry() { Id = 111 },
new ShopEntry() { Id = 222 },
new ShopEntry() { Id = 333 }
};
var collection = GetCollectionSample(
Enumerable.Range(0, 10)
.Select(x => new ShopEntry() { Id = x })
.Concat(subCol)
);
collection.Remove(subCol[1]);
CheckIndices(collection);
Assert.IsTrue(collection.Contains(subCol[0]));
Assert.IsFalse(collection.Contains(subCol[1]));
Assert.IsTrue(collection.Contains(subCol[2]));
}
[Test]
public void EnumeratorTest()
{
var collection = GetCollectionSample<ShopEntry>();
var enumerator = collection.GetEnumerator();
foreach (var item in collection)
{
enumerator.MoveNext();
Assert.AreEqual(item, enumerator.Current);
}
}
[Test]
public void IndexTest()
{
var collection = GetCollectionSample<ShopEntry>();
collection[4] = new ShopEntry() { Id = 444 };
collection[7] = new ShopEntry() { Id = 777 };
CheckIndices(collection);
Assert.AreEqual(444, collection[4].Id);
Assert.AreEqual(777, collection[7].Id);
}
/// <summary>
/// Checks whether all indices of the items are properly ordered.
/// </summary>
/// <typeparam name="T">An indexed, reference type.</typeparam>
/// <param name="collection">The indexed collection to be checked.</param>
private void CheckIndices<T>(IndexedCollection<T> collection) where T : class, IIndexed
{
for (var index = 0; index < collection.Count; index++)
Assert.AreEqual(index, collection[index].Index);
}
/// <summary>
/// Gets an <see cref="IndexedCollection{T}"/> from the specified <paramref name="sample"/> or a collection with 10 shop entries if none is provided.
/// </summary>
/// <typeparam name="T">An indexed, database entity type.</typeparam>
/// <param name="sample">A sample collection to be added as an indexed collection.</param>
/// <returns>An indexed collection of <typeparamref name="T"/>.</returns>
private IndexedCollection<T> GetCollectionSample<T>(IEnumerable<T> sample = default) where T : DbEntity, IIndexed, new()
=> new IndexedCollection<T>(sample ?? Enumerable.Range(0, 10).Select(x => new T() { Id = x }));
}
}

125
Nadeko.Tests/KwumTests.cs Normal file
View File

@@ -0,0 +1,125 @@
using System.Linq;
using NadekoBot.Core.Common;
using NUnit.Framework;
namespace Nadeko.Tests
{
public class KwumTests
{
[Test]
public void TestDefaultHashCode()
{
var num = default(kwum);
Assert.AreEqual(0, num.GetHashCode());
}
[Test]
public void TestEqualGetHashCode()
{
var num1 = new kwum("234");
var num2 = new kwum("234");
Assert.AreEqual(num1.GetHashCode(), num2.GetHashCode());
}
[Test]
public void TestNotEqualGetHashCode()
{
var num1 = new kwum("234");
var num2 = new kwum("235");
Assert.AreNotEqual(num1.GetHashCode(), num2.GetHashCode());
}
[Test]
public void TestLongEqualGetHashCode()
{
var num1 = new kwum("hgbkhdbk");
var num2 = new kwum("hgbkhdbk");
Assert.AreEqual(num1.GetHashCode(), num2.GetHashCode());
}
[Test]
public void TestEqual()
{
var num1 = new kwum("hgbkhd");
var num2 = new kwum("hgbkhd");
Assert.AreEqual(num1, num2);
}
[Test]
public void TestNotEqual()
{
var num1 = new kwum("hgbk5d");
var num2 = new kwum("hgbk4d");
Assert.AreNotEqual(num1, num2);
}
[Test]
public void TestParseValidValue()
{
var validValue = "234e";
Assert.True(kwum.TryParse(validValue, out _));
}
[Test]
public void TestParseInvalidValue()
{
var invalidValue = "1234";
Assert.False(kwum.TryParse(invalidValue, out _));
}
[Test]
public void TestCorrectParseValue()
{
var validValue = "qwerf4bm";
kwum.TryParse(validValue, out var parsedValue);
Assert.AreEqual(parsedValue, new kwum(validValue));
}
[Test]
public void TestToString()
{
var validValue = "46g5yh";
kwum.TryParse(validValue, out var parsedValue);
Assert.AreEqual(validValue, parsedValue.ToString());
}
[Test]
public void TestConversionsToFromInt()
{
var num = new kwum(10);
Assert.AreEqual(10, (int)num);
Assert.AreEqual(num, (kwum)10);
}
[Test]
public void TestConverstionsToString()
{
var num = new kwum(10);
Assert.AreEqual("c", num.ToString());
num = new kwum(123);
Assert.AreEqual("5v", num.ToString());
// leading zeros have no meaning
Assert.AreEqual(new kwum("22225v"), num);
}
[Test]
public void TestMaxValue()
{
var num = new kwum(int.MaxValue - 1);
Assert.AreEqual("3zzzzzy", num.ToString());
num = new kwum(int.MaxValue);
Assert.AreEqual("3zzzzzz", num.ToString());
}
}
}

View File

@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<LangVersion>9.0</LangVersion>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.16.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NadekoBot.Core\NadekoBot.Core.csproj" />
</ItemGroup>
</Project>

136
Nadeko.Tests/PubSubTests.cs Normal file
View File

@@ -0,0 +1,136 @@
using System.Threading.Tasks;
using NadekoBot.Core.Common;
using NUnit.Framework;
using NUnit.Framework.Internal;
namespace Nadeko.Tests
{
public class PubSubTests
{
[Test]
public async Task Test_EventPubSub_PubSub()
{
TypedKey<int> key = "test_key";
var expected = new Randomizer().Next();
var pubsub = new EventPubSub();
await pubsub.Sub(key, data =>
{
Assert.AreEqual(expected, data);
Assert.Pass();
return default;
});
await pubsub.Pub(key, expected);
Assert.Fail("Event not registered");
}
[Test]
public async Task Test_EventPubSub_MeaninglessUnsub()
{
TypedKey<int> key = "test_key";
var expected = new Randomizer().Next();
var pubsub = new EventPubSub();
await pubsub.Sub(key, data =>
{
Assert.AreEqual(expected, data);
Assert.Pass();
return default;
});
await pubsub.Unsub(key, _ => default);
await pubsub.Pub(key, expected);
Assert.Fail("Event not registered");
}
[Test]
public async Task Test_EventPubSub_MeaninglessUnsubThatLooksTheSame()
{
TypedKey<int> key = "test_key";
var expected = new Randomizer().Next();
var pubsub = new EventPubSub();
await pubsub.Sub(key, data =>
{
Assert.AreEqual(expected, data);
Assert.Pass();
return default;
});
await pubsub.Unsub(key, data =>
{
Assert.AreEqual(expected, data);
Assert.Pass();
return default;
});
await pubsub.Pub(key, expected);
Assert.Fail("Event not registered");
}
[Test]
public async Task Test_EventPubSub_MeaningfullUnsub()
{
TypedKey<int> key = "test_key";
var pubsub = new EventPubSub();
ValueTask Action(int data)
{
Assert.Fail("Event is raised when it shouldn't be");
return default;
}
await pubsub.Sub(key, Action);
await pubsub.Unsub(key, Action);
await pubsub.Pub(key, 0);
Assert.Pass();
}
[Test]
public async Task Test_EventPubSub_ObjectData()
{
TypedKey<byte[]> key = "test_key";
var pubsub = new EventPubSub();
var localData = new byte[1];
ValueTask Action(byte[] data)
{
Assert.AreEqual(localData, data);
Assert.Pass();
return default;
}
await pubsub.Sub(key, Action);
await pubsub.Pub(key, localData);
Assert.Fail("Event not raised");
}
[Test]
public async Task Test_EventPubSub_MultiSubUnsub()
{
TypedKey<object> key = "test_key";
var pubsub = new EventPubSub();
var localData = new object();
int successCounter = 0;
ValueTask Action1(object data)
{
Assert.AreEqual(localData, data);
successCounter+=10;
return default;
}
ValueTask Action2(object data)
{
Assert.AreEqual(localData, data);
successCounter++;
return default;
}
await pubsub.Sub(key, Action1); // + 10 \
await pubsub.Sub(key, Action2); // + 1 - + = 12
await pubsub.Sub(key, Action2); // + 1 /
await pubsub.Unsub(key, Action2); // - 1/
await pubsub.Pub(key, localData);
Assert.AreEqual(successCounter, 11, "Not all events are raised.");
}
}
}

25
Nadeko.Tests/Random.cs Normal file
View File

@@ -0,0 +1,25 @@
using System;
using System.Text;
using NadekoBot.Common.Yml;
using NUnit.Framework;
namespace Nadeko.Tests
{
public class RandomTests
{
[SetUp]
public void Setup()
{
Console.OutputEncoding = Encoding.UTF8;
}
[Test]
public void Utf8CodepointsToEmoji()
{
var point = @"0001F338";
var hopefullyEmoji = YamlHelper.UnescapeUnicodeCodePoint(point);
Assert.AreEqual("🌸", hopefullyEmoji, hopefullyEmoji);
}
}
}