<commit_before><?php
declare(strict_types = 1);
/**
 * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
 * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
 *
 * Licensed under The MIT License
 * For full copyright and license information, please see the LICENSE.txt
 * Redistributions of files must retain the above copyright notice.
 *
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
 * @link          https://cakephp.org CakePHP(tm) Project
 * @since         3.0.0
 * @license       https://opensource.org/licenses/mit-license.php MIT License
 */
namespace Shim\Test\TestCase\View\Widget;

use Cake\TestSuite\TestCase;
use Cake\View\StringTemplate;
use Cake\View\Widget\SelectBoxWidget;
use DateTime;
use Shim\View\Widget\DateTimeWidget;

/**
 * DateTime input test case
 */
class DateTimeWidgetTest extends TestCase {

	/**
	 * @return void
	 */
	public function setUp() {
		parent::setUp();
		$templates = [
			'select' => '<select name="{{name}}"{{attrs}}>{{content}}</select>',
			'option' => '<option value="{{value}}"{{attrs}}>{{text}}</option>',
			'optgroup' => '<optgroup label="{{label}}"{{attrs}}>{{content}}</optgroup>',
			'dateWidget' => '{{year}}{{month}}{{day}}{{hour}}{{minute}}{{second}}{{meridian}}',
		];
		$this->templates = new StringTemplate($templates);
		$this->context = $this->getMockBuilder('Cake\View\Form\ContextInterface')->getMock();
		$this->selectBox = new SelectBoxWidget($this->templates);
		$this->DateTime = new DateTimeWidget($this->templates, $this->selectBox);
	}

	/**
	 * Data provider for testing various types of invalid selected values.
	 *
	 * @return array
	 */
	public static function invalidSelectedValuesProvider() {
		return [
			'false' => [false],
			'true' => [true],
			'string' => ['Bag of poop'],
			'array' => [[
				'derp' => 'hurt',
			]],
		];
	}

	/**
	 * test rendering selected values.
	 *
	 * @dataProvider invalidSelectedValuesProvider
	 * @param string $selected
	 * @return void
	 */
	public function testRenderSelectedInvalid($selected) {
		$result = $this->DateTime->render(['val' => $selected], $this->context);
		$now = new DateTime();
		$format = '<option value="%s" selected="selected">%s</option>';
		$this->assertContains(
			sprintf($format, $now->format('Y'), $now->format('Y')),
			$result
		);
	}

	/**
	 * test rendering empty selected.
	 *
	 * @return void
	 */
	public function testRenderSelectedEmpty() {
		$result = $this->DateTime->render([
			'val' => '',
			'year' => ['empty' => true],
			'month' => ['empty' => true],
			'day' => ['empty' => true],
			'hour' => ['empty' => true],
			'minute' => ['empty' => true],
		], $this->context);
		$this->assertContains('<option value="" selected="selected"></option>', $result);
		$this->assertNotRegExp('/value="\d+" selected="selected"/', $result);

		$result = $this->DateTime->render([
			'val' => ['year' => '', 'month' => '', 'day' => '', 'hour' => '', 'minute' => ''],
			'year' => ['empty' => true],
			'month' => ['empty' => true],
			'day' => ['empty' => true],
			'hour' => ['empty' => true],
			'minute' => ['empty' => true],
		], $this->context);
		$this->assertContains('<option value="" selected="selected"></option>', $result);
		$this->assertNotRegExp('/value="\d+" selected="selected"/', $result);
	}

	/**
	 * Test empty with custom values.
	 *
	 * @return void
	 */
	public function testRenderEmptyCustom() {
		$result = $this->DateTime->render([
			'val' => '',
			'year' => [
				'empty' => ['nope' => '(choose one)'],
			],
		], $this->context);
		$this->assertContains('<option value="nope">(choose one)</option>', $result);
		$this->assertNotContains('<optgroup', $result, 'No optgroups should be present.');
	}

	/**
	 * Data provider for testing various acceptable selected values.
	 *
	 * @return array
	 */
	public static function selectedValuesProvider() {
		$date = new DateTime('2014-01-20 12:30:45');

		return [
			'DateTime' => [$date],
			'string' => [$date->format('Y-m-d H:i:s')],
			'int string' => [$date->format('U')],
			'int' => [$date->getTimestamp()],
			'array' => [[
				'year' => '2014', 'month' => '01', 'day' => '20',
				'hour' => '12', 'minute' => '30', 'second' => '45',
			]],
		];
	}

