mockApplication([
            'components' => [
                'request' => [
                    'class' => 'yii\web\Request',
                    'url' => '/test',
                    'scriptUrl' => '/index.php',
                    'hostInfo' => 'http://www.example.com',
                    'enableCsrfValidation' => false,
                ],
                'response' => [
                    'class' => 'yii\web\Response',
                ],
            ],
        ]);
    }
    public function testEncode()
    {
        $this->assertEquals('a<>&"'�', Html::encode("a<>&\"'\x80"));
        $this->assertEquals('Sam & Dark', Html::encode('Sam & Dark'));
    }
    public function testDecode()
    {
        $this->assertEquals("a<>&\"'", Html::decode('a<>&"''));
    }
    public function testTag()
    {
        $this->assertEquals(' ', Html::tag('br'));
        $this->assertEquals(' ', Html::tag('span'));
        $this->assertEquals('
content
', Html::tag('div', 'content'));
        $this->assertEquals(' ', Html::tag('input', '', ['type' => 'text', 'name' => 'test', 'value' => '<>']));
        $this->assertEquals(' ', Html::tag('span', '', ['disabled' => true]));
        $this->assertEquals('test', Html::tag(false, 'test'));
        $this->assertEquals('test', Html::tag(null, 'test'));
    }
    public function testBeginTag()
    {
        $this->assertEquals(' ', Html::beginTag('br'));
        $this->assertEquals('', Html::beginTag('span', ['id' => 'test', 'class' => 'title']));
        $this->assertEquals('', Html::beginTag(null));
        $this->assertEquals('', Html::beginTag(false));
    }
    public function testEndTag()
    {
        $this->assertEquals('', Html::endTag('br'));
        $this->assertEquals(' ', Html::endTag('span'));
        $this->assertEquals('', Html::endTag(null));
        $this->assertEquals('', Html::endTag(false));
    }
    public function testStyle()
    {
        $content = 'a <>';
        $this->assertEquals("", Html::style($content));
        $this->assertEquals("", Html::style($content, ['type' => 'text/less']));
    }
    public function testScript()
    {
        $content = 'a <>';
        $this->assertEquals("", Html::script($content));
        $this->assertEquals("", Html::script($content, ['type' => 'text/js']));
    }
    public function testScriptCustomAttribute()
    {
        $nonce = Yii::$app->security->generateRandomString();
        $this->mockApplication([
            'components' => [
                'view' => [
                    'class' => 'yii\web\View',
                    'scriptOptions' => ['nonce' => $nonce],
                ],
            ],
        ]);
        $content = 'a <>';
        $this->assertEquals("", Html::script($content));
    }
    public function testCssFile()
    {
        $this->assertEquals(' ', Html::cssFile('http://example.com'));
        $this->assertEquals(' ', Html::cssFile(''));
        $this->assertEquals("", Html::cssFile('http://example.com', ['condition' => 'IE 9']));
        $this->assertEquals("\n" . ' ' . "\n", Html::cssFile('http://example.com', ['condition' => '(gte IE 9)|(!IE)']));
        $this->assertEquals(' ', Html::cssFile('http://example.com', ['noscript' => true]));
    }
    public function testJsFile()
    {
        $this->assertEquals('', Html::jsFile('http://example.com'));
        $this->assertEquals('', Html::jsFile(''));
        $this->assertEquals("", Html::jsFile('http://example.com', ['condition' => 'IE 9']));
        $this->assertEquals("\n" . '' . "\n", Html::jsFile('http://example.com', ['condition' => '(gte IE 9)|(!IE)']));
    }
    public function testCsrfMetaTagsDisableCsrfValidation()
    {
        $this->mockApplication([
            'components' => [
                'request' => [
                    'class' => 'yii\web\Request',
                    'enableCsrfValidation' => false,
                ],
            ],
        ]);
        $this->assertEquals('', Html::csrfMetaTags());
    }
    public function testCsrfMetaTagsEnableCsrfValidation()
    {
        $this->mockApplication([
            'components' => [
                'request' => [
                    'class' => 'yii\web\Request',
                    'enableCsrfValidation' => true,
                    'cookieValidationKey' => 'key',
                ],
                'response' => [
                    'class' => 'yii\web\Response',
                ],
            ],
        ]);
        $pattern = ' %A ';
        $actual = Html::csrfMetaTags();
        $this->assertStringMatchesFormat($pattern, $actual);
    }
    public function testCsrfMetaTagsEnableCsrfValidationWithoutCookieValidationKey()
    {
        $this->mockApplication([
            'components' => [
                'request' => [
                    'class' => 'yii\web\Request',
                    'enableCsrfValidation' => true,
                ],
            ],
        ]);
        $this->expectException('yii\base\InvalidConfigException');
        $this->expectExceptionMessage('yii\web\Request::cookieValidationKey must be configured with a secret key.');
        Html::csrfMetaTags();
    }
    /**
     * @dataProvider dataProviderBeginFormSimulateViaPost
     *
     * @param string $expected
     * @param string $method
     */
    public function testBeginFormSimulateViaPost($expected, $method)
    {
        $actual = Html::beginForm('/foo', $method);
        $this->assertStringMatchesFormat($expected, $actual);
    }
    /**
     * Data provider for [[testBeginFormSimulateViaPost()]].
     * @return array test data
     */
    public function dataProviderBeginFormSimulateViaPost()
    {
        return [
          ['', Html::endForm());
    }
    public function testA()
    {
        $this->assertEquals('something<> ', Html::a('something<>'));
        $this->assertEquals('something ', Html::a('something', '/example'));
        $this->assertEquals('something ', Html::a('something', ''));
        $this->assertEquals('http://www.быстроном.рф ', Html::a('http://www.быстроном.рф', 'http://www.быстроном.рф'));
        $this->assertEquals('Test page ', Html::a('Test page', Url::to(['/site/test'], 'https')));
    }
    public function testMailto()
    {
        $this->assertEquals('test<> ', Html::mailto('test<>'));
        $this->assertEquals('test<> ', Html::mailto('test<>', 'test>'));
    }
    /**
     * @return array
     */
    public function imgDataProvider()
    {
        return [
            [
                ' ',
                '/example',
                [],
            ],
            [
                ' ',
                '',
                [],
            ],
            [
                ' ',
                '/example',
                [
                    'alt' => 'something',
                    'width' => 10,
                ],
            ],
            [
                ' ',
                '/base-url',
                [
                    'srcset' => [
                    ],
                ],
            ],
            [
                ' ',
                '/base-url',
                [
                    'srcset' => [
                        '9001w' => '/example-9001w',
                    ],
                ],
            ],
            [
                ' ',
                '/base-url',
                [
                    'srcset' => [
                        '100w' => '/example-100w',
                        '500w' => '/example-500w',
                        '1500w' => '/example-1500w',
                    ],
                ],
            ],
            [
                ' ',
                '/base-url',
                [
                    'srcset' => [
                        '1x' => '/example-1x',
                        '2x' => '/example-2x',
                        '3x' => '/example-3x',
                        '4x' => '/example-4x',
                        '5x' => '/example-5x',
                    ],
                ],
            ],
            [
                ' ',
                '/base-url',
                [
                    'srcset' => [
                        '1.42x' => '/example-1.42x',
                        '2.0x' => '/example-2.0x',
                        '3.99999x' => '/example-3.99999x',
                    ],
                ],
            ],
            [
                ' ',
                '/base-url',
                [
                    'srcset' => '/example-1x 1x,/example-2x 2x,/example-3x 3x',
                ],
            ],
        ];
    }
    /**
     * @dataProvider imgDataProvider
     * @param string $expected
     * @param string $src
     * @param array $options
     */
    public function testImg($expected, $src, $options)
    {
        $this->assertEquals($expected, Html::img($src, $options));
    }
    public function testLabel()
    {
        $this->assertEquals('something<> ', Html::label('something<>'));
        $this->assertEquals('something<> ', Html::label('something<>', 'a'));
        $this->assertEquals('something<> ', Html::label('something<>', 'a', ['class' => 'test']));
    }
    public function testButton()
    {
        $this->assertEquals('Button ', Html::button());
        $this->assertEquals('content<> ', Html::button('content<>', ['name' => 'test', 'value' => 'value']));
        $this->assertEquals('content<> ', Html::button('content<>', ['type' => 'submit', 'name' => 'test', 'value' => 'value', 'class' => 't']));
    }
    public function testSubmitButton()
    {
        $this->assertEquals('Submit ', Html::submitButton());
        $this->assertEquals('content<> ', Html::submitButton('content<>', ['name' => 'test', 'value' => 'value', 'class' => 't']));
    }
    public function testResetButton()
    {
        $this->assertEquals('Reset ', Html::resetButton());
        $this->assertEquals('content<> ', Html::resetButton('content<>', ['name' => 'test', 'value' => 'value', 'class' => 't']));
    }
    public function testInput()
    {
        $this->assertEquals(' ', Html::input('text'));
        $this->assertEquals(' ', Html::input('text', 'test', 'value', ['class' => 't']));
    }
    public function testButtonInput()
    {
        $this->assertEquals(' ', Html::buttonInput());
        $this->assertEquals(' ', Html::buttonInput('text', ['name' => 'test', 'class' => 'a']));
    }
    public function testSubmitInput()
    {
        $this->assertEquals(' ', Html::submitInput());
        $this->assertEquals(' ', Html::submitInput('text', ['name' => 'test', 'class' => 'a']));
    }
    public function testResetInput()
    {
        $this->assertEquals(' ', Html::resetInput());
        $this->assertEquals(' ', Html::resetInput('text', ['name' => 'test', 'class' => 'a']));
    }
    public function testTextInput()
    {
        $this->assertEquals(' ', Html::textInput('test'));
        $this->assertEquals(' ', Html::textInput('test', 'value', ['class' => 't']));
    }
    public function testHiddenInput()
    {
        $this->assertEquals(' ', Html::hiddenInput('test'));
        $this->assertEquals(' ', Html::hiddenInput('test', 'value', ['class' => 't']));
    }
    public function testPasswordInput()
    {
        $this->assertEquals(' ', Html::passwordInput('test'));
        $this->assertEquals(' ', Html::passwordInput('test', 'value', ['class' => 't']));
    }
    public function testFileInput()
    {
        $this->assertEquals(' ', Html::fileInput('test'));
        $this->assertEquals(' ', Html::fileInput('test', 'value', ['class' => 't']));
    }
    /**
     * @return array
     */
    public function textareaDataProvider()
    {
        return [
            [
                '',
                'test',
                null,
                [],
            ],
            [
                '',
                'test',
                'value<>',
                ['class' => 't'],
            ],
            [
                '',
                'test',
                'value<>',
                [],
            ],
            [
                '',
                'test',
                'value<>',
                ['doubleEncode' => false],
            ],
        ];
    }
    /**
     * @dataProvider textareaDataProvider
     * @param string $expected
     * @param string $name
     * @param string $value
     * @param array $options
     */
    public function testTextarea($expected, $name, $value, $options)
    {
        $this->assertEquals($expected, Html::textarea($name, $value, $options));
    }
    public function testRadio()
    {
        $this->assertEquals(' ', Html::radio('test'));
        $this->assertEquals(' ', Html::radio('test', true, ['class' => 'a', 'value' => null]));
        $this->assertEquals(' ', Html::radio('test', true, [
            'class' => 'a',
            'uncheck' => '0',
            'value' => 2
        ]));
        $this->assertEquals(' ', Html::radio('test', false, [
            'disabled' => true,
            'uncheck' => '0',
            'value' => 2
        ]));
        $this->assertEquals('  ccc ', Html::radio('test', true, [
            'class' => 'a',
            'value' => null,
            'label' => 'ccc',
            'labelOptions' => ['class' => 'bbb'],
        ]));
        $this->assertEquals('  ccc ', Html::radio('test', true, [
            'class' => 'a',
            'uncheck' => '0',
            'label' => 'ccc',
            'value' => 2,
        ]));
    }
    public function testCheckbox()
    {
        $this->assertEquals(' ', Html::checkbox('test'));
        $this->assertEquals(' ', Html::checkbox('test', true, ['class' => 'a', 'value' => null]));
        $this->assertEquals(' ', Html::checkbox('test', true, [
            'class' => 'a',
            'uncheck' => '0',
            'value' => 2
        ]));
        $this->assertEquals(' ', Html::checkbox('test', false, [
            'disabled' => true,
            'uncheck' => '0',
            'value' => 2
        ]));
        $this->assertEquals('  ccc ', Html::checkbox('test', true, [
            'class' => 'a',
            'value' => null,
            'label' => 'ccc',
            'labelOptions' => ['class' => 'bbb'],
        ]));
        $this->assertEquals('  ccc ', Html::checkbox('test', true, [
            'class' => 'a',
            'uncheck' => '0',
            'label' => 'ccc',
            'value' => 2,
        ]));
        $this->assertEquals('  ccc ', Html::checkbox('test', true, [
            'class' => 'a',
            'uncheck' => '0',
            'label' => 'ccc',
            'value' => 2,
            'form' => 'test-form',
        ]));
        $this->assertEquals('  ccc ', Html::checkbox('test', false, [
            'class' => 'a',
            'uncheck' => '0',
            'label' => 'ccc',
            'value' => 2,
            'checked' => true,
        ]));
    }
    public function testDropDownList()
    {
        $expected = <<<'EOD'
 
EOD;
        $this->assertEqualsWithoutLE($expected, Html::dropDownList('test'));
        $expected = <<<'EOD'
text1 
text2 
 
EOD;
        $this->assertEqualsWithoutLE($expected, Html::dropDownList('test', null, $this->getDataItems()));
        $expected = <<<'EOD'
text1 
text2 
 
EOD;
        $this->assertEqualsWithoutLE($expected, Html::dropDownList('test', 'value2', $this->getDataItems()));
        $this->assertEqualsWithoutLE(
            $expected,
            Html::dropDownList('test', null, $this->getDataItems(), [
                'options' => [
                    'value2' => ['selected' => true],
                ],
            ])
        );
        $expected = <<<'EOD'
 
EOD;
        $this->assertEqualsWithoutLE($expected, Html::dropDownList('test', null, [], ['multiple' => 'true']));
        $expected = <<<'EOD'
zero 
one 
text3 
 
EOD;
        $this->assertEqualsWithoutLE(
            $expected,
            Html::dropDownList('test', [0], $this->getDataItems3(), ['multiple' => 'true'])
        );
        $this->assertEqualsWithoutLE(
            $expected,
            Html::dropDownList('test', new \ArrayObject([0]), $this->getDataItems3(), ['multiple' => 'true'])
        );
        $expected = <<<'EOD'
zero 
one 
text3 
 
EOD;
        $this->assertEqualsWithoutLE(
            $expected,
            Html::dropDownList('test', ['1', 'value3'], $this->getDataItems3(), ['multiple' => 'true'])
        );
        $this->assertEqualsWithoutLE(
            $expected,
            Html::dropDownList('test', new \ArrayObject(['1', 'value3']), $this->getDataItems3(), ['multiple' => 'true']
            )
        );
    }
    public function providerForNonStrictBooleanDropDownList()
    {
        return [
            [null, false, false, false],
            ['', true, false, false],
            [0, false, false, true],
            [1, false, true, false],
            ['0', false, false, true],
            ['1', false, true, false],
            [false, false, false, true],
            [true, false, true, false],
        ];
    }
    /**
     * @dataProvider providerForNonStrictBooleanDropDownList
     */
    public function testNonStrictBooleanDropDownList($selection, $selectedEmpty, $selectedYes, $selectedNo)
    {
        $selectedEmpty = $selectedEmpty ? ' selected' : '';
        $selectedYes = $selectedYes ? ' selected' : '';
        $selectedNo = $selectedNo ? ' selected' : '';
        $expected = <<
 
Yes 
No 
HTML;
        $this->assertEqualsWithoutLE(
            $expected,
            Html::dropDownList('test', $selection, ['' => '', '1' => 'Yes', '0' => 'No'])
        );
    }
    public function providerForStrictBooleanDropDownList()
    {
        return [
            [null, false, false, false],
            ['', true, false, false],
            [0, false, false, true],
            [1, false, true, false],
            ['0', false, false, true],
            ['1', false, true, false],
            [false, false, false, true],
            [true, false, true, false],
        ];
    }
    /**
     * @dataProvider providerForStrictBooleanDropDownList
     */
    public function testStrictBooleanDropDownList($selection, $selectedEmpty, $selectedYes, $selectedNo)
    {
        $selectedEmpty = $selectedEmpty ? ' selected' : '';
        $selectedYes = $selectedYes ? ' selected' : '';
        $selectedNo = $selectedNo ? ' selected' : '';
        $expected = <<
 
Yes 
No 
HTML;
        $this->assertEqualsWithoutLE(
            $expected,
            Html::dropDownList('test', $selection, ['' => '', '1' => 'Yes', '0' => 'No'], ['strict' => true])
        );
    }
    public function testListBox()
    {
        $expected = <<<'EOD'
 
EOD;
        $this->assertEqualsWithoutLE($expected, Html::listBox('test'));
        $expected = <<<'EOD'
text1 
text2 
 
EOD;
        $this->assertEqualsWithoutLE($expected, Html::listBox('test', null, $this->getDataItems(), ['size' => 5]));
        $expected = <<<'EOD'
text1<> 
text  2 
 
EOD;
        $this->assertEqualsWithoutLE($expected, Html::listBox('test', null, $this->getDataItems2()));
        $expected = <<<'EOD'
text1<> 
text  2 
 
EOD;
        $this->assertEqualsWithoutLE($expected, Html::listBox('test', null, $this->getDataItems2(), ['encodeSpaces' => true]));
        $expected = <<<'EOD'
text1<> 
text  2 
 
EOD;
        $this->assertEqualsWithoutLE($expected, Html::listBox('test', null, $this->getDataItems2(), ['encode' => false]));
        $expected = <<<'EOD'
text1<> 
text  2 
 
EOD;
        $this->assertEqualsWithoutLE($expected, Html::listBox('test', null, $this->getDataItems2(), ['encodeSpaces' => true, 'encode' => false]));
        $expected = <<<'EOD'
text1 
text2 
 
EOD;
        $this->assertEqualsWithoutLE($expected, Html::listBox('test', 'value2', $this->getDataItems()));
        $expected = <<<'EOD'
text1 
text2 
 
EOD;
        $this->assertEqualsWithoutLE($expected, Html::listBox('test', ['value1', 'value2'], $this->getDataItems()));
        $expected = <<<'EOD'
 
EOD;
        $this->assertEqualsWithoutLE($expected, Html::listBox('test', null, [], ['multiple' => true]));
        $this->assertEqualsWithoutLE($expected, Html::listBox('test[]', null, [], ['multiple' => true]));
        $expected = <<<'EOD'
 
EOD;
        $this->assertEqualsWithoutLE($expected, Html::listBox('test', '', [], ['unselect' => '0']));
        $expected = <<<'EOD'
 
EOD;
        $this->assertEqualsWithoutLE($expected, Html::listBox('test', '', [], ['unselect' => '0', 'disabled' => true]));
        $expected = <<<'EOD'
text1 
text2 
 
EOD;
        $this->assertEqualsWithoutLE($expected, Html::listBox('test', new \ArrayObject(['value1', 'value2']), $this->getDataItems()));
        $expected = <<<'EOD'
zero 
one 
text3 
 
EOD;
        $this->assertEqualsWithoutLE($expected, Html::listBox('test', [0], $this->getDataItems3()));
        $this->assertEqualsWithoutLE($expected, Html::listBox('test', new \ArrayObject([0]), $this->getDataItems3()));
        $expected = <<<'EOD'
zero 
one 
text3 
 
EOD;
        $this->assertEqualsWithoutLE($expected, Html::listBox('test', ['1', 'value3'], $this->getDataItems3()));
        $this->assertEqualsWithoutLE($expected, Html::listBox('test', new \ArrayObject(['1', 'value3']), $this->getDataItems3()));
    }
    public function testCheckboxList()
    {
        $this->assertEquals('
', Html::checkboxList('test'));
        $expected = <<<'EOD'
  text1 
  text2
EOD;
        $this->assertEqualsWithoutLE($expected, Html::checkboxList('test', ['value2'], $this->getDataItems()));
        $this->assertEqualsWithoutLE($expected, Html::checkboxList('test[]', ['value2'], $this->getDataItems()));
        $expected = <<<'EOD'
  text1<> 
  text  2
EOD;
        $this->assertEqualsWithoutLE($expected, Html::checkboxList('test', ['value2'], $this->getDataItems2()));
        $expected = <<<'EOD'
  text1 
  text2
EOD;
        $this->assertEqualsWithoutLE($expected, Html::checkboxList('test', ['value2'], $this->getDataItems(), [
            'separator' => " \n",
            'unselect' => '0',
        ]));
        $expected = <<<'EOD'
  text1 
  text2
EOD;
        $this->assertEqualsWithoutLE($expected, Html::checkboxList('test', null, $this->getDataItems(), [
            'separator' => " \n",
            'unselect' => '0',
            'disabled' => true,
        ]));
        $expected = <<<'EOD'
0text1  
1text2  
EOD;
        $this->assertEqualsWithoutLE($expected, Html::checkboxList('test', ['value2'], $this->getDataItems(), [
            'item' => function ($index, $label, $name, $checked, $value) {
                return $index . Html::label($label . ' ' . Html::checkbox($name, $checked, ['value' => $value]));
            },
        ]));
        $expected = <<<'EOD'
0text1  
1text2  
EOD;
        $this->assertEqualsWithoutLE($expected, Html::checkboxList('test', ['value2'], $this->getDataItems(), [
            'item' => function ($index, $label, $name, $checked, $value) {
                return $index . Html::label($label . ' ' . Html::checkbox($name, $checked, ['value' => $value]));
            },
            'tag' => false,
        ]));
        $this->assertEqualsWithoutLE($expected, Html::checkboxList('test', new \ArrayObject(['value2']), $this->getDataItems(), [
            'item' => function ($index, $label, $name, $checked, $value) {
                return $index . Html::label($label . ' ' . Html::checkbox($name, $checked, ['value' => $value]));
            },
            'tag' => false,
        ]));
        $expected = <<<'EOD'
  zero 
  one 
  text3
EOD;
        $this->assertEqualsWithoutLE($expected, Html::checkboxList('test', [0], $this->getDataItems3()));
        $this->assertEqualsWithoutLE($expected, Html::checkboxList('test', new \ArrayObject([0]), $this->getDataItems3()));
        $expected = <<<'EOD'
  zero 
  one 
  text3
EOD;
        $this->assertEqualsWithoutLE($expected, Html::checkboxList('test', ['1', 'value3'], $this->getDataItems3()));
        $this->assertEqualsWithoutLE($expected, Html::checkboxList('test', new \ArrayObject(['1', 'value3']), $this->getDataItems3()));
        $expected = <<<'EOD'
  Test Label 
  Test Label
EOD;
        $this->assertEqualsWithoutLE($expected, Html::checkboxList('test', null, $this->getDataItems(), [
            'itemOptions' => [
                'value' => 0,
                'label' => 'Test Label'
            ]
        ]));
        $expected = <<<'EOD'
  1 
  1.1 
  1.10
EOD;
        $this->assertEqualsWithoutLE($expected, Html::checkboxList('test', ['1.1'], ['1' => '1', '1.1' => '1.1', '1.10' => '1.10'], ['strict' => true]));
        $this->assertEqualsWithoutLE($expected, Html::checkboxList('test', [1.1], ['1' => '1', '1.1' => '1.1', '1.10' => '1.10'], ['strict' => true]));
        $expected = <<<'EOD'
  1 
  1.1 
  1.10
EOD;
        $this->assertEqualsWithoutLE($expected, Html::checkboxList('test', [1.1], ['1' => '1', '1.1' => '1.1', '1.10' => '1.10']));
    }
    public function testRadioListWithArrayExpression()
    {
        $selection = new ArrayExpression(['first']);
        $output = Html::radioList(
            'test',
            $selection,
            [
                'first' => 'first',
                'second' => 'second'
            ]
        );
        $this->assertEqualsWithoutLE('  first 
  second
', $output);
    }
    public function testCheckboxListWithArrayExpression()
    {
        $selection = new ArrayExpression(['first']);
        $output = Html::checkboxList(
            'test',
            $selection,
            [
                'first' => 'first',
                'second' => 'second'
            ]
        );
        $this->assertEqualsWithoutLE('  first 
  second
', $output);
    }
    public function testRenderSelectOptionsWithArrayExpression()
    {
        $selection = new ArrayExpression(['first']);
        $output = Html::renderSelectOptions(
            $selection,
            [
                'first' => 'first',
                'second' => 'second'
            ]
        );
        $this->assertEqualsWithoutLE('first 
second ', $output);
    }
    public function testRadioList()
    {
        $this->assertEquals('
', Html::radioList('test'));
        $expected = <<<'EOD'
  text1 
  text2
EOD;
        $this->assertEqualsWithoutLE($expected, Html::radioList('test', ['value2'], $this->getDataItems()));
        $expected = <<<'EOD'
  text1<> 
  text  2
EOD;
        $this->assertEqualsWithoutLE($expected, Html::radioList('test', ['value2'], $this->getDataItems2()));
        $expected = <<<'EOD'
  text1 
  text2
EOD;
        $this->assertEqualsWithoutLE($expected, Html::radioList('test', ['value2'], $this->getDataItems(), [
            'separator' => " \n",
            'unselect' => '0',
        ]));
        $expected = <<<'EOD'
  text1 
  text2
EOD;
        $this->assertEqualsWithoutLE($expected, Html::radioList('test', null, $this->getDataItems(), [
            'separator' => " \n",
            'unselect' => '0',
            'disabled' => true,
        ]));
        $expected = <<<'EOD'
0text1  
1text2  
EOD;
        $this->assertEqualsWithoutLE($expected, Html::radioList('test', ['value2'], $this->getDataItems(), [
            'item' => function ($index, $label, $name, $checked, $value) {
                return $index . Html::label($label . ' ' . Html::radio($name, $checked, ['value' => $value]));
            },
        ]));
        $expected = <<<'EOD'
0text1  
1text2  
EOD;
        $this->assertEqualsWithoutLE($expected, Html::radioList('test', ['value2'], $this->getDataItems(), [
            'item' => function ($index, $label, $name, $checked, $value) {
                return $index . Html::label($label . ' ' . Html::radio($name, $checked, ['value' => $value]));
            },
            'tag' => false,
        ]));
        $this->assertEqualsWithoutLE($expected, Html::radioList('test', new \ArrayObject(['value2']), $this->getDataItems(), [
            'item' => function ($index, $label, $name, $checked, $value) {
                return $index . Html::label($label . ' ' . Html::radio($name, $checked, ['value' => $value]));
            },
            'tag' => false,
        ]));
        $expected = <<<'EOD'
  zero 
  one 
  text3
EOD;
        $this->assertEqualsWithoutLE($expected, Html::radioList('test', [0], $this->getDataItems3()));
        $this->assertEqualsWithoutLE($expected, Html::radioList('test', new \ArrayObject([0]), $this->getDataItems3()));
        $expected = <<<'EOD'
  zero 
  one 
  text3
EOD;
        $this->assertEqualsWithoutLE($expected, Html::radioList('test', ['value3'], $this->getDataItems3()));
        $this->assertEqualsWithoutLE($expected, Html::radioList('test', new \ArrayObject(['value3']), $this->getDataItems3()));
        $expected = <<<'EOD'
  Test Label 
  Test Label
EOD;
        $this->assertEqualsWithoutLE($expected, Html::radioList('test', null, $this->getDataItems(), [
            'itemOptions' => [
                'value' => 0,
                'label' => 'Test Label'
            ]
        ]));
        $expected = <<<'EOD'
  1 
  1.1 
  1.10
EOD;
        $this->assertEqualsWithoutLE($expected, Html::radioList('test', ['1.1'], ['1' => '1', '1.1' => '1.1', '1.10' => '1.10'], ['strict' => true]));
        $this->assertEqualsWithoutLE($expected, Html::radioList('test', [1.1], ['1' => '1', '1.1' => '1.1', '1.10' => '1.10'], ['strict' => true]));
        $expected = <<<'EOD'
  1 
  1.1 
  1.10
EOD;
        $this->assertEqualsWithoutLE($expected, Html::radioList('test', ['1.1'], ['1' => '1', '1.1' => '1.1', '1.10' => '1.10']));
    }
    public function testUl()
    {
        $data = [
            1, 'abc', '<>',
        ];
        $expected = <<<'EOD'
EOD;
        $this->assertEqualsWithoutLE($expected, Html::ul($data));
        $expected = <<<'EOD'
EOD;
        $this->assertEqualsWithoutLE($expected, Html::ul($data, [
            'class' => 'test',
            'item' => function ($item, $index) {
                return "$item ";
            },
        ]));
        $this->assertEquals('', Html::ul([], ['class' => 'test']));
        $this->assertStringMatchesFormat('%A ', Html::ul([], ['tag' => 'foo']));
    }
    public function testOl()
    {
        $data = [
            1, 'abc', '<>',
        ];
        $expected = <<<'EOD'
1 
abc 
<> 
 
EOD;
        $this->assertEqualsWithoutLE($expected, Html::ol($data, [
            'itemOptions' => ['class' => 'ti'],
        ]));
        $expected = <<<'EOD'
1 
abc 
<> 
 
EOD;
        $this->assertEqualsWithoutLE($expected, Html::ol($data, [
            'class' => 'test',
            'item' => function ($item, $index) {
                return "$item ";
            },
        ]));
        $this->assertEquals(' ', Html::ol([], ['class' => 'test']));
    }
    public function testRenderOptions()
    {
        $data = [
            'value1' => 'label1',
            'group1' => [
                'value11' => 'label11',
                'group11' => [
                    'value111' => 'label111',
                ],
                'group12' => [],
            ],
            'value2' => 'label2',
            'group2' => [],
        ];
        $expected = <<<'EOD'
please select<> 
label1 
label11 
label111 
 
 
 
label2 
 
EOD;
        $attributes = [
            'prompt' => 'please select<>',
            'options' => [
                'value111' => ['class' => 'option'],
            ],
            'groups' => [
                'group12' => ['class' => 'group'],
            ],
            'encodeSpaces' => true,
        ];
        $this->assertEqualsWithoutLE($expected, Html::renderSelectOptions(['value111', 'value1'], $data, $attributes));
        $attributes = [
            'prompt' => 'please select<>',
            'options' => [
                'value111' => ['class' => 'option'],
            ],
            'groups' => [
                'group12' => ['class' => 'group'],
            ],
        ];
        $this->assertEqualsWithoutLE(str_replace(' ', ' ', $expected), Html::renderSelectOptions(['value111', 'value1'], $data, $attributes));
        // Attributes for prompt (https://github.com/yiisoft/yii2/issues/7420)
        $data = [
            'value1' => 'label1',
            'value2' => 'label2',
        ];
        $expected = <<<'EOD'
Please select 
label1 
label2 
EOD;
        $attributes = [
            'prompt' => [
                'text' => 'Please select', 'options' => ['class' => 'prompt', 'value' => '-1', 'label' => 'None'],
            ],
        ];
        $this->assertEqualsWithoutLE($expected, Html::renderSelectOptions(['value1'], $data, $attributes));
        $expected = <<<'EOD'
1 
1.1 
1.10 
EOD;
        $data = ['1' => '1', '1.1' => '1.1', '1.10' => '1.10'];
        $attributes = ['strict' => true];
        $this->assertEqualsWithoutLE($expected, Html::renderSelectOptions(['1.1'], $data, $attributes));
        $attributes = ['strict' => true];
        $this->assertEqualsWithoutLE($expected, Html::renderSelectOptions([1.1], $data, $attributes));
        $expected = <<<'EOD'
1 
1.1 
1.10 
EOD;
        $this->assertEqualsWithoutLE($expected, Html::renderSelectOptions([1.1], $data));
        $expected = <<<'EOD'
1 
1.1 
1.10 
 
EOD;
        $data = ['1' => '1', '1.1' => '1.1', 'group' => ['1.10' => '1.10']];
        $attributes = ['strict' => true];
        $this->assertEqualsWithoutLE($expected, Html::renderSelectOptions(['1.10'], $data, $attributes));
        $expected = <<<'EOD'
Please select 
Yes 
No 
EOD;
        $data = [true => 'Yes', false => 'No'];
        $attributes = ['prompt' => 'Please select'];
        $this->assertEqualsWithoutLE($expected, Html::renderSelectOptions(false, $data, $attributes));
        //$attributes = ['prompt' => 'Please select'];
        //$this->assertEqualsWithoutLE($expected, Html::renderSelectOptions([false], $data, $attributes));
        $attributes = ['prompt' => 'Please select', 'strict' => true];
        $this->assertEqualsWithoutLE($expected, Html::renderSelectOptions(false, $data, $attributes));
        $attributes = ['prompt' => 'Please select', 'strict' => true];
        $this->assertEqualsWithoutLE($expected, Html::renderSelectOptions([false], $data, $attributes));
    }
    public function testRenderTagAttributes()
    {
        $this->assertEquals('', Html::renderTagAttributes([]));
        $this->assertEquals(' name="test" value="1<>"', Html::renderTagAttributes(['name' => 'test', 'empty' => null, 'value' => '1<>']));
        $this->assertEquals(' checked disabled', Html::renderTagAttributes(['checked' => true, 'disabled' => true, 'hidden' => false]));
        $this->assertEquals(' class="first second"', Html::renderTagAttributes(['class' => ['first', 'second']]));
        $this->assertEquals(' class="first second"', Html::renderTagAttributes(['class' => ['first', null, 'second', '']]));
        Html::$normalizeClassAttribute = true;
        $this->assertEquals(' class="first second"', Html::renderTagAttributes(['class' => ['first second', 'first']]));
        $this->assertEquals('', Html::renderTagAttributes(['class' => []]));
        $this->assertEquals(' style="width: 100px; height: 200px;"', Html::renderTagAttributes(['style' => ['width' => '100px', 'height' => '200px']]));
        $this->assertEquals('', Html::renderTagAttributes(['style' => []]));
        $attributes = [
            'data' => [
                'foo' => [],
            ],
        ];
        $this->assertEquals(' data-foo=\'[]\'', Html::renderTagAttributes($attributes));
        $attributes = [
            'data' => [
                'foo' => true,
            ],
        ];
        $this->assertEquals(' data-foo', Html::renderTagAttributes($attributes));
        $attributes = [
            'data' => [
                'foo' => false,
            ],
        ];
        $this->assertEquals('', Html::renderTagAttributes($attributes));
        $attributes = [
            'data' => [
                'foo' => null,
            ],
        ];
        $this->assertEquals('', Html::renderTagAttributes($attributes));
    }
    public function testAddCssClass()
    {
        $options = [];
        Html::addCssClass($options, 'test');
        $this->assertEquals(['class' => 'test'], $options);
        Html::addCssClass($options, 'test');
        $this->assertEquals(['class' => 'test'], $options);
        Html::addCssClass($options, 'test2');
        $this->assertEquals(['class' => 'test test2'], $options);
        Html::addCssClass($options, 'test');
        $this->assertEquals(['class' => 'test test2'], $options);
        Html::addCssClass($options, 'test2');
        $this->assertEquals(['class' => 'test test2'], $options);
        Html::addCssClass($options, 'test3');
        $this->assertEquals(['class' => 'test test2 test3'], $options);
        Html::addCssClass($options, 'test2');
        $this->assertEquals(['class' => 'test test2 test3'], $options);
        $options = [
            'class' => ['test'],
        ];
        Html::addCssClass($options, 'test2');
        $this->assertEquals(['class' => ['test', 'test2']], $options);
        Html::addCssClass($options, 'test2');
        $this->assertEquals(['class' => ['test', 'test2']], $options);
        Html::addCssClass($options, ['test3']);
        $this->assertEquals(['class' => ['test', 'test2', 'test3']], $options);
        $options = [
            'class' => 'test',
        ];
        Html::addCssClass($options, ['test1', 'test2']);
        $this->assertEquals(['class' => 'test test1 test2'], $options);
    }
    /**
     * @depends testAddCssClass
     */
    public function testMergeCssClass()
    {
        $options = [
            'class' => [
                'persistent' => 'test1',
            ],
        ];
        Html::addCssClass($options, ['persistent' => 'test2']);
        $this->assertEquals(['persistent' => 'test1'], $options['class']);
        Html::addCssClass($options, ['additional' => 'test2']);
        $this->assertEquals(['persistent' => 'test1', 'additional' => 'test2'], $options['class']);
    }
    public function testRemoveCssClass()
    {
        $options = ['class' => 'test test2 test3'];
        Html::removeCssClass($options, 'test2');
        $this->assertEquals(['class' => 'test test3'], $options);
        Html::removeCssClass($options, 'test2');
        $this->assertEquals(['class' => 'test test3'], $options);
        Html::removeCssClass($options, 'test');
        $this->assertEquals(['class' => 'test3'], $options);
        Html::removeCssClass($options, 'test3');
        $this->assertEquals([], $options);
        $options = ['class' => ['test', 'test2', 'test3']];
        Html::removeCssClass($options, 'test2');
        $this->assertEquals(['class' => ['test', 2 => 'test3']], $options);
        Html::removeCssClass($options, 'test');
        Html::removeCssClass($options, 'test3');
        $this->assertEquals([], $options);
        $options = [
            'class' => 'test test1 test2',
        ];
        Html::removeCssClass($options, ['test1', 'test2']);
        $this->assertEquals(['class' => 'test'], $options);
    }
    public function testCssStyleFromArray()
    {
        $this->assertEquals('width: 100px; height: 200px;', Html::cssStyleFromArray([
            'width' => '100px',
            'height' => '200px',
        ]));
        $this->assertNull(Html::cssStyleFromArray([]));
    }
    public function testCssStyleToArray()
    {
        $this->assertEquals([
            'width' => '100px',
            'height' => '200px',
        ], Html::cssStyleToArray('width: 100px; height: 200px;'));
        $this->assertEquals([], Html::cssStyleToArray('  '));
    }
    public function testAddCssStyle()
    {
        $options = ['style' => 'width: 100px; height: 200px;'];
        Html::addCssStyle($options, 'width: 110px; color: red;');
        $this->assertEquals('width: 110px; height: 200px; color: red;', $options['style']);
        $options = ['style' => 'width: 100px; height: 200px;'];
        Html::addCssStyle($options, ['width' => '110px', 'color' => 'red']);
        $this->assertEquals('width: 110px; height: 200px; color: red;', $options['style']);
        $options = ['style' => 'width: 100px; height: 200px;'];
        Html::addCssStyle($options, 'width: 110px; color: red;', false);
        $this->assertEquals('width: 100px; height: 200px; color: red;', $options['style']);
        $options = [];
        Html::addCssStyle($options, 'width: 110px; color: red;');
        $this->assertEquals('width: 110px; color: red;', $options['style']);
        $options = [];
        Html::addCssStyle($options, 'width: 110px; color: red;', false);
        $this->assertEquals('width: 110px; color: red;', $options['style']);
        $options = [
            'style' => [
                'width' => '100px',
            ],
        ];
        Html::addCssStyle($options, ['color' => 'red'], false);
        $this->assertEquals('width: 100px; color: red;', $options['style']);
    }
    public function testRemoveCssStyle()
    {
        $options = ['style' => 'width: 110px; height: 200px; color: red;'];
        Html::removeCssStyle($options, 'width');
        $this->assertEquals('height: 200px; color: red;', $options['style']);
        Html::removeCssStyle($options, ['height']);
        $this->assertEquals('color: red;', $options['style']);
        Html::removeCssStyle($options, ['color', 'background']);
        $this->assertNull($options['style']);
        $options = [];
        Html::removeCssStyle($options, ['color', 'background']);
        $this->assertNotTrue(array_key_exists('style', $options));
        $options = [
            'style' => [
                'color' => 'red',
                'width' => '100px',
            ],
        ];
        Html::removeCssStyle($options, ['color']);
        $this->assertEquals('width: 100px;', $options['style']);
    }
    public function testBooleanAttributes()
    {
        $this->assertEquals(' ', Html::input('email', 'mail', null, ['required' => false]));
        $this->assertEquals(' ', Html::input('email', 'mail', null, ['required' => true]));
        $this->assertEquals(' ', Html::input('email', 'mail', null, ['required' => 'hi']));
    }
    public function testDataAttributes()
    {
        $this->assertEquals(' ', Html::tag('link', '', ['src' => 'xyz', 'aria' => ['a' => 1, 'b' => 'c']]));
        $this->assertEquals(' ', Html::tag('link', '', ['src' => 'xyz', 'data' => ['a' => 1, 'b' => 'c']]));
        $this->assertEquals(' ', Html::tag('link', '', ['src' => 'xyz', 'ng' => ['a' => 1, 'b' => 'c']]));
        $this->assertEquals(' ', Html::tag('link', '', ['src' => 'xyz', 'data-ng' => ['a' => 1, 'b' => 'c']]));
        $this->assertEquals(' ', Html::tag('link', '', ['src' => ['a' => 1, 'b' => "It's"]]));
    }
    protected function getDataItems()
    {
        return [
            'value1' => 'text1',
            'value2' => 'text2',
        ];
    }
    protected function getDataItems2()
    {
        return [
            'value1<>' => 'text1<>',
            'value  2' => 'text  2',
        ];
    }
    protected function getDataItems3()
    {
        return [
            'zero',
            'one',
            'value3' => 'text3',
        ];
    }
    /**
     * Data provider for [[testActiveTextInput()]].
     * @return array test data
     */
    public function dataProviderActiveTextInput()
    {
        return [
            [
                'some text',
                [],
                ' ',
            ],
            [
                '',
                [
                    'maxlength' => true,
                ],
                ' ',
            ],
            [
                '',
                [
                    'maxlength' => 99,
                ],
                ' ',
            ],
        ];
    }
    /**
     * @dataProvider dataProviderActiveTextInput
     *
     * @param string $value
     * @param array $options
     * @param string $expectedHtml
     */
    public function testActiveTextInput($value, array $options, $expectedHtml)
    {
        $model = new HtmlTestModel();
        $model->name = $value;
        $this->assertEquals($expectedHtml, Html::activeTextInput($model, 'name', $options));
    }
    /**
     * Data provider for [[testActiveTextInputMaxLength]].
     * @return array test data
     */
    public function dataProviderActiveTextInputMaxLength()
    {
        return [
            [
                'some text',
                [],
                ' ',
                ' ',
            ],
            [
                '',
                [
                    'maxlength' => true,
                ],
                ' ',
                ' ',
            ],
            [
                '',
                [
                    'maxlength' => 99,
                ],
                ' ',
                ' ',
            ],
        ];
    }
    /**
     * @dataProvider dataProviderActiveTextInputMaxLength
     *
     * @param string $value
     * @param array $options
     * @param string $expectedHtmlForTitle
     * @param string $expectedHtmlForAlias
     */
    public function testActiveTextInputMaxLength($value, array $options, $expectedHtmlForTitle, $expectedHtmlForAlias)
    {
        $model = new HtmlTestModel();
        $model->title = $value;
        $model->alias = $value;
        $this->assertEquals($expectedHtmlForTitle, Html::activeInput('text', $model, 'title', $options));
        $this->assertEquals($expectedHtmlForAlias, Html::activeInput('text', $model, 'alias', $options));
    }
    /**
     * Data provider for [[testActivePasswordInput()]].
     * @return array test data
     */
    public function dataProviderActivePasswordInput()
    {
        return [
            [
                'some text',
                [],
                ' ',
            ],
            [
                '',
                [
                    'maxlength' => true,
                ],
                ' ',
            ],
            [
                '',
                [
                    'maxlength' => 99,
                ],
                ' ',
            ],
        ];
    }
    /**
     * @dataProvider dataProviderActivePasswordInput
     *
     * @param string $value
     * @param array $options
     * @param string $expectedHtml
     */
    public function testActivePasswordInput($value, array $options, $expectedHtml)
    {
        $model = new HtmlTestModel();
        $model->name = $value;
        $this->assertEquals($expectedHtml, Html::activePasswordInput($model, 'name', $options));
    }
    /**
     * Data provider for [[testActiveInput_TypeText]].
     * @return array test data
     */
    public function dataProviderActiveInput_TypeText()
    {
        return [
            [
                'some text',
                [],
                ' ',
            ],
            [
                '',
                [
                    'maxlength' => true,
                ],
                ' ',
            ],
            [
                '',
                [
                    'maxlength' => 99,
                ],
                ' ',
            ],
        ];
    }
    /**
     * @dataProvider dataProviderActiveInput_TypeText
     *
     * @param string $value
     * @param array $options
     * @param string $expectedHtml
     */
    public function testActiveInput_TypeText($value, array $options, $expectedHtml)
    {
        $model = new HtmlTestModel();
        $model->name = $value;
        $this->assertEquals($expectedHtml, Html::activeInput('text', $model, 'name', $options));
    }
    public function errorSummaryDataProvider()
    {
        return [
            [
                'ok',
                [],
                'Please fix the following errors:
 ',
            ],
            [
                'ok',
                ['header' => 'Custom header', 'footer' => 'Custom footer', 'style' => 'color: red'],
                'Custom header
Custom footer
 ',
            ],
            [
                str_repeat('long_string', 60),
                [],
                'Please fix the following errors:
Name should contain at most 100 characters.  ',
            ],
            [
                'not_an_integer',
                [],
                'Please fix the following errors:
Error message. Here are some chars: < >  ',
                function ($model) {
                    /* @var $model DynamicModel */
                    $model->addError('name', 'Error message. Here are some chars: < >');
                },
            ],
            [
                'not_an_integer',
                ['encode' => false],
                'Please fix the following errors:
Error message. Here are some chars: < >  ',
                function ($model) {
                    /* @var $model DynamicModel */
                    $model->addError('name', 'Error message. Here are some chars: < >');
                },
            ],
            [
                str_repeat('long_string', 60),
                [],
                'Please fix the following errors:
Error message. Here are some chars: < >  ',
                function ($model) {
                    /* @var $model DynamicModel */
                    $model->addError('name', 'Error message. Here are some chars: < >');
                },
            ],
            [
                'not_an_integer',
                ['showAllErrors' => true],
                'Please fix the following errors:
Error message. Here are some chars: < > 
Error message. Here are even more chars: ""  ',
                function ($model) {
                    /* @var $model DynamicModel */
                    $model->addError('name', 'Error message. Here are some chars: < >');
                    $model->addError('name', 'Error message. Here are even more chars: ""');
                },
            ],
            [
                'empty_class',
                ['emptyClass' => 'd-none'],
                'Please fix the following errors:
 ',
            ],
        ];
    }
    /**
     * @dataProvider errorSummaryDataProvider
     *
     * @param string $value
     * @param array $options
     * @param string $expectedHtml
     * @param \Closure $beforeValidate
     */
    public function testErrorSummary($value, array $options, $expectedHtml, $beforeValidate = null)
    {
        $model = new HtmlTestModel();
        $model->name = $value;
        if ($beforeValidate !== null) {
            call_user_func($beforeValidate, $model);
        }
        $model->validate(null, false);
        $this->assertEqualsWithoutLE($expectedHtml, Html::errorSummary($model, $options));
    }
    public function testError()
    {
        $model = new HtmlTestModel();
        $model->validate();
        $this->assertEquals(
            'Name cannot be blank.
',
            Html::error($model, 'name'),
            'Default error message after calling $model->getFirstError()'
        );
        $this->assertEquals(
            'this is custom error message
',
            Html::error($model, 'name', ['errorSource' => [$model, 'customError']]),
            'Custom error message generated by callback'
        );
        $this->assertEquals(
            'Error in yiiunit\framework\helpers\HtmlTestModel - name
',
            Html::error($model, 'name', ['errorSource' => function ($model, $attribute) {
                return 'Error in ' . get_class($model) . ' - ' . $attribute;
            }]),
            'Custom error message generated by closure'
        );
    }
    /**
     * Test that attributes that output same errors, return unique message error
     * @see https://github.com/yiisoft/yii2/pull/15859
     */
    public function testCollectError()
    {
        $model = new DynamicModel(['attr1', 'attr2']);
        $model->addError('attr1', 'error1');
        $model->addError('attr1', 'error2');
        $model->addError('attr2', 'error1');
        $this->assertEquals(
            'Please fix the following errors:
 ',
            Html::errorSummary($model, ['showAllErrors' => true])
        );
    }
    /**
     * Data provider for [[testActiveTextArea()]].
     * @return array test data
     */
    public function dataProviderActiveTextArea()
    {
        return [
            [
                'some text',
                [],
                '',
            ],
            [
                'some text',
                [
                    'maxlength' => true,
                ],
                '',
            ],
            [
                'some text',
                [
                    'maxlength' => 99,
                ],
                '',
            ],
            [
                'some text',
                [
                    'value' => 'override text',
                ],
                '',
            ],
        ];
    }
    /**
     * @dataProvider dataProviderActiveTextArea
     *
     * @param string $value
     * @param array $options
     * @param string $expectedHtml
     */
    public function testActiveTextArea($value, array $options, $expectedHtml)
    {
        $model = new HtmlTestModel();
        $model->description = $value;
        $this->assertEquals($expectedHtml, Html::activeTextarea($model, 'description', $options));
    }
    /**
     * @see https://github.com/yiisoft/yii2/issues/10078
     */
    public function testCsrfDisable()
    {
        Yii::$app->request->enableCsrfValidation = true;
        Yii::$app->request->cookieValidationKey = 'foobar';
        $csrfForm = Html::beginForm('/index.php', 'post', ['id' => 'mycsrfform']);
        $this->assertEquals(
            '