<?php

namespace airmoi\FileMaker\Object;

use airmoi\FileMaker\FileMaker;
use airmoi\FileMaker\FileMakerValidationException;

/**
 * Generated by PHPUnit_SkeletonGenerator on 2016-09-09 at 19:46:51.
 */
class FieldTest extends \PHPUnit_Framework_TestCase
{

    /**
     * @var FileMaker
     */
    protected $fm;

    /**
     * @var Record
     */
    protected $record;

    public static function setUpBeforeClass()
    {
        parent::setUpBeforeClass();
        $fm = new FileMaker($GLOBALS['DB_FILE'], $GLOBALS['DB_HOST'], $GLOBALS['DB_USER'], $GLOBALS['DB_PASSWD']);
        $fm->newPerformScriptCommand('sample', 'create sample data', 10)->execute();
    }
    /**
     * Sets up the fixture, for example, opens a network connection.
     * This method is called before a test is executed.
     */
    protected function setUp()
    {
        if ($GLOBALS['OFFICIAL_API'] == 1) {
            $this->fm = new \FileMaker($GLOBALS['DB_FILE'], $GLOBALS['DB_HOST'], $GLOBALS['DB_USER'], $GLOBALS['DB_PASSWD']);
        } else {
            $this->fm = new FileMaker($GLOBALS['DB_FILE'], $GLOBALS['DB_HOST'], $GLOBALS['DB_USER'], $GLOBALS['DB_PASSWD'], ['errorHandling' => 'exception']);
        }

        $this->record = $this->fm->newFindAnyCommand('sample')->execute()->getFirstRecord();
    }

    /**
     * Tears down the fixture, for example, closes a network connection.
     * This method is called after a test is executed.
     */
    protected function tearDown()
    {
    }

    /**
     * @covers \airmoi\FileMaker\Object\Field::getName
     */
    public function testGetName()
    {
        $field = $this->record->layout->getField('text_field');
        $this->assertEquals('text_field', $field->getName());
    }

    /**
     * @covers \airmoi\FileMaker\Object\Field::getLayout
     */
    public function testGetLayout()
    {
        $field = $this->record->layout->getField('text_field');
        $this->assertEquals($this->record->layout, $field->getLayout());
    }

    /**
     * @covers \airmoi\FileMaker\Object\Field::isAutoEntered
     */
    public function testIsAutoEntered()
    {
        $field = $this->record->layout->getField('id');
        $this->assertTrue($field->isAutoEntered());
    }

    /**
     * @covers \airmoi\FileMaker\Object\Field::isGlobal
     */
    public function testIsGlobal()
    {

        $field = $this->record->layout->getField('global_field');
        $this->assertTrue($field->isGlobal());
    }

    /**
     * @covers \airmoi\FileMaker\Object\Field::getRepetitionCount
     */
    public function testGetRepetitionCount()
    {
        $field = $this->record->layout->getField('text_field');
        $this->assertEquals(4, $field->getRepetitionCount());
    }

    /**
     * @covers \airmoi\FileMaker\Object\Field::validate
     */
    public function testValidateNotEmpty()
    {
        //Valid values
        $validValues = ["0", "1", 0, 1, "toto", "06/21/2017"];
        foreach ($validValues as $value) {
            $this->record->setField('text_field', $value);
            $this->record->validate('text_field');
        }

        //Invalid Values
        $invalidValues = ['', null, [], [1]];
        foreach ($invalidValues as $value) {
            $e = null;
            try {
                $this->record->setField('text_field', $value);
                $this->record->validate('text_field');
            } catch (FileMakerValidationException $e) {}

            $this->assertInstanceOf(FileMakerValidationException::class, $e);
        }
    }

    /**
     * @covers \airmoi\FileMaker\Object\Field::validate
     */
    public function testValidateNumericOnly()
    {
        $validValues = ["0", "21", 0, 1];
        foreach ($validValues as $value) {
            $this->record->setField('number_field', $value);
            $this->record->validate('number_field');
        }

        //Empty value
        $this->record->setField('number_field', "");
        $this->record->validate('number_field');

        //null value
        $this->record->setField('number_field', null);
        $this->record->validate('number_field');

        $invalidValues = ["some string",[1]];
        foreach ($invalidValues as $value) {
            $e = null;
            try {
                $this->record->setField('number_field', $value);
                $this->record->validate('number_field');
            } catch (FileMakerValidationException $e) {

            }
            $this->assertInstanceOf(FileMakerValidationException::class, $e);
        }
    }