	/**
	 * test rendering selected values.
	 *
	 * @dataProvider selectedValuesProvider
	 * @param string $selected
	 * @return void
	 */
	public function testRenderSelected($selected) {
		$result = $this->DateTime->render(['val' => $selected], $this->context);
		$this->assertContains('<option value="2014" selected="selected">2014</option>', $result);
		$this->assertContains('<option value="01" selected="selected">1</option>', $result);
		$this->assertContains('<option value="20" selected="selected">20</option>', $result);
		$this->assertContains('<option value="12" selected="selected">12</option>', $result);
		$this->assertContains('<option value="30" selected="selected">30</option>', $result);
		$this->assertContains('<option value="45" selected="selected">45</option>', $result);
	}

	public function testRenderInvalidDate() {
		$selected = [
			'year' => '2014', 'month' => '02', 'day' => '31',
			'hour' => '12', 'minute' => '30', 'second' => '45',
		];
		$result = $this->DateTime->render(['val' => $selected], $this->context);
		$this->assertContains('<option value="2014" selected="selected">2014</option>', $result);
		$this->assertContains('<option value="02" selected="selected">2</option>', $result);
		$this->assertContains('<option value="31" selected="selected">31</option>', $result);
		$this->assertContains('<option value="12" selected="selected">12</option>', $result);
		$this->assertContains('<option value="30" selected="selected">30</option>', $result);
		$this->assertContains('<option value="45" selected="selected">45</option>', $result);
	}

	/**
	 * Test that render() works with an array for val that is missing seconds.
	 *<commit_msg>fix test locally for now.<commit_after><?php
declare(strict_types = 1);
/**
 * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
 * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
 *
 * Licensed under The MIT License
 * For full copyright and license information, please see the LICENSE.txt
 * Redistributions of files must retain the above copyright notice.
 *
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
 * @link          https://cakephp.org CakePHP(tm) Project
 * @since         3.0.0
 * @license       https://opensource.org/licenses/mit-license.php MIT License
 */
namespace Shim\Test\TestCase\View\Widget;

use Cake\TestSuite\TestCase;
use Cake\View\Form\ContextInterface;
use Cake\View\StringTemplate;
use Cake\View\Widget\SelectBoxWidget;
use DateTime;
use Shim\View\Widget\DateTimeWidget;

/**
 * DateTime input test case
 */
class DateTimeWidgetTest extends TestCase {

	/**
	 * @var \Cake\View\Form\ContextInterface|\PHPUnit\Framework\MockObject\MockObject
	 */
	protected $context;

	/**
	 * @var \Shim\View\Widget\DateTimeWidget
	 */
	protected $DateTime;

	/**
	 * @return void
	 */
	public function setUp() {
		parent::setUp();

		date_default_timezone_set('UTC');

		$templates = [
			'select' => '<select name="{{name}}"{{attrs}}>{{content}}</select>',
			'option' => '<option value="{{value}}"{{attrs}}>{{text}}</option>',
			'optgroup' => '<optgroup label="{{label}}"{{attrs}}>{{content}}</optgroup>',
			'dateWidget' => '{{year}}{{month}}{{day}}{{hour}}{{minute}}{{second}}{{meridian}}',
		];
		$this->templates = new StringTemplate($templates);
		$this->context = $this->getMockBuilder(ContextInterface::class)->getMock();
		$this->selectBox = new SelectBoxWidget($this->templates);
		$this->DateTime = new DateTimeWidget($this->templates, $this->selectBox);
	}

	/**
	 * Data provider for testing various types of invalid selected values.
	 *
	 * @return array
	 */
	public static function invalidSelectedValuesProvider() {
		return [
			'false' => [false],
			'true' => [true],
			'string' => ['Bag of poop'],
			'array' => [[
				'derp' => 'hurt',
			]],
		];
	}

	/**
	 * test rendering selected values.
	 *
	 * @dataProvider invalidSelectedValuesProvider
	 * @param string $selected
	 * @return void
	 */
	public function testRenderSelectedInvalid($selected) {
		$result = $this->DateTime->render(['val' => $selected], $this->context);
		$now = new DateTime();
		$format = '<option value="%s" selected="selected">%s</option>';
		$this->assertContains(
			sprintf($format, $now->format('Y'), $now->format('Y')),
			$result
		);
	}

