<?php
/**
 * Copyright 2018 Kacper Donat
 *
 * @author Kacper "Kadet" Donat <kacper@kadet.net>
 *
 * Full license available in separate LICENSE file
 */

use function Kadet\Functional\predicate;
use Kadet\Functional\Predicate\ConstantPredicate;

class ConstantPredicateTest extends PHPUnit\Framework\TestCase
{
    use RandomDataTrait;

    private function getTestPredicate()
    {
        return function ($arg = null) {
            return is_bool($arg);
        };
    }

    /**
     * @dataProvider randomDataProvider
     */
    public function testNeverAndPredicate(...$args)
    {
        $predicate = ConstantPredicate::never()->and($this->getTestPredicate());

        $this->assertFalse($predicate(...$args));
    }

    /**
     * @dataProvider randomDataProvider
     */
    public function testNeverOrPredicate(...$args)
    {
        $predicate = predicate($this->getTestPredicate());
        $tested    = ConstantPredicate::never()->or($predicate);

        $this->assertSame($predicate(...$args), $tested(...$args));
    }

    /**
     * @dataProvider randomDataProvider
     */
    public function testAlwaysOrPredicate(...$args)
    {
        $predicate = ConstantPredicate::always()->or($this->getTestPredicate());

        $this->assertTrue($predicate(...$args));
    }

    /**
     * @dataProvider randomDataProvider
     */
    public function testAlwaysAndPredicate(...$args)
    {
        $predicate = predicate($this->getTestPredicate());
        $tested    = ConstantPredicate::always()->and($predicate);

        $this->assertSame($predicate(...$args), $tested(...$args));
    }

    /**
     * @dataProvider randomDataProvider
     */
    public function testNever(...$args)
    {
        $tested = ConstantPredicate::never();

        $this->assertFalse($tested(...$args));
    }

    /**
     * @dataProvider randomDataProvider
     */
    public function testNotAlways(...$args)
    {
        $tested = ConstantPredicate::always()->not();

        $this->assertFalse($tested(...$args));
    }

    /**
     * @dataProvider randomDataProvider
     */
    public function testNotNever(...$args)
    {
        $tested = ConstantPredicate::never()->not();

        $this->assertTrue($tested(...$args));
    }

    /**
     * @dataProvider randomDataProvider
     */
    public function testAlways(...$args)
    {
        $tested = ConstantPredicate::always();

        $this->assertTrue($tested(...$args));
    }

    public function testAliases()
    {
        $this->assertSame(\Kadet\Functional\always(), ConstantPredicate::always());
        $this->assertSame(\Kadet\Functional\never(), ConstantPredicate::never());
    }
}