    /**
     * @covers \airmoi\FileMaker\Object\Field::validate
     */
    public function testValidateFourDigitDate()
    {
        //Test with date Field
        //DateFormat auto convert 2 to 4 digits
        $validValues = ["06/17/2017", "01/01/2000"];
        foreach ($validValues as $value) {
            $this->record->setField('dateFourDigit_field', $value);
            $this->record->validate('dateFourDigit_field');
        }


        /*$invalidValues = ["06/17/17"];
        foreach ($invalidValues as $value) {
            $this->fm->dateFormat = 'm/d/y';
            $e = null;
            try {
                $this->record->setField('dateFourDigit_field', $value);
                $this->record->validate('dateFourDigit_field');
            } catch (FileMakerValidationException $e) {

            }
            $this->assertInstanceOf(FileMakerValidationException::class, $e);
        }*/

        //Test with Timestamp Field
        //DateFormat auto convert 2 to 4 digits
        $validValues = ["06/17/2017 00:00:00", "01/01/2017 00:00:00"];
        foreach ($validValues as $value) {
            $this->record->setField('timestamp_field', $value);
            $this->record->validate('timestamp_field');
        }


        /*$invalidValues = ["06/17/17 00:00:00"];
        foreach ($invalidValues as $value) {
            $e = null;
            try {
                $this->record->setField('timestamp_field', $value);
                $this->record->validate('timestamp_field');
            } catch (FileMakerValidationException $e) {

            }
            $this->assertInstanceOf(FileMakerValidationException::class, $e);
        }*/

        //Test with text Fields
        $validValues = ["06/17/2017"];
        foreach ($validValues as $value) {
            $this->record->setField('textFourDigitDate_field', $value);
            $this->record->validate('textFourDigitDate_field');
        }


        $invalidValues = ["06/17/17"];
        foreach ($invalidValues as $value) {
            $e = null;
            try {
                $this->record->setField('textFourDigitDate_field', $value);
                $this->record->validate('textFourDigitDate_field');
            } catch (FileMakerValidationException $e) {

            }
            $this->assertInstanceOf(FileMakerValidationException::class, $e);
        }
    }

    /**
     * @covers \airmoi\FileMaker\Object\Field::getLocalValidationRules
     */
    public function testGetLocalValidationRules()
    {
        $field = $this->record->layout->getField('text_field');
        $this->assertEquals(2, sizeof($field->getLocalValidationRules()));
    }

    /**
     * @covers \airmoi\FileMaker\Object\Field::getMaxCharacters
     */
    public function testGetMaxCharacters()
    {
        $field = $this->record->layout->getField('text_field');
        $this->assertEquals(50, $field->getMaxCharacters());
    }

    /**
     * @covers \airmoi\FileMaker\Object\Field::getValidationRules
     */
    public function testGetValidationRules()
    {
        $field = $this->record->layout->getField('text_field');
        $this->assertEquals(2, sizeof($field->getValidationRules()));
    }

    /**
     * @covers \airmoi\FileMaker\Object\Field::getValidationMask
     */
    public function testGetValidationMask()
    {
        $field = $this->record->layout->getField('text_field');
        $this->assertEquals(3, $field->getValidationMask());
    }

    /**
     * @covers \airmoi\FileMaker\Object\Field::hasValidationRule
     */
    public function testHasValidationRule()
    {
        $field = $this->record->layout->getField('text_field');
        $this->assertEquals(true, $field->hasValidationRule(FileMaker::RULE_NOTEMPTY));
        $this->assertEquals(true, $field->hasValidationRule(FileMaker::RULE_MAXCHARACTERS));
    }

    /**
     * @covers \airmoi\FileMaker\Object\Field::describeValidationRule
     */
    public function testDescribeValidationRule()
    {
        $field = $this->record->layout->getField('text_field');
        $this->assertEquals(null, $field->describeValidationRule(FileMaker::RULE_NOTEMPTY));
    }

