Skip to content

Commit 359a189

Browse files
authored
Merge pull request #26 from in-async/release/v0.7.0
Release/v0.7.0
2 parents eef2062 + c1b3318 commit 359a189

8 files changed

+93
-4
lines changed

Directory.Build.props

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<Project>
22
<PropertyGroup>
3-
<LangVersion>8.0</LangVersion>
3+
<LangVersion>9.0</LangVersion>
44
<Nullable>enable</Nullable>
55
</PropertyGroup>
66
</Project>

Inasync.PrimitiveAssert.Tests/Inasync.PrimitiveAssert.Tests.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFrameworks>netcoreapp3.1;netcoreapp2.1;net461</TargetFrameworks>
4+
<TargetFrameworks>netcoreapp3.1;netcoreapp2.1;net48;net461</TargetFrameworks>
55

66
<IsPackable>false</IsPackable>
77

Inasync.PrimitiveAssert.Tests/PrimitiveAssertTests_AssertIs.cs

+14
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections;
33
using System.Collections.Generic;
4+
using System.Linq;
45
using Microsoft.VisualStudio.TestTools.UnitTesting;
56

67
namespace Inasync.Tests {
@@ -49,6 +50,19 @@ public void AssertIs_Reference() {
4950
}.Invoke();
5051
}
5152

