Skip to content

Commit

Permalink
Replace custom Comparer and Constraint example from test-helper package
Browse files Browse the repository at this point in the history
  • Loading branch information
nowsprinting committed Nov 8, 2023
1 parent 96d50f1 commit dc1b643
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 66 deletions.
51 changes: 23 additions & 28 deletions Assets/APIExamples/Tests/Runtime/NUnit/CustomComparerExample.cs
Original file line number Diff line number Diff line change
@@ -1,67 +1,62 @@
// Copyright (c) 2021 Koji Hasegawa.
// Copyright (c) 2021-2023 Koji Hasegawa.
// This software is released under the MIT License.

using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using NUnit.Framework;
using NUnit.Framework.Constraints;
using UnityEngine;

// ReSharper disable AccessToStaticMemberViaDerivedType

namespace APIExamples.NUnit
{
/// <summary>
/// <see cref="EqualConstraint"/> + Using修飾子と、カスタム<see cref="IComparer{T}"/>の使用例
/// Using修飾子と、カスタム<see cref="IComparer{T}"/>の使用例
/// </summary>
public class CustomComparerExample
{
[Test]
public void EqualConstraint_Using修飾子で比較()
public void EqualConstraint_Using修飾子でカスタムComparerを指定して比較()
{
var actual = new CompositeKeySUT("Foo", "Bar", 1);
var actual = new GameObject("test object");
var expected = new GameObject("test object");

Assert.That(actual, Is.EqualTo(new CompositeKeySUT("Foo", "Bar", 10)).Using(new CompositeKeySUTComparer()));
Assert.That(actual, Is.EqualTo(expected).Using(new GameObjectNameComparer()));
// 失敗時メッセージ例:
// Expected: <APIExamples.NUnit.CompositeKeySUT>
// But was: <APIExamples.NUnit.CompositeKeySUT>
// Expected: <test object (UnityEngine.GameObject)>
// But was: <test (UnityEngine.GameObject)>
}

[Test]
public void EqualConstraint_コレクションの要素をUsing修飾子で比較()
public void CollectionContainsConstraint_コレクションの要素をUsing修飾子でカスタムComparerを指定して比較()
{
var actual = new[] { new CompositeKeySUT("Foo", "Bar", 1), new CompositeKeySUT("Bar", "Baz", 2) };
var actual = new[] { new GameObject("test1"), new GameObject("test2"), new GameObject("test3"), };
var expected = new GameObject("test3");

Assert.That(actual,
Is.EqualTo(new[] { new CompositeKeySUT("Foo", "Bar", 10), new CompositeKeySUT("Bar", "Baz", 20) })
.Using(new CompositeKeySUTComparer()));
Assert.That(actual, Does.Contain(expected).Using(new GameObjectNameComparer()));
// 失敗時メッセージ例:
// Expected and actual are both <APIExamples.NUnit.CompositeKeySUT[2]>
// Values differ at index [1]
// Expected: <APIExamples.NUnit.CompositeKeySUT>
// But was: <APIExamples.NUnit.CompositeKeySUT>
// Expected: collection containing <test4 (UnityEngine.GameObject)>
// But was: < <test1 (UnityEngine.GameObject)>, <test2 (UnityEngine.GameObject)>, <test3 (UnityEngine.GameObject)> >
}
}

/// <summary>
/// カスタム<see cref="IComparer{T}"/>の実装例
/// カスタム<see cref="IComparer{T}"/>の実装例.
/// このコードは、Test Helperパッケージ(com.nowsprinting.test-helper)内のコードに日本語コメントをつけたものです。
/// </summary>
public class CompositeKeySUTComparer : IComparer<CompositeKeySUT>
public class GameObjectNameComparer : IComparer<GameObject>
{
/// <summary>
/// Key1 + Key2 で比較
/// <c>GameObject</c> 同士を、参照でなく <c>name</c> プロパティで比較するカスタムComparer
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
public int Compare(CompositeKeySUT x, CompositeKeySUT y)
[SuppressMessage("ReSharper", "PossibleNullReferenceException")]
public int Compare(GameObject x, GameObject y)
{
var key1Comparison = string.Compare(x.Key1, y.Key1, StringComparison.Ordinal);
if (key1Comparison != 0)
{
return key1Comparison;
}

return string.Compare(x.Key2, y.Key2, StringComparison.Ordinal);
return string.Compare(x.name, y.name, StringComparison.Ordinal);
}
}
}
116 changes: 78 additions & 38 deletions Assets/APIExamples/Tests/Runtime/NUnit/CustomConstraintExample.cs
Original file line number Diff line number Diff line change
@@ -1,98 +1,138 @@
// Copyright (c) 2021 Koji Hasegawa.
// Copyright (c) 2021-2023 Koji Hasegawa.
// This software is released under the MIT License.

