IRC parsing, tokenization, and state handling in C#
at ircrobotsv2 88 lines 2.9 kB view raw
1using YamlDotNet.Serialization; 2using YamlDotNet.Serialization.NamingConventions; 3 4// ReSharper disable CollectionNeverUpdated.Global 5// ReSharper disable ClassNeverInstantiated.Global 6 7namespace IRCSharp.Tests.Tokenization; 8 9public class Parser 10{ 11 [Test] 12 [YamlDataGenerator<TestCase>("Tokenization/Data/msg-split.yaml")] 13 [ArgumentDisplayFormatter<TestCase>] 14 public async Task Split(TestCase test) 15 { 16 var atoms = test.Atoms; 17 var line = new Line(test.Input); 18 19 await Assert.That(line.Command).IsEqualTo(atoms.Verb.ToUpperInvariant()) 20 .Because($"command failed on: '{test.Input}'"); 21 22 await Assert.That(line.Source).IsEqualTo(atoms.Source) 23 .Because($"source failed on: '{test.Input}'"); 24 25 await Assert.That(line.Params).IsEquivalentTo(atoms.Params ?? []) 26 .Because($"params failed on: '{test.Input}'"); 27 28 if (atoms.Tags is null) 29 { 30 await Assert.That(line.Tags).IsNull() 31 .Because("tags should be null"); 32 } 33 else 34 { 35 await Assert.That(line.Tags).IsEquivalentTo(atoms.Tags) 36 .Because($"tags failed on: '{test.Input}'"); 37 } 38 } 39 40 [Test] 41 [YamlDataGenerator<TestCase>("Tokenization/Data/msg-join.yaml")] 42 [ArgumentDisplayFormatter<TestCase>] 43 public async Task Join(TestCase test) 44 { 45 var atoms = test.Atoms; 46 var line = new Line { Command = atoms.Verb, Params = atoms.Params, Source = atoms.Source, Tags = atoms.Tags }; 47 48 await Assert.That(test.Matches).Contains(line.Format()).Because(test.Description); 49 } 50} 51 52public class YamlDataGeneratorAttribute<T>(string yamlPath) : AsyncDataSourceGeneratorAttribute<T> 53 where T : class 54{ 55 private readonly IDeserializer _deserializer = new DeserializerBuilder() 56 .WithNamingConvention(CamelCaseNamingConvention.Instance) 57 .Build(); 58 59 protected override async IAsyncEnumerable<Func<Task<T>>> GenerateDataSourcesAsync( 60 DataGeneratorMetadata dataGeneratorMetadata) 61 { 62 foreach (var item in _deserializer.Deserialize<List<T>>(await File.ReadAllTextAsync(yamlPath))) 63 yield return () => Task.FromResult(item); 64 } 65} 66 67public class TestCase : ArgumentDisplayFormatter 68{ 69 [YamlMember(Alias = "desc")] 70 public string Description { get; set; } 71 public Atoms Atoms { get; set; } 72 public List<string> Matches { get; set; } 73 public string Input { get; set; } 74 public override bool CanHandle(object value) => value is TestCase; 75 public override string FormatValue(object value) 76 { 77 var testCase = (TestCase)value!; 78 return testCase.Input ?? testCase.Description; 79 } 80} 81 82public class Atoms 83{ 84 public Dictionary<string, string> Tags { get; set; } 85 public string Source { get; set; } 86 public string Verb { get; set; } 87 public List<string> Params { get; set; } 88}