/
home
/
sjslayjy
/
public_html
/
theweavenest
/
vendor
/
phpunit
/
phpunit
/
tests
/
unit
/
Framework
/
Constraint
/
Upload File
HOME
<?php declare(strict_types=1); /* * This file is part of PHPUnit. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace PHPUnit\Framework\Constraint; use function array_map; use function sprintf; use PHPUnit\Framework\ExpectationFailedException; use PHPUnit\TestFixture\BooleanConstraint; use PHPUnit\TestFixture\CountConstraint; use PHPUnit\TestFixture\NamedConstraint; use ReflectionClass; use ReflectionMethod; abstract class UnaryOperatorTestCase extends OperatorTestCase { /** * Shall return the name of the operator under test. */ abstract public static function getOperatorName(): string; /** * Shall return the precedence of the operator under test. */ abstract public static function getOperatorPrecedence(): int; /** * Shall return series of two-element arrays [$input, $expected]. */ abstract public function providerToStringWithNativeTransformations(); /** * Takes a boolean values and returns the expected evaluation result for * the logical operator under test. */ abstract public function evaluateExpectedResult(bool $input): bool; final public function testIsSubclassOfOperator(): void { $className = $this->className(); $reflection = new ReflectionClass($className); $this->assertTrue($reflection->isSubclassOf(Operator::class), sprintf( 'Failed to assert that "%s" is subclass of "%s".', $className, Operator::class, )); } final public function testOperatorName(): void { $className = $this->className(); $constraint = new $className($this->getMockBuilder(Constraint::class)->getMock()); $this->assertSame($this->getOperatorName(), $constraint->operator()); } final public function testOperatorPrecedence(): void { $className = $this->className(); $constraint = new $className($this->getMockBuilder(Constraint::class)->getMock()); $this->assertSame($this->getOperatorPrecedence(), $constraint->precedence()); } final public function testOperatorCount(): void { $className = $this->className(); $constraint = new $className(CountConstraint::fromCount(3)); $this->assertSame(3, $constraint->count()); } final public function testOperatorArity(): void { $className = $this->className(); $constraint = new $className(CountConstraint::fromCount(3)); $this->assertSame(1, $constraint->arity()); } final public function testConstructorAcceptsConstraintArgument(): void { $className = $this->className(); $nice = $this->getMockBuilder(Constraint::class) ->onlyMethods(['toStringInContext']) ->getMockForAbstractClass(); $constraint = new $className($nice); $string = 'is ' . $this->getOperatorName() . ' nice'; $nice->expects($this->once()) ->method('toStringInContext') ->with($this->identicalTo($constraint), 0) ->willReturn($string); $this->assertSame($string, $constraint->toString()); } public function testNonRestrictedConstructParameterIsHandled(): void { $className = $this->className(); $constraint = new $className('test'); $withIsEqual = new $className(new IsEqual('test')); $this->assertSame($withIsEqual->toString(), $constraint->toString()); } final public function providerUnaryTruthTable() { return array_map(function (bool $input): array { return [$input, $this->evaluateExpectedResult($input)]; }, [false, true]); } /** * @dataProvider providerUnaryTruthTable */ final public function testEvaluateReturnsCorrectBooleanResult(bool $input, bool $expected): void { $operand = BooleanConstraint::fromBool($input); $className = $this->className(); $constraint = new $className($operand); $message = 'Failed asserting that ' . $constraint->toString() . ' is ' . ($expected ? 'true' : 'false'); $this->assertSame($expected, $constraint->evaluate(null, '', true), $message); } /** * @dataProvider providerUnaryTruthTable */ final public function testEvaluateReturnsNullOnSuccessAndThrowsExceptionOnFailure(bool $input, bool $expected): void { $operand = BooleanConstraint::fromBool($input); $className = $this->className(); $constraint = new $className($operand); if ($expected) { $this->assertNull($constraint->evaluate(null)); return; } $expectedString = $operand->toString(); $message = "Failed asserting that 'the following expression is not true' " . $expectedString; $this->expectException(ExpectationFailedException::class); $this->expectExceptionMessage($message); $constraint->evaluate('the following expression is true'); } /** * @dataProvider providerToStringWithNativeTransformations */ final public function testToStringWithNativeTransformations(string $input, string $expected): void { $operand = NamedConstraint::fromName($input); $className = $this->className(); $constraint = new $className($operand); $this->assertSame($expected, $constraint->toString()); } public function testToStringWithNonContextualTerminalConstraint(): void { $methods = [ 'toStringInContext', 'toString', ]; $operand = $this->getMockBuilder(Constraint::class) ->onlyMethods($methods) ->getMockForAbstractClass(); $className = $this->className(); $operator = new $className($operand); $string = 'John Smith'; $operand->expects($this->once()) ->method('toStringInContext') ->with($this->identicalTo($operator), 0) ->willReturn(''); $operand->expects($this->once()) ->method('toString') ->with() ->willReturn($string); $this->assertSame($string, $operator->toString()); } public function testToStringWithContextualTerminalConstraint(): void { $methods = [ 'toStringInContext', 'toString', ]; $operand = $this->getMockBuilder(Constraint::class) ->onlyMethods($methods) ->getMockForAbstractClass(); $className = $this->className(); $operator = new $className($operand); $string = 'John ' . $this->getOperatorName() . ' Smith'; $operand->expects($this->once()) ->method('toStringInContext') ->with($this->identicalTo($operator), 0) ->willReturn($string); $operand->expects($this->never()) ->method('toString'); $this->assertSame($string, $operator->toString()); } public function testToStringWithContextualUnaryOperator(): void { $methods = [ 'toStringInContext', 'toString', 'arity', 'precedence', ]; $operand = $this->getMockBuilder(Operator::class) ->onlyMethods($methods) ->getMockForAbstractClass(); $className = $this->className(); $operator = new $className($operand); $string = 'John ' . $this->getOperatorName() . ' Smith'; $operand->expects($this->once()) ->method('arity') ->with() ->willReturn(1); $operand->expects($this->never()) ->method('precedence'); $operand->expects($this->once()) ->method('toStringInContext') ->with($this->identicalTo($operator), 0) ->willReturn($string); $operand->expects($this->never()) ->method('toString'); $this->assertSame($string, $operator->toString()); } public function testToStringWithNonContextualBinaryOperatorOfHigherPrecedence(): void { $methods = [ 'toStringInContext', 'toString', 'arity', 'precedence', ]; $operand = $this->getMockBuilder(Operator::class) ->onlyMethods($methods) ->getMockForAbstractClass(); $className = $this->className(); $operator = new $className($operand); $string = 'tree of apples'; $operand->expects($this->once()) ->method('arity') ->with() ->willReturn(2); $operand->expects($this->once()) ->method('precedence') ->with() ->willReturn(-1); $operand->expects($this->once()) ->method('toStringInContext') ->with($this->identicalTo($operator), 0) ->willReturn(''); $operand->expects($this->once()) ->method('toString') ->with() ->willReturn($string); $this->assertSame($string, $operator->toString()); } public function testToStringWithContextualBinaryOperatorOfHigherPrecedence(): void { $methods = [ 'toStringInContext', 'toString', 'arity', 'precedence', ]; $operand = $this->getMockBuilder(Operator::class) ->onlyMethods($methods) ->getMockForAbstractClass(); $className = $this->className(); $operator = new $className($operand); $string = 'tree of apples'; $operand->expects($this->once()) ->method('arity') ->with() ->willReturn(2); $operand->expects($this->once()) ->method('precedence') ->with() ->willReturn(-1); $operand->expects($this->once()) ->method('toStringInContext') ->with($this->identicalTo($operator), 0) ->willReturn($string); $operand->expects($this->never()) ->method('toString'); $this->assertSame($string, $operator->toString()); } public function testToStringWithBinaryOperatorOfLowerPrecedence(): void { $methods = [ 'toStringInContext', 'toString', 'arity', 'precedence', ]; $operand = $this->getMockBuilder(Operator::class) ->onlyMethods($methods) ->getMockForAbstractClass(); $className = $this->className(); $operator = new $className($operand); $string = 'apple or banana'; $operand->expects($this->once()) ->method('arity') ->with() ->willReturn(2); $operand->expects($this->once()) ->method('precedence') ->with() ->willReturn(10000); $operand->expects($this->never()) ->method('toStringInContext'); $operand->expects($this->once()) ->method('toString') ->with() ->willReturn($string); $expected = $this->getOperatorName() . '( ' . $string . ' )'; $this->assertSame($expected, $operator->toString()); } /** * @dataProvider providerToStringWithNativeTransformations */ public function testFailureDescriptionWithNativeTransformations(string $input, string $expected): void { $operand = NamedConstraint::fromName($input); $className = $this->className(); $constraint = new $className($operand); $method = (new ReflectionMethod($className, 'failureDescription')); $method->setAccessible(true); $this->assertSame("'whatever' " . $expected, $method->invokeArgs($constraint, ['whatever'])); } public function testFailureDescriptionWithNonContextualTerminalConstraint(): void { $methods = [ 'toStringInContext', 'toString', ]; $operand = $this->getMockBuilder(Constraint::class) ->onlyMethods($methods) ->getMockForAbstractClass(); $className = $this->className(); $operator = new $className($operand); $string = 'John Smith'; $operand->expects($this->once()) ->method('toStringInContext') ->with($this->identicalTo($operator), 0) ->willReturn(''); $operand->expects($this->once()) ->method('toString') ->with() ->willReturn($string); $method = (new ReflectionMethod($className, 'failureDescription')); $method->setAccessible(true); $expected = "'whatever' " . $string; $this->assertSame($expected, $method->invokeArgs($operator, ['whatever'])); } public function testFailureDescriptionWithContextualTerminalConstraint(): void { $methods = [ 'toStringInContext', 'toString', ]; $operand = $this->getMockBuilder(Constraint::class) ->onlyMethods($methods) ->getMockForAbstractClass(); $className = $this->className(); $operator = new $className($operand); $string = 'John ' . $this->getOperatorName() . ' Smith'; $operand->expects($this->once()) ->method('toStringInContext') ->with($this->identicalTo($operator), 0) ->willReturn($string); $operand->expects($this->never()) ->method('toString'); $method = (new ReflectionMethod($className, 'failureDescription')); $method->setAccessible(true); $expected = "'whatever' " . $string; $this->assertSame($expected, $method->invokeArgs($operator, ['whatever'])); } public function testFailureDescriptionWithContextualUnaryOperator(): void { $methods = [ 'toStringInContext', 'toString', 'arity', 'precedence', ]; $operand = $this->getMockBuilder(Operator::class) ->onlyMethods($methods) ->getMockForAbstractClass(); $className = $this->className(); $operator = new $className($operand); $string = 'John ' . $this->getOperatorName() . ' Smith'; $operand->expects($this->once()) ->method('arity') ->with() ->willReturn(1); $operand->expects($this->never()) ->method('precedence'); $operand->expects($this->once()) ->method('toStringInContext') ->with($this->identicalTo($operator), 0) ->willReturn($string); $operand->expects($this->never()) ->method('toString'); $method = (new ReflectionMethod($className, 'failureDescription')); $method->setAccessible(true); $expected = "'whatever' " . $string; $this->assertSame($expected, $method->invokeArgs($operator, ['whatever'])); } public function testFailureDescriptionWithNonContextualBinaryOperatorOfHigherPrecedence(): void { $methods = [ 'toStringInContext', 'toString', 'arity', 'precedence', ]; $operand = $this->getMockBuilder(Operator::class) ->onlyMethods($methods) ->getMockForAbstractClass(); $className = $this->className(); $operator = new $className($operand); $string = 'tree of apples'; $operand->expects($this->once()) ->method('arity') ->with() ->willReturn(2); $operand->expects($this->once()) ->method('precedence') ->with() ->willReturn(-1); $operand->expects($this->once()) ->method('toStringInContext') ->with($this->identicalTo($operator), 0) ->willReturn(''); $operand->expects($this->once()) ->method('toString') ->with() ->willReturn($string); $method = (new ReflectionMethod($className, 'failureDescription')); $method->setAccessible(true); $expected = "'whatever' " . $string; $this->assertSame($expected, $method->invokeArgs($operator, ['whatever'])); } public function testFailureDescriptionWithContextualBinaryOperatorOfHigherPrecedence(): void { $methods = [ 'toStringInContext', 'toString', 'arity', 'precedence', ]; $operand = $this->getMockBuilder(Operator::class) ->onlyMethods($methods) ->getMockForAbstractClass(); $className = $this->className(); $operator = new $className($operand); $string = 'tree of apples'; $operand->expects($this->once()) ->method('arity') ->with() ->willReturn(2); $operand->expects($this->once()) ->method('precedence') ->with() ->willReturn(-1); $operand->expects($this->once()) ->method('toStringInContext') ->with($this->identicalTo($operator), 0) ->willReturn($string); $operand->expects($this->never()) ->method('toString'); $method = (new ReflectionMethod($className, 'failureDescription')); $method->setAccessible(true); $expected = "'whatever' " . $string; $this->assertSame($expected, $method->invokeArgs($operator, ['whatever'])); } public function testFailureDescriptionWithBinaryOperatorOfLowerPrecedence(): void { $methods = [ 'toStringInContext', 'toString', 'arity', 'precedence', ]; $operand = $this->getMockBuilder(Operator::class) ->onlyMethods($methods) ->getMockForAbstractClass(); $className = $this->className(); $operator = new $className($operand); $string = 'apple or banana'; $operand->expects($this->once()) ->method('arity') ->with() ->willReturn(2); $operand->expects($this->once()) ->method('precedence') ->with() ->willReturn(10000); $operand->expects($this->never()) ->method('toStringInContext'); $operand->expects($this->once()) ->method('toString') ->with() ->willReturn($string); $method = (new ReflectionMethod($className, 'failureDescription')); $method->setAccessible(true); $expected = $this->getOperatorName() . "( 'whatever' " . $string . ' )'; $this->assertSame($expected, $method->invokeArgs($operator, ['whatever'])); } }