using NUnit.Framework;
using NUnit.Framework.Constraints;
using UnityEngine;

// ReSharper disable AccessToStaticMemberViaDerivedType

namespace APIExamples.NUnit
{
/// <summary>
/// カスタム<see cref="Constraint"/>の使用例
/// カスタム制約の使用例
/// </summary>
[TestFixture]
public class CustomConstraintExample
{
private static GameObject CreateDestroyedObject()
{
var gameObject = new GameObject("Foo");
GameObject.DestroyImmediate(gameObject);
return gameObject;
}

[Test]
public void CustomConstraint_Constraintの実装だけで可能な書きかた()
{
var actual = CreateDestroyedObject();

Assert.That(actual, new DestroyedConstraint());
// 失敗時メッセージ例:
// Expected: destroyed GameObject
// But was: <Foo (UnityEngine.GameObject)>
}

[Test]
public void CustomEqConstraint_Constraintの実装だけで可能な書きかた()
public void CustomConstraint_Extensionsの実装も行なうと可能な書きかた()
{
var actual = "Foo bar";
var actual = CreateDestroyedObject();

Assert.That(actual, new CustomEqConstraint("Foo bar"));
Assert.That(actual, Is.Not.Null.And.Destroyed());
// 失敗時メッセージ例:
// Expected: "Foo bar"(カスタム制約)
// But was: "Foo bar baz"
// Expected: not null and destroyed GameObject
// But was: <Foo (UnityEngine.GameObject)>
}

[Test]
public void CustomEqConstraint_Extensionsの実装も行なうと可能な書きかた()
public void CustomConstraint_Isの実装も行なうと可能な書きかた()
{
var actual = "Foo bar";
var actual = CreateDestroyedObject();

Assert.That(actual, Is.Not.Null.And.CustomEq("Foo bar"));
Assert.That(actual, Is.Destroyed);
// 失敗時メッセージ例:
// Expected: not null and "Foo bar"(カスタム制約)
// But was: "Foo bar baz"
// Expected: destroyed GameObject
// But was: <Foo (UnityEngine.GameObject)>
}

[Test]
public void CustomEqConstraint_Isの実装も行なうと可能な書きかた()
public void CustomConstraint_Isの実装も行なうと可能な書きかた_Not()
{
var actual = "Foo bar";
var actual = new GameObject("Bar");

Assert.That(actual, Is.CustomEq("Foo bar"));
Assert.That(actual, Is.Not.Destroyed());
// 失敗時メッセージ例:
// Expected: "Foo bar"(カスタム制約)
// But was: "Foo bar baz"
// Expected: not destroyed GameObject
// But was: <null>
}
}

/// <summary>
/// カスタム<see cref="Constraint"/>の実装例
/// カスタム制約の実装例.
/// このコードは、Test Helperパッケージ(com.nowsprinting.test-helper)内のコードに日本語コメントをつけたものです。
/// </summary>
/// <remarks>
/// 内容は文字列が一致するか判定しているだけ
/// </remarks>
public class CustomEqConstraint : Constraint
public class DestroyedConstraint : Constraint
{
public CustomEqConstraint(params object[] args) : base(args) { }
public DestroyedConstraint(params object[] args) : base(args)
{
base.Description = "destroyed GameObject"; // 失敗時メッセージに出力される
}

/// <summary>
/// Assert.Thatから渡されるactualオブジェクトを検証する、カスタム制約の本体
/// </summary>
/// <param name="actual">検証対象オブジェクト</param>
/// <returns>制約の成否</returns>
public override ConstraintResult ApplyTo(object actual)
{
return new ConstraintResult(this, actual, actual.ToString() == Arguments[0].ToString());
}
if (actual is GameObject actualGameObject)
{
return new ConstraintResult(this, actual, (bool)actualGameObject == false);
// GameObjectであれば、破棄されているかを判定して結果として返す
}

public override string Description { get { return $"\"{Arguments[0]}\"(カスタム制約)"; } }
return new ConstraintResult(this, actual, false);
// GameObjectでなければ常にfalse
}
}