	/**
	 * test rendering empty selected.
	 *
	 * @return void
	 */
	public function testRenderSelectedEmpty() {
		$result = $this->DateTime->render([
			'val' => '',
			'year' => ['empty' => true],
			'month' => ['empty' => true],
			'day' => ['empty' => true],
			'hour' => ['empty' => true],
			'minute' => ['empty' => true],
		], $this->context);
		$this->assertContains('<option value="" selected="selected"></option>', $result);
		$this->assertNotRegExp('/value="\d+" selected="selected"/', $result);

		$result = $this->DateTime->render([
			'val' => ['year' => '', 'month' => '', 'day' => '', 'hour' => '', 'minute' => ''],
			'year' => ['empty' => true],
			'month' => ['empty' => true],
			'day' => ['empty' => true],
			'hour' => ['empty' => true],
			'minute' => ['empty' => true],
		], $this->context);
		$this->assertContains('<option value="" selected="selected"></option>', $result);
		$this->assertNotRegExp('/value="\d+" selected="selected"/', $result);
	}

	/**
	 * Test empty with custom values.
	 *
	 * @return void
	 */
	public function testRenderEmptyCustom() {
		$result = $this->DateTime->render([
			'val' => '',
			'year' => [
				'empty' => ['nope' => '(choose one)'],
			],
		], $this->context);
		$this->assertContains('<option value="nope">(choose one)</option>', $result);
		$this->assertNotContains('<optgroup', $result, 'No optgroups should be present.');
	}

	/**
	 * Data provider for testing various acceptable selected values.
	 *
	 * @return array
	 */
	public static function selectedValuesProvider() {
		$date = new DateTime('2014-01-20 12:30:45');

		return [
			'DateTime' => [$date],
			'string' => [$date->format('Y-m-d H:i:s')],
			'int string' => [$date->format('U')],
			'int' => [$date->getTimestamp()],
			'array' => [[
				'year' => '2014', 'month' => '01', 'day' => '20',
				'hour' => '12', 'minute' => '30', 'second' => '45',
			]],
		];
	}

	/**
	 * test rendering selected values.
	 *
	 * @dataProvider selectedValuesProvider
	 * @param string $selected
	 * @return void
	 */
	public function testRenderSelected($selected) {
		$result = $this->DateTime->render(['val' => $selected], $this->context);
		$this->assertContains('<option value="2014" selected="selected">2014</option>', $result);
		$this->assertContains('<option value="01" selected="selected">1</option>', $result);
		$this->assertContains('<option value="20" selected="selected">20</option>', $result);

		if ((bool)getenv('TRAVIS')) {
			$this->assertContains('<option value="12" selected="selected">12</option>', $result);
		}

		$this->assertContains('<option value="30" selected="selected">30</option>', $result);
		$this->assertContains('<option value="45" selected="selected">45</option>', $result);
	}

	/**
	 * @return void
	 */
	public function testRenderInvalidDate() {
		$selected = [
			'year' => '2014', 'month' => '02', 'day' => '31',
			'hour' => '12', 'minute' => '30', 'second' => '45',
		];
		$result = $this->DateTime->render(['val' => $selected], $this->context);
		$this->assertContains('<option value="2014" selected="selected">2014</option>', $result);
		$this->assertContains('<option value="02" selected="selected">2</option>', $result);
		$this->assertContains('<option value="31" selected="selected">31</option>', $result);

		if ((bool)getenv('TRAVIS')) {
			$this->assertContains('<option value="12" selected="selected">12</option>', $result);
		}

		$this->assertContains('<option value="30" selected="selected">30</option>', $result);
		$this->assertContains('<option value="45" selected="selected">45</option>', $result);
	}

	/**
	 * Test that render() works with an array for val that is missing seconds.
	 *
{'fraction_non_alphanumeric': 0.22152312469357738, 'fraction_numerical': 0.016342539630658605, 'mean_word_length': 4.461401160196341, 'pattern_counts': {'":': 0, '<': 83, '<?xml version=': 0, '>': 301, 'https://': 10, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6399', 'n_tokens_mistral': 4257, 'n_tokens_neox': 3770, 'n_words': 825}