    /**
     * @covers \airmoi\FileMaker\Object\Field::describeLocalValidationRules
     * @todo   Implement testDescribeLocalValidationRules().
     */
    public function testDescribeLocalValidationRules()
    {
        // Remove the following lines when you implement this test.
        $this->markTestIncomplete(
            'This test has not been implemented yet.'
        );
    }

    /**
     * @covers \airmoi\FileMaker\Object\Field::describeValidationRules
     * @todo   Implement testDescribeValidationRules().
     */
    public function testDescribeValidationRules()
    {
        // Remove the following lines when you implement this test.
        $this->markTestIncomplete(
            'This test has not been implemented yet.'
        );
    }

    /**
     * @covers \airmoi\FileMaker\Object\Field::getResult
     */
    public function testGetResult()
    {
        $field = $this->record->layout->getField('text_field');
        $this->assertEquals('text', $field->getResult());
    }

    /**
     * @covers \airmoi\FileMaker\Object\Field::getType
     */
    public function testGetType()
    {
        $field = $this->record->layout->getField('text_field');
        $this->assertEquals('normal', $field->getType());

        $field = $this->record->layout->getField('calculation_field');
        $this->assertEquals('calculation', $field->getType());

        $field = $this->record->layout->getField('summary_field');
        $this->assertEquals('summary', $field->getType());
    }

    /**
     * @covers \airmoi\FileMaker\Object\Field::getValueList
     */
    public function testGetValueList()
    {
        $field = $this->record->layout->getField('text_field');
        $this->assertEquals(['Hello',  'World'], $field->getValueList());
    }

    /**
     * @covers \airmoi\FileMaker\Object\Field::getStyleType
     */
    public function testGetStyleType()
    {
        $field = $this->record->layout->getField('text_field');
        $this->assertEquals('POPUPLIST', $field->getStyleType());
    }

    /**
     * @covers \airmoi\FileMaker\Object\Field::checkTimeStampFormatFourDigitYear
     */
    public function testCheckTimeStampFormatFourDigitYear()
    {
        $field = $this->record->layout->getField('timestamp_field');
        //Valid values
        $validValues = [
            "06/12/2004 00:00:00",
            "06-12/2004 00:00:00",
            "06-12\\2004 00:00:00",
            "06/12/2004 16:10:00",
            "06/12/2004 4:00 PM",
            "06/12/2004 4:00 aM",
            "06/12/2004 4:00:00 Pm",
        ];
        foreach ($validValues as $value) {
            $this->assertEquals(1, $field->checkTimeStampFormatFourDigitYear($value), 'value : ' . $value);
        }

        //Invalid Values
        $invalidValues = [
            "06/12/2004",
            "01:04",
            "foo bar",
            0,
            true,
            null,
        ];
        foreach ($invalidValues as $value) {
            $this->assertEquals(0, $field->checkTimeStampFormatFourDigitYear($value), 'value : ' . $value);
        }
    }

    /**
     * @covers \airmoi\FileMaker\Object\Field::checkTimeStampFormat
     */
    public function testCheckTimeStampFormat()
    {
        $field = $this->record->layout->getField('timestamp_field');
        //Valid values
        $validValues = [
            "06/12/04 00:00:00",
            "06-12-04 00:00:00",
            "06\\12\\04 00:00:00",
            "06/12/004 16:10:00",
            "06/12/1004 4:00 PM",
            "06/12/4 4:00 aM",
            "06/12/2004 4:00:00 Pm",
        ];
        foreach ($validValues as $value) {
            $this->assertEquals(1, $field->checkTimeStampFormat($value), 'value : ' . $value);
        }

        //Invalid Values
        $invalidValues = [
            "06/12/2004",
            "01:04",
            "foo bar",
            0,
            true,
            null,
        ];
        foreach ($invalidValues as $value) {
            $this->assertEquals(0, $field->checkTimeStampFormat($value), 'value : ' . $value);
        }
    }

    /**
     * @covers \airmoi\FileMaker\Object\Field::checkDateFormat
     */
    public function testCheckDateFormat()
    {
        $field = $this->record->layout->getField('timestamp_field');
        //Valid values
        $validValues = [
            "06/12/04",
            "06-12-04",
            "06\\12\\04",
            "06/12/004",
            "06/12/2004",
        ];
        foreach ($validValues as $value) {
            $this->assertEquals(1, $field->checkDateFormat($value), 'value : ' . $value);
        }

        //Invalid Values
        $invalidValues = [
            "106/12/2004",
            "01:04",
            "foo bar",
            0,
            true,
            null,
        ];
        foreach ($invalidValues as $value) {
            $this->assertEquals(0, $field->checkDateFormat($value), 'value : ' . $value);
        }
    }

