diff --git a/.gitignore b/.gitignore
index ed9e4e552e6..790c55c2ea1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -43,11 +43,11 @@ ext/run-tests.php
lemon
.libs/
-.temp/
autom4te.cache/
/vendor
/ide/
+.zephir/
boxfile.yml
composer.lock
php_test_results_*.txt
diff --git a/CHANGELOG-4.0.md b/CHANGELOG-4.0.md
index 91545add933..360c351fb6d 100644
--- a/CHANGELOG-4.0.md
+++ b/CHANGELOG-4.0.md
@@ -12,7 +12,7 @@
- Added more column types for the Mysql adapter. The adapter supports `TYPE_BIGINTEGER`, `TYPE_BIT`, `TYPE_BLOB`, `TYPE_BOOLEAN`, `TYPE_CHAR`, `TYPE_DATE`, `TYPE_DATETIME`, `TYPE_DECIMAL`, `TYPE_DOUBLE`, `TYPE_ENUM`, `TYPE_FLOAT`, `TYPE_INTEGER`, `TYPE_JSON`, `TYPE_JSONB`, `TYPE_LONGBLOB`, `TYPE_LONGTEXT`, `TYPE_MEDIUMBLOB`, `TYPE_MEDIUMINTEGER`, `TYPE_MEDIUMTEXT`, `TYPE_SMALLINTEGER`, `TYPE_TEXT`, `TYPE_TIME`, `TYPE_TIMESTAMP`, `TYPE_TINYBLOB`, `TYPE_TINYINTEGER`, `TYPE_TINYTEXT`, `TYPE_VARCHAR` [#13151](https://github.com/phalcon/cphalcon/issues/13151), [#12223](https://github.com/phalcon/cphalcon/issues/12223), [#524](https://github.com/phalcon/cphalcon/issues/524), [#13225](https://github.com/phalcon/cphalcon/pull/13225) [@zGaron](https://github.com/zGaron), [#12523](https://github.com/phalcon/cphalcon/pull/12523) [@Studentsov](https://github.com/Studentsov), [#12471](https://github.com/phalcon/cphalcon/pull/12471) [@ruudboon](https://github.com/ruudboon)
- Added `Phalcon\Acl\Adapter\Memory::addRole` support multiple inherited
- Added `Phalcon\Tag::renderTitle()` that renders the title enclosed in `
` tags. [#13547](https://github.com/phalcon/cphalcon/issues/13547)
-- Added `hasHeader()` method to `Phalcon\Http\Response` to provide the ability to check if a header exists. [PR-12189](https://github.com/phalcon/cphalcon/pull/12189)
+- Added `hasHeader()` method to `Phalcon\Http\Response` to provide the ability to check if a header exists. [#12189](https://github.com/phalcon/cphalcon/pull/12189)
- Added global setting `orm.case_insensitive_column_map` to attempt to find value in the column map case-insensitively. Can be also enabled by setting `caseInsensitiveColumnMap` key in `\Phalcon\Mvc\Model::setup()`. [#11802](https://github.com/phalcon/cphalcon/pull/11802)
- Added the ability to use FrontendInterface to serialize Model and ResultSet - Inject a `serializer` object which implements `FrontendInterface` in DI to use it. [#12808] (https://github.com/phalcon/cphalcon/pull/12888)
- Added `Phalcon\Mvc\Model\Query\BuilderInterface::offset` [#13599](https://github.com/phalcon/cphalcon/pull/13599)
@@ -22,22 +22,23 @@
- Added response handler to `Phalcon\Mvc\Micro`, `Phalcon\Mvc\Micro::setResponseHandler`, to allow use of a custom response handler. [#12452](https://github.com/phalcon/cphalcon/pull/12452)
- Added two new events `response::beforeSendHeaders` and `response::afterSendHeaders` to `Phalcon\Http\Response` [#10689](https://github.com/phalcon/cphalcon/issue/10689)
- Added a retainer for the current token to be used during the checkings, so when `Phalcon\Security::getToken` is called the token used for checkings don't change. [#12392](https://github.com/phalcon/cphalcon/issues/12392)
+- Added `Phalcon\Html\Tag`, a component that creates HTML elements. It will replace `Phalcon\Tag` in a future version. This component does not use static method calls. [#12392](https://github.com/phalcon/cphalcon/issues/12392)
## Changed
-- By configuring `prefix` and `statsKey` the `Phalcon\Cache\Backend\Redis::queryKeys` no longer returns prefixed keys, now it returns original keys without prefix. [PR-13456](https://github.com/phalcon/cphalcon/pull/13456)
+- By configuring `prefix` and `statsKey` the `Phalcon\Cache\Backend\Redis::queryKeys` no longer returns prefixed keys, now it returns original keys without prefix. [#13656](https://github.com/phalcon/cphalcon/pull/13656)
- Now Phalcon requires the [PSR PHP extension](https://github.com/jbboehr/php-psr) to be installed and enabled
-- The `Phalcon\Mvc\Application`, `Phalcon\Mvc\Micro` and `Phalcon\Mvc\Router` now must have a URI to process [PR-12380](https://github.com/phalcon/cphalcon/pull/12380)
-- Response headers and cookies are no longer prematurely sent [PR-12378](https://github.com/phalcon/cphalcon/pull/12378)
+- The `Phalcon\Mvc\Application`, `Phalcon\Mvc\Micro` and `Phalcon\Mvc\Router` now must have a URI to process [#12380](https://github.com/phalcon/cphalcon/pull/12380)
+- Response headers and cookies are no longer prematurely sent [#12378](https://github.com/phalcon/cphalcon/pull/12378)
- You can no longer assign data to models whilst saving them [#12317](https://github.com/phalcon/cphalcon/issues/12317)
- The `Phalcon\Mvc\Model\Manager::load` no longer reuses already initialized models [#12317](https://github.com/phalcon/cphalcon/issues/12317)
- Changed `Phalcon\Db\Dialect\Postgresql::describeReferences` to generate correct SQL, added "on update" and "on delete" constraints
- Changed catch `Exception` to `Throwable` [#12288](https://github.com/phalcon/cphalcon/issues/12288)
-- Changed `Phalcon\Mvc\Model\Query\Builder::addFrom` to remove third parameter `$with` [PR-13109](https://github.com/phalcon/cphalcon/pull/13109)
-- `Phalcon\Forms\Form::clear` will no longer call `Phalcon\Forms\Element::clear`, instead it will clear/set default value itself, and `Phalcon\Forms\Element::clear` will now call `Phalcon\Forms\Form::clear` if it's assigned to the form, otherwise it will just clear itself. [PR-13500](https://github.com/phalcon/cphalcon/pull/13500)
-- `Phalcon\Forms\Form::getValue` will now also try to get the value by calling `Tag::getValue` or element's `getDefault` method before returning `null`, and `Phalcon\Forms\Element::getValue` calls `Tag::getDefault` only if it's not added to the form. [PR-13500](https://github.com/phalcon/cphalcon/pull/13500)
+- Changed `Phalcon\Mvc\Model\Query\Builder::addFrom` to remove third parameter `$with` [#13109](https://github.com/phalcon/cphalcon/pull/13109)
+- `Phalcon\Forms\Form::clear` will no longer call `Phalcon\Forms\Element::clear`, instead it will clear/set default value itself, and `Phalcon\Forms\Element::clear` will now call `Phalcon\Forms\Form::clear` if it's assigned to the form, otherwise it will just clear itself. [#13500](https://github.com/phalcon/cphalcon/pull/13500)
+- `Phalcon\Forms\Form::getValue` will now also try to get the value by calling `Tag::getValue` or element's `getDefault` method before returning `null`, and `Phalcon\Forms\Element::getValue` calls `Tag::getDefault` only if it's not added to the form. [#13500](https://github.com/phalcon/cphalcon/pull/13500)
- Changed `Phalcon\Mvc\Model` to use the `Phalcon\Messages\Message` object for its messages [#13114](https://github.com/phalcon/cphalcon/issues/13114)
- Changed `Phalcon\Validation\*` to use the `Phalcon\Messages\Message` object for its messages [#13114](https://github.com/phalcon/cphalcon/issues/13114)
-- Collections now use the Validation component [PR-12376](https://github.com/phalcon/cphalcon/pull/12376)
+- Collections now use the Validation component [#12376](https://github.com/phalcon/cphalcon/pull/12376)
- Made the `specialKey` (`_PHCR`) optional for the `Phalcon\Cache\Backend\Redis` adapter [#10905](https://github.com/phalcon/cphalcon/issues/10905), [#11608](https://github.com/phalcon/cphalcon/pull/11608)
- Refactored `Phalcon\Db\Adapter\Pdo::query` to use PDO's prepare and execute. `Phalcon\Db\Adapter::fetchAll` to use PDO's fetchAll
- Fixed `\Phalcon\Http\Response::setFileToSend` filename last much _
diff --git a/phalcon/html/exception.zep b/phalcon/html/exception.zep
new file mode 100644
index 00000000000..9cf48a6c4c8
--- /dev/null
+++ b/phalcon/html/exception.zep
@@ -0,0 +1,22 @@
+
+/**
+ * This file is part of the Phalcon Framework.
+ *
+ * (c) Phalcon Team
+ *
+ * For the full copyright and license information, please view the LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+namespace Phalcon\Html;
+
+/**
+ * Phalcon\Html\Tag\Exception
+ *
+ * Exceptions thrown in Phalcon\Html\Tag will use this class
+ *
+ */
+class Exception extends \Phalcon\Exception
+{
+
+}
diff --git a/phalcon/html/tag.zep b/phalcon/html/tag.zep
new file mode 100644
index 00000000000..854534603da
--- /dev/null
+++ b/phalcon/html/tag.zep
@@ -0,0 +1,1779 @@
+
+/**
+ * This file is part of the Phalcon Framework.
+ *
+ * (c) Phalcon Team
+ *
+ * For the full copyright and license information, please view the LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+namespace Phalcon\Html;
+
+use Phalcon\DiInterface;
+use Phalcon\Di\InjectionAwareInterface;
+use Phalcon\Escaper;
+use Phalcon\EscaperInterface;
+use Phalcon\Html\Exception;
+use Phalcon\UrlInterface;
+
+/**
+ * Phalcon\Html\Tag
+ *
+ * Phalcon\Tag is designed to simplify building of HTML tags. It provides a set
+ * of helpers to dynamically generate HTML.
+ */
+class Tag implements InjectionAwareInterface
+{
+ /**
+ * @var
+ */
+ protected container;
+
+ /**
+ * @var array
+ */
+ private append = [];
+
+ /**
+ * @var int
+ */
+ private docType = 5; // HTML5
+
+ /**
+ * @var
+ */
+ private escaper;
+
+ /**
+ * @var array
+ */
+ private prepend = [];
+
+ /**
+ * @var string
+ */
+ private separator = "";
+
+ /**
+ * @var string
+ */
+ private title = "";
+
+ /**
+ * @var array
+ */
+ private values = [];
+
+ /**
+ * @var
+ */
+ private url;
+
+ /**
+ * Constants
+ */
+ const HTML32 = 1;
+ const HTML401_STRICT = 2;
+ const HTML401_TRANSITIONAL = 3;
+ const HTML401_FRAMESET = 4;
+ const HTML5 = 5;
+ const XHTML10_STRICT = 6;
+ const XHTML10_TRANSITIONAL = 7;
+ const XHTML10_FRAMESET = 8;
+ const XHTML11 = 9;
+ const XHTML20 = 10;
+ const XHTML5 = 11;
+
+ /**
+ * Appends a text to current document title
+ */
+ public function appendTitle(array title) ->
+ {
+ let this->append = title;
+
+ return this;
+ }
+
+ /**
+ * Builds a HTML input[type="button"] tag
+ *
+ *
+ * use Phalcon\Html\Tag;
+ *
+ * $tag = new Tag();
+ *
+ * echo $tag->button('Click Me')
+ *
+ *
+ * Volt syntax:
+ *
+ * {{ button('Click Me) }}
+ *
+ */
+ public function button(string! name, array parameters = []) -> string
+ {
+ return this->renderInput("button", name, parameters);
+ }
+
+ /**
+ * Resets the request and internal values to avoid those fields will have
+ * any default value.
+ */
+ public function clear() -> void
+ {
+ let this->append = [],
+ this->docType = self::HTML5,
+ this->prepend = [],
+ this->separator = "",
+ this->title = "",
+ this->values = [];
+ }
+
+ /**
+ * Builds a HTML tag
+ *
+ * Parameters
+ * `onlyStart` Only process the start of th element
+ * `selfClose` It is a self close element
+ * `useEol` Append PHP_EOL at the end
+ *
+ */
+ public function element(string! tag, array parameters = []) -> string
+ {
+ var onlyStart, output, selfClose, useEol;
+
+ let useEol = this->arrayGetDefault("useEol", parameters, false),
+ onlyStart = this->arrayGetDefault("onlyStart", parameters, false),
+ selfClose = this->arrayGetDefault("selfClose", parameters, false);
+
+ /**
+ * Unset options for this control
+ */
+ unset parameters["onlyStart"];
+ unset parameters["selfClose"];
+ unset parameters["useEol"];
+
+ let output = this->renderAttributes("<" . tag, parameters);
+
+ if this->docType > self::HTML5 {
+ if selfClose {
+ let output .= " />";
+ } else {
+ let output .= ">";
+ }
+ } else {
+ if onlyStart {
+ let output .= ">";
+ } else {
+ let output .= ">" . tag . ">";
+ }
+ }
+
+ if useEol {
+ let output .= PHP_EOL;
+ }
+
+ return output;
+ }
+
+ /**
+ * Builds the closing tag of an html element
+ *
+ * Parameters
+ * `useEol` Append PHP_EOL at the end
+ *
+ *
+ * use Phalcon\Html\Tag;
+ *
+ * $tab = new Tag();
+ *
+ * echo $tag->elementClose(
+ * [
+ * 'name' => 'aside',
+ * ]
+ * ); //
+ *
+ * echo $tag->elementClose(
+ * [
+ * 'name' => 'aside',
+ * 'useEol' => true,
+ * ]
+ * ); // '' . PHP_EOL
+ *
+ *
+ */
+ public function elementClose(string! tag, array parameters = []) -> string
+ {
+ var useEol = false;
+
+ let useEol = this->arrayGetDefault("useEol", parameters, false);
+
+ if useEol {
+ return "" . tag . ">" . PHP_EOL;
+ }
+ return "" . tag . ">";
+
+ }
+
+ /**
+ * Returns the closing tag of a form element
+ */
+ public function endForm(bool eol = true) -> string
+ {
+ if eol {
+ return "" . PHP_EOL;
+ } else {
+ return "";
+ }
+ }
+
+ /**
+ * Builds a HTML FORM tag
+ *
+ *
+ * use Phalcon\Html\Tag;
+ *
+ * $tab = new Tag();
+ *
+ * echo $tag->form('posts/save');
+ *
+ * echo $tag->form(
+ * 'posts/save',
+ * [
+ * "method" => "post",
+ * ]
+ * );
+ *
+ *
+ * Volt syntax:
+ *
+ * {{ form('posts/save') }}
+ * {{ form('posts/save', ['method': 'post') }}
+ *
+ */
+ public function form(string action, array parameters = []) -> string
+ {
+ var output, params, service;
+
+ let service = this->getService("url");
+
+ let parameters["method"] = this->arrayGetDefault("method", parameters, "post"),
+ parameters["action"] = service->get(action);
+
+ /**
+ * Check for extra parameters
+ */
+ if fetch params, parameters["parameters"] {
+ let parameters["action"] .= "?" . params;
+ unset parameters["parameters"];
+ }
+
+ let output = this->renderAttributes("';
+ $actual = $tag->endForm(false);
+ $I->assertEquals($expected, $actual);
+ }
+
+ /**
+ * Tests Phalcon\Html\Tag :: endForm() - EOL
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2018-11-13
+ */
+ public function htmlTagEndFormEol(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - endForm() - EOL');
+ $tag = new Tag();
+
+ $expected = '' . PHP_EOL;
+ $actual = $tag->endForm();
+ $I->assertEquals($expected, $actual);
+ }
+}
diff --git a/tests/unit/Html/Tag/FormCest.php b/tests/unit/Html/Tag/FormCest.php
new file mode 100644
index 00000000000..a71ec116efd
--- /dev/null
+++ b/tests/unit/Html/Tag/FormCest.php
@@ -0,0 +1,37 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+namespace Phalcon\Test\Unit\Html\Tag;
+
+use UnitTester;
+
+/**
+ * Class FormCest
+ *
+ * @package Phalcon\Test\Unit\Html\Tag
+ */
+class FormCest
+{
+ /**
+ * Tests Phalcon\Html\Tag :: form()
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2018-11-13
+ */
+ public function htmlTagForm(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - form()');
+ $I->skipTest('Need implementation');
+ }
+}
diff --git a/tests/unit/Html/Tag/FriendlyTitleCest.php b/tests/unit/Html/Tag/FriendlyTitleCest.php
new file mode 100644
index 00000000000..7d67bcafa8e
--- /dev/null
+++ b/tests/unit/Html/Tag/FriendlyTitleCest.php
@@ -0,0 +1,225 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+namespace Phalcon\Test\Unit\Html\Tag;
+
+use Phalcon\Html\Exception;
+use Phalcon\Html\Tag;
+use Phalcon\Test\Fixtures\Traits\DiTrait;
+use Phalcon\Test\Fixtures\Traits\TagSetupTrait;
+use UnitTester;
+
+/**
+ * Class FriendlyTitleCest
+ *
+ * @package Phalcon\Test\Unit\Html\Tag
+ */
+class FriendlyTitleCest
+{
+ use DiTrait;
+ use TagSetupTrait;
+
+ /**
+ * Tests Phalcon\Html\Tag :: friendlyTitle()
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2014-09-11
+ */
+ public function htmlTagFriendlyTitle(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - friendlyTitle()');
+ $tag = new Tag();
+
+ $text = 'This is a Test';
+ $expected = 'this-is-a-test';
+ $actual = $tag->friendlyTitle($text);
+ $I->assertEquals($expected, $actual);
+ }
+
+ /**
+ * Tests Phalcon\Html\Tag :: friendlyTitle() - separator
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2014-09-11
+ */
+ public function htmlTagFriendlyTitleSeparator(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - friendlyTitle() - separator');
+ $tag = new Tag();
+
+ $text = 'This is a Test';
+ $options = [
+ 'separator' => '_',
+ ];
+ $expected = 'this_is_a_test';
+ $actual = $tag->friendlyTitle($text, $options);
+ $I->assertEquals($expected, $actual);
+ }
+
+ /**
+ * Tests Phalcon\Html\Tag :: friendlyTitle() - lowercase
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2014-09-11
+ */
+ public function htmlTagFriendlyTitleLowercase(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - friendlyTitle() - lowercase');
+ $tag = new Tag();
+
+ $text = 'This is a Test';
+ $options = [
+ 'lowercase' => false,
+ ];
+ $expected = 'This-is-a-Test';
+ $actual = $tag->friendlyTitle($text, $options);
+ $I->assertEquals($expected, $actual);
+ }
+
+ /**
+ * Tests Phalcon\Html\Tag :: friendlyTitle() - replace string
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2014-09-11
+ */
+ public function htmlTagFriendlyTitleReplaceString(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - friendlyTitle() - replace string');
+ $tag = new Tag();
+
+ $text = 'This is a Test';
+ $options = [
+ 'replace' => 'i',
+ ];
+ $expected = 'ths-s-a-test';
+ $actual = $tag->friendlyTitle($text, $options);
+ $I->assertEquals($expected, $actual);
+ }
+
+ /**
+ * Tests Phalcon\Html\Tag :: friendlyTitle() - replace array
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2014-09-11
+ */
+ public function htmlTagFriendlyTitleReplaceArray(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - friendlyTitle() - replace array');
+ $tag = new Tag();
+
+ $text = 'This is a Test';
+ $options = [
+ 'replace' => ['i', 'h'],
+ ];
+ $expected = 't-s-s-a-test';
+ $actual = $tag->friendlyTitle($text, $options);
+ $I->assertEquals($expected, $actual);
+ }
+
+ /**
+ * Tests Phalcon\Html\Tag :: friendlyTitle() - special characters and
+ * escaping
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2014-09-11
+ */
+ public function htmlTagFriendlyTitleSpecialCharacters(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - friendlyTitle() - special characters and escaping');
+ $tag = new Tag();
+
+ $text = "Mess'd up --text-- just (to) stress /test/ ?our! "
+ . "`little` \\clean\\ url fun.ction!?-->";
+ $expected = 'messd-up-text-just-to-stress-test-our-little-'
+ . 'clean-url-function';
+ $actual = $tag->friendlyTitle($text);
+ $I->assertEquals($expected, $actual);
+ }
+
+ /**
+ * Tests Phalcon\Html\Tag :: friendlyTitle() - accented characters replace
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2014-09-11
+ */
+ public function htmlTagFriendlyTitleAccentedCharactersReplace(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - friendlyTitle() - accented characters replace');
+ $tag = new Tag();
+
+ $text = "Perché l'erba è verde?";
+ $expected = 'perche-lerba-e-verde';
+ $options = [
+ 'replace' => "'",
+ ];
+ $actual = $tag->friendlyTitle($text, $options);
+ $I->assertEquals($expected, $actual);
+ }
+
+ /**
+ * Tests Phalcon\Html\Tag :: friendlyTitle() - accented characters replace
+ * array
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2014-09-11
+ */
+ public function htmlTagFriendlyTitleAccentedCharactersReplaceArray(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - friendlyTitle() - accented characters replace array');
+ $tag = new Tag();
+
+ $text = "Perché l'erba è verde?";
+ $expected = 'p-rch-l-rb-v-rd';
+ $options = [
+ 'replace' => ['e', 'a'],
+ ];
+ $actual = $tag->friendlyTitle($text, $options);
+ $I->assertEquals($expected, $actual);
+ }
+
+ /**
+ * Tests Phalcon\Html\Tag :: friendlyTitle() - replace exception
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2014-09-11
+ */
+ public function htmlTagFriendlyTitleReplaceException(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - friendlyTitle() - replace exception');
+ $I->expectThrowable(
+ new Exception('Parameter replace must be an array or a string'),
+ function () {
+ $tag = new Tag();
+ $options = ['replace' => true];
+ $tag->friendlyTitle('test', $options);
+ }
+ );
+ }
+}
diff --git a/tests/unit/Html/Tag/GetSetDICest.php b/tests/unit/Html/Tag/GetSetDICest.php
new file mode 100644
index 00000000000..d58e1c82f54
--- /dev/null
+++ b/tests/unit/Html/Tag/GetSetDICest.php
@@ -0,0 +1,48 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+namespace Phalcon\Test\Unit\Html\Tag;
+
+use Phalcon\Di;
+use Phalcon\Html\Tag;
+use Phalcon\Test\Fixtures\Traits\DiTrait;
+use UnitTester;
+
+/**
+ * Class GetSetDICest
+ *
+ * @package Phalcon\Test\Unit\Html\Tag
+ */
+class GetSetDICest
+{
+ use DiTrait;
+
+ /**
+ * Tests Phalcon\Html\Tag :: getDI()/setDI()
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2018-11-13
+ */
+ public function htmlTagGetSetDI(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - getDI()/setDI()');
+ $tag = new Tag();
+ $this->newDi();
+ $tag->setDI($this->container);
+
+ $class = Di::class;
+ $actual = $tag->getDI();
+ $I->assertInstanceOf($class, $actual);
+ }
+}
diff --git a/tests/unit/Html/Tag/GetSetDocTypeCest.php b/tests/unit/Html/Tag/GetSetDocTypeCest.php
new file mode 100644
index 00000000000..5d289fee410
--- /dev/null
+++ b/tests/unit/Html/Tag/GetSetDocTypeCest.php
@@ -0,0 +1,119 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+namespace Phalcon\Test\Unit\Html\Tag;
+
+use Codeception\Example;
+use Phalcon\Html\Tag;
+use UnitTester;
+
+/**
+ * Class GetSetDocTypeCest
+ *
+ * @package Phalcon\Test\Unit\Html\Tag
+ */
+class GetSetDocTypeCest
+{
+ /**
+ * Tests Phalcon\Html\Tag :: getDocType()/setDocType()
+ *
+ * @param UnitTester $I
+ * @param Example $example
+ *
+ * @dataProvider getDocTypes
+ *
+ * @author Phalcon Team
+ * @since 2018-11-13
+ */
+ public function htmlTagGetSetDocType(UnitTester $I, Example $example)
+ {
+ $I->wantToTest(sprintf('Html\Tag - getDocType()/setDocType() - %s', $example['name']));
+
+ $tag = new Tag();
+ $tag->setDocType($example['value']);
+ $expected = $example['string'];
+ $actual = $tag->getDocType();
+ $I->assertEquals($expected, $actual);
+ }
+
+ /**
+ * @return array
+ */
+ private function getDocTypes(): array
+ {
+ return [
+ [
+ 'name' => 'HTML_32',
+ 'value' => 1,
+ 'string' => "" . PHP_EOL,
+ ],
+ [
+ 'name' => 'HTML401_STRICT',
+ 'value' => 2,
+ 'string' => "" . PHP_EOL,
+ ],
+ [
+ 'name' => 'HTML401_TRANSITIONAL',
+ 'value' => 3,
+ 'string' => "" . PHP_EOL,
+ ],
+ [
+ 'name' => 'HTML401_FRAMESET',
+ 'value' => 4,
+ 'string' => "" . PHP_EOL,
+ ],
+ [
+ 'name' => 'HTML5',
+ 'value' => 5,
+ 'string' => "" . PHP_EOL,
+ ],
+ [
+ 'name' => 'XHTML10_STRICT',
+ 'value' => 6,
+ 'string' => "" . PHP_EOL,
+ ],
+ [
+ 'name' => 'XHTML10_TRANSITIONAL',
+ 'value' => 7,
+ 'string' => "" . PHP_EOL,
+ ],
+ [
+ 'name' => 'XHTML10_FRAMESET',
+ 'value' => 8,
+ 'string' => "" . PHP_EOL,
+ ],
+ [
+ 'name' => 'XHTML11',
+ 'value' => 9,
+ 'string' => "" . PHP_EOL,
+ ],
+ [
+ 'name' => 'XHTML20',
+ 'value' => 10,
+ 'string' => "" . PHP_EOL,
+ ],
+ [
+ 'name' => 'XHTML5',
+ 'value' => 11,
+ 'string' => "" . PHP_EOL,
+ ],
+ ];
+ }
+}
diff --git a/tests/unit/Html/Tag/GetTitleCest.php b/tests/unit/Html/Tag/GetTitleCest.php
new file mode 100644
index 00000000000..3da60a97a57
--- /dev/null
+++ b/tests/unit/Html/Tag/GetTitleCest.php
@@ -0,0 +1,72 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+namespace Phalcon\Test\Unit\Html\Tag;
+
+use Phalcon\Html\Tag;
+use Phalcon\Test\Fixtures\Traits\DiTrait;
+use Phalcon\Test\Fixtures\Traits\TagSetupTrait;
+use UnitTester;
+
+/**
+ * Class GetTitleCest
+ *
+ * @package Phalcon\Test\Unit\Html\Tag
+ */
+class GetTitleCest
+{
+ use DiTrait;
+ use TagSetupTrait;
+
+ /**
+ * Tests Phalcon\Html\Tag :: getTitle()
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2018-11-13
+ */
+ public function htmlTagGetTitle(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - getTitle()');
+ $tag = new Tag();
+ $tag->setDI($this->container);
+ $value = "Hello Title";
+
+ $tag->setTitle($value);
+ $expected = 'Hello Title';
+ $actual = $tag->getTitle();
+ $I->assertEquals($expected, $actual);
+ }
+
+ /**
+ * Tests Phalcon\Html\Tag :: getTitle() - escape
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2018-11-13
+ */
+ public function htmlTagGetTitleEscape(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - getTitle() - escape');
+ $tag = new Tag();
+ $tag->setDI($this->container);
+ $value = "Hello ";
+
+ $tag->setTitle($value);
+ $expected = 'Hello </title><script>alert(''
+ . 'Got your nose!');</script><title>';
+ $actual = $tag->getTitle();
+ $I->assertEquals($expected, $actual);
+ }
+}
diff --git a/tests/unit/Html/Tag/GetTitleSeparatorCest.php b/tests/unit/Html/Tag/GetTitleSeparatorCest.php
new file mode 100644
index 00000000000..a888f1a1c82
--- /dev/null
+++ b/tests/unit/Html/Tag/GetTitleSeparatorCest.php
@@ -0,0 +1,46 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+namespace Phalcon\Test\Unit\Html\Tag;
+
+use Phalcon\Html\Tag;
+use UnitTester;
+
+/**
+ * Class GetTitleSeparatorCest
+ *
+ * @package Phalcon\Test\Unit\Html\Tag
+ */
+class GetTitleSeparatorCest
+{
+ /**
+ * Tests Phalcon\Html\Tag :: getTitleSeparator()
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2018-11-13
+ */
+ public function htmlTagGetTitleSeparator(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - getTitleSeparator()');
+ $tag = new Tag();
+
+ $actual = $tag->getTitleSeparator();
+ $I->assertEmpty($actual);
+
+ $separator = '--::--';
+ $tag->setTitleSeparator($separator);
+ $actual = $tag->getTitleSeparator();
+ $I->assertEquals($separator, $actual);
+ }
+}
diff --git a/tests/unit/Html/Tag/GetValueCest.php b/tests/unit/Html/Tag/GetValueCest.php
new file mode 100644
index 00000000000..cfaccc39af0
--- /dev/null
+++ b/tests/unit/Html/Tag/GetValueCest.php
@@ -0,0 +1,86 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+namespace Phalcon\Test\Unit\Html\Tag;
+
+use Phalcon\Html\Tag;
+use UnitTester;
+
+/**
+ * Class GetValueCest
+ *
+ * @package Phalcon\Test\Unit\Html\Tag
+ */
+class GetValueCest
+{
+ /**
+ * Tests Phalcon\Html\Tag :: getValue()
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2018-11-13
+ */
+ public function htmlTagGetValue(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - getValue()');
+ $tag = new Tag();
+
+ $attributes = ['value' => 'Phalcon'];
+ $expected = 'Phalcon';
+ $actual = $tag->getValue('name', $attributes);
+ $I->assertEquals($expected, $actual);
+ }
+
+ /**
+ * Tests Phalcon\Html\Tag :: getValue() - internal array
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2018-11-13
+ */
+ public function htmlTagGetValueInternal(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - getValue() - internal array');
+ $tag = new Tag();
+
+ $tag->setAttribute('name', 'Phalcon');
+ $expected = 'Phalcon';
+ $actual = $tag->getValue('name');
+ $I->assertEquals($expected, $actual);
+ }
+
+ /**
+ * Tests Phalcon\Html\Tag :: getValue() - POST
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2018-11-13
+ */
+ public function htmlTagGetValuePost(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - getValue() - POST');
+ $tag = new Tag();
+
+ $oldPost = $_POST;
+ $_POST = [];
+ $_POST['name'] = 'Phalcon';
+
+ $expected = 'Phalcon';
+ $actual = $tag->getValue('name');
+ $I->assertEquals($expected, $actual);
+
+ $_POST = $oldPost;
+ }
+}
diff --git a/tests/unit/Html/Tag/HasValueCest.php b/tests/unit/Html/Tag/HasValueCest.php
new file mode 100644
index 00000000000..68b17c18d71
--- /dev/null
+++ b/tests/unit/Html/Tag/HasValueCest.php
@@ -0,0 +1,66 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+namespace Phalcon\Test\Unit\Html\Tag;
+
+use Phalcon\Html\Tag;
+use UnitTester;
+
+/**
+ * Class HasValueCest
+ *
+ * @package Phalcon\Test\Unit\Html\Tag
+ */
+class HasValueCest
+{
+ /**
+ * Tests Phalcon\Html\Tag :: hasValue()
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2018-11-13
+ */
+ public function htmlTagHasValue(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - hasValue()');
+ $tag = new Tag();
+
+ $tag->setAttribute('name', 'Phalcon');
+
+ $actual = $tag->hasValue('name');
+ $I->assertTrue($actual);
+ }
+
+ /**
+ * Tests Phalcon\Html\Tag :: hasValue() - POST
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2018-11-13
+ */
+ public function htmlTagHasValuePost(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - hasValue() - POST');
+ $tag = new Tag();
+
+ $oldPost = $_POST;
+ $_POST = [];
+ $_POST['name'] = 'Phalcon';
+
+ $actual = $tag->hasValue('name');
+ $I->assertTrue($actual);
+
+ $_POST = $oldPost;
+ }
+}
diff --git a/tests/unit/Html/Tag/ImageCest.php b/tests/unit/Html/Tag/ImageCest.php
new file mode 100644
index 00000000000..ce77200df58
--- /dev/null
+++ b/tests/unit/Html/Tag/ImageCest.php
@@ -0,0 +1,173 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+namespace Phalcon\Test\Unit\Html\Tag;
+
+use Phalcon\Html\Tag;
+use Phalcon\Test\Fixtures\Traits\DiTrait;
+use Phalcon\Test\Fixtures\Traits\TagSetupTrait;
+use UnitTester;
+
+/**
+ * Class ImageCest
+ *
+ * @package Phalcon\Test\Unit\Html\Tag
+ */
+class ImageCest
+{
+ use DiTrait;
+ use TagSetupTrait;
+
+ /**
+ * Tests Phalcon\Html\Tag :: image()
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2014-09-05
+ */
+ public function htmlTagImage(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - image()');
+ $tag = new Tag();
+ $tag->setDI($this->container);
+
+ $name = 'img/hello.gif';
+ $options = [];
+ $expected = 'testFieldParameter($I, $tag, $name, 'image', $options, $expected);
+ $this->testFieldParameter($I, $tag, $name, 'image', $options, $expected, true);
+ }
+
+ /**
+ * Tests Phalcon\Html\Tag :: image() - remote
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2014-09-05
+ */
+ public function htmlTagImageRemote(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - image() - remote');
+ $tag = new Tag();
+ $tag->setDI($this->container);
+
+ $name = 'http://phalconphp.com/img/hello.gif';
+ $options = [
+ 'local' => false,
+ 'alt' => 'picture',
+ ];
+ $expected = 'testFieldParameter($I, $tag, $name, 'image', $options, $expected);
+ $this->testFieldParameter($I, $tag, $name, 'image', $options, $expected, true);
+ }
+
+ /**
+ * Tests Phalcon\Html\Tag :: image() - params
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2014-09-05
+ */
+ public function htmlTagImageParameters(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - image() - params');
+ $tag = new Tag();
+ $tag->setDI($this->container);
+
+ $name = 'img/hello.gif';
+ $options = [
+ 'class' => 'x_class',
+ ];
+ $expected = 'testFieldParameter($I, $tag, $name, 'image', $options, $expected);
+ $this->testFieldParameter($I, $tag, $name, 'image', $options, $expected, true);
+ }
+
+ /**
+ * Tests Phalcon\Html\Tag :: image() - params src
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2014-09-05
+ */
+ public function htmlTagImageParametersSrc(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - image() - params src');
+ $tag = new Tag();
+ $tag->setDI($this->container);
+
+ $name = 'img/hello.gif';
+ $options = [
+ 'class' => 'x_class',
+ 'src' => 'img/goodbye.gif',
+ ];
+ $expected = 'testFieldParameter($I, $tag, $name, 'image', $options, $expected);
+ $this->testFieldParameter($I, $tag, $name, 'image', $options, $expected, true);
+ }
+
+ /**
+ * Tests Phalcon\Html\Tag :: image() - setAttribute()
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2014-09-05
+ */
+ public function htmlTagImageSetAttribute(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - image() - setAttribute()');
+ $tag = new Tag();
+ $tag->setDI($this->container);
+
+ $name = 'img/hello.gif';
+ $options = [
+ 'class' => 'x_class',
+ ];
+ $expected = 'testFieldParameter($I, $tag, $name, 'image', $options, $expected, false, 'setAttribute');
+ $this->testFieldParameter($I, $tag, $name, 'image', $options, $expected, true, 'setAttribute');
+ }
+
+ /**
+ * Tests Phalcon\Html\Tag :: image() - setAttribute() element not present
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2014-09-05
+ */
+ public function htmlTagImageSetAttributeElementNotPresent(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - image() - setAttribute() element not present');
+ $tag = new Tag();
+ $tag->setDI($this->container);
+
+ $name = 'img/hello.gif';
+ $options = [
+ 'class' => 'x_class',
+ ];
+ $expected = 'testFieldParameter($I, $tag, $name, 'image', $options, $expected, false, 'setAttribute');
+ $this->testFieldParameter($I, $tag, $name, 'image', $options, $expected, true, 'setAttribute');
+ }
+}
diff --git a/tests/unit/Html/Tag/InputCheckboxCest.php b/tests/unit/Html/Tag/InputCheckboxCest.php
new file mode 100644
index 00000000000..70f815ca747
--- /dev/null
+++ b/tests/unit/Html/Tag/InputCheckboxCest.php
@@ -0,0 +1,32 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+namespace Phalcon\Test\Unit\Html\Tag;
+
+use Phalcon\Test\Fixtures\Traits\DiTrait;
+use Phalcon\Test\Fixtures\Traits\TagHelperTrait;
+use Phalcon\Test\Fixtures\Traits\TagSetupTrait;
+
+/**
+ * Class InputCheckboxCest
+ *
+ * @package Phalcon\Test\Unit\Html\Tag
+ */
+class InputCheckboxCest
+{
+ use DiTrait;
+ use TagSetupTrait;
+ use TagHelperTrait;
+
+ protected $function = 'inputCheckbox';
+ protected $inputType = 'checkbox';
+}
diff --git a/tests/unit/Html/Tag/InputColorCest.php b/tests/unit/Html/Tag/InputColorCest.php
new file mode 100644
index 00000000000..4f2ab137566
--- /dev/null
+++ b/tests/unit/Html/Tag/InputColorCest.php
@@ -0,0 +1,32 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+namespace Phalcon\Test\Unit\Html\Tag;
+
+use Phalcon\Test\Fixtures\Traits\DiTrait;
+use Phalcon\Test\Fixtures\Traits\TagHelperTrait;
+use Phalcon\Test\Fixtures\Traits\TagSetupTrait;
+
+/**
+ * Class InputColorCest
+ *
+ * @package Phalcon\Test\Unit\Html\Tag
+ */
+class InputColorCest
+{
+ use DiTrait;
+ use TagSetupTrait;
+ use TagHelperTrait;
+
+ protected $function = 'inputColor';
+ protected $inputType = 'color';
+}
diff --git a/tests/unit/Html/Tag/InputDateCest.php b/tests/unit/Html/Tag/InputDateCest.php
new file mode 100644
index 00000000000..45b317c1f7e
--- /dev/null
+++ b/tests/unit/Html/Tag/InputDateCest.php
@@ -0,0 +1,32 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+namespace Phalcon\Test\Unit\Html\Tag;
+
+use Phalcon\Test\Fixtures\Traits\DiTrait;
+use Phalcon\Test\Fixtures\Traits\TagHelperTrait;
+use Phalcon\Test\Fixtures\Traits\TagSetupTrait;
+
+/**
+ * Class InputDateCest
+ *
+ * @package Phalcon\Test\Unit\Html\Tag
+ */
+class InputDateCest
+{
+ use DiTrait;
+ use TagSetupTrait;
+ use TagHelperTrait;
+
+ protected $function = 'inputDate';
+ protected $inputType = 'date';
+}
diff --git a/tests/unit/Html/Tag/InputDateTimeCest.php b/tests/unit/Html/Tag/InputDateTimeCest.php
new file mode 100644
index 00000000000..e5c59495b6b
--- /dev/null
+++ b/tests/unit/Html/Tag/InputDateTimeCest.php
@@ -0,0 +1,32 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+namespace Phalcon\Test\Unit\Html\Tag;
+
+use Phalcon\Test\Fixtures\Traits\DiTrait;
+use Phalcon\Test\Fixtures\Traits\TagHelperTrait;
+use Phalcon\Test\Fixtures\Traits\TagSetupTrait;
+
+/**
+ * Class InputDateTimeCest
+ *
+ * @package Phalcon\Test\Unit\Html\Tag
+ */
+class InputDateTimeCest
+{
+ use DiTrait;
+ use TagSetupTrait;
+ use TagHelperTrait;
+
+ protected $function = 'inputDateTime';
+ protected $inputType = 'datetime';
+}
diff --git a/tests/unit/Html/Tag/InputDateTimeLocalCest.php b/tests/unit/Html/Tag/InputDateTimeLocalCest.php
new file mode 100644
index 00000000000..6985115fec1
--- /dev/null
+++ b/tests/unit/Html/Tag/InputDateTimeLocalCest.php
@@ -0,0 +1,32 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+namespace Phalcon\Test\Unit\Html\Tag;
+
+use Phalcon\Test\Fixtures\Traits\DiTrait;
+use Phalcon\Test\Fixtures\Traits\TagHelperTrait;
+use Phalcon\Test\Fixtures\Traits\TagSetupTrait;
+
+/**
+ * Class InputDateTimeLocalCest
+ *
+ * @package Phalcon\Test\Unit\Html\Tag
+ */
+class InputDateTimeLocalCest
+{
+ use DiTrait;
+ use TagSetupTrait;
+ use TagHelperTrait;
+
+ protected $function = 'inputDateTimeLocal';
+ protected $inputType = 'datetime-local';
+}
diff --git a/tests/unit/Html/Tag/InputEmailCest.php b/tests/unit/Html/Tag/InputEmailCest.php
new file mode 100644
index 00000000000..77e55a513d6
--- /dev/null
+++ b/tests/unit/Html/Tag/InputEmailCest.php
@@ -0,0 +1,32 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+namespace Phalcon\Test\Unit\Html\Tag;
+
+use Phalcon\Test\Fixtures\Traits\DiTrait;
+use Phalcon\Test\Fixtures\Traits\TagHelperTrait;
+use Phalcon\Test\Fixtures\Traits\TagSetupTrait;
+
+/**
+ * Class InputEmailCest
+ *
+ * @package Phalcon\Test\Unit\Html\Tag
+ */
+class InputEmailCest
+{
+ use DiTrait;
+ use TagSetupTrait;
+ use TagHelperTrait;
+
+ protected $function = 'inputEmail';
+ protected $inputType = 'email';
+}
diff --git a/tests/unit/Html/Tag/InputFileCest.php b/tests/unit/Html/Tag/InputFileCest.php
new file mode 100644
index 00000000000..312ee45ef04
--- /dev/null
+++ b/tests/unit/Html/Tag/InputFileCest.php
@@ -0,0 +1,32 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+namespace Phalcon\Test\Unit\Html\Tag;
+
+use Phalcon\Test\Fixtures\Traits\DiTrait;
+use Phalcon\Test\Fixtures\Traits\TagHelperTrait;
+use Phalcon\Test\Fixtures\Traits\TagSetupTrait;
+
+/**
+ * Class InputFileCest
+ *
+ * @package Phalcon\Test\Unit\Html\Tag
+ */
+class InputFileCest
+{
+ use DiTrait;
+ use TagSetupTrait;
+ use TagHelperTrait;
+
+ protected $function = 'inputFile';
+ protected $inputType = 'file';
+}
diff --git a/tests/unit/Html/Tag/InputHiddenCest.php b/tests/unit/Html/Tag/InputHiddenCest.php
new file mode 100644
index 00000000000..2fc21f873c3
--- /dev/null
+++ b/tests/unit/Html/Tag/InputHiddenCest.php
@@ -0,0 +1,32 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+namespace Phalcon\Test\Unit\Html\Tag;
+
+use Phalcon\Test\Fixtures\Traits\DiTrait;
+use Phalcon\Test\Fixtures\Traits\TagHelperTrait;
+use Phalcon\Test\Fixtures\Traits\TagSetupTrait;
+
+/**
+ * Class InputHiddenCest
+ *
+ * @package Phalcon\Test\Unit\Html\Tag
+ */
+class InputHiddenCest
+{
+ use DiTrait;
+ use TagSetupTrait;
+ use TagHelperTrait;
+
+ protected $function = 'inputHidden';
+ protected $inputType = 'hidden';
+}
diff --git a/tests/unit/Html/Tag/InputImageCest.php b/tests/unit/Html/Tag/InputImageCest.php
new file mode 100644
index 00000000000..ee5c43eeab7
--- /dev/null
+++ b/tests/unit/Html/Tag/InputImageCest.php
@@ -0,0 +1,32 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+namespace Phalcon\Test\Unit\Html\Tag;
+
+use Phalcon\Test\Fixtures\Traits\DiTrait;
+use Phalcon\Test\Fixtures\Traits\TagHelperTrait;
+use Phalcon\Test\Fixtures\Traits\TagSetupTrait;
+
+/**
+ * Class InputImageCest
+ *
+ * @package Phalcon\Test\Unit\Html\Tag
+ */
+class InputImageCest
+{
+ use DiTrait;
+ use TagSetupTrait;
+ use TagHelperTrait;
+
+ protected $function = 'inputImage';
+ protected $inputType = 'image';
+}
diff --git a/tests/unit/Html/Tag/InputMonthCest.php b/tests/unit/Html/Tag/InputMonthCest.php
new file mode 100644
index 00000000000..6ee31c3067c
--- /dev/null
+++ b/tests/unit/Html/Tag/InputMonthCest.php
@@ -0,0 +1,32 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+namespace Phalcon\Test\Unit\Html\Tag;
+
+use Phalcon\Test\Fixtures\Traits\DiTrait;
+use Phalcon\Test\Fixtures\Traits\TagHelperTrait;
+use Phalcon\Test\Fixtures\Traits\TagSetupTrait;
+
+/**
+ * Class InputMonthCest
+ *
+ * @package Phalcon\Test\Unit\Html\Tag
+ */
+class InputMonthCest
+{
+ use DiTrait;
+ use TagSetupTrait;
+ use TagHelperTrait;
+
+ protected $function = 'inputMonth';
+ protected $inputType = 'month';
+}
diff --git a/tests/unit/Html/Tag/InputNumericCest.php b/tests/unit/Html/Tag/InputNumericCest.php
new file mode 100644
index 00000000000..5ce5689627e
--- /dev/null
+++ b/tests/unit/Html/Tag/InputNumericCest.php
@@ -0,0 +1,32 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+namespace Phalcon\Test\Unit\Html\Tag;
+
+use Phalcon\Test\Fixtures\Traits\DiTrait;
+use Phalcon\Test\Fixtures\Traits\TagHelperTrait;
+use Phalcon\Test\Fixtures\Traits\TagSetupTrait;
+
+/**
+ * Class InputNumericCest
+ *
+ * @package Phalcon\Test\Unit\Html\Tag
+ */
+class InputNumericCest
+{
+ use DiTrait;
+ use TagSetupTrait;
+ use TagHelperTrait;
+
+ protected $function = 'inputNumeric';
+ protected $inputType = 'numeric';
+}
diff --git a/tests/unit/Html/Tag/InputPasswordCest.php b/tests/unit/Html/Tag/InputPasswordCest.php
new file mode 100644
index 00000000000..10104d2e2ad
--- /dev/null
+++ b/tests/unit/Html/Tag/InputPasswordCest.php
@@ -0,0 +1,32 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+namespace Phalcon\Test\Unit\Html\Tag;
+
+use Phalcon\Test\Fixtures\Traits\DiTrait;
+use Phalcon\Test\Fixtures\Traits\TagHelperTrait;
+use Phalcon\Test\Fixtures\Traits\TagSetupTrait;
+
+/**
+ * Class InputPasswordCest
+ *
+ * @package Phalcon\Test\Unit\Html\Tag
+ */
+class InputPasswordCest
+{
+ use DiTrait;
+ use TagSetupTrait;
+ use TagHelperTrait;
+
+ protected $function = 'inputPassword';
+ protected $inputType = 'password';
+}
diff --git a/tests/unit/Html/Tag/InputRadioCest.php b/tests/unit/Html/Tag/InputRadioCest.php
new file mode 100644
index 00000000000..824af0cb6d0
--- /dev/null
+++ b/tests/unit/Html/Tag/InputRadioCest.php
@@ -0,0 +1,32 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+namespace Phalcon\Test\Unit\Html\Tag;
+
+use Phalcon\Test\Fixtures\Traits\DiTrait;
+use Phalcon\Test\Fixtures\Traits\TagHelperTrait;
+use Phalcon\Test\Fixtures\Traits\TagSetupTrait;
+
+/**
+ * Class InputRadioCest
+ *
+ * @package Phalcon\Test\Unit\Html\Tag
+ */
+class InputRadioCest
+{
+ use DiTrait;
+ use TagSetupTrait;
+ use TagHelperTrait;
+
+ protected $function = 'inputRadio';
+ protected $inputType = 'radio';
+}
diff --git a/tests/unit/Html/Tag/InputRangeCest.php b/tests/unit/Html/Tag/InputRangeCest.php
new file mode 100644
index 00000000000..250f2fabbb4
--- /dev/null
+++ b/tests/unit/Html/Tag/InputRangeCest.php
@@ -0,0 +1,32 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+namespace Phalcon\Test\Unit\Html\Tag;
+
+use Phalcon\Test\Fixtures\Traits\DiTrait;
+use Phalcon\Test\Fixtures\Traits\TagHelperTrait;
+use Phalcon\Test\Fixtures\Traits\TagSetupTrait;
+
+/**
+ * Class InputRangeCest
+ *
+ * @package Phalcon\Test\Unit\Html\Tag
+ */
+class InputRangeCest
+{
+ use DiTrait;
+ use TagSetupTrait;
+ use TagHelperTrait;
+
+ protected $function = 'inputRange';
+ protected $inputType = 'range';
+}
diff --git a/tests/unit/Html/Tag/InputSearchCest.php b/tests/unit/Html/Tag/InputSearchCest.php
new file mode 100644
index 00000000000..207e8f77be4
--- /dev/null
+++ b/tests/unit/Html/Tag/InputSearchCest.php
@@ -0,0 +1,32 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+namespace Phalcon\Test\Unit\Html\Tag;
+
+use Phalcon\Test\Fixtures\Traits\DiTrait;
+use Phalcon\Test\Fixtures\Traits\TagHelperTrait;
+use Phalcon\Test\Fixtures\Traits\TagSetupTrait;
+
+/**
+ * Class InputSearchCest
+ *
+ * @package Phalcon\Test\Unit\Html\Tag
+ */
+class InputSearchCest
+{
+ use DiTrait;
+ use TagSetupTrait;
+ use TagHelperTrait;
+
+ protected $function = 'inputSearch';
+ protected $inputType = 'search';
+}
diff --git a/tests/unit/Html/Tag/InputTelCest.php b/tests/unit/Html/Tag/InputTelCest.php
new file mode 100644
index 00000000000..00870b42acc
--- /dev/null
+++ b/tests/unit/Html/Tag/InputTelCest.php
@@ -0,0 +1,32 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+namespace Phalcon\Test\Unit\Html\Tag;
+
+use Phalcon\Test\Fixtures\Traits\DiTrait;
+use Phalcon\Test\Fixtures\Traits\TagHelperTrait;
+use Phalcon\Test\Fixtures\Traits\TagSetupTrait;
+
+/**
+ * Class InputTelCest
+ *
+ * @package Phalcon\Test\Unit\Html\Tag
+ */
+class InputTelCest
+{
+ use DiTrait;
+ use TagSetupTrait;
+ use TagHelperTrait;
+
+ protected $function = 'inputTel';
+ protected $inputType = 'tel';
+}
diff --git a/tests/unit/Html/Tag/InputTextCest.php b/tests/unit/Html/Tag/InputTextCest.php
new file mode 100644
index 00000000000..32422f2a622
--- /dev/null
+++ b/tests/unit/Html/Tag/InputTextCest.php
@@ -0,0 +1,32 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+namespace Phalcon\Test\Unit\Html\Tag;
+
+use Phalcon\Test\Fixtures\Traits\DiTrait;
+use Phalcon\Test\Fixtures\Traits\TagHelperTrait;
+use Phalcon\Test\Fixtures\Traits\TagSetupTrait;
+
+/**
+ * Class InputTextCest
+ *
+ * @package Phalcon\Test\Unit\Html\Tag
+ */
+class InputTextCest
+{
+ use DiTrait;
+ use TagSetupTrait;
+ use TagHelperTrait;
+
+ protected $function = 'inputText';
+ protected $inputType = 'text';
+}
diff --git a/tests/unit/Html/Tag/InputTimeCest.php b/tests/unit/Html/Tag/InputTimeCest.php
new file mode 100644
index 00000000000..6a6939d8613
--- /dev/null
+++ b/tests/unit/Html/Tag/InputTimeCest.php
@@ -0,0 +1,32 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+namespace Phalcon\Test\Unit\Html\Tag;
+
+use Phalcon\Test\Fixtures\Traits\DiTrait;
+use Phalcon\Test\Fixtures\Traits\TagHelperTrait;
+use Phalcon\Test\Fixtures\Traits\TagSetupTrait;
+
+/**
+ * Class InputTimeCest
+ *
+ * @package Phalcon\Test\Unit\Html\Tag
+ */
+class InputTimeCest
+{
+ use DiTrait;
+ use TagSetupTrait;
+ use TagHelperTrait;
+
+ protected $function = 'inputTime';
+ protected $inputType = 'time';
+}
diff --git a/tests/unit/Html/Tag/InputUrlCest.php b/tests/unit/Html/Tag/InputUrlCest.php
new file mode 100644
index 00000000000..6cb0eb612dc
--- /dev/null
+++ b/tests/unit/Html/Tag/InputUrlCest.php
@@ -0,0 +1,32 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+namespace Phalcon\Test\Unit\Html\Tag;
+
+use Phalcon\Test\Fixtures\Traits\DiTrait;
+use Phalcon\Test\Fixtures\Traits\TagHelperTrait;
+use Phalcon\Test\Fixtures\Traits\TagSetupTrait;
+
+/**
+ * Class InputUrlCest
+ *
+ * @package Phalcon\Test\Unit\Html\Tag
+ */
+class InputUrlCest
+{
+ use DiTrait;
+ use TagSetupTrait;
+ use TagHelperTrait;
+
+ protected $function = 'inputUrl';
+ protected $inputType = 'url';
+}
diff --git a/tests/unit/Html/Tag/InputWeekCest.php b/tests/unit/Html/Tag/InputWeekCest.php
new file mode 100644
index 00000000000..9b901ae2d1f
--- /dev/null
+++ b/tests/unit/Html/Tag/InputWeekCest.php
@@ -0,0 +1,32 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+namespace Phalcon\Test\Unit\Html\Tag;
+
+use Phalcon\Test\Fixtures\Traits\DiTrait;
+use Phalcon\Test\Fixtures\Traits\TagHelperTrait;
+use Phalcon\Test\Fixtures\Traits\TagSetupTrait;
+
+/**
+ * Class InputWeekCest
+ *
+ * @package Phalcon\Test\Unit\Html\Tag
+ */
+class InputWeekCest
+{
+ use DiTrait;
+ use TagSetupTrait;
+ use TagHelperTrait;
+
+ protected $function = 'inputWeek';
+ protected $inputType = 'week';
+}
diff --git a/tests/unit/Html/Tag/JavascriptCest.php b/tests/unit/Html/Tag/JavascriptCest.php
new file mode 100644
index 00000000000..a0d37cf6b81
--- /dev/null
+++ b/tests/unit/Html/Tag/JavascriptCest.php
@@ -0,0 +1,71 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+namespace Phalcon\Test\Unit\Html\Tag;
+
+use Phalcon\Html\Tag;
+use Phalcon\Test\Fixtures\Traits\DiTrait;
+use Phalcon\Test\Fixtures\Traits\TagSetupTrait;
+use UnitTester;
+
+/**
+ * Class JavascriptCest
+ *
+ * @package Phalcon\Test\Unit\Html\Tag
+ */
+class JavascriptCest
+{
+ use DiTrait;
+ use TagSetupTrait;
+
+ /**
+ * Tests Phalcon\Tag :: javascript() - local
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2014-09-29
+ */
+ public function htmlTagJavascriptLocal(UnitTester $I)
+ {
+ $I->wantToTest("Tag - javascript() - local");
+ $tag = new Tag();
+ $tag->setDI($this->container);
+
+ $url = 'js/phalcon.js';
+ $expected = '' . PHP_EOL;
+ $actual = $tag->javascript($url);
+ $I->assertEquals($expected, $actual);
+ }
+
+
+ /**
+ * Tests Phalcon\Tag :: javascript() - remote
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2014-09-29
+ */
+ public function htmlTagJavascriptRemote(UnitTester $I)
+ {
+ $I->wantToTest("Tag - javascript() - remote link");
+ $tag = new Tag();
+ $tag->setDI($this->container);
+
+ $url = 'http://my.local.com/js/phalcon.js';
+ $options = ['local' => false];
+ $expected = '' . PHP_EOL;
+ $actual = $tag->javascript($url, $options);
+ $I->assertEquals($expected, $actual);
+ }
+}
diff --git a/tests/unit/Html/Tag/LinkCest.php b/tests/unit/Html/Tag/LinkCest.php
new file mode 100644
index 00000000000..b2ce7dcf7d0
--- /dev/null
+++ b/tests/unit/Html/Tag/LinkCest.php
@@ -0,0 +1,208 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+namespace Phalcon\Test\Unit\Html\Tag;
+
+use Phalcon\Html\Tag;
+use Phalcon\Test\Fixtures\Traits\DiTrait;
+use Phalcon\Test\Fixtures\Traits\TagSetupTrait;
+use UnitTester;
+
+/**
+ * Class LinkCest
+ *
+ * @package Phalcon\Test\Unit\Html\Tag
+ */
+class LinkCest
+{
+ use DiTrait;
+ use TagSetupTrait;
+
+ /**
+ * Tests Phalcon\Html\Tag :: link()
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2014-09-29
+ */
+ public function htmlTagLink(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - link()');
+ $tag = new Tag();
+ $tag->setDI($this->container);
+
+ $url = 'x_url';
+ $name = 'x_name';
+
+ $expected = 'x_name';
+ $actual = $tag->link($url, $name);
+ $I->assertEquals($expected, $actual);
+ }
+
+ /**
+ * Tests Phalcon\Html\Tag :: link() - params with query
+ *
+ * @param UnitTester $I
+ *
+ * @issue https://github.com/phalcon/cphalcon/issues/2002
+ *
+ * @author Phalcon Team
+ * @author Dreamszhu
+ * @since 2014-03-10
+ */
+ public function htmlTagLinkParamsWithQuery(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - link() - params with query');
+ $tag = new Tag();
+ $tag->setDI($this->container);
+
+ $url = 'signup/register';
+ $name = 'Register Here!';
+ $params = [
+ 'class' => 'btn-primary',
+ 'query' => [
+ 'from' => 'github',
+ 'token' => '123456',
+ ],
+ ];
+
+ $expected = 'Register Here!';
+ $actual = $tag->link($url, $name, $params);
+ $I->assertEquals($expected, $actual);
+ }
+
+ /**
+ * Tests Phalcon\Html\Tag :: link() - empty url
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2014-09-29
+ */
+ public function htmlTagLinkEmptyUrl(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - link() - empty url');
+ $tag = new Tag();
+ $tag->setDI($this->container);
+
+ $url = '';
+ $name = 'x_name';
+
+ $expected = 'x_name';
+ $actual = $tag->link($url, $name);
+ $I->assertEquals($expected, $actual);
+ }
+
+ /**
+ * Tests Phalcon\Html\Tag :: link() - named array as a parameter
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2014-09-29
+ */
+ public function htmlTagLinkNamedParameters(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - link() - named array as a parameter');
+ $tag = new Tag();
+ $tag->setDI($this->container);
+
+ $url = '';
+ $name = '';
+ $params = [
+ 'url' => 'x_url',
+ 'text' => 'x_name',
+ 'class' => 'x_class',
+ ];
+
+ $expected = 'x_name';
+ $actual = $tag->link($url, $name, $params);
+ $I->assertEquals($expected, $actual);
+ }
+
+ /**
+ * Tests Phalcon\Html\Tag :: link() - complex url local
+ *
+ * @param UnitTester $I
+ *
+ * @issue https://github.com/phalcon/cphalcon/issues/1679
+ *
+ * @author Phalcon Team
+ * @author Dreamszhu
+ * @since 2014-09-29
+ */
+ public function htmlTagLinkComplexUrlLocal(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - link() - complex url local');
+ $tag = new Tag();
+ $tag->setDI($this->container);
+
+ $url = "x_action/x_param";
+ $name = 'x_name';
+ $params = [
+ 'class' => 'x_class',
+ ];
+ $expected = 'x_name';
+ $actual = $tag->link($url, $name, $params);
+ $I->assertEquals($expected, $actual);
+ }
+
+ /**
+ * Tests Phalcon\Html\Tag :: link() - complex url remote
+ *
+ * @param UnitTester $I
+ *
+ * @issue https://github.com/phalcon/cphalcon/issues/1679
+ *
+ * @author Phalcon Team
+ * @author Dreamszhu
+ * @since 2014-09-29
+ */
+ public function htmlTagLinkComplexUrlRemote(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - link() - complex url remote');
+ $tag = new Tag();
+ $tag->setDI($this->container);
+
+ $url = "http://phalconphp.com/en/";
+ $name = 'x_name';
+ $params = [
+ 'local' => false,
+ 'class' => 'x_class',
+ ];
+ $expected = 'x_name';
+ $actual = $tag->link($url, $name, $params);
+ $I->assertEquals($expected, $actual);
+
+ $url = "http://phalconphp.com/en/";
+ $name = 'x_name';
+ $params = [
+ 'local' => false,
+ 'class' => 'x_class',
+ 'text' => 'Website'
+ ];
+ $expected = 'Website';
+ $actual = $tag->link($url, $name, $params);
+ $I->assertEquals($expected, $actual);
+
+ $url = "mailto:someone@phalconphp.com";
+ $name = 'someone@phalconphp.com';
+ $params = [
+ 'local' => false,
+ ];
+ $expected = 'someone@phalconphp.com';
+ $actual = $tag->link($url, $name, $params);
+ $I->assertEquals($expected, $actual);
+ }
+}
diff --git a/tests/unit/Html/Tag/PrependTitleCest.php b/tests/unit/Html/Tag/PrependTitleCest.php
new file mode 100644
index 00000000000..f2fd3e4b852
--- /dev/null
+++ b/tests/unit/Html/Tag/PrependTitleCest.php
@@ -0,0 +1,189 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+namespace Phalcon\Test\Unit\Html\Tag;
+
+use Phalcon\Html\Tag;
+use Phalcon\Test\Fixtures\Traits\DiTrait;
+use Phalcon\Test\Fixtures\Traits\TagSetupTrait;
+use UnitTester;
+
+/**
+ * Class PrependTitleCest
+ *
+ * @package Phalcon\Test\Unit\Html\Tag
+ */
+class PrependTitleCest
+{
+ use DiTrait;
+ use TagSetupTrait;
+
+ /**
+ * Tests Phalcon\Html\Tag :: prependTitle()
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2018-11-13
+ */
+ public function htmlTagPrependTitle(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - prependTitle()');
+ $tag = new Tag();
+ $tag->setDI($this->container);
+ $tag
+ ->setTitle('Title')
+ ->prependTitle(['Class'])
+ ;
+
+ $expected = "Title";
+ $actual = $tag->getTitle(false);
+ $I->assertEquals($expected, $actual);
+
+ $expected = "ClassTitle";
+ $actual = $tag->getTitle(true);
+ $I->assertEquals($expected, $actual);
+
+ $expected = "ClassTitle" . PHP_EOL;
+ $actual = $tag->renderTitle();
+ $I->assertEquals($expected, $actual);
+ }
+
+ /**
+ * Tests Phalcon\Html\Tag :: prependTitle() - separator
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2018-11-13
+ */
+ public function htmlTagPrependTitleSeparator(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - prependTitle() - separator');
+ $tag = new Tag();
+ $tag->setDI($this->container);
+ $tag
+ ->setTitle('Title')
+ ->setTitleSeparator('|')
+ ->prependTitle(['Class'])
+ ;
+
+ $expected = "Title";
+ $actual = $tag->getTitle(false);
+ $I->assertEquals($expected, $actual);
+
+ $expected = "Class|Title";
+ $actual = $tag->getTitle(true);
+ $I->assertEquals($expected, $actual);
+
+ $expected = "Class|Title" . PHP_EOL;
+ $actual = $tag->renderTitle();
+ $I->assertEquals($expected, $actual);
+ }
+
+ /**
+ * Tests Phalcon\Html\Tag :: prependTitle() - double call
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2018-11-13
+ */
+ public function htmlTagPrependTitleDoubleCall(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - prependTitle() - double call');
+ $tag = new Tag();
+ $tag->setDI($this->container);
+ $tag
+ ->setTitle('Main')
+ ->setTitleSeparator(' - ')
+ ->prependTitle(['Category'])
+ ->prependTitle(['Title'])
+ ;
+
+ $expected = "Main";
+ $actual = $tag->getTitle(false);
+ $I->assertEquals($expected, $actual);
+
+ $expected = "Title - Main";
+ $actual = $tag->getTitle(true);
+ $I->assertEquals($expected, $actual);
+
+ $expected = "Title - Main" . PHP_EOL;
+ $actual = $tag->renderTitle();
+ $I->assertEquals($expected, $actual);
+ }
+
+ /**
+ * Tests Phalcon\Html\Tag :: prependTitle() - many
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2018-11-13
+ */
+ public function htmlTagPrependTitleMany(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - prependTitle() - many');
+ $tag = new Tag();
+ $tag->setDI($this->container);
+ $tag
+ ->setTitle('Main')
+ ->setTitleSeparator(' - ')
+ ->prependTitle(['Category', 'Title'])
+ ;
+
+ $expected = "Main";
+ $actual = $tag->getTitle(false);
+ $I->assertEquals($expected, $actual);
+
+ $expected = "Title - Category - Main";
+ $actual = $tag->getTitle(true);
+ $I->assertEquals($expected, $actual);
+
+ $expected = "Title - Category - Main" . PHP_EOL;
+ $actual = $tag->renderTitle();
+ $I->assertEquals($expected, $actual);
+ }
+
+ /**
+ * Tests Phalcon\Html\Tag :: prependTitle() - empty array
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2018-11-13
+ */
+ public function htmlTagPrependTitleEmptyArray(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - prependTitle() - empty array');
+ $tag = new Tag();
+ $tag->setDI($this->container);
+ $tag
+ ->setTitle('Main')
+ ->setTitleSeparator(' - ')
+ ->prependTitle([])
+ ;
+
+ $expected = "Main";
+ $actual = $tag->getTitle(false);
+ $I->assertEquals($expected, $actual);
+
+ $expected = "Main";
+ $actual = $tag->getTitle(true);
+ $I->assertEquals($expected, $actual);
+
+ $expected = "Main" . PHP_EOL;
+ $actual = $tag->renderTitle();
+ $I->assertEquals($expected, $actual);
+ }
+}
diff --git a/tests/unit/Html/Tag/RenderTitleCest.php b/tests/unit/Html/Tag/RenderTitleCest.php
new file mode 100644
index 00000000000..c5b045498ee
--- /dev/null
+++ b/tests/unit/Html/Tag/RenderTitleCest.php
@@ -0,0 +1,51 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+namespace Phalcon\Test\Unit\Html\Tag;
+
+use Phalcon\Html\Tag;
+use Phalcon\Test\Fixtures\Traits\DiTrait;
+use Phalcon\Test\Fixtures\Traits\TagSetupTrait;
+use UnitTester;
+
+/**
+ * Class RenderTitleCest
+ *
+ * @package Phalcon\Test\Unit\Html\Tag
+ */
+class RenderTitleCest
+{
+ use DiTrait;
+ use TagSetupTrait;
+
+ /**
+ * Tests Phalcon\Html\Tag :: renderTitle()
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2018-11-13
+ */
+ public function htmlTagRenderTitle(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - renderTitle()');
+ $tag = new Tag();
+ $tag->setDI($this->container);
+ $value = "Hello ";
+
+ $tag->setTitle($value);
+ $expected = 'Hello </title><script>alert(''
+ . 'Got your nose!');</script><title>' . PHP_EOL;
+ $actual = $tag->renderTitle();
+ $I->assertEquals($expected, $actual);
+ }
+}
diff --git a/tests/unit/Html/Tag/ResetCest.php b/tests/unit/Html/Tag/ResetCest.php
new file mode 100644
index 00000000000..b816d9dfe52
--- /dev/null
+++ b/tests/unit/Html/Tag/ResetCest.php
@@ -0,0 +1,32 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+namespace Phalcon\Test\Unit\Html\Tag;
+
+use Phalcon\Test\Fixtures\Traits\DiTrait;
+use Phalcon\Test\Fixtures\Traits\TagHelperTrait;
+use Phalcon\Test\Fixtures\Traits\TagSetupTrait;
+
+/**
+ * Class ResetCest
+ *
+ * @package Phalcon\Test\Unit\Html\Tag
+ */
+class ResetCest
+{
+ use DiTrait;
+ use TagSetupTrait;
+ use TagHelperTrait;
+
+ protected $function = 'reset';
+ protected $inputType = 'reset';
+}
diff --git a/tests/unit/Html/Tag/SelectCest.php b/tests/unit/Html/Tag/SelectCest.php
new file mode 100644
index 00000000000..ee3343f6b95
--- /dev/null
+++ b/tests/unit/Html/Tag/SelectCest.php
@@ -0,0 +1,411 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+namespace Phalcon\Test\Unit\Html\Tag;
+
+use Phalcon\Html\Tag;
+use Phalcon\Test\Fixtures\Traits\DiTrait;
+use Phalcon\Test\Fixtures\Traits\TagSetupTrait;
+use UnitTester;
+
+/**
+ * Class SelectCest
+ *
+ * @package Phalcon\Test\Unit\Html\Tag
+ */
+class SelectCest
+{
+ use DiTrait;
+ use TagSetupTrait;
+
+ /**
+ * Tests Phalcon\Html\Tag :: select()
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2014-09-05
+ */
+ public function htmlTagSelect(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - select()');
+ $tag = new Tag();
+ $tag->setDI($this->container);
+ $name = 'x_name';
+ $data = [
+ 'A' => 'Active',
+ 'I' => 'Inactive',
+ ];
+ $expected = '';
+
+ $actual = $tag->select($name, [], $data);
+ $I->assertEquals($expected, $actual);
+ }
+
+ /**
+ * Tests Phalcon\Html\Tag :: select() - id
+ *
+ * @param UnitTester $I
+ *
+ * @issue https://github.com/phalcon/cphalcon/issues/54
+ *
+ * @author Phalcon Team
+ * @since 2014-09-05
+ */
+ public function htmlTagSelectWithId(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - select() - id');
+ $tag = new Tag();
+ $tag->setDI($this->container);
+ $name = 'x_name';
+ $params = [
+ 'id' => 'x_id',
+ 'class' => 'x_class',
+ ];
+ $data = [
+ 'A' => 'Active',
+ 'I' => 'Inactive',
+ ];
+ $expected = '';
+
+ $actual = $tag->select($name, $params, $data);
+ $I->assertEquals($expected, $actual);
+ }
+
+ /**
+ * Tests Phalcon\Html\Tag :: select() - name
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2014-09-05
+ */
+ public function htmlTagSelectWithName(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - select() - name');
+ $tag = new Tag();
+ $tag->setDI($this->container);
+ $name = 'x_name';
+ $params = [
+ 'name' => 'x_other',
+ 'class' => 'x_class',
+ ];
+ $data = [
+ 'A' => 'Active',
+ 'I' => 'Inactive',
+ ];
+ $expected = '';
+
+ $actual = $tag->select($name, $params, $data);
+ $I->assertEquals($expected, $actual);
+ }
+
+ /**
+ * Tests Phalcon\Html\Tag :: select() - value
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2014-09-05
+ */
+ public function htmlTagSelectWithValue(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - select() - value');
+ $tag = new Tag();
+ $tag->setDI($this->container);
+ $name = 'x_name';
+ $params = [
+ 'value' => 'I',
+ 'class' => 'x_class',
+ ];
+ $data = [
+ 'A' => 'Active',
+ 'I' => 'Inactive',
+ ];
+ $expected = '';
+
+ $actual = $tag->select($name, $params, $data);
+ $I->assertEquals($expected, $actual);
+ }
+
+ /**
+ * Tests Phalcon\Html\Tag :: select() - setAttribute()
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2014-09-05
+ */
+ public function htmlTagSelectSetAttribute(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - select() - setAttribute()');
+ $tag = new Tag();
+ $tag->setDI($this->container);
+ $name = 'x_name';
+ $params = [
+ 'class' => 'x_class',
+ 'size' => '10',
+ ];
+ $data = [
+ 'A' => 'Active',
+ 'I' => 'Inactive',
+ ];
+ $expected = '';
+
+ $actual = $tag
+ ->setAttribute('x_name', 'I')
+ ->select($name, $params, $data);
+ $I->assertEquals($expected, $actual);
+ }
+
+ /**
+ * Tests Phalcon\Html\Tag :: select() - setAttribute() element not present
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2014-09-05
+ */
+ public function htmlTagSelectSetAttributeElementNotPresent(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - select() - setAttribute() element not present');
+ $tag = new Tag();
+ $tag->setDI($this->container);
+ $name = 'x_name';
+ $params = [
+ 'name' => 'x_other',
+ 'class' => 'x_class',
+ 'size' => '10',
+ ];
+ $data = [
+ 'A' => 'Active',
+ 'I' => 'Inactive',
+ ];
+ $expected = '';
+
+ $actual = $tag
+ ->setAttribute('x_name', 'Z')
+ ->select($name, $params, $data);
+ $I->assertEquals($expected, $actual);
+ }
+
+ /**
+ * Tests Phalcon\Html\Tag :: select() - optgroup array with id
+ *
+ * @param UnitTester $I
+ *
+ * @issue https://github.com/phalcon/cphalcon/issues/54
+ *
+ * @author Phalcon Team
+ * @since 2014-09-05
+ */
+ public function htmlTagSelectOptGroupWithId(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - select() - optgroup array with id');
+ $tag = new Tag();
+ $tag->setDI($this->container);
+ $name = 'x_name';
+ $params = [
+ 'id' => 'x_id',
+ 'class' => 'x_class',
+ ];
+ $data = [
+ "Active" => [
+ 'A1' => 'A One',
+ 'A2' => 'A Two',
+ ],
+ "B" => "B One",
+ ];
+ $expected = '';
+
+ $actual = $tag->select($name, $params, $data);
+ $I->assertEquals($expected, $actual);
+ }
+
+ /**
+ * Tests Phalcon\Html\Tag :: select() - optgroup array without id
+ *
+ * @param UnitTester $I
+ *
+ * @issue https://github.com/phalcon/cphalcon/issues/54
+ *
+ * @author Phalcon Team
+ * @since 2014-09-05
+ */
+ public function htmlTagSelectOptGroupWithoutId(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - select() - optgroup array without id');
+ $tag = new Tag();
+ $tag->setDI($this->container);
+ $name = 'x_name';
+ $params = [
+ 'class' => 'x_class',
+ ];
+ $data = [
+ "Active" => [
+ 'A1' => 'A One',
+ 'A2' => 'A Two',
+ ],
+ "B" => "B One",
+ ];
+ $expected = '';
+
+ $actual = $tag->select($name, $params, $data);
+ $I->assertEquals($expected, $actual);
+ }
+
+ /**
+ * Tests Phalcon\Html\Tag :: select() - optgroup array with value
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2014-09-05
+ */
+ public function htmlTagSelectOptGroupWithValue(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - select() - optgroup array with value');
+ $tag = new Tag();
+ $tag->setDI($this->container);
+ $name = 'x_name';
+ $params = [
+ 'value' => 'A1',
+ 'class' => 'x_class',
+ ];
+ $data = [
+ "Active" => [
+ 'A1' => 'A One',
+ 'A2' => 'A Two',
+ ],
+ "B" => "B One",
+ ];
+ $expected = '';
+
+ $actual = $tag->select($name, $params, $data);
+ $I->assertEquals($expected, $actual);
+ }
+
+ /**
+ * Tests Phalcon\Html\Tag :: select() - optgroup setAttribute()
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2014-09-05
+ */
+ public function htmlTagSelectOptGroupSetAttribute(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - select() - optgroup setAttribute()');
+ $tag = new Tag();
+ $tag->setDI($this->container);
+ $name = 'x_name';
+ $params = [
+ 'class' => 'x_class',
+ 'size' => '10',
+ ];
+ $data = [
+ "Active" => [
+ 'A1' => 'A One',
+ 'A2' => 'A Two',
+ ],
+ "B" => "B One",
+ ];
+ $expected = '';
+
+ $actual = $tag
+ ->setAttribute('x_name', 'A2')
+ ->select($name, $params, $data);
+ $I->assertEquals($expected, $actual);
+ }
+
+ /**
+ * Tests Phalcon\Html\Tag :: select() - optgroup setAttribute() element not present
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2014-09-05
+ */
+ public function htmlTagSelectOptGroupSetAttributeElementNotPresent(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - select() - optgroup setAttribute() element not present');
+ $tag = new Tag();
+ $tag->setDI($this->container);
+ $name = 'x_name';
+ $params = [
+ 'name' => 'x_other',
+ 'class' => 'x_class',
+ 'size' => '10',
+ ];
+ $data = [
+ "Active" => [
+ 'A1' => 'A One',
+ 'A2' => 'A Two',
+ ],
+ "B" => "B One",
+ ];
+ $expected = '';
+
+ $actual = $tag
+ ->setAttribute('x_name', 'Z')
+ ->select($name, $params, $data);
+ $I->assertEquals($expected, $actual);
+ }
+}
diff --git a/tests/unit/Html/Tag/SetAttributeCest.php b/tests/unit/Html/Tag/SetAttributeCest.php
new file mode 100644
index 00000000000..f0074200ee0
--- /dev/null
+++ b/tests/unit/Html/Tag/SetAttributeCest.php
@@ -0,0 +1,43 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+namespace Phalcon\Test\Unit\Html\Tag;
+
+use Phalcon\Html\Tag;
+use UnitTester;
+
+/**
+ * Class SetAttributeCest
+ *
+ * @package Phalcon\Test\Unit\Html\Tag
+ */
+class SetAttributeCest
+{
+ /**
+ * Tests Phalcon\Html\Tag :: setAttribute()
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2018-11-13
+ */
+ public function htmlTagSetAttribute(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - setAttribute()');
+ $tag = new Tag();
+
+ $tag->setAttribute('name', 'Phalcon');
+ $expected = 'Phalcon';
+ $actual = $tag->getValue('name');
+ $I->assertEquals($expected, $actual);
+ }
+}
diff --git a/tests/unit/Html/Tag/SetAttributesCest.php b/tests/unit/Html/Tag/SetAttributesCest.php
new file mode 100644
index 00000000000..bccf4b32153
--- /dev/null
+++ b/tests/unit/Html/Tag/SetAttributesCest.php
@@ -0,0 +1,52 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+namespace Phalcon\Test\Unit\Html\Tag;
+
+use Phalcon\Html\Tag;
+use UnitTester;
+
+/**
+ * Class SetAttributesCest
+ *
+ * @package Phalcon\Test\Unit\Html\Tag
+ */
+class SetAttributesCest
+{
+ /**
+ * Tests Phalcon\Html\Tag :: setAttributes()
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2018-11-13
+ */
+ public function htmlTagSetAttributes(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - setAttributes()');
+ $tag = new Tag();
+
+ $tag->setAttributes(
+ [
+ 'name' => 'Phalcon',
+ 'cols' => 100,
+ ]
+ );
+ $expected = 'Phalcon';
+ $actual = $tag->getValue('name');
+ $I->assertEquals($expected, $actual);
+
+ $expected = 100;
+ $actual = $tag->getValue('cols');
+ $I->assertEquals($expected, $actual);
+ }
+}
diff --git a/tests/unit/Html/Tag/SetTitleCest.php b/tests/unit/Html/Tag/SetTitleCest.php
new file mode 100644
index 00000000000..53386aa8a74
--- /dev/null
+++ b/tests/unit/Html/Tag/SetTitleCest.php
@@ -0,0 +1,56 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+namespace Phalcon\Test\Unit\Html\Tag;
+
+use Phalcon\Html\Tag;
+use Phalcon\Test\Fixtures\Traits\DiTrait;
+use Phalcon\Test\Fixtures\Traits\TagSetupTrait;
+use UnitTester;
+
+/**
+ * Class SetTitleCest
+ *
+ * @package Phalcon\Test\Unit\Html\Tag
+ */
+class SetTitleCest
+{
+ use DiTrait;
+ use TagSetupTrait;
+
+ /**
+ * Tests Phalcon\Html\Tag :: setTitle()
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2018-11-13
+ */
+ public function htmlTagSetTitle(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - setTitle()');
+ $tag = new Tag();
+ $tag->setDI($this->container);
+
+ $value = 'This is my title';
+ $expected = "{$value}" . PHP_EOL;
+ $actual = $tag
+ ->setTitle($value)
+ ->renderTitle()
+ ;
+ $I->assertEquals($expected, $actual);
+
+ $expected = "{$value}";
+ $actual = $tag->getTitle();
+ $I->assertEquals($expected, $actual);
+ }
+}
diff --git a/tests/unit/Html/Tag/SetTitleSeparatorCest.php b/tests/unit/Html/Tag/SetTitleSeparatorCest.php
new file mode 100644
index 00000000000..0aa9d57ebff
--- /dev/null
+++ b/tests/unit/Html/Tag/SetTitleSeparatorCest.php
@@ -0,0 +1,46 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+namespace Phalcon\Test\Unit\Html\Tag;
+
+use Phalcon\Html\Tag;
+use UnitTester;
+
+/**
+ * Class SetTitleSeparatorCest
+ *
+ * @package Phalcon\Test\Unit\Html\Tag
+ */
+class SetTitleSeparatorCest
+{
+ /**
+ * Tests Phalcon\Html\Tag :: setTitleSeparator()
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2018-11-13
+ */
+ public function htmlTagSetTitleSeparator(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - setTitleSeparator()');
+ $tag = new Tag();
+
+ $actual = $tag->getTitleSeparator();
+ $I->assertEmpty($actual);
+
+ $separator = '--::--';
+ $tag->setTitleSeparator($separator);
+ $actual = $tag->getTitleSeparator();
+ $I->assertEquals($separator, $actual);
+ }
+}
diff --git a/tests/unit/Html/Tag/StylesheetCest.php b/tests/unit/Html/Tag/StylesheetCest.php
new file mode 100644
index 00000000000..40321bb9c7f
--- /dev/null
+++ b/tests/unit/Html/Tag/StylesheetCest.php
@@ -0,0 +1,136 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+namespace Phalcon\Test\Unit\Html\Tag;
+
+use Phalcon\Html\Tag;
+use Phalcon\Test\Fixtures\Traits\DiTrait;
+use Phalcon\Test\Fixtures\Traits\TagSetupTrait;
+use UnitTester;
+
+/**
+ * Class StylesheetCest
+ *
+ * @package Phalcon\Test\Unit\Html\Tag
+ */
+class StylesheetCest
+{
+ use DiTrait;
+ use TagSetupTrait;
+
+ /**
+ * Tests Phalcon\Html\Tag :: stylesheet() - local
+ *
+ * @param UnitTester $I
+ *
+ * @issue https://github.com/phalcon/cphalcon/issues/1486
+ * @author Dreamszhu
+ * @since 2014-09-12
+ */
+ public function htmlTagStylesheet(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - stylesheet() - local');
+ $tag = new Tag();
+ $tag->setDI($this->container);
+ $url = 'css/phalcon.css';
+ $expected = ''
+ . PHP_EOL;
+
+ $actual = $tag
+ ->setDocType(Tag::XHTML10_STRICT)
+ ->stylesheet($url)
+ ;
+
+ $I->assertEquals($expected, $actual);
+
+ $expected = ''
+ . PHP_EOL;
+ $actual = $tag
+ ->setDocType(Tag::HTML5)
+ ->stylesheet($url)
+ ;
+ $I->assertEquals($expected, $actual);
+ }
+
+ /**
+ * Tests Phalcon\Html\Tag :: stylesheet() - remote
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2014-09-12
+ */
+ public function htmlTagStylesheetRemote(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - stylesheet() - remote');
+ $tag = new Tag();
+ $tag->setDI($this->container);
+ $url = 'http://phalconphp.com/css/phalcon.css';
+ $options = ['local' => false];
+ $expected = ''
+ . PHP_EOL;
+
+ $actual = $tag
+ ->setDocType(Tag::XHTML10_STRICT)
+ ->stylesheet($url, $options)
+ ;
+ $I->assertEquals($expected, $actual);
+
+ $expected = ''
+ . PHP_EOL;
+ $actual = $tag
+ ->setDocType(Tag::HTML5)
+ ->stylesheet($url)
+ ;
+ $I->assertEquals($expected, $actual);
+ }
+
+ /**
+ * Tests Phalcon\Html\Tag :: stylesheet() - override rel
+ *
+ * @param UnitTester $I
+ *
+ * @issue https://github.com/phalcon/cphalcon/issues/2142
+ * @author Dreamszhu
+ * @since 2014-09-12
+ */
+ public function htmlTagStylesheetOverrideRel(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - stylesheet() - override rel');
+ $tag = new Tag();
+ $tag->setDI($this->container);
+ $url = 'css/phalcon.css';
+ $options = ['rel' => 'stylesheet/less'];
+ $expected = ''
+ . PHP_EOL;
+
+ $actual = $tag
+ ->setDocType(Tag::XHTML10_STRICT)
+ ->stylesheet($url, $options)
+ ;
+ $I->assertEquals($expected, $actual);
+
+ $expected = ''
+ . PHP_EOL;
+ $actual = $tag
+ ->setDocType(Tag::HTML5)
+ ->stylesheet($url, $options)
+ ;
+ $I->assertEquals($expected, $actual);
+ }
+}
diff --git a/tests/unit/Html/Tag/SubmitCest.php b/tests/unit/Html/Tag/SubmitCest.php
new file mode 100644
index 00000000000..0cdee959ae4
--- /dev/null
+++ b/tests/unit/Html/Tag/SubmitCest.php
@@ -0,0 +1,32 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+namespace Phalcon\Test\Unit\Html\Tag;
+
+use Phalcon\Test\Fixtures\Traits\DiTrait;
+use Phalcon\Test\Fixtures\Traits\TagHelperTrait;
+use Phalcon\Test\Fixtures\Traits\TagSetupTrait;
+
+/**
+ * Class SubmitCest
+ *
+ * @package Phalcon\Test\Unit\Html\Tag
+ */
+class SubmitCest
+{
+ use DiTrait;
+ use TagSetupTrait;
+ use TagHelperTrait;
+
+ protected $function = 'submit';
+ protected $inputType = 'submit';
+}
diff --git a/tests/unit/Html/Tag/TextAreaCest.php b/tests/unit/Html/Tag/TextAreaCest.php
new file mode 100644
index 00000000000..e8c9cec5df2
--- /dev/null
+++ b/tests/unit/Html/Tag/TextAreaCest.php
@@ -0,0 +1,145 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE.txt
+ * file that was distributed with this source code.
+ */
+
+namespace Phalcon\Test\Unit\Html\Tag;
+
+use Phalcon\Html\Tag;
+use Phalcon\Test\Fixtures\Traits\DiTrait;
+use Phalcon\Test\Fixtures\Traits\TagSetupTrait;
+use UnitTester;
+
+/**
+ * Class TextAreaCest
+ *
+ * @package Phalcon\Test\Unit\Html\Tag
+ */
+class TextAreaCest
+{
+ use DiTrait;
+ use TagSetupTrait;
+
+ /**
+ * Tests Phalcon\Html\Tag :: textArea()
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2014-09-05
+ */
+ public function htmlTagTextArea(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - textArea()');
+ $tag = new Tag();
+ $tag->setDI($this->container);
+ $expected = 'testFieldParameter($I, $tag, 'x_name', 'textArea', [], $expected);
+ }
+
+ /**
+ * Tests Phalcon\Html\Tag :: textArea() - array as a parameters and id in it
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2014-09-05
+ */
+ public function htmlTagTextAreaWithId(UnitTester $I)
+ {
+ $I->wantToTest("Html\Tag - textArea() - with id");
+ $tag = new Tag();
+ $tag->setDI($this->container);
+ $options = [
+ 'id' => 'x_id',
+ 'class' => 'x_class',
+ 'size' => '10',
+ ];
+ $expected = 'testFieldParameter($I, $tag, 'x_name', 'textArea', $options, $expected);
+ }
+
+ /**
+ * Tests Phalcon\Html\Tag :: textArea() - setAttribute()
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2014-09-05
+ */
+ public function htmlTagTextAreaSetAttribute(UnitTester $I)
+ {
+ $I->wantToTest('Html\Tag - textArea() - setAttribute()');
+ $tag = new Tag();
+ $tag->setDI($this->container);
+ $options = [
+ 'name' => 'x_other',
+ 'class' => 'x_class',
+ 'size' => '10',
+ ];
+ $expected = 'testFieldParameter($I, $tag, 'x_name', 'textArea', $options, $expected, false, 'setAttribute');
+ $this->testFieldParameter($I, $tag, 'x_name', 'textArea', $options, $expected, true, 'setAttribute');
+ }
+
+ /**
+ * Tests Phalcon\Html\Tag :: textArea() - setAttribute() element not present
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2014-09-05
+ */
+ public function htmlTagTextAreaSetAttributeElementNotPresent(UnitTester $I)
+ {
+ $I->wantToTest("Tag - textArea() - setAttribute() element not present");
+ $tag = new Tag();
+ $tag->setDI($this->container);
+ $options = [
+ 'name' => 'x_other',
+ 'class' => 'x_class',
+ 'size' => '10',
+ ];
+ $expected = 'testFieldParameter($I, $tag, 'x_name', 'textArea', $options, $expected, false, 'setAttribute');
+ $this->testFieldParameter($I, $tag, 'x_name', 'textArea', $options, $expected, true, 'setAttribute');
+ }
+
+ /**
+ * Tests Phalcon\Html\Tag :: textArea() - setAttribute() with newline
+ *
+ * @param UnitTester $I
+ *
+ * @author Phalcon Team
+ * @since 2014-10-03
+ */
+ public function htmlTagTextAreaSetAttributeNewLine(UnitTester $I)
+ {
+ $I->wantToTest("Tag - textArea() - setAttribute() with newline");
+ $tag = new Tag();
+ $tag->setDI($this->container);
+ $options = 'x_name';
+ $value = "\r\nx_content";
+ $expected = '';
+
+ $tag->setAttribute('x_name', $value);
+ $actual = $tag->textArea($options);
+ $tag->setAttribute('x_name', '');
+
+ $I->assertEquals($expected, $actual);
+ }
+}