Skip to content

Commit

Permalink
Merge pull request #9 from in-async/release/v0.4.0
Browse files Browse the repository at this point in the history
Resolve #5, #6

* 戻り値が ValueTask の act を受け取る Act() オーバーロードを追加。
* 戻り値の検証をスキップし例外検証のみ行う TestActual.Assert() オーバーロードを追加。
* 簡易例外検証にインスタンスではなく例外型を使用するよう変更。
  • Loading branch information
in-async authored Nov 23, 2019
2 parents 9131930 + 2223ecf commit 6f3eb77
Show file tree
Hide file tree
Showing 10 changed files with 336 additions and 74 deletions.
26 changes: 19 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ TestAA.Act(() => { /* ここでテスト対象のメソッドを呼ぶ */ })
検証はラムダ式やデリゲートではなく値を直接入力する事でも可能です。テストの失敗は、既定では `TestAssertFailedException` のスローによって通知されます。
```cs
TestAA.Act(() => int.Parse("123")).Assert(123); // OK
TestAA.Act(() => int.Parse("abc")).Assert(ret => { }, new FormatException()); // OK
TestAA.Act(() => int.Parse("abc")).Assert<FormatException>(); // OK
TestAA.Act(() => int.Parse("abc")).Assert(123); // TestAssertFailedException
```

Expand All @@ -59,7 +59,7 @@ TestAA.Act(() => int.Parse("123")).Assert(123);
```
### Throws Exception
```cs
TestAA.Act(() => int.Parse("abc")).Assert(ret => { }, exception: new FormatException());
TestAA.Act(() => int.Parse("abc")).Assert<FormatException>();
```

### Out Parameter
Expand All @@ -81,23 +81,35 @@ TestAA.Act(() => int.Parse("123")).Assert(

### Task Synchronously
```cs
// Task
TestAA.Act(() => Task.FromResult(123)).Assert(123);

// ValueTask
TestAA.Act(() => new ValueTask<int>(123)).Assert(123);
```

### Task Throws Exception
```cs
TestAA.Act(() => Task.FromException(new ApplicationException())).Assert(new ApplicationException());
// Task
TestAA.Act(() => Task.FromException(new ApplicationException())).Assert<ApplicationException>();

// ValueTask
TestAA.Act(() => new ValueTask(Task.FromException(new ApplicationException()))).Assert<ApplicationException>();
```

### Raw Task
```cs
// Task
var task = Task.FromResult(123);
TestAA.Act<Task<int>>(() => task).Assert(task);

// ValueTask
TestAA.Act<ValueTask<int>>(() => new ValueTask<int>(123)).Assert(new ValueTask<int>(123));
```

### Immediate Enumerable Evaluation
```cs
TestAA.Act(() => CreateEnumerable()).Assert(ret => { }, new ApplicationException());
TestAA.Act(() => CreateEnumerable()).Assert<ApplicationException>();