    /**
     * @covers \airmoi\FileMaker\Object\Field::checkTimeFormat
     */
    public function testCheckTimeFormat()
    {
        $field = $this->record->layout->getField('time_field');
        //Valid values
        $validValues = [
            "04:30",
            "04:01:53",
            "04:01:53 PM",
            "16:30",
            "16:30:00",
            "02:30 Pm",
            "02:30 AM",
            "02:30 aM",
        ];
        foreach ($validValues as $value) {
            $this->assertEquals(1, $field->checkTimeFormat($value), 'value : ' . $value);
        }

        //Invalid Values
        $invalidValues = [
            "06/12/2004",
            "foo bar",
            0,
            true,
            null,
        ];
        foreach ($invalidValues as $value) {
            $this->assertEquals(0, $field->checkTimeFormat($value), 'value : ' . $value);
        }
    }

    /**
     * @covers \airmoi\FileMaker\Object\Field::checkNumericOnly
     */
    public function testCheckNumericOnly()
    {
        $field = $this->record->layout->getField('number_field');
        //Valid values
        $validValues = [
            1,
            205,
            2E+003,
            6.88713E+009,
            "2E3",
            "6.88713E+009",
            "25",
            "0",
            10^4,
        ];
        foreach ($validValues as $value) {
            $this->assertFalse( $field->checkNumericOnly($value), 'value : ' . $value);
        }

        //Invalid Values
        $invalidValues = [
            "06/12/2004",
            "foo bar",
            true,
            null,
        ];
        foreach ($invalidValues as $value) {
            $this->assertTrue( $field->checkNumericOnly($value), 'value : ' . $value);
        }
    }

    /**
     * @covers \airmoi\FileMaker\Object\Field::checkDateValidity
     */
    public function testCheckDateValidity()
    {
        $field = $this->record->layout->getField('timestamp_field');
        //Valid values
        $validValues = [
            "06/12/00",
            "06/12/04",
            "06-12-04",
            "06\\12\\04",
            "01/27/004",
            "12/30/2017",
        ];
        foreach ($validValues as $value) {
            $exception = new FileMakerValidationException($this->fm);
            $field->checkDateValidity($value, FileMaker::RULE_DATE_FIELD, $exception);
            $this->assertEquals(0, $exception->numErrors(), 'value : ' . $value);
        }

        //Invalid Values
        $invalidValues = [
            "15/12/2017",
            "01/32/2017",
            "01/01/4017",
        ];
        foreach ($invalidValues as $value) {
            $exception = new FileMakerValidationException($this->fm);
            $field->checkDateValidity($value, FileMaker::RULE_DATE_FIELD, $exception);
            $this->assertEquals(1, $exception->numErrors(), 'value : ' . $value);
        }
    }

    /**
     * @covers \airmoi\FileMaker\Object\Field::checkTimeValidity
     */
    public function testCheckTimeValidity()
    {
        $field = $this->record->layout->getField('time_field');
        //Valid values
        $validValues = [
            "04:30" => false,
            "04:01:53" => false,
            "04:01:53 PM" => true,
            "16:30" => false,
            "16:30:00" => false,
            "02:30 Pm" => true,
            "02:30 AM" => true,
            "02:30 aM" => true,
        ];
        foreach ($validValues as $value => $shortFormat) {
            $exception = new FileMakerValidationException($this->fm);
            $field->checkTimeValidity($value, FileMaker::RULE_DATE_FIELD, $exception, $shortFormat);
            $this->assertEquals(0, $exception->numErrors(), 'value : ' . $value);
        }

        //Invalid Values
        $invalidValues = [
            "17:00" => true,
            "25:00" => false,
            "12:87" => true,
        ];
        foreach ($invalidValues as $value => $shortFormat) {
            $exception = new FileMakerValidationException($this->fm);
            $field->checkTimeValidity($value, FileMaker::RULE_DATE_FIELD, $exception, $shortFormat);
            $this->assertEquals(1, $exception->numErrors(), 'value : ' . $value);
        }
    }
}
