Skip to content

Commit

Permalink
Importing AttributeValueAssert (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffAshton authored Dec 11, 2020
1 parent 35021aa commit 0199695
Show file tree
Hide file tree
Showing 8 changed files with 1,303 additions and 7 deletions.
40 changes: 33 additions & 7 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,30 @@ env:
VERSION_PREFIX: "0.0.1"

jobs:
build:

# Need to test and pack separately because github actions only support docker services in linux,
# but linux doesn't support targetting net45 framework.
test:
runs-on: ubuntu-latest

services:
dynamo:
image: amazon/dynamodb-local
ports: [ '8000:8000' ]

steps:

- uses: Brightspace/third-party-actions@actions/checkout

- name: Setup .NET Core
uses: Brightspace/third-party-actions@actions/setup-dotnet
with:
dotnet-version: 3.1.x

- name: dotnet test --framework "netcoreapp3.1"
run: dotnet test --configuration Release --framework "netcoreapp3.1"

pack:
runs-on: windows-latest

steps:
Expand All @@ -23,11 +46,14 @@ jobs:
- name: Generate version properties
run: dotnet ci-version-properties --output VersionInfo.props && cat VersionInfo.props

- name: dotnet restore
run: dotnet restore
- name: dotnet test
run: dotnet pack --configuration Release

- name: dotnet build
run: dotnet build --configuration Release
- name: Copy *.nuget to dist/
run: mkdir dist/ && cp src/D2L.DynamoDBv2.NUnitHelpers/bin/Release/*.nupkg dist/

- name: dotnet test
run: dotnet test --configuration Release --no-build
- name: Archive dist/
uses: actions/upload-artifact@v1
with:
name: dist
path: dist/
1 change: 1 addition & 0 deletions D2L.DynamoDBv2.NUnitHelpers.sln
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{356A87B5-A285-4018-8923-D8409A373B54}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
.github\workflows\build.yml = .github\workflows\build.yml
Directory.Build.props = Directory.Build.props
EndProjectSection
EndProject
Expand Down
59 changes: 59 additions & 0 deletions src/D2L.DynamoDBv2.NUnitHelpers/AmazonDynamoDBAssert.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.Model;
using NUnit.Framework;

namespace D2L.DynamoDBv2.NUnitHelpers {

public static class AmazonDynamoDBAssert {

public static async Task AssertItemAsync(
this IAmazonDynamoDB db,
string tableName,
Dictionary<string, AttributeValue> key,
Dictionary<string, AttributeValue> expectedItem
) {

GetItemRequest request = new GetItemRequest {
TableName = tableName,
Key = key,
ConsistentRead = true
};

GetItemResponse response = await db
.GetItemAsync( request )
.ConfigureAwait( false );

if( !response.IsItemSet ) {
Assert.Fail( "Item should exist." );
}

AttributeValueAssert.AreEqual(
actual: response.Item,
expected: expectedItem
);
}

public static async Task AssertItemDoesNotExistAsync(
this IAmazonDynamoDB db,
string tableName,
Dictionary<string, AttributeValue> key
) {

GetItemRequest request = new GetItemRequest {
TableName = tableName,
Key = key,
ConsistentRead = true
};

GetItemResponse response = await db
.GetItemAsync( request )
.ConfigureAwait( false );

if( response.IsItemSet ) {
Assert.Fail( "Item should not exist." );
}
}
}
}
33 changes: 33 additions & 0 deletions src/D2L.DynamoDBv2.NUnitHelpers/AmazonDynamoDBLocal.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System;
using Amazon.DynamoDBv2;
using Amazon.Runtime;

namespace D2L.DynamoDBv2.NUnitHelpers {

public static class AmazonDynamoDBLocal {

/// <summary>
/// Creates an <see cref="IAmazonDynamoDB"/> client for DynamoDB local.
///
/// The service url is defined by the environment variable DYNAMODB_LOCAL_SERVICE_URL if set; otherwise <c>http://localhost:8000</c> will be used.
/// </summary>
/// <returns>Returns an Amazon DynamoDB client.</returns>
public static IAmazonDynamoDB CreateClient() {

string? serviceUrl = Environment.GetEnvironmentVariable( "DYNAMODB_LOCAL_SERVICE_URL" );
if( serviceUrl == null ) {
serviceUrl = "http://localhost:8000";
}

return new AmazonDynamoDBClient(
credentials: new BasicAWSCredentials(
accessKey: "accessKey",
secretKey: "secretKey"
),
clientConfig: new AmazonDynamoDBConfig {
ServiceURL = serviceUrl
}
);
}
}
}
227 changes: 227 additions & 0 deletions src/D2L.DynamoDBv2.NUnitHelpers/AttributeValueAssert.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
using System;
using System.Collections.Generic;
using System.IO;
using Amazon.DynamoDBv2.Model;
using NUnit.Framework;

namespace D2L.DynamoDBv2.NUnitHelpers {

public static class AttributeValueAssert {

public static void AreEqual(
Dictionary<string, AttributeValue> actual,
Dictionary<string, AttributeValue> expected
) {

AssertMapAttributes(
path: "M",
actual: actual,
expected: expected
);
}

public static void AreEqual(
AttributeValue actual,
AttributeValue expected
) {

AssertAttributeValue(
path: string.Empty,
actual: actual,
expected: expected
);
}

private static void AssertListAttributes(
string path,
List<AttributeValue> actual,
List<AttributeValue> expected
) {

Assert.That(
actual.Count,
Is.EqualTo( expected.Count ),
"List length must be equal ({0})",
path
);

for( int i = 0; i < actual.Count; i++ ) {

AssertAttributeValue(
path: $"{ path }[{ i }].",
actual: actual[ i ],
expected: expected[ i ]
);
}
}

private static void AssertMapAttributes(
string path,
Dictionary<string, AttributeValue> actual,
Dictionary<string, AttributeValue> expected
) {

Assert.That(
actual.Keys,
Is.EquivalentTo( expected.Keys ),
"{0}.Keys must be equivalent",
path
);

foreach( KeyValuePair<string, AttributeValue> pair in actual ) {

AssertAttributeValue(
path: $"{ path }[{ pair.Key }].",
actual: pair.Value,
expected: expected[ pair.Key ]
);
}
}

private static void AssertAttributeValue(
string path,
AttributeValue actual,
AttributeValue expected
) {

if( actual.B != null && expected.B != null ) {

Assert.That(
actual.B.ToArray(),
Is.EqualTo( expected.B.ToArray() ),
"{0}B must be equal",
path
);

} else {

Assert.That(
actual.B,
Is.EqualTo( expected.B ),
"{0}B must be equal",
path
);
}

Assert.That(
actual.IsBOOLSet,
Is.EqualTo( expected.IsBOOLSet ),
"{0}IsBOOLSet must be equal",
path
);

Assert.That(
actual.BOOL,
Is.EqualTo( expected.BOOL ),
"{0}BOOL must be equal",
path
);

Assert.That(
actual.BS,
Is.EquivalentTo( expected.BS ).Using( MemoryStreamEqualityComparer.Instance ),
"{0}BS must be equivalent",
path
);

Assert.That(
actual.IsLSet,
Is.EqualTo( expected.IsLSet ),
"{0}IsLSet must be equal",
path
);

AssertListAttributes(
path: $"{ path }L",
actual: actual.L,
expected: expected.L
);

Assert.That(
actual.IsMSet,
Is.EqualTo( expected.IsMSet ),
"{0}IsMSet must be equal",
path
);

AssertMapAttributes(
path: $"{ path }M",
actual: actual.M,
expected: expected.M
);

Assert.That(
actual.N,
Is.EqualTo( expected.N ),
"{0}N must be equal",
path
);

Assert.That(
actual.NULL,
Is.EqualTo( expected.NULL ),
"{0}NULL must be equal",
path
);

Assert.That(
actual.NS,
Is.EquivalentTo( expected.NS ),
"{0}NS must be equivalent",
path
);

Assert.That(
actual.S,
Is.EqualTo( expected.S ),
"{0}S must be equal",
path
);

Assert.That(
actual.SS,
Is.EquivalentTo( expected.SS ),
"{0}SS must be equivalent",
path
);
}

private sealed class MemoryStreamEqualityComparer : IEqualityComparer<MemoryStream> {

internal static readonly IEqualityComparer<MemoryStream> Instance = new MemoryStreamEqualityComparer();
private MemoryStreamEqualityComparer() { }

bool IEqualityComparer<MemoryStream>.Equals( MemoryStream? x, MemoryStream? y ) {

if( ReferenceEquals( x, y ) ) {
return true;
}

if( x != null && y != null ) {

if( x.Length != y.Length ) {
return false;
}

byte[] xBytes = x.ToArray();
byte[] yBytes = y.ToArray();

for( int i = 0; i < xBytes.Length; i++ ) {

if( xBytes[ i ] != yBytes[ i ] ) {
return false;
}
}

return true;
}

return false;
}

int IEqualityComparer<MemoryStream>.GetHashCode( MemoryStream obj ) {
throw new NotImplementedException();
}
}
}
}
Loading

0 comments on commit 0199695

Please sign in to comment.