Skip to content

Commit 26b1711

Browse files
authored
Fix bug with set management (#93)
1 parent eb0d1e7 commit 26b1711

File tree

13 files changed

+163
-45
lines changed

13 files changed

+163
-45
lines changed

src/DynamoDBGenerator.SourceGenerator/Generations/UnMarshaller.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ private static CodeFactory CreateMethod(TypeIdentifier typeIdentifier, Func<ITyp
132132
.CreateScope(
133133
$"if ({Value} is null || {Value}.SS is null)"
134134
.CreateScope(singleGeneric.ReturnNullOrThrow(DataMember))
135-
.Append($"return new {(singleGeneric.TypeSymbol.TypeKind is TypeKind.Interface ? $"HashSet<{(singleGeneric.T.IsSupposedToBeNull ? "string?" : "string")}>" : null)}({(singleGeneric.T.IsSupposedToBeNull ? $"{Value}.SS" : $"{Value}.SS.Select((y,i) => y ?? throw {ExceptionHelper.NullExceptionMethod}($\"{{{DataMember}}}[UNKNOWN]\")")}));")
135+
.Append($"return new {(singleGeneric.TypeSymbol.TypeKind is TypeKind.Interface ? $"HashSet<{(singleGeneric.T.IsSupposedToBeNull ? "string?" : "string")}>" : null)}({(singleGeneric.T.IsSupposedToBeNull ? $"{Value}.SS" : $"{Value}.SS.Select((y,i) => y ?? throw {ExceptionHelper.NullExceptionMethod}($\"{{{DataMember}}}[UNKNOWN]\"))")});")
136136
)
137137
.ToConversion(),
138138
SingleGeneric.SupportedType.Set when singleGeneric.T.IsNumeric => signature

tests/DynamoDBGenerator.SourceGenerator.Tests/DynamoDBDocumentTests/Marshaller/Generics/Sets/Asserters/NoneNullableElementAsserter.cs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,20 @@
33

44
namespace DynamoDBGenerator.SourceGenerator.Tests.DynamoDBDocumentTests.Marshaller.Generics.Sets.Asserters;
55

6-
public abstract class NoneNullableElementAsserter<TSet, TElement> : SetAsserter<TSet, TElement>
7-
where TSet : IEnumerable<TElement> where TElement : class
6+
public abstract class NoneNullableElementAsserter<TSet, TElement>(
7+
IEnumerable<TElement> seed,
8+
Func<IEnumerable<TElement>, TSet> fn
9+
) : SetAsserter<TSet, TElement>(seed, fn)
10+
where TSet : IEnumerable<TElement>
11+
where TElement : class
812
{
9-
protected NoneNullableElementAsserter(IEnumerable<TElement> seed, Func<IEnumerable<TElement>, TSet> fn) : base(seed,
10-
fn)
11-
{
12-
}
13-
1413
protected static IEnumerable<string> Strings()
1514
{
1615
yield return "John";
1716
yield return "Tom";
1817
yield return "Michael";
1918
}
2019

21-
2220
[Fact]
2321
public void Marshall_NullElement_ShouldThrow()
2422
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
namespace DynamoDBGenerator.SourceGenerator.Tests.DynamoDBDocumentTests.Marshaller.Generics.Sets.Asserters;
2+
3+
public abstract class NullableElementAsserter<TSet, TElement> : SetAsserter<TSet, TElement?>
4+
where TSet : IEnumerable<TElement?> where TElement : class
5+
{
6+
protected NullableElementAsserter(IEnumerable<TElement?> seed, Func<IEnumerable<TElement?>, TSet> fn) : base(seed,
7+
fn)
8+
{
9+
}
10+
11+
protected static IEnumerable<string> Strings()
12+
{
13+
yield return "John";
14+
yield return "Tom";
15+
yield return "Michael";
16+
}
17+
18+
[Fact]
19+
public void Marshall_NullElement_ShouldNotThrow()
20+
{
21+
Arguments().Should().AllSatisfy(x =>
22+
{
23+
var items = x.element.Element.Append(null).ToList();
24+
var args = CreateArguments(items);
25+
var act = () => MarshallImplementation(args.element);
26+
act.Should().NotThrow();
27+
});
28+
}
29+
}

tests/DynamoDBGenerator.SourceGenerator.Tests/DynamoDBDocumentTests/Marshaller/Generics/Sets/Asserters/SetAsserter.cs

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,25 @@
44

55
namespace DynamoDBGenerator.SourceGenerator.Tests.DynamoDBDocumentTests.Marshaller.Generics.Sets.Asserters;
66

7-
public abstract class SetAsserter<TSet, TElement> : MarshalAsserter<Container<TSet>> where TSet : IEnumerable<TElement>
7+
public abstract class SetAsserter<TSet, TElement>(
8+
IEnumerable<TElement> seed,
9+
Func<IEnumerable<TElement>, TSet> fn
10+
) : MarshalAsserter<Container<TSet>>
11+
where TSet : IEnumerable<TElement>
812
{
913
private static readonly bool IsStringSet = typeof(TElement) == typeof(string);
10-
private readonly Func<IEnumerable<TElement>, TSet> _fn;
11-
private readonly IEnumerable<TElement> _seed;
12-
13-
protected SetAsserter(IEnumerable<TElement> seed, Func<IEnumerable<TElement>, TSet> fn)
14-
{
15-
_seed = seed;
16-
_fn = fn;
17-
}
1814

1915

2016
protected override IEnumerable<(Container<TSet> element, Dictionary<string, AttributeValue> attributeValues)>
2117
Arguments()
2218
{
23-
yield return CreateArguments(_seed);
19+
yield return CreateArguments(seed);
2420
}
2521

2622
protected (Container<TSet> element, Dictionary<string, AttributeValue> attributeValues) CreateArguments(
2723
IEnumerable<TElement> arg)
2824
{
29-
var res = _fn(arg);
25+
var res = fn(arg);
3026
if (res is not IReadOnlySet<TElement> or not ISet<TElement>)
3127
throw new InvalidOperationException(
3228
$"The type '{nameof(TSet)}' must either one of 'ISet<{nameof(TElement)}>, 'IReadonlySet<{nameof(TElement)}>'.");

tests/DynamoDBGenerator.SourceGenerator.Tests/DynamoDBDocumentTests/Marshaller/Generics/Sets/HashSetTests.cs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,9 @@
66
namespace DynamoDBGenerator.SourceGenerator.Tests.DynamoDBDocumentTests.Marshaller.Generics.Sets;
77

88
[DynamoDBMarshaller(EntityType = typeof(Container<HashSet<string>>))]
9-
public partial class HashSetTests : NoneNullableElementAsserter<HashSet<string>, string>
9+
public partial class HashSetTests()
10+
: NoneNullableElementAsserter<HashSet<string>, string>(Strings(), x => new HashSet<string>(x))
1011
{
11-
public HashSetTests() : base(Strings(), x => new HashSet<string>(x))
12-
{
13-
}
14-
1512
protected override Dictionary<string, AttributeValue> MarshallImplementation(Container<HashSet<string>> element)
1613
{
1714
return ContainerMarshaller.Marshall(element);

tests/DynamoDBGenerator.SourceGenerator.Tests/DynamoDBDocumentTests/Marshaller/Generics/Sets/IReadOnlySetTests.cs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,9 @@
66
namespace DynamoDBGenerator.SourceGenerator.Tests.DynamoDBDocumentTests.Marshaller.Generics.Sets;
77

88
[DynamoDBMarshaller(EntityType = typeof(Container<IReadOnlySet<string>>))]
9-
public partial class IReadOnlySetTests : NoneNullableElementAsserter<IReadOnlySet<string>, string>
9+
public partial class IReadOnlySetTests()
10+
: NoneNullableElementAsserter<IReadOnlySet<string>, string>(Strings(), x => new SortedSet<string>(x))
1011
{
11-
public IReadOnlySetTests() : base(Strings(), x => new SortedSet<string>(x))
12-
{
13-
}
14-
1512
protected override Dictionary<string, AttributeValue> MarshallImplementation(
1613
Container<IReadOnlySet<string>> element)
1714
{

tests/DynamoDBGenerator.SourceGenerator.Tests/DynamoDBDocumentTests/Marshaller/Generics/Sets/ISetTests.cs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,8 @@
66
namespace DynamoDBGenerator.SourceGenerator.Tests.DynamoDBDocumentTests.Marshaller.Generics.Sets;
77

88
[DynamoDBMarshaller(EntityType = typeof(Container<ISet<string>>))]
9-
public partial class ISetTests : NoneNullableElementAsserter<ISet<string>, string>
9+
public partial class ISetTests() : NoneNullableElementAsserter<ISet<string>, string>(Strings(), x => new HashSet<string>(x))
1010
{
11-
public ISetTests() : base(Strings(), x => new HashSet<string>(x))
12-
{
13-
}
14-
1511
protected override Dictionary<string, AttributeValue> MarshallImplementation(Container<ISet<string>> element)
1612
{
1713
return ContainerMarshaller.Marshall(element);

tests/DynamoDBGenerator.SourceGenerator.Tests/DynamoDBDocumentTests/Marshaller/Generics/Sets/IntHashSetTests.cs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,8 @@
66
namespace DynamoDBGenerator.SourceGenerator.Tests.DynamoDBDocumentTests.Marshaller.Generics.Sets;
77

88
[DynamoDBMarshaller(EntityType = typeof(Container<HashSet<int>>))]
9-
public partial class IntHashSetTests : SetAsserter<HashSet<int>, int>
9+
public partial class IntHashSetTests() : SetAsserter<HashSet<int>, int>([2, 3, 4, 5], x => new HashSet<int>(x))
1010
{
11-
public IntHashSetTests() : base(new[] { 2, 3, 4, 5 }, x => new HashSet<int>(x))
12-
{
13-
}
14-
1511
protected override Dictionary<string, AttributeValue> MarshallImplementation(Container<HashSet<int>> element)
1612
{
1713
return ContainerMarshaller.Marshall(element);
@@ -24,6 +20,22 @@ protected override Container<HashSet<int>> UnmarshallImplementation(
2420
}
2521
}
2622

23+
// TODO Support
24+
//[DynamoDBMarshaller(EntityType = typeof(Container<HashSet<int?>>))]
25+
//public partial class NUllableIntHashSetTests() : SetAsserter<HashSet<int?>, int?>([2, 3, 4, 5], x => new HashSet<int?>(x))
26+
//{
27+
// protected override Container<HashSet<int?>> UnmarshallImplementation(
28+
// Dictionary<string, AttributeValue> attributeValues)
29+
// {
30+
// return ContainerMarshaller.Unmarshall(attributeValues);
31+
// }
32+
//
33+
// protected override Dictionary<string, AttributeValue> MarshallImplementation(Container<HashSet<int?>> element)
34+
// {
35+
// return ContainerMarshaller.Marshall(element);
36+
// }
37+
//}
38+
2739
[DynamoDBMarshaller(EntityType = typeof(Container<HashSet<decimal>>))]
2840
public partial class DecimalHashSetTests : SetAsserter<HashSet<decimal>, decimal>
2941
{
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using Amazon.DynamoDBv2.Model;
2+
using DynamoDBGenerator.Attributes;
3+
using DynamoDBGenerator.SourceGenerator.Tests.DynamoDBDocumentTests.Marshaller.Asserters;
4+
using DynamoDBGenerator.SourceGenerator.Tests.DynamoDBDocumentTests.Marshaller.Generics.Sets.Asserters;
5+
6+
namespace DynamoDBGenerator.SourceGenerator.Tests.DynamoDBDocumentTests.Marshaller.Generics.Sets;
7+
8+
[DynamoDBMarshaller(EntityType = typeof(Container<HashSet<string?>>))]
9+
public partial class NullableHashSetTests() : NullableElementAsserter<HashSet<string?>, string>(Strings(), x => new HashSet<string?>(x))
10+
{
11+
protected override Container<HashSet<string?>> UnmarshallImplementation(Dictionary<string, AttributeValue> attributeValues)
12+
{
13+
return ContainerMarshaller.Unmarshall(attributeValues);
14+
}
15+
16+
protected override Dictionary<string, AttributeValue> MarshallImplementation(Container<HashSet<string?>> element)
17+
{
18+
return ContainerMarshaller.Marshall(element);
19+
}
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using Amazon.DynamoDBv2.Model;
2+
using DynamoDBGenerator.Attributes;
3+
using DynamoDBGenerator.SourceGenerator.Tests.DynamoDBDocumentTests.Marshaller.Asserters;
4+
using DynamoDBGenerator.SourceGenerator.Tests.DynamoDBDocumentTests.Marshaller.Generics.Sets.Asserters;
5+
6+
namespace DynamoDBGenerator.SourceGenerator.Tests.DynamoDBDocumentTests.Marshaller.Generics.Sets;
7+
8+
[DynamoDBMarshaller(EntityType = typeof(Container<IReadOnlySet<string?>>))]
9+
public partial class NullableIReadOnlySetTests() : NullableElementAsserter<IReadOnlySet<string?>, string>(Strings(), x => new HashSet<string?>(x))
10+
{
11+
protected override Dictionary<string, AttributeValue> MarshallImplementation(Container<IReadOnlySet<string?>> element)
12+
{
13+
return ContainerMarshaller.Marshall(element);
14+
}
15+
16+
protected override Container<IReadOnlySet<string?>> UnmarshallImplementation(
17+
Dictionary<string, AttributeValue> attributeValues)
18+
{
19+
return ContainerMarshaller.Unmarshall(attributeValues);
20+
}
21+
22+
[Fact]
23+
public void Unmarshall_Implementation_ShouldBeHashset()
24+
{
25+
Arguments().Should().AllSatisfy(x =>
26+
ContainerMarshaller.Unmarshall(x.attributeValues).Element.Should().BeOfType<HashSet<string?>>());
27+
}
28+
}

0 commit comments

Comments
 (0)