|
| 1 | +using System.Text.Json.Serialization; |
| 2 | +using NUnit.Framework; |
| 3 | +using Tomlyn.Serialization; |
| 4 | + |
| 5 | +namespace Tomlyn.Tests; |
| 6 | + |
| 7 | +public class NewApiPolymorphismTests |
| 8 | +{ |
| 9 | + [TomlPolymorphic(TypeDiscriminatorPropertyName = "kind")] |
| 10 | + [TomlDerivedType(typeof(Cat), "cat")] |
| 11 | + [TomlDerivedType(typeof(Dog), "dog")] |
| 12 | + private abstract class Animal |
| 13 | + { |
| 14 | + public string? Name { get; set; } |
| 15 | + } |
| 16 | + |
| 17 | + private sealed class Cat : Animal |
| 18 | + { |
| 19 | + public int Lives { get; set; } |
| 20 | + } |
| 21 | + |
| 22 | + private sealed class Dog : Animal |
| 23 | + { |
| 24 | + public bool GoodBoy { get; set; } |
| 25 | + } |
| 26 | + |
| 27 | + [Test] |
| 28 | + public void Serialize_Polymorphic_WritesDiscriminator() |
| 29 | + { |
| 30 | + Animal value = new Cat { Name = "Nyan", Lives = 9 }; |
| 31 | + var toml = TomlSerializer.Serialize(value); |
| 32 | + |
| 33 | + Assert.That(toml, Does.Contain("kind")); |
| 34 | + Assert.That(toml, Does.Contain("cat")); |
| 35 | + Assert.That(toml, Does.Contain("Name")); |
| 36 | + Assert.That(toml, Does.Contain("Nyan")); |
| 37 | + Assert.That(toml, Does.Contain("Lives")); |
| 38 | + Assert.That(toml, Does.Contain("9")); |
| 39 | + } |
| 40 | + |
| 41 | + [Test] |
| 42 | + public void Deserialize_Polymorphic_UsesDiscriminatorWhenNotFirst() |
| 43 | + { |
| 44 | + var toml = |
| 45 | + """ |
| 46 | + kind = "cat" |
| 47 | + Name = "Nyan" |
| 48 | + Lives = 9 |
| 49 | + """; |
| 50 | + |
| 51 | + var result = TomlSerializer.Deserialize<Animal>(toml); |
| 52 | + |
| 53 | + Assert.That(result, Is.TypeOf<Cat>()); |
| 54 | + var cat = (Cat)result!; |
| 55 | + Assert.That(cat.Name, Is.EqualTo("Nyan")); |
| 56 | + Assert.That(cat.Lives, Is.EqualTo(9)); |
| 57 | + } |
| 58 | + |
| 59 | + [Test] |
| 60 | + public void Deserialize_Polymorphic_UnknownDiscriminator_FailsByDefault() |
| 61 | + { |
| 62 | + var toml = |
| 63 | + """ |
| 64 | + kind = "fox" |
| 65 | + Name = "X" |
| 66 | + """; |
| 67 | + |
| 68 | + Assert.Throws<TomlException>(() => TomlSerializer.Deserialize<Animal>(toml)); |
| 69 | + } |
| 70 | + |
| 71 | + [TomlPolymorphic(TypeDiscriminatorPropertyName = "kind")] |
| 72 | + [TomlDerivedType(typeof(DerivedPet), "derived")] |
| 73 | + private class Pet |
| 74 | + { |
| 75 | + public string? Name { get; set; } |
| 76 | + } |
| 77 | + |
| 78 | + private sealed class DerivedPet : Pet |
| 79 | + { |
| 80 | + public int Age { get; set; } |
| 81 | + } |
| 82 | + |
| 83 | + [Test] |
| 84 | + public void Deserialize_Polymorphic_UnknownDiscriminator_CanFallbackToBase() |
| 85 | + { |
| 86 | + var toml = |
| 87 | + """ |
| 88 | + kind = "unknown" |
| 89 | + Name = "Base" |
| 90 | + extra = 123 |
| 91 | + """; |
| 92 | + |
| 93 | + var options = new TomlSerializerOptions |
| 94 | + { |
| 95 | + PolymorphismOptions = new TomlPolymorphismOptions |
| 96 | + { |
| 97 | + TypeDiscriminatorPropertyName = "kind", |
| 98 | + UnknownDerivedTypeHandling = TomlUnknownDerivedTypeHandling.FallBackToBaseType, |
| 99 | + }, |
| 100 | + }; |
| 101 | + |
| 102 | + var result = TomlSerializer.Deserialize<Pet>(toml, options); |
| 103 | + Assert.That(result, Is.TypeOf<Pet>()); |
| 104 | + Assert.That(result!.Name, Is.EqualTo("Base")); |
| 105 | + } |
| 106 | + |
| 107 | + [JsonPolymorphic(TypeDiscriminatorPropertyName = "kind")] |
| 108 | + [JsonDerivedType(typeof(JsonCat), "cat")] |
| 109 | + private abstract class JsonAnimal |
| 110 | + { |
| 111 | + public string? Name { get; set; } |
| 112 | + } |
| 113 | + |
| 114 | + private sealed class JsonCat : JsonAnimal |
| 115 | + { |
| 116 | + public int Lives { get; set; } |
| 117 | + } |
| 118 | + |
| 119 | + [Test] |
| 120 | + public void Deserialize_Polymorphic_RespectsSystemTextJsonAttributes() |
| 121 | + { |
| 122 | + var toml = |
| 123 | + """ |
| 124 | + kind = "cat" |
| 125 | + Name = "Ada" |
| 126 | + Lives = 9 |
| 127 | + """; |
| 128 | + |
| 129 | + var result = TomlSerializer.Deserialize<JsonAnimal>(toml); |
| 130 | + Assert.That(result, Is.TypeOf<JsonCat>()); |
| 131 | + Assert.That(((JsonCat)result!).Lives, Is.EqualTo(9)); |
| 132 | + } |
| 133 | +} |
0 commit comments