53+
[TestMethod]
54+
public void AssertIs_Predicate() {
55+
var targetType = new Type?[] { null, typeof(DummyStruct), typeof(DummyClass) }.OrderBy(x => Guid.NewGuid()).First();
56+
var obj = "foo";
57+
new[] {
58+
TestCase( 0, target: targetType, x: obj, y: new AssertPredicate(x => true) ),
59+
TestCase( 1, target: targetType, x: obj, y: new AssertPredicate(x => false) , expectedException: typeof(PrimitiveAssertFailedException)), // アサート条件が false。
60+
TestCase(10, target: targetType, x: obj, y: new AssertPredicate<string>(x => true) ),
61+
TestCase(11, target: targetType, x: obj, y: new AssertPredicate<object>(x => true) ),
62+
TestCase(12, target: targetType, x: obj, y: new AssertPredicate<DummyClass>(x => true), expectedException: typeof(PrimitiveAssertFailedException)), // actual は DummyClass にキャストできない。
63+
}.Invoke();
64+
}
65+
5266
[TestMethod]
5367
public void AssertIs_Numeric() {
5468
new[] {

Inasync.PrimitiveAssert.Tests/UsageTests.cs

+32
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Security.Cryptography;
34
using Microsoft.VisualStudio.TestTools.UnitTesting;
45

56
namespace Inasync.Tests {
@@ -97,6 +98,37 @@ public void Usage6() {
9798
});
9899
}
99100

101+
#if !NET461
102+
103+
[TestMethod]
104+
public void Usage7() {
105+
using ECDsa ecdsa = ECDsa.Create();
106+
ecdsa.GenerateKey(ECCurve.NamedCurves.nistP256);
107+
108+
var message = new byte[] { 1, 2, 3 };
109+
byte[] signature = ecdsa.SignData(message, HashAlgorithmName.SHA256);
110+
111+
var actual = new {
112+
Id = 123,
113+
CreatedAt = DateTime.Now,
114+
Details = new {
115+
Age = 25,
116+
Signature = signature,
117+
},
118+
};
119+
120+
actual.AssertIs(new {
121+
Id = 123,
122+
CreatedAt = new AssertPredicate(x => true), // Ignore assert
123+
Details = new {
124+
Age = new AssertPredicate<int>(x => x > 20),
125+
Signature = new AssertPredicate<byte[]>(x => ecdsa.VerifyData(message, signature: x, HashAlgorithmName.SHA256)),
126+
},
127+
});
128+
}
129+
130+
#endif
131+
100132
#region Helpers
101133

102134
public interface IAccount {
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
namespace Inasync {
2+
3+
/// <summary>
4+
/// <see cref="PrimitiveAssert"/> の <c>expected</c> に指定する事で任意のアサート条件が記述できるデリゲート。
5+
/// </summary>
6+
/// <param name="actual">検証対象の実値。</param>
7+
/// <returns><paramref name="actual"/> がアサートに成功した場合は <c>true</c>、失敗した場合は <c>false</c>。</returns>
8+
public delegate bool AssertPredicate(object? actual);
9+
10+
/// <summary>
11+
/// <see cref="PrimitiveAssert"/> の <c>expected</c> に指定する事で任意のアサート条件が記述できるデリゲート。
12+
/// </summary>
13+
/// <typeparam name="T"><paramref name="actual"/> で受けたい型。キャストできない場合はアサートに失敗した扱いになる。</typeparam>
14+
/// <param name="actual">検証対象の実値。</param>
15+
/// <returns><paramref name="actual"/> がアサートに成功した場合は <c>true</c>、失敗した場合は <c>false</c>。</returns>
16+
public delegate bool AssertPredicate<T>(T actual);
17+
}

Inasync.PrimitiveAssert/Inasync.PrimitiveAssert.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<PackageProjectUrl>https://github.com/in-async/PrimitiveAssert</PackageProjectUrl>
1010
<PackageLicenseUrl>https://github.com/in-async/PrimitiveAssert/blob/master/LICENSE</PackageLicenseUrl>
1111
<PackageTags>library test unittest assert deep</PackageTags>
12-
<Version>0.6.0</Version>
12+
<Version>0.7.0</Version>
1313
</PropertyGroup>
1414

1515
</Project>

Inasync.PrimitiveAssert/Internals/AssertIsImpl.cs

+26
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ public void AssertIs(AssertNode node) {
2323

2424
_logger?.Write($"{node.MemberName}: {node.TargetType?.GetFriendlyName() ?? "(null)"} = ");
2525
try {
26+
if (TryPredicateAssertIs(targetType, actual, expected, node)) { return; }
27+
2628
// null 比較
2729
if (targetType is null) {
2830
if (!(actual is null)) { throw new PrimitiveAssertFailedException(node, "ターゲット型は null ですが、actual は非 null です。", _message); }
@@ -79,6 +81,30 @@ private void WriteLog(AssertNode node, string additionalMessage) {
7981
_logger.WriteLine();
8082
}
8183

84+
private bool TryPredicateAssertIs(Type? targetType, object? actual, object? expected, AssertNode node) {
85+
if (expected is null) { return false; }
86+
87+
if (expected is AssertPredicate predicate) {
88+
if (!predicate(actual)) { throw new PrimitiveAssertFailedException(node, "actual はカスタム条件に一致しませんでした。", _message); }
89+
90+
WriteLog(node, "actual はカスタム条件に一致しました。");
91+
return true;
92+
}
93+
94+
Type expectedType = expected.GetType();
95+
if (expectedType.IsGenericType && expectedType.GetGenericTypeDefinition() == typeof(AssertPredicate<>)) {
96+
Type genericType = expectedType.GetGenericArguments()[0];
97+
98+
if (!genericType.IsAssignableFrom(actual?.GetType())) { throw new PrimitiveAssertFailedException(node, "actual はカスタム条件の型引数にキャストできませんでした。", _message); }
99+
if (!(bool)expectedType.GetMethod("Invoke").Invoke(expected, new[] { actual })) { throw new PrimitiveAssertFailedException(node, "actual はカスタム条件に一致しませんでした。", _message); }
100+
101+
WriteLog(node, "actual はカスタム条件に一致しました。");
102+
return true;
103+
}
104+
105+
return false;
106+
}
107+
82108
private bool TryNumericAssertIs(Type targetType, object actual, object expected, AssertNode node) {
83109
if (!Numeric.IsNumeric(targetType)) { return false; }
84110

appveyor.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,6 @@ deploy:
1616
appveyor_repo_tag: true
1717
- provider: NuGet
1818
api_key:
19-
secure: 6Uequ3x7ky4YviiGDGcQGjlaScD1g5Ypv6MtcdJX8Otz9pLFcL9PuU1xvG7zdDGS
19+
secure: ccm+uv1mL5n9OdO3gu9MZdUIFnVws0G8cjiVQdO1o2ZzhTsXpbuJW+Iz+D1SlqcF
2020
on:
2121
appveyor_repo_tag: true

0 commit comments

Comments
 (0)