IEnumerable<int> CreateEnumerable() {
yield return 123;
Expand All @@ -120,15 +132,15 @@ TestAA.Act(() => int.Parse("123")).Assert(123); // Assert.AreEqual()

### Test Cases
```cs
Action TestCase(int testNumber, string input, int expected, Exception expectedException = null) => () => {
Action TestCase(int testNumber, string input, int expected, Type expectedException = null) => () => {
var msg = "No." + testNumber;

TestAA.Act(() => int.Parse(input)).Assert(expected, expectedException, msg);
};

foreach (var action in new[] {
TestCase( 0, null , expected: 0 , expectedException: new ArgumentNullException()),
TestCase( 1, "abc", expected: 0 , expectedException: new FormatException()),
TestCase( 0, null , expected: 0 , expectedException: typeof(ArgumentNullException)),
TestCase( 1, "abc", expected: 0 , expectedException: typeof(FormatException)),
TestCase( 2, "123", expected: 123),
}) { action(); }
```
Expand Down
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ deploy:
appveyor_repo_tag: true
- provider: NuGet
api_key:
secure: 5auKjaKm29nXAKSDhhZOM1V+1H+MsUwIRi8xw+vZa4t9rlhg2hHX+BExGh/8XOAd
secure: LAo0c9SiVqvPguwNcKUMbQGnMMYq6s0QhvXHrwfZyN8djLKimZB7pbykxIAiNcFH
on:
appveyor_repo_tag: true
6 changes: 5 additions & 1 deletion src/Inasync.TestAA/Inasync.TestAA.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@
<PackageProjectUrl>https://github.com/in-async/TestAA</PackageProjectUrl>
<PackageLicenseUrl>https://github.com/in-async/TestAA/blob/master/LICENSE</PackageLicenseUrl>
<PackageTags>library test unittest AAA</PackageTags>
<Version>0.3.0</Version>
<Version>0.4.0</Version>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.3" />
</ItemGroup>

</Project>
50 changes: 44 additions & 6 deletions src/Inasync.TestAA/TestAA.Act.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,19 @@ public static TestActual<TReturn> Act<TReturn>(Func<TReturn> act) {

public static partial class TestAA {

/// <summary>
/// テスト対象のデリゲートを実行し、戻り値のシーケンスを配列化します。
/// </summary>
/// <typeparam name="TItem">テスト対象のデリゲートが戻り値とするシーケンスの要素の型。</typeparam>
/// <param name="act">テスト対象のデリゲート。</param>
/// <returns>デリゲートの実行結果。</returns>
/// <exception cref="ArgumentNullException"><paramref name="act"/> is <c>null</c>.</exception>
public static TestActual<TItem[]> Act<TItem>(Func<IEnumerable<TItem>> act) {
if (act == null) { throw new ArgumentNullException(nameof(act)); }

return Act(() => act().ToArray());
}

/// <summary>
/// テスト対象の非同期デリゲートを同期的に実行します。
/// </summary>
Expand All @@ -62,6 +75,18 @@ public static TestActual Act(Func<Task> act) {
return Act(() => act().GetAwaiter().GetResult());
}

/// <summary>
/// テスト対象の非同期デリゲートを同期的に実行します。
/// </summary>
/// <param name="act">テスト対象の非同期デリゲート。</param>
/// <returns>非同期デリゲートの実行結果。</returns>
/// <exception cref="ArgumentNullException"><paramref name="act"/> is <c>null</c>.</exception>
public static TestActual Act(Func<ValueTask> act) {
if (act == null) { throw new ArgumentNullException(nameof(act)); }

return Act(() => act().GetAwaiter().GetResult());
}

/// <summary>
/// テスト対象の非同期デリゲートを同期的に実行します。
/// </summary>
Expand All @@ -76,16 +101,16 @@ public static TestActual<TReturn> Act<TReturn>(Func<Task<TReturn>> act) {
}

/// <summary>
/// テスト対象のデリゲートを実行し、戻り値のシーケンスを配列化します
/// テスト対象の非同期デリゲートを同期的に実行します
/// </summary>
/// <typeparam name="TItem">テスト対象のデリゲートが戻り値とするシーケンスの要素の型。</typeparam>
/// <param name="act">テスト対象のデリゲート。</param>
/// <returns>デリゲートの実行結果。</returns>
/// <typeparam name="TReturn">テスト対象の非同期デリゲートの戻り値の型。</typeparam>
/// <param name="act">テスト対象の非同期デリゲート。</param>
/// <returns>非同期デリゲートの実行結果。</returns>
/// <exception cref="ArgumentNullException"><paramref name="act"/> is <c>null</c>.</exception>
public static TestActual<TItem[]> Act<TItem>(Func<IEnumerable<TItem>> act) {
public static TestActual<TReturn> Act<TReturn>(Func<ValueTask<TReturn>> act) {
if (act == null) { throw new ArgumentNullException(nameof(act)); }

return Act(() => act().ToArray());
return Act(() => act().GetAwaiter().GetResult());
}

/// <summary>
Expand All @@ -100,5 +125,18 @@ public static TestActual<TItem[]> Act<TItem>(Func<Task<IEnumerable<TItem>>> act)

return Act(() => act().GetAwaiter().GetResult().ToArray());
}

/// <summary>
/// テスト対象の非同期デリゲートを同期的に実行し、戻り値のシーケンスを配列化します。
/// </summary>
/// <typeparam name="TItem">テスト対象の非同期デリゲートが戻り値とするシーケンスの要素の型。</typeparam>
/// <param name="act">テスト対象の非同期デリゲート。</param>
/// <returns>非同期デリゲートの実行結果。</returns>
/// <exception cref="ArgumentNullException"><paramref name="act"/> is <c>null</c>.</exception>
public static TestActual<TItem[]> Act<TItem>(Func<ValueTask<IEnumerable<TItem>>> act) {
if (act == null) { throw new ArgumentNullException(nameof(act)); }

return Act(() => act().GetAwaiter().GetResult().ToArray());
}
}
}
52 changes: 46 additions & 6 deletions src/Inasync.TestAA/TestActual.Assert.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,26 @@ public void Assert(Action<Exception> exception) {
/// Act の実行結果を検証します。
/// </summary>
/// <param name="exception">
/// Act で生じる事が予期される例外。例外が生じない事が予期される場合は <c>null</c>。
/// Act で生じる事が予期される例外の型。例外が生じない事が予期される場合は <c>null</c>。
/// <see cref="TestAA.TestAssert"/> によって実際の例外と比較されます。
/// </param>
/// <param name="message">テスト失敗時に結果に表示されるメッセージ。</param>
public void Assert(Exception exception = null, string message = null) {
public void Assert(Type exception = null, string message = null) {
var actual = this;
Assert(ex => TestAA.TestAssert.AssertException(actual.Exception, exception, message));
}

/// <summary>
/// Act の実行結果を検証します。
/// </summary>
/// <typeparam name="TException">
/// Act で生じる事が予期される例外の型。
/// <see cref="Assert(Type, string)"/> によって実際の例外と比較されます。
/// </typeparam>
/// <param name="message">テスト失敗時に結果に表示されるメッセージ。</param>
public void Assert<TException>(string message = null) where TException : Exception {
Assert(exception: typeof(TException), message: message);
}
}

public partial struct TestActual<TReturn> {
Expand Down Expand Up @@ -55,12 +67,12 @@ public void Assert(Action<TReturn> @return, Action<Exception> exception) {
/// </summary>
/// <param name="return">Act の戻り値を検証するデリゲート。Act で例外が生じた場合は呼ばれません。</param>
/// <param name="exception">
/// Act で生じる事が予期される例外。例外が生じない事が予期される場合は <c>null</c>。
/// Act で生じる事が予期される例外の型。例外が生じない事が予期される場合は <c>null</c>。
/// <see cref="TestAA.TestAssert"/> によって実際の例外と比較されます。
/// </param>
/// <param name="message">テスト失敗時に結果に表示されるメッセージ。</param>
/// <exception cref="ArgumentNullException"><paramref name="return"/> is <c>null</c>.</exception>
public void Assert(Action<TReturn> @return, Exception exception = null, string message = null) {
public void Assert(Action<TReturn> @return, Type exception = null, string message = null) {
var actual = this;
Assert(
@return
Expand All @@ -77,16 +89,44 @@ public void Assert(Action<TReturn> @return, Exception exception = null, string m
/// Act で例外が生じた場合は比較されません。
/// </param>
/// <param name="exception">
/// Act で生じる事が予期される例外。例外が生じない事が予期される場合は <c>null</c>。
/// Act で生じる事が予期される例外の型。例外が生じない事が予期される場合は <c>null</c>。
/// <see cref="TestAA.TestAssert"/> によって実際の例外と比較されます。
/// </param>
/// <param name="message">テスト失敗時に結果に表示されるメッセージ。</param>
public void Assert(TReturn @return, Exception exception = null, string message = null) {
public void Assert(TReturn @return, Type exception = null, string message = null) {
var actual = this;
Assert(
ret => TestAA.TestAssert.Is(actual.Return, @return, message)
, ex => TestAA.TestAssert.AssertException(actual.Exception, exception, message)
);
}

/// <summary>
/// Act の実行結果を検証します。
/// </summary>
/// <param name="exception">
/// Act で生じる事が予期される例外の型。例外が生じない事が予期される場合は <c>null</c>。
/// <see cref="TestAA.TestAssert"/> によって実際の例外と比較されます。
/// </param>
/// <param name="message">テスト失敗時に結果に表示されるメッセージ。</param>
public void Assert(Type exception = null, string message = null) {
var actual = this;
Assert(
ret => { }
, ex => TestAA.TestAssert.AssertException(actual.Exception, exception, message)
);
}

/// <summary>
/// Act の実行結果を検証します。
/// </summary>
/// <typeparam name="TException">
/// Act で生じる事が予期される例外の型。
/// <see cref="Assert(Type, string)"/> によって実際の例外と比較されます。
/// </typeparam>
/// <param name="message">テスト失敗時に結果に表示されるメッセージ。</param>
public void Assert<TException>(string message = null) where TException : Exception {
Assert(exception: typeof(TException), message: message);
}
}
}
10 changes: 5 additions & 5 deletions src/Inasync.TestAA/TestAssert.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,20 +37,20 @@ public virtual void Is<TReturn>(TReturn actual, TReturn expected, string message
}

/// <summary>
/// 2 つの例外が等しいかどうかのテストを行います
/// 生じた例外が予期した型かどうかのテストを行います
/// </summary>
/// <remarks>
/// 既定では、2 つの例外の型を <see cref="Is{TReturn}(TReturn, TReturn, string)"/> によって比較します。
/// </remarks>
/// <param name="actual">実際の例外。</param>
/// <param name="expected">予期している例外。</param>
/// <param name="message"><paramref name="actual"/> <paramref name="expected"/> が等しくない場合にテスト結果に表示されるメッセージ。</param>
public virtual void AssertException(Exception actual, Exception expected, string message) {
/// <param name="expectedType">予期している例外の型。</param>
/// <param name="message"><paramref name="actual"/> の型と <paramref name="expectedType"/> が等しくない場合にテスト結果に表示されるメッセージ。</param>
public virtual void AssertException(Exception actual, Type expectedType, string message) {
var finalMessage = message;
if (actual != null) {
finalMessage += Environment.NewLine + "Actual Exception: " + actual;
}
Is(actual?.GetType(), expected?.GetType(), finalMessage);
Is(actual?.GetType(), expectedType, finalMessage);
}
}

Expand Down
Loading

0 comments on commit 6f3eb77

Please sign in to comment.