/// <summary>
/// カスタム<see cref="Constraint"/>向けの<see cref="ConstraintExpression"/>拡張メソッド
/// カスタム制約のための<see cref="ConstraintExpression"/>拡張クラス.
/// このコードは、Test Helperパッケージ(com.nowsprinting.test-helper)内のコードに日本語コメントをつけたものです。
/// </summary>
public static class CustomConstraintExtensions
public static class ConstraintExtensions
{
public static CustomEqConstraint CustomEq(this ConstraintExpression expression, object expected)
/// <summary>
/// カスタム制約のための<see cref="ConstraintExpression"/>拡張メソッド.
/// 式にDestroyedが指定されたとき、Destroyed制約のインスタンスをexpressionに追加して返します。
/// </summary>
/// <param name="expression"></param>
/// <returns>constraint to destroyed GameObject</returns>
public static DestroyedConstraint Destroyed(this ConstraintExpression expression)
// Note: 比較対象がある制約の場合、第2引数で object expected を受け取ります
{
var constraint = new CustomEqConstraint(expected);
var constraint = new DestroyedConstraint();
expression.Append(constraint);
return constraint;
}
}

/// <summary>
/// カスタム<see cref="Constraint"/>向けの<see cref="Is"/>クラス
/// カスタム制約のための<see cref="Is"/>クラス.
/// このコードは、Test Helperパッケージ(com.nowsprinting.test-helper)内のコードに日本語コメントをつけたものです。
/// </summary>
/// <remarks>
/// Unity Test Framework には NUnit.Framework.Is を継承した UnityEngine.TestTools.Constraints.Is がすでにあるため、
/// これを継承して作ります
/// UnityEngine.TestTools.Constraints.Is が必要なければ、直接 global::NUnit.Framework.Is を継承しても構いません。
/// Unity Test Framework には NUnit.Framework.Is を継承した UnityEngine.TestTools.Constraints.Is がすでにあるため、これを継承して作ります。
/// Test Helperパッケージも使用するのであれば、TestHelper.Constraints.Is を継承します
/// UnityEngine.TestTools.Constraints.Is も TestHelper.Constraints.Is も必要なければ、直接 global::NUnit.Framework.Is を継承しても構いません。
/// </remarks>
// ReSharper disable once ClassNeverInstantiated.Global
public class Is : UnityEngine.TestTools.Constraints.Is
{
public static CustomEqConstraint CustomEq(object expected)
{
return new CustomEqConstraint(expected);
}
/// <summary>
/// Create constraint to destroyed GameObject.
/// </summary>
public static DestroyedConstraint Destroyed => new DestroyedConstraint();
// Note: 比較対象がある制約の場合、引数で object expected を受け取ります
}
}

0 comments on commit dc1b643

Please sign in to comment.