From e8c16a5f8728b90e22346ac3b5c6baa72114bae2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Kucha=C5=99?= <honza.kuchar@grifart.cz>
Date: Mon, 1 May 2017 14:24:35 +0200
Subject: [PATCH] tests: added assertions for assertion messages

---
 src/exceptions.php                            | 17 +++---
 tests/fn.assertSignature.allNullable.phpt     | 56 ++++++++++++++-----
 tests/fn.assertSignature.allRequired.phpt     | 31 ++++++----
 ...ssertSignature.wrongNumberOfArguments.phpt | 16 ++++--
 4 files changed, 82 insertions(+), 38 deletions(-)

diff --git a/src/exceptions.php b/src/exceptions.php
index d2075fd..b5d1414 100644
--- a/src/exceptions.php
+++ b/src/exceptions.php
@@ -28,7 +28,7 @@ final class FunctionSignatureAssertionError extends \AssertionError {
 
 	public static function wrongNumberOrArguments(\ReflectionFunction $reflection, int $numberOfParameters, int $actualCount): self
 	{
-		return new self($reflection,  "Given wrong number of parameters. Expected $numberOfParameters, $actualCount given.");
+		return new self($reflection,  "Wrong number of arguments in given function. Expected $numberOfParameters, $actualCount given.");
 	}
 
 
@@ -52,20 +52,23 @@ final class FunctionSignatureAssertionError extends \AssertionError {
 
 	public static function parameterNullability(\ReflectionFunction $functionReflection, \ReflectionParameter $param, bool $expectedNullable, bool $actuallyNullable): self
 	{
+		$paramIndex = $param->getPosition() + 1; // 0-based indexes are not human-readable
 		return new self(
 			$functionReflection,
 			$expectedNullable
-				? "Function should have parameter {$param->getName()} nullable but it is not."
-				: "Function should have parameter {$param->getName()} required but it is not."
+				? "Parameter #{$paramIndex} (\${$param->getName()}) is expected to be nullable. But it is required."
+				: "Parameter #{$paramIndex} (\${$param->getName()}) is expected to be required. But it is nullable."
 		);
+
 	}
 
 
 	public static function wrongParameterType(\ReflectionFunction $functionReflection, \ReflectionParameter $parameterReflection, string $expectedParameterType, \ReflectionType $actualParameterType): self
 	{
+		$paramIndex = ($parameterReflection->getPosition() + 1);
 		return new self(
 			$functionReflection,
-			"Wrong parameter type given in function {$parameterReflection}. {$expectedParameterType} expected. {$actualParameterType} defined in function."
+			"Given function parameter #{$paramIndex} \${$parameterReflection->getName()} has type {$parameterReflection->getType()}. However this parameter is expected to be {$expectedParameterType}."
 		);
 	}
 
@@ -75,8 +78,8 @@ final class FunctionSignatureAssertionError extends \AssertionError {
 		return new self(
 			$reflectionFunction,
 			$expectingNullable
-				? 'Wrong return type nullability. Expecting nullable, but was required.'
-				: 'Wrong return type nullability. Expecting required, but was nullable.'
+				? 'Return-type is expected to be nullable. But it is required.'
+				: 'Return-type is expected to be required. But it is nullable.'
 		);
 	}
 
@@ -85,7 +88,7 @@ final class FunctionSignatureAssertionError extends \AssertionError {
 	{
 		return new self(
 			$reflection,
-			"Expected return type of type '$expectedReturnType', but function declares '$actualReturnType'"
+			"Expected return type of type '$expectedReturnType', but given function declares '$actualReturnType'."
 		);
 	}
 };
diff --git a/tests/fn.assertSignature.allNullable.phpt b/tests/fn.assertSignature.allNullable.phpt
index a89737a..1398408 100644
--- a/tests/fn.assertSignature.allNullable.phpt
+++ b/tests/fn.assertSignature.allNullable.phpt
@@ -3,30 +3,56 @@ namespace MyTestNamespace;
 require __DIR__ . '/bootstrap.php';
 require __DIR__ . '/testClasses.php';
 use function Grifart\AssertFunction\{assertSignature, nullable, params};
+use Grifart\AssertFunction\FunctionSignatureAssertionError;
 use Tester\Assert;
+$place = 'tests/' . basename(__FILE__) . ':' . (__LINE__ +2) . ' ';
 
 $fn = function(?T1 $t1, ?T2 $t2): ?T3 {return new T3;};
+
+// Correct signature assertion
 assertSignature($fn, params(nullable(T1::class), nullable(T2::class)), nullable(T3::class));
 
 // parameter is nullable, non-nullable is expected
-Assert::exception(function () use ($fn) { // 1st param
-	assertSignature($fn, params(T1::class, nullable(T2::class)), nullable(T3::class));
-}, \AssertionError::class /* todo: assert message */);
+Assert::exception(
+	function () use ($fn) { // 1st param
+		assertSignature($fn, params(T1::class, nullable(T2::class)), nullable(T3::class));
+	},
+	FunctionSignatureAssertionError::class,
+	$place . 'Parameter #1 ($t1) is expected to be required. But it is nullable.'
+);
 
-Assert::exception(function () use ($fn) { // 2nd param
-	assertSignature($fn, params(nullable(T1::class), T2::class), nullable(T3::class));
-}, \AssertionError::class /* todo: assert message */);
+Assert::exception(
+	function () use ($fn) { // 2nd param
+		assertSignature($fn, params(nullable(T1::class), T2::class), nullable(T3::class));
+	},
+	FunctionSignatureAssertionError::class,
+	$place . 'Parameter #2 ($t2) is expected to be required. But it is nullable.'
+);
 
-Assert::exception(function () use ($fn) { // return type
-	assertSignature($fn, params(nullable(T1::class), nullable(T2::class)), T3::class);
-}, \AssertionError::class /* todo: assert message */);
+Assert::exception(
+	function () use ($fn) { // return type
+		assertSignature($fn, params(nullable(T1::class), nullable(T2::class)), T3::class);
+	},
+	FunctionSignatureAssertionError::class,
+	$place . 'Return-type is expected to be required. But it is nullable.'
+);
 
 // Wrong return type
-Assert::exception(function () use ($fn) {
-	assertSignature($fn, params(nullable(T1::class), nullable(T2::class)), nullable(T2::class));
-}, \AssertionError::class /* todo: assert message */);
+Assert::exception(
+	function () use ($fn) {
+		assertSignature($fn, params(nullable(T1::class), nullable(T2::class)), nullable(T2::class));
+	},
+	FunctionSignatureAssertionError::class,
+	$place . "Expected return type of type '" . T2::class . "', "
+		. "but given function declares '" . T3::class . "'."
+);
 
 // Wrong parameter type
-Assert::exception(function () use ($fn) {
-	assertSignature($fn, params(nullable(T1::class), nullable(T1::class)), nullable(T3::class));
-}, \AssertionError::class /* todo: assert message */);
+Assert::exception(
+	function () use ($fn) {
+		assertSignature($fn, params(nullable(T1::class), nullable(T1::class)), nullable(T3::class));
+	},
+	FunctionSignatureAssertionError::class,
+	$place . 'Given function parameter #2 $t2 has type ' . T2::class . '. '
+		. 'However this parameter is expected to be ' . T1::class . '.'
+);
diff --git a/tests/fn.assertSignature.allRequired.phpt b/tests/fn.assertSignature.allRequired.phpt
index 227e440..5f1b0a1 100644
--- a/tests/fn.assertSignature.allRequired.phpt
+++ b/tests/fn.assertSignature.allRequired.phpt
@@ -3,22 +3,33 @@ namespace MyTestNamespace;
 require __DIR__ . '/bootstrap.php';
 require __DIR__ . '/testClasses.php';
 use function Grifart\AssertFunction\{assertSignature, nullable, params};
+use Grifart\AssertFunction\FunctionSignatureAssertionError;
 use Tester\Assert;
 
+$place = 'tests/' . basename(__FILE__) . ':' . (__LINE__ +2) . ' ';
 
 $f1 = function(T1 $t1, T2 $t2): T3 {return new T3;};
 
 // Positive scenario
 assertSignature($f1, params(T1::class, T2::class), T3::class);
-assertSignature($f1, [T1::class, T2::class], T3::class); // alternative syntax
+assertSignature($f1, [T1::class, T2::class], T3::class); // alternative shorter less-self explaining syntax
 
-// Optional by accident: parameter
-Assert::exception(function () use ($f1) {
-	assertSignature($f1, params(nullable(T1::class), T2::class), T3::class);
-}, \AssertionError::class);
+// Requires optional parameter, function has required
+Assert::exception(
+	function () use ($f1) {
+		assertSignature($f1, params(nullable(T1::class), T2::class), T3::class);
+	},
+	FunctionSignatureAssertionError::class,
+	$place . 'Parameter #1 ($t1) is expected to be nullable. '
+		. 'But it is required.'
+);
 
-// Optional by accident: return type
-Assert::exception(function () use ($f1) {
-	assertSignature($f1, params(T1::class, T2::class), nullable(T3::class));
-//	assertFunction($f1, [params(T1::class, T2::class) => nullable(T3::class)]);
-}, \AssertionError::class);
+// Requires optional return type, function has required
+Assert::exception(
+	function () use ($f1) {
+		assertSignature($f1, params(T1::class, T2::class), nullable(T3::class));
+	},
+	FunctionSignatureAssertionError::class,
+	$place . 'Return-type is expected to be nullable. '
+		. 'But it is required.'
+);
diff --git a/tests/fn.assertSignature.wrongNumberOfArguments.phpt b/tests/fn.assertSignature.wrongNumberOfArguments.phpt
index af4f147..8b6667c 100644
--- a/tests/fn.assertSignature.wrongNumberOfArguments.phpt
+++ b/tests/fn.assertSignature.wrongNumberOfArguments.phpt
@@ -2,9 +2,13 @@
 namespace MyTestNamespace;
 require __DIR__ . '/bootstrap.php';
 require __DIR__ . '/testClasses.php';
-use function Grifart\AssertFunction\{assertSignature, nullable, params};
+use Grifart\AssertFunction\FunctionSignatureAssertionError;
 use Tester\Assert;
-$position = 'tests/fn.assertSignature.wrongNumberOfArguments.phpt:9';
+use function Grifart\AssertFunction\{
+	assertSignature, params
+};
+
+$position = 'tests/' . basename(__FILE__) . ':' . (__LINE__ + 2);
 
 $f1 = function(T1 $t1, T2 $t2): T3 {return new T3;};
 
@@ -13,14 +17,14 @@ Assert::exception(
 	function () use ($f1) {
 		assertSignature($f1, params(T1::class), T3::class);
 	},
-	\AssertionError::class,
-	"$position Given wrong number of parameters. Expected 1, 2 given."
+	FunctionSignatureAssertionError::class,
+	"$position Wrong number of arguments in given function. Expected 1, 2 given."
 );
 
 Assert::exception(
 	function () use ($f1) {
 		assertSignature($f1, params(T1::class, T2::class, T1::class), T3::class);
 	},
-	\AssertionError::class,
-	"$position Given wrong number of parameters. Expected 3, 2 given."
+	FunctionSignatureAssertionError::class,
+	"$position Wrong number of arguments in given function. Expected 3, 2 given."
 );
-- 
GitLab