= $block->escapeHtml(__('Signifyd Guarantee Decision')) ?> | += $block->escapeHtml($block->getCaseGuaranteeDisposition()) ?> | +
---|
diff --git a/.htaccess.sample b/.htaccess.sample index 8e6e702ced716..3c412725f2134 100644 --- a/.htaccess.sample +++ b/.htaccess.sample @@ -111,7 +111,8 @@ ############################################ ## enable rewrites - Options +FollowSymLinks + # The following line has better security but add some performance overhead - see https://httpd.apache.org/docs/2.4/en/misc/perf-tuning.html + Options -FollowSymLinks +SymLinksIfOwnerMatch RewriteEngine on ############################################ diff --git a/COPYING.txt b/COPYING.txt index d2cbcd01539dd..2ba7d78d58a25 100644 --- a/COPYING.txt +++ b/COPYING.txt @@ -1,4 +1,4 @@ -Copyright © 2013-2017 Magento, Inc. +Copyright © 2013-2018 Magento, Inc. Each Magento source file included in this distribution is licensed under OSL 3.0 or the Magento Enterprise Edition (MEE) license diff --git a/README.md b/README.md index 9b1aa1b7b3e28..c72357db26d16 100644 --- a/README.md +++ b/README.md @@ -5,13 +5,13 @@ Welcome to Magento 2 installation! We're glad you chose to install Magento 2, a cutting edge, feature-rich eCommerce solution that gets results. ## Magento system requirements -[Magento system requirements](http://devdocs.magento.com/magento-system-requirements.html) +[Magento system requirements](http://devdocs.magento.com/guides/v2.2/install-gde/system-requirements2.html) ## Install Magento To install Magento, see either: * [Magento DevBox](https://magento.com/tech-resources/download), the easiest way to get started with Magento. -* [Installation guide](http://devdocs.magento.com/guides/v2.0/install-gde/bk-install-guide.html) +* [Installation guide](http://devdocs.magento.com/guides/v2.2/install-gde/bk-install-guide.html)
Magento supports PHP 7.0.2, 7.0.4, and 7.0.6 or later. Please read
-
+
Magento System Requirements.
HTML;
@@ -49,12 +49,13 @@
unset($_SERVER['ORIG_PATH_INFO']);
}
-if (!empty($_SERVER['MAGE_PROFILER'])
+if (
+ (!empty($_SERVER['MAGE_PROFILER']) || file_exists(BP . '/var/profiler.flag'))
&& isset($_SERVER['HTTP_ACCEPT'])
&& strpos($_SERVER['HTTP_ACCEPT'], 'text/html') !== false
) {
\Magento\Framework\Profiler::applyConfig(
- $_SERVER['MAGE_PROFILER'],
+ (isset($_SERVER['MAGE_PROFILER']) && strlen($_SERVER['MAGE_PROFILER'])) ? $_SERVER['MAGE_PROFILER'] : trim(file_get_contents(BP . '/var/profiler.flag')),
BP,
!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest'
);
diff --git a/app/code/Magento/AdminNotification/Model/Feed.php b/app/code/Magento/AdminNotification/Model/Feed.php
index 1766425fb19b1..d3b0b8501c864 100644
--- a/app/code/Magento/AdminNotification/Model/Feed.php
+++ b/app/code/Magento/AdminNotification/Model/Feed.php
@@ -214,9 +214,6 @@ public function getFeedData()
);
$curl->write(\Zend_Http_Client::GET, $this->getFeedUrl(), '1.0');
$data = $curl->read();
- if ($data === false) {
- return false;
- }
$data = preg_split('/^\r?$/m', $data, 2);
$data = trim($data[1]);
$curl->close();
diff --git a/app/code/Magento/AdminNotification/Setup/InstallSchema.php b/app/code/Magento/AdminNotification/Setup/InstallSchema.php
deleted file mode 100644
index 081be974dc809..0000000000000
--- a/app/code/Magento/AdminNotification/Setup/InstallSchema.php
+++ /dev/null
@@ -1,124 +0,0 @@
-startSetup();
- /**
- * Create table 'adminnotification_inbox'
- */
- $table = $installer->getConnection()->newTable(
- $installer->getTable('adminnotification_inbox')
- )->addColumn(
- 'notification_id',
- \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
- null,
- ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
- 'Notification id'
- )->addColumn(
- 'severity',
- \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
- null,
- ['unsigned' => true, 'nullable' => false, 'default' => '0'],
- 'Problem type'
- )->addColumn(
- 'date_added',
- \Magento\Framework\DB\Ddl\Table::TYPE_TIMESTAMP,
- null,
- ['nullable' => false, 'default' => \Magento\Framework\DB\Ddl\Table::TIMESTAMP_INIT],
- 'Create date'
- )->addColumn(
- 'title',
- \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
- 255,
- ['nullable' => false],
- 'Title'
- )->addColumn(
- 'description',
- \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
- '64k',
- [],
- 'Description'
- )->addColumn(
- 'url',
- \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
- 255,
- [],
- 'Url'
- )->addColumn(
- 'is_read',
- \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
- null,
- ['unsigned' => true, 'nullable' => false, 'default' => '0'],
- 'Flag if notification read'
- )->addColumn(
- 'is_remove',
- \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
- null,
- ['unsigned' => true, 'nullable' => false, 'default' => '0'],
- 'Flag if notification might be removed'
- )->addIndex(
- $installer->getIdxName('adminnotification_inbox', ['severity']),
- ['severity']
- )->addIndex(
- $installer->getIdxName('adminnotification_inbox', ['is_read']),
- ['is_read']
- )->addIndex(
- $installer->getIdxName('adminnotification_inbox', ['is_remove']),
- ['is_remove']
- )->setComment(
- 'Adminnotification Inbox'
- );
- $installer->getConnection()->createTable($table);
-
- /**
- * Create table 'admin_system_messages'
- */
- $table = $installer->getConnection()->newTable(
- $installer->getTable('admin_system_messages')
- )->addColumn(
- 'identity',
- \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
- 100,
- ['nullable' => false, 'primary' => true],
- 'Message id'
- )->addColumn(
- 'severity',
- \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
- null,
- ['unsigned' => true, 'nullable' => false, 'default' => '0'],
- 'Problem type'
- )->addColumn(
- 'created_at',
- \Magento\Framework\DB\Ddl\Table::TYPE_TIMESTAMP,
- null,
- ['nullable' => false, 'default' => \Magento\Framework\DB\Ddl\Table::TIMESTAMP_INIT],
- 'Create date'
- )->setComment(
- 'Admin System Messages'
- );
- $installer->getConnection()->createTable($table);
-
- $installer->endSetup();
- }
-}
diff --git a/app/code/Magento/AdminNotification/etc/db_schema.xml b/app/code/Magento/AdminNotification/etc/db_schema.xml
new file mode 100644
index 0000000000000..6d969b3f0090a
--- /dev/null
+++ b/app/code/Magento/AdminNotification/etc/db_schema.xml
@@ -0,0 +1,47 @@
+
+
+
-
- = /* @escapeNotVerified */ __('Pregenerated product images files') ?>
-
-
- = /* @escapeNotVerified */ __('Themes JavaScript and CSS files combined to one file') ?>
-
-
- = /* @escapeNotVerified */ __('Preprocessed view files and static files') ?>
-
+
+ = $block->escapeHtml(__('Pregenerated product images files')); ?>
+
+
+ = $block->escapeHtml(__('Themes JavaScript and CSS files combined to one file')) ?>
+
+
+ = $block->escapeHtml(__('Preprocessed view files and static files')); ?>
+ ' . $this->escapeHtml($url) . ' ' .
+ $this->escapeHtml(__('Learn more')) . '
+ {{trans 'About Us' url_about_us=$url_about_us |raw}}
+
+ {{trans 'Customer Service' url_customer_service=$url_customer_service |raw}}
+ Test text
+
+
+
+
+
+
+
+
@@ -39,7 +39,7 @@
href="= /* @escapeNotVerified */ $block->getUrl('adminhtml/system_account/index') ?>"
= /* @escapeNotVerified */ $block->getUiId('user', 'account', 'settings') ?>
title="= $block->escapeHtml(__('Account Setting')) ?>">
- = /* @escapeNotVerified */ __('Account Setting') ?> (= $block->escapeHtml($block->getUser()->getUsername()) ?>)
+ = /* @escapeNotVerified */ __('Account Setting') ?> (= $block->escapeHtml($block->getUser()->getUserName()) ?>)
diff --git a/app/code/Magento/Backend/view/adminhtml/templates/system/cache/additional.phtml b/app/code/Magento/Backend/view/adminhtml/templates/system/cache/additional.phtml
index 84bbc4ea601ef..8e30afdf51f7f 100644
--- a/app/code/Magento/Backend/view/adminhtml/templates/system/cache/additional.phtml
+++ b/app/code/Magento/Backend/view/adminhtml/templates/system/cache/additional.phtml
@@ -5,34 +5,39 @@
*/
// @codingStandardsIgnoreFile
+
+/** @var \Magento\Backend\Block\Cache\Permissions|null $permissions */
+$permissions = $block->getData('permissions');
?>
-
- = /* @escapeNotVerified */ __('Additional Cache Management') ?>
-
-
+ = $block->escapeHtml(__('Additional Cache Management')); ?>
+
+
';
+ $newItemValue = "itemValue
\n";
$dataSource = [
'data' => [
'items' => [
@@ -57,7 +57,7 @@ public function testPrepareDataSource()
];
$this->model->setData('name', $itemName);
- $this->escaper->expects($this->once())->method('escapeHtml')->with($newItemValue)->willReturnArgument(0);
+ $this->escaper->expects($this->any())->method('escapeHtml')->with($oldItemValue)->willReturnArgument(0);
$dataSource = $this->model->prepareDataSource($dataSource);
$this->assertEquals($newItemValue, $dataSource['data']['items'][0][$itemName]);
}
diff --git a/app/code/Magento/Sales/Ui/Component/Listing/Column/Address.php b/app/code/Magento/Sales/Ui/Component/Listing/Column/Address.php
index 23a6e7a41a5b7..d900bb7ba670f 100644
--- a/app/code/Magento/Sales/Ui/Component/Listing/Column/Address.php
+++ b/app/code/Magento/Sales/Ui/Component/Listing/Column/Address.php
@@ -49,9 +49,7 @@ public function prepareDataSource(array $dataSource)
{
if (isset($dataSource['data']['items'])) {
foreach ($dataSource['data']['items'] as & $item) {
- $item[$this->getData('name')] = $this->escaper->escapeHtml(
- str_replace("\n", '
', $item[$this->getData('name')])
- );
+ $item[$this->getData('name')] = nl2br($this->escaper->escapeHtml($item[$this->getData('name')]));
}
}
diff --git a/app/code/Magento/Sales/etc/db_schema.xml b/app/code/Magento/Sales/etc/db_schema.xml
new file mode 100644
index 0000000000000..c084a5b87b109
--- /dev/null
+++ b/app/code/Magento/Sales/etc/db_schema.xml
@@ -0,0 +1,2063 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
- getDataId() == 'cart'): ?>
- = /* @noEscape */ $block->getItemPrice($_item->getProduct()) ?>
-
- = /* @noEscape */ $block->getItemPrice($_item) ?>
-
+ = /* @noEscape */ $block->getItemPrice($block->getProduct($_item)) ?>
diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/view/history.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/view/history.phtml
index 1ec51ffb793c6..6ac6e13a873ed 100644
--- a/app/code/Magento/Sales/view/adminhtml/templates/order/view/history.phtml
+++ b/app/code/Magento/Sales/view/adminhtml/templates/order/view/history.phtml
@@ -5,7 +5,7 @@
*/
// @codingStandardsIgnoreFile
-
+/** @var \Magento\Sales\Block\Adminhtml\Order\View\History $block */
?>
= /* @escapeNotVerified */ $_item->getQty() * 1 ?>
- = /* @escapeNotVerified */ $block->getItemPrice($_item) ?>
+ = /* @escapeNotVerified */ $block->getItemPrice($_item->getOrderItem()) ?>
diff --git a/app/code/Magento/SalesRule/Model/Rule/Condition/Product/Subselect.php b/app/code/Magento/SalesRule/Model/Rule/Condition/Product/Subselect.php
index 108cc341253ae..1e8fbf43ec3bc 100644
--- a/app/code/Magento/SalesRule/Model/Rule/Condition/Product/Subselect.php
+++ b/app/code/Magento/SalesRule/Model/Rule/Condition/Product/Subselect.php
@@ -136,6 +136,7 @@ public function asHtml()
*
* @param \Magento\Framework\Model\AbstractModel $model
* @return bool
+ * @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/
public function validate(\Magento\Framework\Model\AbstractModel $model)
{
@@ -145,8 +146,22 @@ public function validate(\Magento\Framework\Model\AbstractModel $model)
$attr = $this->getAttribute();
$total = 0;
foreach ($model->getQuote()->getAllVisibleItems() as $item) {
- if (parent::validate($item)) {
- $total += $item->getData($attr);
+ $hasValidChild = false;
+ $useChildrenTotal = ($item->getProductType() == \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE);
+ $childrenAttrTotal = 0;
+ $children = $item->getChildren();
+ if (!empty($children)) {
+ foreach ($children as $child) {
+ if (parent::validate($child)) {
+ $hasValidChild = true;
+ if ($useChildrenTotal) {
+ $childrenAttrTotal += $child->getData($attr);
+ }
+ }
+ }
+ }
+ if ($hasValidChild || parent::validate($item)) {
+ $total += (($hasValidChild && $useChildrenTotal) ? $childrenAttrTotal : $item->getData($attr));
}
}
return $this->validateAttribute($total);
diff --git a/app/code/Magento/SalesRule/Setup/InstallSchema.php b/app/code/Magento/SalesRule/Setup/InstallSchema.php
deleted file mode 100644
index e49933c211d20..0000000000000
--- a/app/code/Magento/SalesRule/Setup/InstallSchema.php
+++ /dev/null
@@ -1,794 +0,0 @@
-startSetup();
- $customerGroupTable = $setup->getConnection()->describeTable($setup->getTable('customer_group'));
- $customerGroupIdType = $customerGroupTable['customer_group_id']['DATA_TYPE'] == 'int'
- ? \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER : $customerGroupTable['customer_group_id']['DATA_TYPE'];
- /**
- * Create table 'salesrule'
- */
- $table = $installer->getConnection()->newTable(
- $installer->getTable('salesrule')
- )->addColumn(
- 'rule_id',
- \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
- null,
- ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
- 'Rule Id'
- )->addColumn(
- 'name',
- \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
- 255,
- [],
- 'Name'
- )->addColumn(
- 'description',
- \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
- '64k',
- [],
- 'Description'
- )->addColumn(
- 'from_date',
- \Magento\Framework\DB\Ddl\Table::TYPE_DATE,
- null,
- ['nullable' => true, 'default' => null],
- 'From'
- )->addColumn(
- 'to_date',
- \Magento\Framework\DB\Ddl\Table::TYPE_DATE,
- null,
- ['nullable' => true, 'default' => null],
- 'To'
- )->addColumn(
- 'uses_per_customer',
- \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
- null,
- ['nullable' => false, 'default' => '0'],
- 'Uses Per Customer'
- )->addColumn(
- 'is_active',
- \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
- null,
- ['nullable' => false, 'default' => '0'],
- 'Is Active'
- )->addColumn(
- 'conditions_serialized',
- \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
- '2M',
- [],
- 'Conditions Serialized'
- )->addColumn(
- 'actions_serialized',
- \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
- '2M',
- [],
- 'Actions Serialized'
- )->addColumn(
- 'stop_rules_processing',
- \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
- null,
- ['nullable' => false, 'default' => '1'],
- 'Stop Rules Processing'
- )->addColumn(
- 'is_advanced',
- \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
- null,
- ['unsigned' => true, 'nullable' => false, 'default' => '1'],
- 'Is Advanced'
- )->addColumn(
- 'product_ids',
- \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
- '64k',
- [],
- 'Product Ids'
- )->addColumn(
- 'sort_order',
- \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
- null,
- ['unsigned' => true, 'nullable' => false, 'default' => '0'],
- 'Sort Order'
- )->addColumn(
- 'simple_action',
- \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
- 32,
- [],
- 'Simple Action'
- )->addColumn(
- 'discount_amount',
- \Magento\Framework\DB\Ddl\Table::TYPE_DECIMAL,
- [12, 4],
- ['nullable' => false, 'default' => '0.0000'],
- 'Discount Amount'
- )->addColumn(
- 'discount_qty',
- \Magento\Framework\DB\Ddl\Table::TYPE_DECIMAL,
- [12, 4],
- [],
- 'Discount Qty'
- )->addColumn(
- 'discount_step',
- \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
- null,
- ['unsigned' => true, 'nullable' => false],
- 'Discount Step'
- )->addColumn(
- 'apply_to_shipping',
- \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
- null,
- ['unsigned' => true, 'nullable' => false, 'default' => '0'],
- 'Apply To Shipping'
- )->addColumn(
- 'times_used',
- \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
- null,
- ['unsigned' => true, 'nullable' => false, 'default' => '0'],
- 'Times Used'
- )->addColumn(
- 'is_rss',
- \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
- null,
- ['nullable' => false, 'default' => '0'],
- 'Is Rss'
- )->addColumn(
- 'coupon_type',
- \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
- null,
- ['unsigned' => true, 'nullable' => false, 'default' => '1'],
- 'Coupon Type'
- )->addColumn(
- 'use_auto_generation',
- \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
- null,
- ['unsigned' => false, 'nullable' => false, 'default' => 0],
- 'Use Auto Generation'
- )->addColumn(
- 'uses_per_coupon',
- \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
- null,
- ['nullable' => false, 'default' => 0],
- 'User Per Coupon'
- )->addIndex(
- $installer->getIdxName('salesrule', ['is_active', 'sort_order', 'to_date', 'from_date']),
- ['is_active', 'sort_order', 'to_date', 'from_date']
- )->setComment(
- 'Salesrule'
- );
- $installer->getConnection()->createTable($table);
-
- /**
- * Create table 'salesrule_coupon'
- */
- $table = $installer->getConnection()->newTable(
- $installer->getTable('salesrule_coupon')
- )->addColumn(
- 'coupon_id',
- \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
- null,
- ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
- 'Coupon Id'
- )->addColumn(
- 'rule_id',
- \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
- null,
- ['unsigned' => true, 'nullable' => false],
- 'Rule Id'
- )->addColumn(
- 'code',
- \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
- 255,
- [],
- 'Code'
- )->addColumn(
- 'usage_limit',
- \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
- null,
- ['unsigned' => true],
- 'Usage Limit'
- )->addColumn(
- 'usage_per_customer',
- \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
- null,
- ['unsigned' => true],
- 'Usage Per Customer'
- )->addColumn(
- 'times_used',
- \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
- null,
- ['unsigned' => true, 'nullable' => false, 'default' => '0'],
- 'Times Used'
- )->addColumn(
- 'expiration_date',
- \Magento\Framework\DB\Ddl\Table::TYPE_TIMESTAMP,
- null,
- [],
- 'Expiration Date'
- )->addColumn(
- 'is_primary',
- \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
- null,
- ['unsigned' => true],
- 'Is Primary'
- )->addColumn(
- 'created_at',
- \Magento\Framework\DB\Ddl\Table::TYPE_TIMESTAMP,
- null,
- ['nullable' => true],
- 'Coupon Code Creation Date'
- )->addColumn(
- 'type',
- \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
- null,
- ['nullable' => true, 'default' => 0],
- 'Coupon Code Type'
- )->addIndex(
- $installer->getIdxName(
- 'salesrule_coupon',
- ['code'],
- \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE
- ),
- ['code'],
- ['type' => \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE]
- )->addIndex(
- $installer->getIdxName(
- 'salesrule_coupon',
- ['rule_id', 'is_primary'],
- \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE
- ),
- ['rule_id', 'is_primary'],
- ['type' => \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE]
- )->addIndex(
- $installer->getIdxName('salesrule_coupon', ['rule_id']),
- ['rule_id']
- )->addForeignKey(
- $installer->getFkName('salesrule_coupon', 'rule_id', 'salesrule', 'rule_id'),
- 'rule_id',
- $installer->getTable('salesrule'),
- 'rule_id',
- \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
- )->setComment(
- 'Salesrule Coupon'
- );
- $installer->getConnection()->createTable($table);
-
- /**
- * Create table 'salesrule_coupon_usage'
- */
- $table = $installer->getConnection()->newTable(
- $installer->getTable('salesrule_coupon_usage')
- )->addColumn(
- 'coupon_id',
- \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
- null,
- ['unsigned' => true, 'nullable' => false, 'primary' => true],
- 'Coupon Id'
- )->addColumn(
- 'customer_id',
- \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
- null,
- ['unsigned' => true, 'nullable' => false, 'primary' => true],
- 'Customer Id'
- )->addColumn(
- 'times_used',
- \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
- null,
- ['unsigned' => true, 'nullable' => false, 'default' => '0'],
- 'Times Used'
- )->addIndex(
- $installer->getIdxName('salesrule_coupon_usage', ['customer_id']),
- ['customer_id']
- )->addForeignKey(
- $installer->getFkName('salesrule_coupon_usage', 'coupon_id', 'salesrule_coupon', 'coupon_id'),
- 'coupon_id',
- $installer->getTable('salesrule_coupon'),
- 'coupon_id',
- \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
- )->addForeignKey(
- $installer->getFkName('salesrule_coupon_usage', 'customer_id', 'customer_entity', 'entity_id'),
- 'customer_id',
- $installer->getTable('customer_entity'),
- 'entity_id',
- \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
- )->setComment(
- 'Salesrule Coupon Usage'
- );
- $installer->getConnection()->createTable($table);
-
- /**
- * Create table 'salesrule_customer'
- */
- $table = $installer->getConnection()->newTable(
- $installer->getTable('salesrule_customer')
- )->addColumn(
- 'rule_customer_id',
- \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
- null,
- ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
- 'Rule Customer Id'
- )->addColumn(
- 'rule_id',
- \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
- null,
- ['unsigned' => true, 'nullable' => false, 'default' => '0'],
- 'Rule Id'
- )->addColumn(
- 'customer_id',
- \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
- null,
- ['unsigned' => true, 'nullable' => false, 'default' => '0'],
- 'Customer Id'
- )->addColumn(
- 'times_used',
- \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
- null,
- ['unsigned' => true, 'nullable' => false, 'default' => '0'],
- 'Times Used'
- )->addIndex(
- $installer->getIdxName('salesrule_customer', ['rule_id', 'customer_id']),
- ['rule_id', 'customer_id']
- )->addIndex(
- $installer->getIdxName('salesrule_customer', ['customer_id', 'rule_id']),
- ['customer_id', 'rule_id']
- )->addForeignKey(
- $installer->getFkName('salesrule_customer', 'customer_id', 'customer_entity', 'entity_id'),
- 'customer_id',
- $installer->getTable('customer_entity'),
- 'entity_id',
- \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
- )->addForeignKey(
- $installer->getFkName('salesrule_customer', 'rule_id', 'salesrule', 'rule_id'),
- 'rule_id',
- $installer->getTable('salesrule'),
- 'rule_id',
- \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
- )->setComment(
- 'Salesrule Customer'
- );
- $installer->getConnection()->createTable($table);
-
- /**
- * Create table 'salesrule_label'
- */
- $table = $installer->getConnection()->newTable(
- $installer->getTable('salesrule_label')
- )->addColumn(
- 'label_id',
- \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
- null,
- ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
- 'Label Id'
- )->addColumn(
- 'rule_id',
- \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
- null,
- ['unsigned' => true, 'nullable' => false],
- 'Rule Id'
- )->addColumn(
- 'store_id',
- \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
- null,
- ['unsigned' => true, 'nullable' => false],
- 'Store Id'
- )->addColumn(
- 'label',
- \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
- 255,
- [],
- 'Label'
- )->addIndex(
- $installer->getIdxName(
- 'salesrule_label',
- ['rule_id', 'store_id'],
- \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE
- ),
- ['rule_id', 'store_id'],
- ['type' => \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE]
- )->addIndex(
- $installer->getIdxName('salesrule_label', ['store_id']),
- ['store_id']
- )->addForeignKey(
- $installer->getFkName('salesrule_label', 'rule_id', 'salesrule', 'rule_id'),
- 'rule_id',
- $installer->getTable('salesrule'),
- 'rule_id',
- \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
- )->addForeignKey(
- $installer->getFkName('salesrule_label', 'store_id', 'store', 'store_id'),
- 'store_id',
- $installer->getTable('store'),
- 'store_id',
- \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
- )->setComment(
- 'Salesrule Label'
- );
- $installer->getConnection()->createTable($table);
-
- /**
- * Create table 'salesrule_product_attribute'
- */
- $table = $installer->getConnection()->newTable(
- $installer->getTable('salesrule_product_attribute')
- )->addColumn(
- 'rule_id',
- \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
- null,
- ['unsigned' => true, 'nullable' => false, 'primary' => true],
- 'Rule Id'
- )->addColumn(
- 'website_id',
- \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
- null,
- ['unsigned' => true, 'nullable' => false, 'primary' => true],
- 'Website Id'
- )->addColumn(
- 'customer_group_id',
- $customerGroupIdType,
- null,
- ['unsigned' => true, 'nullable' => false, 'primary' => true],
- 'Customer Group Id'
- )->addColumn(
- 'attribute_id',
- \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
- null,
- ['unsigned' => true, 'nullable' => false, 'primary' => true],
- 'Attribute Id'
- )->addIndex(
- $installer->getIdxName('salesrule_product_attribute', ['website_id']),
- ['website_id']
- )->addIndex(
- $installer->getIdxName('salesrule_product_attribute', ['customer_group_id']),
- ['customer_group_id']
- )->addIndex(
- $installer->getIdxName('salesrule_product_attribute', ['attribute_id']),
- ['attribute_id']
- )->addForeignKey(
- $installer->getFkName('salesrule_product_attribute', 'attribute_id', 'eav_attribute', 'attribute_id'),
- 'attribute_id',
- $installer->getTable('eav_attribute'),
- 'attribute_id',
- \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
- )->addForeignKey(
- $installer->getFkName(
- 'salesrule_product_attribute',
- 'customer_group_id',
- 'customer_group',
- 'customer_group_id'
- ),
- 'customer_group_id',
- $installer->getTable('customer_group'),
- 'customer_group_id',
- \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
- )->addForeignKey(
- $installer->getFkName('salesrule_product_attribute', 'rule_id', 'salesrule', 'rule_id'),
- 'rule_id',
- $installer->getTable('salesrule'),
- 'rule_id',
- \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
- )->addForeignKey(
- $installer->getFkName('salesrule_product_attribute', 'website_id', 'store_website', 'website_id'),
- 'website_id',
- $installer->getTable('store_website'),
- 'website_id',
- \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
- )->setComment(
- 'Salesrule Product Attribute'
- );
- $installer->getConnection()->createTable($table);
-
- /**
- * Create table 'salesrule_coupon_aggregated'
- */
- $table = $installer->getConnection()->newTable(
- $installer->getTable('salesrule_coupon_aggregated')
- )->addColumn(
- 'id',
- \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
- null,
- ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
- 'Id'
- )->addColumn(
- 'period',
- \Magento\Framework\DB\Ddl\Table::TYPE_DATE,
- null,
- ['nullable' => false],
- 'Period'
- )->addColumn(
- 'store_id',
- \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
- null,
- ['unsigned' => true],
- 'Store Id'
- )->addColumn(
- 'order_status',
- \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
- 50,
- [],
- 'Order Status'
- )->addColumn(
- 'coupon_code',
- \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
- 50,
- [],
- 'Coupon Code'
- )->addColumn(
- 'coupon_uses',
- \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
- null,
- ['nullable' => false, 'default' => '0'],
- 'Coupon Uses'
- )->addColumn(
- 'subtotal_amount',
- \Magento\Framework\DB\Ddl\Table::TYPE_DECIMAL,
- [12, 4],
- ['nullable' => false, 'default' => '0.0000'],
- 'Subtotal Amount'
- )->addColumn(
- 'discount_amount',
- \Magento\Framework\DB\Ddl\Table::TYPE_DECIMAL,
- [12, 4],
- ['nullable' => false, 'default' => '0.0000'],
- 'Discount Amount'
- )->addColumn(
- 'total_amount',
- \Magento\Framework\DB\Ddl\Table::TYPE_DECIMAL,
- [12, 4],
- ['nullable' => false, 'default' => '0.0000'],
- 'Total Amount'
- )->addColumn(
- 'subtotal_amount_actual',
- \Magento\Framework\DB\Ddl\Table::TYPE_DECIMAL,
- [12, 4],
- ['nullable' => false, 'default' => '0.0000'],
- 'Subtotal Amount Actual'
- )->addColumn(
- 'discount_amount_actual',
- \Magento\Framework\DB\Ddl\Table::TYPE_DECIMAL,
- [12, 4],
- ['nullable' => false, 'default' => '0.0000'],
- 'Discount Amount Actual'
- )->addColumn(
- 'total_amount_actual',
- \Magento\Framework\DB\Ddl\Table::TYPE_DECIMAL,
- [12, 4],
- ['nullable' => false, 'default' => '0.0000'],
- 'Total Amount Actual'
- )->addColumn(
- 'rule_name',
- \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
- 255,
- [],
- 'Rule Name'
- )->addIndex(
- $installer->getIdxName(
- 'salesrule_coupon_aggregated',
- ['period', 'store_id', 'order_status', 'coupon_code'],
- \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE
- ),
- ['period', 'store_id', 'order_status', 'coupon_code'],
- ['type' => \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE]
- )->addIndex(
- $installer->getIdxName('salesrule_coupon_aggregated', ['store_id']),
- ['store_id']
- )->addIndex(
- $installer->getIdxName('salesrule_coupon_aggregated', ['rule_name']),
- ['rule_name']
- )->addForeignKey(
- $installer->getFkName('salesrule_coupon_aggregated', 'store_id', 'store', 'store_id'),
- 'store_id',
- $installer->getTable('store'),
- 'store_id',
- \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
- )->setComment(
- 'Coupon Aggregated'
- );
- $installer->getConnection()->createTable($table);
-
- $installer->getConnection()->createTable(
- $installer->getConnection()->createTableByDdl(
- $installer->getTable('salesrule_coupon_aggregated'),
- $installer->getTable('salesrule_coupon_aggregated_updated')
- )
- );
-
- /**
- * Create table 'salesrule_coupon_aggregated_order'
- */
- $table = $installer->getConnection()->newTable(
- $installer->getTable('salesrule_coupon_aggregated_order')
- )->addColumn(
- 'id',
- \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
- null,
- ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
- 'Id'
- )->addColumn(
- 'period',
- \Magento\Framework\DB\Ddl\Table::TYPE_DATE,
- null,
- ['nullable' => false],
- 'Period'
- )->addColumn(
- 'store_id',
- \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
- null,
- ['unsigned' => true],
- 'Store Id'
- )->addColumn(
- 'order_status',
- \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
- 50,
- [],
- 'Order Status'
- )->addColumn(
- 'coupon_code',
- \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
- 50,
- [],
- 'Coupon Code'
- )->addColumn(
- 'coupon_uses',
- \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
- null,
- ['nullable' => false, 'default' => '0'],
- 'Coupon Uses'
- )->addColumn(
- 'subtotal_amount',
- \Magento\Framework\DB\Ddl\Table::TYPE_DECIMAL,
- [12, 4],
- ['nullable' => false, 'default' => '0.0000'],
- 'Subtotal Amount'
- )->addColumn(
- 'discount_amount',
- \Magento\Framework\DB\Ddl\Table::TYPE_DECIMAL,
- [12, 4],
- ['nullable' => false, 'default' => '0.0000'],
- 'Discount Amount'
- )->addColumn(
- 'total_amount',
- \Magento\Framework\DB\Ddl\Table::TYPE_DECIMAL,
- [12, 4],
- ['nullable' => false, 'default' => '0.0000'],
- 'Total Amount'
- )->addColumn(
- 'rule_name',
- \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
- 255,
- [],
- 'Rule Name'
- )->addIndex(
- $installer->getIdxName(
- 'salesrule_coupon_aggregated_order',
- ['period', 'store_id', 'order_status', 'coupon_code'],
- \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE
- ),
- ['period', 'store_id', 'order_status', 'coupon_code'],
- ['type' => \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE]
- )->addIndex(
- $installer->getIdxName('salesrule_coupon_aggregated_order', ['store_id']),
- ['store_id']
- )->addIndex(
- $installer->getIdxName('salesrule_coupon_aggregated_order', ['rule_name']),
- ['rule_name']
- )->addForeignKey(
- $installer->getFkName('salesrule_coupon_aggregated_order', 'store_id', 'store', 'store_id'),
- 'store_id',
- $installer->getTable('store'),
- 'store_id',
- \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
- )->setComment(
- 'Coupon Aggregated Order'
- );
- $installer->getConnection()->createTable($table);
-
- $websitesTable = $installer->getTable('store_website');
- $customerGroupsTable = $installer->getTable('customer_group');
- $rulesWebsitesTable = $installer->getTable('salesrule_website');
- $rulesCustomerGroupsTable = $installer->getTable('salesrule_customer_group');
-
- /**
- * Create table 'salesrule_website' if not exists. This table will be used instead of
- * column website_ids of main catalog rules table
- */
- $table = $installer->getConnection()->newTable(
- $rulesWebsitesTable
- )->addColumn(
- 'rule_id',
- \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
- null,
- ['unsigned' => true, 'nullable' => false, 'primary' => true],
- 'Rule Id'
- )->addColumn(
- 'website_id',
- \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
- null,
- ['unsigned' => true, 'nullable' => false, 'primary' => true],
- 'Website Id'
- )->addIndex(
- $installer->getIdxName('salesrule_website', ['website_id']),
- ['website_id']
- )->addForeignKey(
- $installer->getFkName('salesrule_website', 'rule_id', 'salesrule', 'rule_id'),
- 'rule_id',
- $installer->getTable('salesrule'),
- 'rule_id',
- \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
- )->addForeignKey(
- $installer->getFkName('salesrule_website', 'website_id', 'store_website', 'website_id'),
- 'website_id',
- $websitesTable,
- 'website_id',
- \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
- )->setComment(
- 'Sales Rules To Websites Relations'
- );
-
- $installer->getConnection()->createTable($table);
-
- /**
- * Create table 'salesrule_customer_group' if not exists. This table will be used instead of
- * column customer_group_ids of main catalog rules table
- */
- $table = $installer->getConnection()->newTable(
- $rulesCustomerGroupsTable
- )->addColumn(
- 'rule_id',
- \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
- null,
- ['unsigned' => true, 'nullable' => false, 'primary' => true],
- 'Rule Id'
- )->addColumn(
- 'customer_group_id',
- $customerGroupIdType,
- null,
- ['unsigned' => true, 'nullable' => false, 'primary' => true],
- 'Customer Group Id'
- )->addIndex(
- $installer->getIdxName('salesrule_customer_group', ['customer_group_id']),
- ['customer_group_id']
- )->addForeignKey(
- $installer->getFkName('salesrule_customer_group', 'rule_id', 'salesrule', 'rule_id'),
- 'rule_id',
- $installer->getTable('salesrule'),
- 'rule_id',
- \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
- )->addForeignKey(
- $installer->getFkName(
- 'salesrule_customer_group',
- 'customer_group_id',
- 'customer_group',
- 'customer_group_id'
- ),
- 'customer_group_id',
- $customerGroupsTable,
- 'customer_group_id',
- \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
- )->setComment(
- 'Sales Rules To Customer Groups Relations'
- );
-
- $installer->getConnection()->createTable($table);
-
- $installer->endSetup();
- }
-}
diff --git a/app/code/Magento/SalesRule/Setup/UpgradeSchema.php b/app/code/Magento/SalesRule/Setup/UpgradeSchema.php
deleted file mode 100644
index c39536d121064..0000000000000
--- a/app/code/Magento/SalesRule/Setup/UpgradeSchema.php
+++ /dev/null
@@ -1,53 +0,0 @@
-startSetup();
-
- if (version_compare($context->getVersion(), '2.0.1', '<')) {
- $this->addDefaultValueForDiscountStep($setup);
- }
-
- $setup->endSetup();
- }
-
- /**
- * Add default value of 0 for the discount step column
- * @param SchemaSetupInterface $setup
- * @return void
- */
- private function addDefaultValueForDiscountStep(SchemaSetupInterface $setup)
- {
- $connection = $setup->getConnection();
- $connection->modifyColumn(
- $setup->getTable('salesrule'),
- 'discount_step',
- [
- 'type' => Table::TYPE_INTEGER,
- 'unsigned' => true,
- 'nullable' => false,
- 'default' => '0',
- 'comment' => 'Discount Step',
- ]
- );
- }
-}
diff --git a/app/code/Magento/SalesRule/etc/db_schema.xml b/app/code/Magento/SalesRule/etc/db_schema.xml
new file mode 100644
index 0000000000000..ed205d88d9a2d
--- /dev/null
+++ b/app/code/Magento/SalesRule/etc/db_schema.xml
@@ -0,0 +1,356 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
]]>
+
For support contact support@signifyd.com.]]>
+
+
+
+
+
+
+
+
+
+
+ = $block->escapeHtml(__('Signifyd Guarantee Decision')) ?>
+ = $block->escapeHtml($block->getCaseGuaranteeDisposition()) ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+ {{depend url_about_us}}
+
{{depend store_phone}}
diff --git a/app/design/frontend/Magento/luma/Magento_Newsletter/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_Newsletter/web/css/source/_module.less
index 94d7c7e4e5bff..9ccd6c190ec0e 100644
--- a/app/design/frontend/Magento/luma/Magento_Newsletter/web/css/source/_module.less
+++ b/app/design/frontend/Magento/luma/Magento_Newsletter/web/css/source/_module.less
@@ -67,6 +67,7 @@
border-bottom-left-radius: 0;
border-top-left-radius: 0;
margin-left: -1px;
+ white-space: nowrap;
}
}
}
diff --git a/app/design/frontend/Magento/luma/Magento_Theme/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_Theme/web/css/source/_module.less
index a845a8dce2818..fd004ef2c14d9 100644
--- a/app/design/frontend/Magento/luma/Magento_Theme/web/css/source/_module.less
+++ b/app/design/frontend/Magento/luma/Magento_Theme/web/css/source/_module.less
@@ -333,6 +333,7 @@
.widget.block {
.lib-css(margin, @indent__base 0);
}
+ .links .widget.block { margin: 0; }
}
.no-display:extend(.abs-no-display all) {
diff --git a/app/design/frontend/Magento/luma/etc/view.xml b/app/design/frontend/Magento/luma/etc/view.xml
index f688c232b93c9..349224a34022c 100644
--- a/app/design/frontend/Magento/luma/etc/view.xml
+++ b/app/design/frontend/Magento/luma/etc/view.xml
@@ -12,9 +12,9 @@
+
+" + escapeText( document.title ) + "
" +
- "" +
- "" +
- "" +
- "";
- }
-
- tests = id( "qunit-tests" );
- banner = id( "qunit-banner" );
- result = id( "qunit-testresult" );
-
- if ( tests ) {
- tests.innerHTML = "";
- }
-
- if ( banner ) {
- banner.className = "";
- }
-
- if ( result ) {
- result.parentNode.removeChild( result );
- }
-
- if ( tests ) {
- result = document.createElement( "p" );
- result.id = "qunit-testresult";
- result.className = "result";
- tests.parentNode.insertBefore( result, tests );
- result.innerHTML = "Running...
";
- }
- },
-
- // Resets the test setup. Useful for tests that modify the DOM.
- /*
- DEPRECATED: Use multiple tests instead of resetting inside a test.
- Use testStart or testDone for custom cleanup.
- This method will throw an error in 2.0, and will be removed in 2.1
- */
- reset: function() {
- var fixture = id( "qunit-fixture" );
- if ( fixture ) {
- fixture.innerHTML = config.fixture;
- }
- },
-
- // Safe object type checking
- is: function( type, obj ) {
- return QUnit.objectType( obj ) === type;
- },
-
- objectType: function( obj ) {
- if ( typeof obj === "undefined" ) {
- return "undefined";
- }
-
- // Consider: typeof null === object
- if ( obj === null ) {
- return "null";
- }
-
- var match = toString.call( obj ).match(/^\[object\s(.*)\]$/),
- type = match && match[1] || "";
-
- switch ( type ) {
- case "Number":
- if ( isNaN(obj) ) {
- return "nan";
- }
- return "number";
- case "String":
- case "Boolean":
- case "Array":
- case "Date":
- case "RegExp":
- case "Function":
- return type.toLowerCase();
- }
- if ( typeof obj === "object" ) {
- return "object";
- }
- return undefined;
- },
-
- push: function( result, actual, expected, message ) {
- if ( !config.current ) {
- throw new Error( "assertion outside test context, was " + sourceFromStacktrace() );
- }
-
- var output, source,
- details = {
- module: config.current.module,
- name: config.current.testName,
- result: result,
- message: message,
- actual: actual,
- expected: expected
- };
-
- message = escapeText( message ) || ( result ? "okay" : "failed" );
- message = "" + message + "";
- output = message;
-
- if ( !result ) {
- expected = escapeText( QUnit.jsDump.parse(expected) );
- actual = escapeText( QUnit.jsDump.parse(actual) );
- output += "
";
- }
-
- runLoggingCallbacks( "log", QUnit, details );
-
- config.current.assertions.push({
- result: !!result,
- message: output
- });
- },
-
- pushFailure: function( message, source, actual ) {
- if ( !config.current ) {
- throw new Error( "pushFailure() assertion outside test context, was " + sourceFromStacktrace(2) );
- }
-
- var output,
- details = {
- module: config.current.module,
- name: config.current.testName,
- result: false,
- message: message
- };
-
- message = escapeText( message ) || "error";
- message = "" + message + "";
- output = message;
-
- output += " ";
-
- if ( actual !== expected ) {
- output += "Expected: " + expected + "
";
- output += "Result: " + actual + "
";
- }
-
- source = sourceFromStacktrace();
-
- if ( source ) {
- details.source = source;
- output += "Diff: " + QUnit.diff( expected, actual ) + "
";
- }
-
- output += "Source: " + escapeText( source ) + "
";
-
- if ( actual ) {
- output += "
";
-
- runLoggingCallbacks( "log", QUnit, details );
-
- config.current.assertions.push({
- result: false,
- message: output
- });
- },
-
- url: function( params ) {
- params = extend( extend( {}, QUnit.urlParams ), params );
- var key,
- querystring = "?";
-
- for ( key in params ) {
- if ( hasOwn.call( params, key ) ) {
- querystring += encodeURIComponent( key ) + "=" +
- encodeURIComponent( params[ key ] ) + "&";
- }
- }
- return window.location.protocol + "//" + window.location.host +
- window.location.pathname + querystring.slice( 0, -1 );
- },
-
- extend: extend,
- id: id,
- addEvent: addEvent,
- addClass: addClass,
- hasClass: hasClass,
- removeClass: removeClass
- // load, equiv, jsDump, diff: Attached later
-});
-
-/**
- * @deprecated: Created for backwards compatibility with test runner that set the hook function
- * into QUnit.{hook}, instead of invoking it and passing the hook function.
- * QUnit.constructor is set to the empty F() above so that we can add to it's prototype here.
- * Doing this allows us to tell if the following methods have been overwritten on the actual
- * QUnit object.
- */
-extend( QUnit.constructor.prototype, {
-
- // Logging callbacks; all receive a single argument with the listed properties
- // run test/logs.html for any related changes
- begin: registerLoggingCallback( "begin" ),
-
- // done: { failed, passed, total, runtime }
- done: registerLoggingCallback( "done" ),
-
- // log: { result, actual, expected, message }
- log: registerLoggingCallback( "log" ),
-
- // testStart: { name }
- testStart: registerLoggingCallback( "testStart" ),
-
- // testDone: { name, failed, passed, total, runtime }
- testDone: registerLoggingCallback( "testDone" ),
-
- // moduleStart: { name }
- moduleStart: registerLoggingCallback( "moduleStart" ),
-
- // moduleDone: { name, failed, passed, total }
- moduleDone: registerLoggingCallback( "moduleDone" )
-});
-
-if ( !defined.document || document.readyState === "complete" ) {
- config.autorun = true;
-}
-
-QUnit.load = function() {
- runLoggingCallbacks( "begin", QUnit, {} );
-
- // Initialize the config, saving the execution queue
- var banner, filter, i, j, label, len, main, ol, toolbar, val, selection,
- urlConfigContainer, moduleFilter, userAgent,
- numModules = 0,
- moduleNames = [],
- moduleFilterHtml = "",
- urlConfigHtml = "",
- oldconfig = extend( {}, config );
-
- QUnit.init();
- extend(config, oldconfig);
-
- config.blocking = false;
-
- len = config.urlConfig.length;
-
- for ( i = 0; i < len; i++ ) {
- val = config.urlConfig[i];
- if ( typeof val === "string" ) {
- val = {
- id: val,
- label: val
- };
- }
- config[ val.id ] = QUnit.urlParams[ val.id ];
- if ( !val.value || typeof val.value === "string" ) {
- urlConfigHtml += "";
- } else {
- urlConfigHtml += "";
- }
- }
- for ( i in config.modules ) {
- if ( config.modules.hasOwnProperty( i ) ) {
- moduleNames.push(i);
- }
- }
- numModules = moduleNames.length;
- moduleNames.sort( function( a, b ) {
- return a.localeCompare( b );
- });
- moduleFilterHtml += "";
-
- // `userAgent` initialized at top of scope
- userAgent = id( "qunit-userAgent" );
- if ( userAgent ) {
- userAgent.innerHTML = navigator.userAgent;
- }
-
- // `banner` initialized at top of scope
- banner = id( "qunit-header" );
- if ( banner ) {
- banner.innerHTML = "" + banner.innerHTML + " ";
- }
-
- // `toolbar` initialized at top of scope
- toolbar = id( "qunit-testrunner-toolbar" );
- if ( toolbar ) {
- // `filter` initialized at top of scope
- filter = document.createElement( "input" );
- filter.type = "checkbox";
- filter.id = "qunit-filter-pass";
-
- addEvent( filter, "click", function() {
- var tmp,
- ol = id( "qunit-tests" );
-
- if ( filter.checked ) {
- ol.className = ol.className + " hidepass";
- } else {
- tmp = " " + ol.className.replace( /[\n\t\r]/g, " " ) + " ";
- ol.className = tmp.replace( / hidepass /, " " );
- }
- if ( defined.sessionStorage ) {
- if (filter.checked) {
- sessionStorage.setItem( "qunit-filter-passed-tests", "true" );
- } else {
- sessionStorage.removeItem( "qunit-filter-passed-tests" );
- }
- }
- });
-
- if ( config.hidepassed || defined.sessionStorage && sessionStorage.getItem( "qunit-filter-passed-tests" ) ) {
- filter.checked = true;
- // `ol` initialized at top of scope
- ol = id( "qunit-tests" );
- ol.className = ol.className + " hidepass";
- }
- toolbar.appendChild( filter );
-
- // `label` initialized at top of scope
- label = document.createElement( "label" );
- label.setAttribute( "for", "qunit-filter-pass" );
- label.setAttribute( "title", "Only show tests and assertions that fail. Stored in sessionStorage." );
- label.innerHTML = "Hide passed tests";
- toolbar.appendChild( label );
-
- urlConfigContainer = document.createElement("span");
- urlConfigContainer.innerHTML = urlConfigHtml;
- // For oldIE support:
- // * Add handlers to the individual elements instead of the container
- // * Use "click" instead of "change" for checkboxes
- // * Fallback from event.target to event.srcElement
- addEvents( urlConfigContainer.getElementsByTagName("input"), "click", function( event ) {
- var params = {},
- target = event.target || event.srcElement;
- params[ target.name ] = target.checked ?
- target.defaultValue || true :
- undefined;
- window.location = QUnit.url( params );
- });
- addEvents( urlConfigContainer.getElementsByTagName("select"), "change", function( event ) {
- var params = {},
- target = event.target || event.srcElement;
- params[ target.name ] = target.options[ target.selectedIndex ].value || undefined;
- window.location = QUnit.url( params );
- });
- toolbar.appendChild( urlConfigContainer );
-
- if (numModules > 1) {
- moduleFilter = document.createElement( "span" );
- moduleFilter.setAttribute( "id", "qunit-modulefilter-container" );
- moduleFilter.innerHTML = moduleFilterHtml;
- addEvent( moduleFilter.lastChild, "change", function() {
- var selectBox = moduleFilter.getElementsByTagName("select")[0],
- selectedModule = decodeURIComponent(selectBox.options[selectBox.selectedIndex].value);
-
- window.location = QUnit.url({
- module: ( selectedModule === "" ) ? undefined : selectedModule,
- // Remove any existing filters
- filter: undefined,
- testNumber: undefined
- });
- });
- toolbar.appendChild(moduleFilter);
- }
- }
-
- // `main` initialized at top of scope
- main = id( "qunit-fixture" );
- if ( main ) {
- config.fixture = main.innerHTML;
- }
-
- if ( config.autostart ) {
- QUnit.start();
- }
-};
-
-if ( defined.document ) {
- addEvent( window, "load", QUnit.load );
-}
-
-// `onErrorFnPrev` initialized at top of scope
-// Preserve other handlers
-onErrorFnPrev = window.onerror;
-
-// Cover uncaught exceptions
-// Returning true will suppress the default browser handler,
-// returning false will let it run.
-window.onerror = function ( error, filePath, linerNr ) {
- var ret = false;
- if ( onErrorFnPrev ) {
- ret = onErrorFnPrev( error, filePath, linerNr );
- }
-
- // Treat return value as window.onerror itself does,
- // Only do our handling if not suppressed.
- if ( ret !== true ) {
- if ( QUnit.config.current ) {
- if ( QUnit.config.current.ignoreGlobalErrors ) {
- return true;
- }
- QUnit.pushFailure( error, filePath + ":" + linerNr );
- } else {
- QUnit.test( "global failure", extend( function() {
- QUnit.pushFailure( error, filePath + ":" + linerNr );
- }, { validTest: validTest } ) );
- }
- return false;
- }
-
- return ret;
-};
-
-function done() {
- config.autorun = true;
-
- // Log the last module results
- if ( config.previousModule ) {
- runLoggingCallbacks( "moduleDone", QUnit, {
- name: config.previousModule,
- failed: config.moduleStats.bad,
- passed: config.moduleStats.all - config.moduleStats.bad,
- total: config.moduleStats.all
- });
- }
- delete config.previousModule;
-
- var i, key,
- banner = id( "qunit-banner" ),
- tests = id( "qunit-tests" ),
- runtime = +new Date() - config.started,
- passed = config.stats.all - config.stats.bad,
- html = [
- "Tests completed in ",
- runtime,
- " milliseconds. ";
- }
-
- if ( source ) {
- details.source = source;
- output += "Result: " + escapeText( actual ) + "
";
- }
-
- output += "Source: " + escapeText( source ) + "
",
- "",
- passed,
- " assertions of ",
- config.stats.all,
- " passed, ",
- config.stats.bad,
- " failed."
- ].join( "" );
-
- if ( banner ) {
- banner.className = ( config.stats.bad ? "qunit-fail" : "qunit-pass" );
- }
-
- if ( tests ) {
- id( "qunit-testresult" ).innerHTML = html;
- }
-
- if ( config.altertitle && defined.document && document.title ) {
- // show ✖ for good, ✔ for bad suite result in title
- // use escape sequences in case file gets loaded with non-utf-8-charset
- document.title = [
- ( config.stats.bad ? "\u2716" : "\u2714" ),
- document.title.replace( /^[\u2714\u2716] /i, "" )
- ].join( " " );
- }
-
- // clear own sessionStorage items if all tests passed
- if ( config.reorder && defined.sessionStorage && config.stats.bad === 0 ) {
- // `key` & `i` initialized at top of scope
- for ( i = 0; i < sessionStorage.length; i++ ) {
- key = sessionStorage.key( i++ );
- if ( key.indexOf( "qunit-test-" ) === 0 ) {
- sessionStorage.removeItem( key );
- }
- }
- }
-
- // scroll back to top to show results
- if ( config.scrolltop && window.scrollTo ) {
- window.scrollTo(0, 0);
- }
-
- runLoggingCallbacks( "done", QUnit, {
- failed: config.stats.bad,
- passed: passed,
- total: config.stats.all,
- runtime: runtime
- });
-}
-
-/** @return Boolean: true if this test should be ran */
-function validTest( test ) {
- var include,
- filter = config.filter && config.filter.toLowerCase(),
- module = config.module && config.module.toLowerCase(),
- fullName = ( test.module + ": " + test.testName ).toLowerCase();
-
- // Internally-generated tests are always valid
- if ( test.callback && test.callback.validTest === validTest ) {
- delete test.callback.validTest;
- return true;
- }
-
- if ( config.testNumber.length > 0 ) {
- if ( inArray( test.testNumber, config.testNumber ) < 0 ) {
- return false;
- }
- }
-
- if ( module && ( !test.module || test.module.toLowerCase() !== module ) ) {
- return false;
- }
-
- if ( !filter ) {
- return true;
- }
-
- include = filter.charAt( 0 ) !== "!";
- if ( !include ) {
- filter = filter.slice( 1 );
- }
-
- // If the filter matches, we need to honour include
- if ( fullName.indexOf( filter ) !== -1 ) {
- return include;
- }
-
- // Otherwise, do the opposite
- return !include;
-}
-
-// so far supports only Firefox, Chrome and Opera (buggy), Safari (for real exceptions)
-// Later Safari and IE10 are supposed to support error.stack as well
-// See also https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error/Stack
-function extractStacktrace( e, offset ) {
- offset = offset === undefined ? 3 : offset;
-
- var stack, include, i;
-
- if ( e.stacktrace ) {
- // Opera
- return e.stacktrace.split( "\n" )[ offset + 3 ];
- } else if ( e.stack ) {
- // Firefox, Chrome
- stack = e.stack.split( "\n" );
- if (/^error$/i.test( stack[0] ) ) {
- stack.shift();
- }
- if ( fileName ) {
- include = [];
- for ( i = offset; i < stack.length; i++ ) {
- if ( stack[ i ].indexOf( fileName ) !== -1 ) {
- break;
- }
- include.push( stack[ i ] );
- }
- if ( include.length ) {
- return include.join( "\n" );
- }
- }
- return stack[ offset ];
- } else if ( e.sourceURL ) {
- // Safari, PhantomJS
- // hopefully one day Safari provides actual stacktraces
- // exclude useless self-reference for generated Error objects
- if ( /qunit.js$/.test( e.sourceURL ) ) {
- return;
- }
- // for actual exceptions, this is useful
- return e.sourceURL + ":" + e.line;
- }
-}
-function sourceFromStacktrace( offset ) {
- try {
- throw new Error();
- } catch ( e ) {
- return extractStacktrace( e, offset );
- }
-}
-
-/**
- * Escape text for attribute or text content.
- */
-function escapeText( s ) {
- if ( !s ) {
- return "";
- }
- s = s + "";
- // Both single quotes and double quotes (for attributes)
- return s.replace( /['"<>&]/g, function( s ) {
- switch( s ) {
- case "'":
- return "'";
- case "\"":
- return """;
- case "<":
- return "<";
- case ">":
- return ">";
- case "&":
- return "&";
- }
- });
-}
-
-function synchronize( callback, last ) {
- config.queue.push( callback );
-
- if ( config.autorun && !config.blocking ) {
- process( last );
- }
-}
-
-function process( last ) {
- function next() {
- process( last );
- }
- var start = new Date().getTime();
- config.depth = config.depth ? config.depth + 1 : 1;
-
- while ( config.queue.length && !config.blocking ) {
- if ( !defined.setTimeout || config.updateRate <= 0 || ( ( new Date().getTime() - start ) < config.updateRate ) ) {
- config.queue.shift()();
- } else {
- setTimeout( next, 13 );
- break;
- }
- }
- config.depth--;
- if ( last && !config.blocking && !config.queue.length && config.depth === 0 ) {
- done();
- }
-}
-
-function saveGlobal() {
- config.pollution = [];
-
- if ( config.noglobals ) {
- for ( var key in window ) {
- if ( hasOwn.call( window, key ) ) {
- // in Opera sometimes DOM element ids show up here, ignore them
- if ( /^qunit-test-output/.test( key ) ) {
- continue;
- }
- config.pollution.push( key );
- }
- }
- }
-}
-
-function checkPollution() {
- var newGlobals,
- deletedGlobals,
- old = config.pollution;
-
- saveGlobal();
-
- newGlobals = diff( config.pollution, old );
- if ( newGlobals.length > 0 ) {
- QUnit.pushFailure( "Introduced global variable(s): " + newGlobals.join(", ") );
- }
-
- deletedGlobals = diff( old, config.pollution );
- if ( deletedGlobals.length > 0 ) {
- QUnit.pushFailure( "Deleted global variable(s): " + deletedGlobals.join(", ") );
- }
-}
-
-// returns a new Array with the elements that are in a but not in b
-function diff( a, b ) {
- var i, j,
- result = a.slice();
-
- for ( i = 0; i < result.length; i++ ) {
- for ( j = 0; j < b.length; j++ ) {
- if ( result[i] === b[j] ) {
- result.splice( i, 1 );
- i--;
- break;
- }
- }
- }
- return result;
-}
-
-function extend( a, b ) {
- for ( var prop in b ) {
- if ( hasOwn.call( b, prop ) ) {
- // Avoid "Member not found" error in IE8 caused by messing with window.constructor
- if ( !( prop === "constructor" && a === window ) ) {
- if ( b[ prop ] === undefined ) {
- delete a[ prop ];
- } else {
- a[ prop ] = b[ prop ];
- }
- }
- }
- }
-
- return a;
-}
-
-/**
- * @param {HTMLElement} elem
- * @param {string} type
- * @param {Function} fn
- */
-function addEvent( elem, type, fn ) {
- if ( elem.addEventListener ) {
-
- // Standards-based browsers
- elem.addEventListener( type, fn, false );
- } else if ( elem.attachEvent ) {
-
- // support: IE <9
- elem.attachEvent( "on" + type, fn );
- } else {
-
- // Caller must ensure support for event listeners is present
- throw new Error( "addEvent() was called in a context without event listener support" );
- }
-}
-
-/**
- * @param {Array|NodeList} elems
- * @param {string} type
- * @param {Function} fn
- */
-function addEvents( elems, type, fn ) {
- var i = elems.length;
- while ( i-- ) {
- addEvent( elems[i], type, fn );
- }
-}
-
-function hasClass( elem, name ) {
- return (" " + elem.className + " ").indexOf(" " + name + " ") > -1;
-}
-
-function addClass( elem, name ) {
- if ( !hasClass( elem, name ) ) {
- elem.className += (elem.className ? " " : "") + name;
- }
-}
-
-function removeClass( elem, name ) {
- var set = " " + elem.className + " ";
- // Class name may appear multiple times
- while ( set.indexOf(" " + name + " ") > -1 ) {
- set = set.replace(" " + name + " " , " ");
- }
- // If possible, trim it for prettiness, but not necessarily
- elem.className = typeof set.trim === "function" ? set.trim() : set.replace(/^\s+|\s+$/g, "");
-}
-
-function id( name ) {
- return defined.document && document.getElementById && document.getElementById( name );
-}
-
-function registerLoggingCallback( key ) {
- return function( callback ) {
- config[key].push( callback );
- };
-}
-
-// Supports deprecated method of completely overwriting logging callbacks
-function runLoggingCallbacks( key, scope, args ) {
- var i, callbacks;
- if ( QUnit.hasOwnProperty( key ) ) {
- QUnit[ key ].call(scope, args );
- } else {
- callbacks = config[ key ];
- for ( i = 0; i < callbacks.length; i++ ) {
- callbacks[ i ].call( scope, args );
- }
- }
-}
-
-// from jquery.js
-function inArray( elem, array ) {
- if ( array.indexOf ) {
- return array.indexOf( elem );
- }
-
- for ( var i = 0, length = array.length; i < length; i++ ) {
- if ( array[ i ] === elem ) {
- return i;
- }
- }
-
- return -1;
-}
-
-function Test( settings ) {
- extend( this, settings );
- this.assertions = [];
- this.testNumber = ++Test.count;
-}
-
-Test.count = 0;
-
-Test.prototype = {
- init: function() {
- var a, b, li,
- tests = id( "qunit-tests" );
-
- if ( tests ) {
- b = document.createElement( "strong" );
- b.innerHTML = this.nameHtml;
-
- // `a` initialized at top of scope
- a = document.createElement( "a" );
- a.innerHTML = "Rerun";
- a.href = QUnit.url({ testNumber: this.testNumber });
-
- li = document.createElement( "li" );
- li.appendChild( b );
- li.appendChild( a );
- li.className = "running";
- li.id = this.id = "qunit-test-output" + testId++;
-
- tests.appendChild( li );
- }
- },
- setup: function() {
- if (
- // Emit moduleStart when we're switching from one module to another
- this.module !== config.previousModule ||
- // They could be equal (both undefined) but if the previousModule property doesn't
- // yet exist it means this is the first test in a suite that isn't wrapped in a
- // module, in which case we'll just emit a moduleStart event for 'undefined'.
- // Without this, reporters can get testStart before moduleStart which is a problem.
- !hasOwn.call( config, "previousModule" )
- ) {
- if ( hasOwn.call( config, "previousModule" ) ) {
- runLoggingCallbacks( "moduleDone", QUnit, {
- name: config.previousModule,
- failed: config.moduleStats.bad,
- passed: config.moduleStats.all - config.moduleStats.bad,
- total: config.moduleStats.all
- });
- }
- config.previousModule = this.module;
- config.moduleStats = { all: 0, bad: 0 };
- runLoggingCallbacks( "moduleStart", QUnit, {
- name: this.module
- });
- }
-
- config.current = this;
-
- this.testEnvironment = extend({
- setup: function() {},
- teardown: function() {}
- }, this.moduleTestEnvironment );
-
- this.started = +new Date();
- runLoggingCallbacks( "testStart", QUnit, {
- name: this.testName,
- module: this.module
- });
-
- /*jshint camelcase:false */
-
-
- /**
- * Expose the current test environment.
- *
- * @deprecated since 1.12.0: Use QUnit.config.current.testEnvironment instead.
- */
- QUnit.current_testEnvironment = this.testEnvironment;
-
- /*jshint camelcase:true */
-
- if ( !config.pollution ) {
- saveGlobal();
- }
- if ( config.notrycatch ) {
- this.testEnvironment.setup.call( this.testEnvironment, QUnit.assert );
- return;
- }
- try {
- this.testEnvironment.setup.call( this.testEnvironment, QUnit.assert );
- } catch( e ) {
- QUnit.pushFailure( "Setup failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 1 ) );
- }
- },
- run: function() {
- config.current = this;
-
- var running = id( "qunit-testresult" );
-
- if ( running ) {
- running.innerHTML = "Running:
" + this.nameHtml;
- }
-
- if ( this.async ) {
- QUnit.stop();
- }
-
- this.callbackStarted = +new Date();
-
- if ( config.notrycatch ) {
- this.callback.call( this.testEnvironment, QUnit.assert );
- this.callbackRuntime = +new Date() - this.callbackStarted;
- return;
- }
-
- try {
- this.callback.call( this.testEnvironment, QUnit.assert );
- this.callbackRuntime = +new Date() - this.callbackStarted;
- } catch( e ) {
- this.callbackRuntime = +new Date() - this.callbackStarted;
-
- QUnit.pushFailure( "Died on test #" + (this.assertions.length + 1) + " " + this.stack + ": " + ( e.message || e ), extractStacktrace( e, 0 ) );
- // else next test will carry the responsibility
- saveGlobal();
-
- // Restart the tests if they're blocking
- if ( config.blocking ) {
- QUnit.start();
- }
- }
- },
- teardown: function() {
- config.current = this;
- if ( config.notrycatch ) {
- if ( typeof this.callbackRuntime === "undefined" ) {
- this.callbackRuntime = +new Date() - this.callbackStarted;
- }
- this.testEnvironment.teardown.call( this.testEnvironment, QUnit.assert );
- return;
- } else {
- try {
- this.testEnvironment.teardown.call( this.testEnvironment, QUnit.assert );
- } catch( e ) {
- QUnit.pushFailure( "Teardown failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 1 ) );
- }
- }
- checkPollution();
- },
- finish: function() {
- config.current = this;
- if ( config.requireExpects && this.expected === null ) {
- QUnit.pushFailure( "Expected number of assertions to be defined, but expect() was not called.", this.stack );
- } else if ( this.expected !== null && this.expected !== this.assertions.length ) {
- QUnit.pushFailure( "Expected " + this.expected + " assertions, but " + this.assertions.length + " were run", this.stack );
- } else if ( this.expected === null && !this.assertions.length ) {
- QUnit.pushFailure( "Expected at least one assertion, but none were run - call expect(0) to accept zero assertions.", this.stack );
- }
-
- var i, assertion, a, b, time, li, ol,
- test = this,
- good = 0,
- bad = 0,
- tests = id( "qunit-tests" );
-
- this.runtime = +new Date() - this.started;
- config.stats.all += this.assertions.length;
- config.moduleStats.all += this.assertions.length;
-
- if ( tests ) {
- ol = document.createElement( "ol" );
- ol.className = "qunit-assert-list";
-
- for ( i = 0; i < this.assertions.length; i++ ) {
- assertion = this.assertions[i];
-
- li = document.createElement( "li" );
- li.className = assertion.result ? "pass" : "fail";
- li.innerHTML = assertion.message || ( assertion.result ? "okay" : "failed" );
- ol.appendChild( li );
-
- if ( assertion.result ) {
- good++;
- } else {
- bad++;
- config.stats.bad++;
- config.moduleStats.bad++;
- }
- }
-
- // store result when possible
- if ( QUnit.config.reorder && defined.sessionStorage ) {
- if ( bad ) {
- sessionStorage.setItem( "qunit-test-" + this.module + "-" + this.testName, bad );
- } else {
- sessionStorage.removeItem( "qunit-test-" + this.module + "-" + this.testName );
- }
- }
-
- if ( bad === 0 ) {
- addClass( ol, "qunit-collapsed" );
- }
-
- // `b` initialized at top of scope
- b = document.createElement( "strong" );
- b.innerHTML = this.nameHtml + " (" + bad + ", " + good + ", " + this.assertions.length + ")";
-
- addEvent(b, "click", function() {
- var next = b.parentNode.lastChild,
- collapsed = hasClass( next, "qunit-collapsed" );
- ( collapsed ? removeClass : addClass )( next, "qunit-collapsed" );
- });
-
- addEvent(b, "dblclick", function( e ) {
- var target = e && e.target ? e.target : window.event.srcElement;
- if ( target.nodeName.toLowerCase() === "span" || target.nodeName.toLowerCase() === "b" ) {
- target = target.parentNode;
- }
- if ( window.location && target.nodeName.toLowerCase() === "strong" ) {
- window.location = QUnit.url({ testNumber: test.testNumber });
- }
- });
-
- // `time` initialized at top of scope
- time = document.createElement( "span" );
- time.className = "runtime";
- time.innerHTML = this.runtime + " ms";
-
- // `li` initialized at top of scope
- li = id( this.id );
- li.className = bad ? "fail" : "pass";
- li.removeChild( li.firstChild );
- a = li.firstChild;
- li.appendChild( b );
- li.appendChild( a );
- li.appendChild( time );
- li.appendChild( ol );
-
- } else {
- for ( i = 0; i < this.assertions.length; i++ ) {
- if ( !this.assertions[i].result ) {
- bad++;
- config.stats.bad++;
- config.moduleStats.bad++;
- }
- }
- }
-
- runLoggingCallbacks( "testDone", QUnit, {
- name: this.testName,
- module: this.module,
- failed: bad,
- passed: this.assertions.length - bad,
- total: this.assertions.length,
- runtime: this.runtime,
- // DEPRECATED: this property will be removed in 2.0.0, use runtime instead
- duration: this.runtime
- });
-
- QUnit.reset();
-
- config.current = undefined;
- },
-
- queue: function() {
- var bad,
- test = this;
-
- synchronize(function() {
- test.init();
- });
- function run() {
- // each of these can by async
- synchronize(function() {
- test.setup();
- });
- synchronize(function() {
- test.run();
- });
- synchronize(function() {
- test.teardown();
- });
- synchronize(function() {
- test.finish();
- });
- }
-
- // `bad` initialized at top of scope
- // defer when previous test run passed, if storage is available
- bad = QUnit.config.reorder && defined.sessionStorage &&
- +sessionStorage.getItem( "qunit-test-" + this.module + "-" + this.testName );
-
- if ( bad ) {
- run();
- } else {
- synchronize( run, true );
- }
- }
-};
-
-// `assert` initialized at top of scope
-// Assert helpers
-// All of these must either call QUnit.push() or manually do:
-// - runLoggingCallbacks( "log", .. );
-// - config.current.assertions.push({ .. });
-assert = QUnit.assert = {
- /**
- * Asserts rough true-ish result.
- * @name ok
- * @function
- * @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" );
- */
- ok: function( result, msg ) {
- if ( !config.current ) {
- throw new Error( "ok() assertion outside test context, was " + sourceFromStacktrace(2) );
- }
- result = !!result;
- msg = msg || ( result ? "okay" : "failed" );
-
- var source,
- details = {
- module: config.current.module,
- name: config.current.testName,
- result: result,
- message: msg
- };
-
- msg = "" + escapeText( msg ) + "";
-
- if ( !result ) {
- source = sourceFromStacktrace( 2 );
- if ( source ) {
- details.source = source;
- msg += "
";
- }
- }
- runLoggingCallbacks( "log", QUnit, details );
- config.current.assertions.push({
- result: result,
- message: msg
- });
- },
-
- /**
- * Assert that the first two arguments are equal, with an optional message.
- * Prints out both actual and expected values.
- * @name equal
- * @function
- * @example equal( format( "Received {0} bytes.", 2), "Received 2 bytes.", "format() replaces {0} with next argument" );
- */
- equal: function( actual, expected, message ) {
- /*jshint eqeqeq:false */
- QUnit.push( expected == actual, actual, expected, message );
- },
-
- /**
- * @name notEqual
- * @function
- */
- notEqual: function( actual, expected, message ) {
- /*jshint eqeqeq:false */
- QUnit.push( expected != actual, actual, expected, message );
- },
-
- /**
- * @name propEqual
- * @function
- */
- propEqual: function( actual, expected, message ) {
- actual = objectValues(actual);
- expected = objectValues(expected);
- QUnit.push( QUnit.equiv(actual, expected), actual, expected, message );
- },
-
- /**
- * @name notPropEqual
- * @function
- */
- notPropEqual: function( actual, expected, message ) {
- actual = objectValues(actual);
- expected = objectValues(expected);
- QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message );
- },
-
- /**
- * @name deepEqual
- * @function
- */
- deepEqual: function( actual, expected, message ) {
- QUnit.push( QUnit.equiv(actual, expected), actual, expected, message );
- },
-
- /**
- * @name notDeepEqual
- * @function
- */
- notDeepEqual: function( actual, expected, message ) {
- QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message );
- },
-
- /**
- * @name strictEqual
- * @function
- */
- strictEqual: function( actual, expected, message ) {
- QUnit.push( expected === actual, actual, expected, message );
- },
-
- /**
- * @name notStrictEqual
- * @function
- */
- notStrictEqual: function( actual, expected, message ) {
- QUnit.push( expected !== actual, actual, expected, message );
- },
-
- "throws": function( block, expected, message ) {
- var actual,
- expectedOutput = expected,
- ok = false;
-
- // 'expected' is optional
- if ( !message && typeof expected === "string" ) {
- message = expected;
- expected = null;
- }
-
- config.current.ignoreGlobalErrors = true;
- try {
- block.call( config.current.testEnvironment );
- } catch (e) {
- actual = e;
- }
- config.current.ignoreGlobalErrors = false;
-
- if ( actual ) {
-
- // we don't want to validate thrown error
- if ( !expected ) {
- ok = true;
- expectedOutput = null;
-
- // expected is an Error object
- } else if ( expected instanceof Error ) {
- ok = actual instanceof Error &&
- actual.name === expected.name &&
- actual.message === expected.message;
-
- // expected is a regexp
- } else if ( QUnit.objectType( expected ) === "regexp" ) {
- ok = expected.test( errorString( actual ) );
-
- // expected is a string
- } else if ( QUnit.objectType( expected ) === "string" ) {
- ok = expected === errorString( actual );
-
- // expected is a constructor
- } else if ( actual instanceof expected ) {
- ok = true;
-
- // expected is a validation function which returns true is validation passed
- } else if ( expected.call( {}, actual ) === true ) {
- expectedOutput = null;
- ok = true;
- }
-
- QUnit.push( ok, actual, expectedOutput, message );
- } else {
- QUnit.pushFailure( message, null, "No exception was thrown." );
- }
- }
-};
-
-/**
- * @deprecated since 1.8.0
- * Kept assertion helpers in root for backwards compatibility.
- */
-extend( QUnit.constructor.prototype, assert );
-
-/**
- * @deprecated since 1.9.0
- * Kept to avoid TypeErrors for undefined methods.
- */
-QUnit.constructor.prototype.raises = function() {
- QUnit.push( false, false, false, "QUnit.raises has been deprecated since 2012 (fad3c1ea), use QUnit.throws instead" );
-};
-
-/**
- * @deprecated since 1.0.0, replaced with error pushes since 1.3.0
- * Kept to avoid TypeErrors for undefined methods.
- */
-QUnit.constructor.prototype.equals = function() {
- QUnit.push( false, false, false, "QUnit.equals has been deprecated since 2009 (e88049a0), use QUnit.equal instead" );
-};
-QUnit.constructor.prototype.same = function() {
- QUnit.push( false, false, false, "QUnit.same has been deprecated since 2009 (e88049a0), use QUnit.deepEqual instead" );
-};
-
-// Test for equality any JavaScript type.
-// Author: Philippe Rathé Source: " +
- escapeText( source ) +
- "
" : "\n" : this.HTML ? " " : " ";
- },
- // extra can be a number, shortcut for increasing-calling-decreasing
- indent: function( extra ) {
- if ( !this.multiline ) {
- return "";
- }
- var chr = this.indentChar;
- if ( this.HTML ) {
- chr = chr.replace( /\t/g, " " ).replace( / /g, " " );
- }
- return new Array( this.depth + ( extra || 0 ) ).join(chr);
- },
- up: function( a ) {
- this.depth += a || 1;
- },
- down: function( a ) {
- this.depth -= a || 1;
- },
- setParser: function( name, parser ) {
- this.parsers[name] = parser;
- },
- // The next 3 are exposed so you can use them
- quote: quote,
- literal: literal,
- join: join,
- //
- depth: 1,
- // This is the list of parsers, to modify them, use jsDump.setParser
- parsers: {
- window: "[Window]",
- document: "[Document]",
- error: function(error) {
- return "Error(\"" + error.message + "\")";
- },
- unknown: "[Unknown]",
- "null": "null",
- "undefined": "undefined",
- "function": function( fn ) {
- var ret = "function",
- // functions never have name in IE
- name = "name" in fn ? fn.name : (reName.exec(fn) || [])[1];
-
- if ( name ) {
- ret += " " + name;
- }
- ret += "( ";
-
- ret = [ ret, QUnit.jsDump.parse( fn, "functionArgs" ), "){" ].join( "" );
- return join( ret, QUnit.jsDump.parse(fn,"functionCode" ), "}" );
- },
- array: array,
- nodelist: array,
- "arguments": array,
- object: function( map, stack ) {
- /*jshint forin:false */
- var ret = [ ], keys, key, val, i;
- QUnit.jsDump.up();
- keys = [];
- for ( key in map ) {
- keys.push( key );
- }
- keys.sort();
- for ( i = 0; i < keys.length; i++ ) {
- key = keys[ i ];
- val = map[ key ];
- ret.push( QUnit.jsDump.parse( key, "key" ) + ": " + QUnit.jsDump.parse( val, undefined, stack ) );
- }
- QUnit.jsDump.down();
- return join( "{", ret, "}" );
- },
- node: function( node ) {
- var len, i, val,
- open = QUnit.jsDump.HTML ? "<" : "<",
- close = QUnit.jsDump.HTML ? ">" : ">",
- tag = node.nodeName.toLowerCase(),
- ret = open + tag,
- attrs = node.attributes;
-
- if ( attrs ) {
- for ( i = 0, len = attrs.length; i < len; i++ ) {
- val = attrs[i].nodeValue;
- // IE6 includes all attributes in .attributes, even ones not explicitly set.
- // Those have values like undefined, null, 0, false, "" or "inherit".
- if ( val && val !== "inherit" ) {
- ret += " " + attrs[i].nodeName + "=" + QUnit.jsDump.parse( val, "attribute" );
- }
- }
- }
- ret += close;
-
- // Show content of TextNode or CDATASection
- if ( node.nodeType === 3 || node.nodeType === 4 ) {
- ret += node.nodeValue;
- }
-
- return ret + open + "/" + tag + close;
- },
- // function calls it internally, it's the arguments part of the function
- functionArgs: function( fn ) {
- var args,
- l = fn.length;
-
- if ( !l ) {
- return "";
- }
-
- args = new Array(l);
- while ( l-- ) {
- // 97 is 'a'
- args[l] = String.fromCharCode(97+l);
- }
- return " " + args.join( ", " ) + " ";
- },
- // object calls it internally, the key part of an item in a map
- key: quote,
- // function calls it internally, it's the content of the function
- functionCode: "[code]",
- // node calls it internally, it's an html attribute value
- attribute: quote,
- string: quote,
- date: quote,
- regexp: literal,
- number: literal,
- "boolean": literal
- },
- // if true, entities are escaped ( <, >, \t, space and \n )
- HTML: false,
- // indentation unit
- indentChar: " ",
- // if true, items in a collection, are separated by a \n, else just a space.
- multiline: true
- };
-
- return jsDump;
-}());
-
-/*
- * Javascript Diff Algorithm
- * By John Resig (http://ejohn.org/)
- * Modified by Chu Alan "sprite"
- *
- * Released under the MIT license.
- *
- * More Info:
- * http://ejohn.org/projects/javascript-diff-algorithm/
- *
- * Usage: QUnit.diff(expected, actual)
- *
- * QUnit.diff( "the quick brown fox jumped over", "the quick fox jumps over" ) == "the quick brown fox jumped jumps over"
- */
-QUnit.diff = (function() {
- /*jshint eqeqeq:false, eqnull:true */
- function diff( o, n ) {
- var i,
- ns = {},
- os = {};
-
- for ( i = 0; i < n.length; i++ ) {
- if ( !hasOwn.call( ns, n[i] ) ) {
- ns[ n[i] ] = {
- rows: [],
- o: null
- };
- }
- ns[ n[i] ].rows.push( i );
- }
-
- for ( i = 0; i < o.length; i++ ) {
- if ( !hasOwn.call( os, o[i] ) ) {
- os[ o[i] ] = {
- rows: [],
- n: null
- };
- }
- os[ o[i] ].rows.push( i );
- }
-
- for ( i in ns ) {
- if ( hasOwn.call( ns, i ) ) {
- if ( ns[i].rows.length === 1 && hasOwn.call( os, i ) && os[i].rows.length === 1 ) {
- n[ ns[i].rows[0] ] = {
- text: n[ ns[i].rows[0] ],
- row: os[i].rows[0]
- };
- o[ os[i].rows[0] ] = {
- text: o[ os[i].rows[0] ],
- row: ns[i].rows[0]
- };
- }
- }
- }
-
- for ( i = 0; i < n.length - 1; i++ ) {
- if ( n[i].text != null && n[ i + 1 ].text == null && n[i].row + 1 < o.length && o[ n[i].row + 1 ].text == null &&
- n[ i + 1 ] == o[ n[i].row + 1 ] ) {
-
- n[ i + 1 ] = {
- text: n[ i + 1 ],
- row: n[i].row + 1
- };
- o[ n[i].row + 1 ] = {
- text: o[ n[i].row + 1 ],
- row: i + 1
- };
- }
- }
-
- for ( i = n.length - 1; i > 0; i-- ) {
- if ( n[i].text != null && n[ i - 1 ].text == null && n[i].row > 0 && o[ n[i].row - 1 ].text == null &&
- n[ i - 1 ] == o[ n[i].row - 1 ]) {
-
- n[ i - 1 ] = {
- text: n[ i - 1 ],
- row: n[i].row - 1
- };
- o[ n[i].row - 1 ] = {
- text: o[ n[i].row - 1 ],
- row: i - 1
- };
- }
- }
-
- return {
- o: o,
- n: n
- };
- }
-
- return function( o, n ) {
- o = o.replace( /\s+$/, "" );
- n = n.replace( /\s+$/, "" );
-
- var i, pre,
- str = "",
- out = diff( o === "" ? [] : o.split(/\s+/), n === "" ? [] : n.split(/\s+/) ),
- oSpace = o.match(/\s+/g),
- nSpace = n.match(/\s+/g);
-
- if ( oSpace == null ) {
- oSpace = [ " " ];
- }
- else {
- oSpace.push( " " );
- }
-
- if ( nSpace == null ) {
- nSpace = [ " " ];
- }
- else {
- nSpace.push( " " );
- }
-
- if ( out.n.length === 0 ) {
- for ( i = 0; i < out.o.length; i++ ) {
- str += "" + out.o[i] + oSpace[i] + "";
- }
- }
- else {
- if ( out.n[0].text == null ) {
- for ( n = 0; n < out.o.length && out.o[n].text == null; n++ ) {
- str += "" + out.o[n] + oSpace[n] + "";
- }
- }
-
- for ( i = 0; i < out.n.length; i++ ) {
- if (out.n[i].text == null) {
- str += "" + out.n[i] + nSpace[i] + "";
- }
- else {
- // `pre` initialized at top of scope
- pre = "";
-
- for ( n = out.n[i].row + 1; n < out.o.length && out.o[n].text == null; n++ ) {
- pre += "" + out.o[n] + oSpace[n] + "";
- }
- str += " " + out.n[i].text + nSpace[i] + pre;
- }
- }
- }
-
- return str;
- };
-}());
-
-// For browser, export only select globals
-if ( typeof window !== "undefined" ) {
- extend( window, QUnit.constructor.prototype );
- window.QUnit = QUnit;
-}
-
-// For CommonJS environments, export everything
-if ( typeof module !== "undefined" && module.exports ) {
- module.exports = QUnit;
-}
-
-
-// Get a reference to the global object, like window in browsers
-}( (function() {
- return this;
-})() ));
diff --git a/dev/tests/js/JsTestDriver/framework/requirejs-util.js b/dev/tests/js/JsTestDriver/framework/requirejs-util.js
deleted file mode 100644
index b9d6b833d36af..0000000000000
--- a/dev/tests/js/JsTestDriver/framework/requirejs-util.js
+++ /dev/null
@@ -1,53 +0,0 @@
-/**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-(function ($, window) {
- "use strict";
-
- // List of define() calls with arguments and call stack
- var defineCalls = [];
-
- // Get current call stack, including script path information
- var getFileStack = function() {
- try {
- throw new Error();
- } catch (e) {
- if (!e.stack) {
- throw new Error('The browser needs to support Error.stack property');
- }
- return e.stack;
- }
- };
-
- // Intercept RequireJS define() calls, which are performed by AMD scripts upon loading
- window.define = function () {
- var stack = getFileStack();
- defineCalls.push({
- stack: stack,
- args: arguments
- });
- };
-
- window.require = function(dependencies, callback){
- return callback && callback();
- };
-
- // Exposed interface
- var requirejsUtil = {
- getDefineArgsInScript: function (scriptPath) {
- var result;
- for (var i = 0; i < defineCalls.length; i++) {
- if (defineCalls[i].stack.indexOf(scriptPath) >= 0) {
- result = defineCalls[i].args;
- break;
- }
- }
- return result;
- }
- };
-
- window.jsunit = window.jsunit || {};
- $.extend(window.jsunit, {requirejsUtil: requirejsUtil});
-})(jQuery, window);
diff --git a/dev/tests/js/JsTestDriver/framework/stub.js b/dev/tests/js/JsTestDriver/framework/stub.js
deleted file mode 100644
index c966ab578cac8..0000000000000
--- a/dev/tests/js/JsTestDriver/framework/stub.js
+++ /dev/null
@@ -1,132 +0,0 @@
-/**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-(function ($, window) {
- "use strict";
-
- function wrapMethod(object, property, method, copyProperties) {
- if (!object) {
- throw new TypeError("Should wrap property of object");
- }
-
- if (typeof method != "function") {
- throw new TypeError("Method wrapper should be function");
- }
-
- var wrappedMethod = object[property],
- error;
-
- if ($.type(wrappedMethod) !== 'function') {
- error = new TypeError("Attempted to wrap " + (typeof wrappedMethod) + " property " +
- property + " as function");
- }
-
- if (wrappedMethod.restore) {
- error = new TypeError("Attempted to wrap " + property + " which is already wrapped");
- }
-
- if (error) {
- if (wrappedMethod._stack) {
- error.stack += '\n--------------\n' + wrappedMethod._stack;
- }
- throw error;
- }
-
- // IE 8 does not support hasOwnProperty.
- var owned = object.hasOwnProperty ?
- object.hasOwnProperty(property) :
- Object.prototype.hasOwnProperty.call(object, property);
-
- object[property] = method;
- method.displayName = property;
- // Stack trace which can be used to find what line of code the original method was created on.
- method._stack = (new Error('Stack Trace for original')).stack;
-
- method.restore = function () {
- if (!owned) {
- delete object[property];
- }
- if (object[property] === method) {
- object[property] = wrappedMethod;
- }
- };
-
- if (copyProperties) {
- for (var prop in wrappedMethod) {
- if (!Object.prototype.hasOwnProperty.call(method, prop)) {
- method[prop] = wrappedMethod[prop];
- }
- }
- }
-
- return method;
- }
-
- function stub(object, property, func, copyProperties) {
- if (!!func && typeof func != "function") {
- throw new TypeError("Custom stub should be function");
- }
-
- var wrapper;
-
- if (func) {
- wrapper = func;
- } else {
- wrapper = stub.create();
- }
-
- if (!object && typeof property === "undefined") {
- return stub.create();
- }
-
- if (typeof property === "undefined" && typeof object == "object") {
- for (var prop in object) {
- if (typeof object[prop] === "function") {
- stub(object, prop);
- }
- }
-
- return object;
- }
-
- return wrapMethod(object, property, wrapper, copyProperties);
- }
-
- $.extend(stub, (function () {
- var proto = {
- create: function create() {
- var functionStub = function () {
- functionStub.callCount = functionStub.callCount ? functionStub.callCount + 1 : 1;
- functionStub.lastCallArgs = arguments;
- functionStub.callArgsStack.push(arguments);
- if (functionStub.returnCallback && $.type(functionStub.returnCallback) === 'function') {
- return functionStub.returnCallback.apply(functionStub.returnCallback, arguments);
- } else if (functionStub.returnValue) {
- return functionStub.returnValue;
- }
- };
- $.extend(functionStub, stub);
- functionStub.reset();
- functionStub.displayName = "stub";
- return functionStub;
- },
-
- reset: function() {
- this.callCount = null;
- this.lastCallArgs = [];
- this.callArgsStack = [];
- this.returnValue = null;
- this.returnCallback = null;
- }
- };
-
- return proto;
- }()));
-
- window.jsunit = window.jsunit || {};
- $.extend(window.jsunit, {
- stub: stub
- });
-})(jQuery, window);
diff --git a/dev/tests/js/JsTestDriver/jsTestDriver.php.dist b/dev/tests/js/JsTestDriver/jsTestDriver.php.dist
deleted file mode 100644
index 089e5220f2d8f..0000000000000
--- a/dev/tests/js/JsTestDriver/jsTestDriver.php.dist
+++ /dev/null
@@ -1,35 +0,0 @@
- 'http://localhost:9876',
- 'load' => array(
- '/dev/tests/js/JsTestDriver/framework',
- '/lib/web/mage/webapi.js',
- '/lib/web/mage/validation/validation.js',
- '/lib/web/jquery/jstree/jquery.jstree.js',
- '/lib/web/jquery/jquery-ui-timepicker-addon.js',
- '/lib/web/mage/cookies.js',
- '/lib/web/mage/calendar.js',
- '/lib/web/mage/loader_old.js',
- '/lib/web/mage/edit-trigger.js',
- '/lib/web/mage/translate-inline.js',
- '/lib/web/mage/translate-inline-vde.js',
- '/lib/web/mage/backend/form.js',
- '/lib/web/mage/backend/button.js',
- '/lib/web/mage/backend/tabs.js',
- '/lib/web/mage/backend/menu.js',
- '/lib/web/mage/backend/suggest.js',
- '/lib/web/mage/backend/tree-suggest.js',
- '/lib/web/mage/zoom.js',
- ),
- 'test' => array('/dev/tests/js/JsTestDriver/testsuite'),
- 'JsTestDriver' => '{{path_to_jstestdriver_jar}}'
-);
diff --git a/dev/tests/js/JsTestDriver/jsTestDriverOrder.php b/dev/tests/js/JsTestDriver/jsTestDriverOrder.php
deleted file mode 100644
index 8ee790a281655..0000000000000
--- a/dev/tests/js/JsTestDriver/jsTestDriverOrder.php
+++ /dev/null
@@ -1,25 +0,0 @@
- 0) {
- fwrite($fh, "proxy:" . PHP_EOL);
- foreach ($proxies as $proxy) {
- $proxyServer = sprintf($proxy['server'], $server, normalize(RELATIVE_APP_ROOT));
- fwrite($fh, ' - {matcher: "' . $proxy['matcher'] . '", server: "' . $proxyServer . '"}' . PHP_EOL);
- }
-}
-
-fwrite($fh, "load:" . PHP_EOL);
-foreach ($sortedFiles as $file) {
- if (!in_array($file, $serveFiles)) {
- fwrite($fh, " - " . $file . PHP_EOL);
- }
-}
-
-fwrite($fh, "test:" . PHP_EOL);
-foreach ($testFiles as $file) {
- fwrite($fh, " - " . $file . PHP_EOL);
-}
-
-if (count($serveFiles) > 0) {
- fwrite($fh, "serve:" . PHP_EOL);
- foreach ($serveFiles as $file) {
- fwrite($fh, " - " . $file . PHP_EOL);
- }
-}
-
-fclose($fh);
-
-$testOutput = __DIR__ . '/test-output';
-
-$filesystemAdapter = new \Magento\Framework\Filesystem\Driver\File();
-if ($filesystemAdapter->isExists($testOutput)) {
- $filesystemAdapter->deleteDirectory($testOutput);
-}
-mkdir($testOutput);
-
-$command
- = 'java -jar "' . $jsTestDriver . '" --config "' . $jsTestDriverConf . '" --reset --port ' . $port .
- ' --browser "' . $browser . '" --raiseOnFailure true --tests all --testOutput "' . $testOutput . '"';
-
-echo $command . PHP_EOL;
-
-if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
- system($command);
-} else {
- $commandFile = __DIR__ . '/run_js_tests.sh';
- $fh = fopen($commandFile, 'w');
-
- $shellCommand
- = 'LSOF=`/usr/sbin/lsof -i :' . $port . ' -t`
- if [ "$LSOF" != "" ];
- then
- kill -9 $LSOF
- fi
-
- # Skip Xvfb setup for OS X since there browsers do not support headless display that way
- if [ "$(uname)" != "Darwin" ]; then
- DISPLAY_NUM=99
- ps -ef | egrep "[X]vfb.*:$DISPLAY_NUM"
- if [ $? -eq 0 ] ; then
- pkill Xvfb
- fi
-
- XVFB=`which Xvfb`
- if [ "$?" -eq 1 ];
- then
- echo "Xvfb not found."
- exit 1
- fi
-
- $XVFB :$DISPLAY_NUM -nolisten inet6 -ac &
- PID_XVFB="$!" # take the process ID
- export DISPLAY=:$DISPLAY_NUM # set display to use that of the Xvfb
- fi
-
- USER=`whoami`
- SUDO=`which sudo`
-
- # run the tests
- $SUDO -u $USER ' . $command . '
-
- if [ "$(uname)" != "Darwin" ]; then
- kill -9 $PID_XVFB # shut down Xvfb (firefox will shut down cleanly by JsTestDriver)
- fi
- echo "Done."';
-
- fwrite($fh, $shellCommand . PHP_EOL);
- fclose($fh);
- chmod($commandFile, 0750);
-
- exec($commandFile);
-}
-
-/**
- * Show a message that displays how to use (invoke) this PHP script and exit.
- */
-function showUsage()
-{
- reportError('Usage: php run_js_tests.php');
-}
-
-/**
- * Reports an error given an error message and exits, effectively halting the PHP script's execution.
- *
- * @param string $message - Error message to be displayed to the user.
- *
- * @SuppressWarnings(PHPMD.ExitExpression)
- */
-function reportError($message)
-{
- echo $message . PHP_EOL;
- exit(1);
-}
-
-/**
- * Takes a file or directory path in any form and normalizes it to fully absolute canonical form
- * relative to this PHP script's location.
- *
- * @param string $filePath - File or directory path to be fully normalized to canonical form.
- *
- * @return string - The fully resolved path converted to absolute form.
- */
-function normalize($filePath)
-{
- return str_replace('\\', '/', realpath(__DIR__ . '/' . $filePath));
-}
-
-/**
- * Accepts an array of directories and generates a list of Javascript files (.js) in those directories and
- * all subdirectories recursively.
- *
- * @param array $dirs - An array of directories as specified in the configuration file (i.e. $configFile).
- *
- * @return array - An array of directory paths to all Javascript files found by recursively searching the
- * specified array of directories.
- */
-function listFiles($dirs)
-{
- $baseDir = normalize(RELATIVE_APP_ROOT);
- $result = [];
- foreach ($dirs as $dir) {
- $path = $baseDir . $dir;
- if (is_file($path)) {
- $path = substr_replace($path, RELATIVE_APP_ROOT, 0, strlen($baseDir));
- array_push($result, $path);
- } else {
- $paths = glob($path . '/*', GLOB_ONLYDIR | GLOB_NOSORT);
- $paths = substr_replace($paths, '', 0, strlen($baseDir));
- $result = array_merge($result, listFiles($paths));
-
- $files = glob($path . '/*.js', GLOB_NOSORT);
- $files = substr_replace($files, RELATIVE_APP_ROOT, 0, strlen($baseDir));
- $result = array_merge($result, $files);
- }
- }
- return $result;
-}
diff --git a/dev/tests/js/JsTestDriver/testsuite/lib/ko/datepicker/datepicker.js b/dev/tests/js/JsTestDriver/testsuite/lib/ko/datepicker/datepicker.js
deleted file mode 100644
index 267c5d3df9a91..0000000000000
--- a/dev/tests/js/JsTestDriver/testsuite/lib/ko/datepicker/datepicker.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-test('DatepickerBinding', function () {
- expect(1);
-
- var element = $('#datepicker'),
- observable = ko.observable(),
- openBtn,
- todayBtn,
- todayDate,
- dateFormat,
- result;
-
- ko.applyBindingsToNode(element, {
- datepicker: observable
- });
-
- dateFormat = $(element).datepicker('option', 'dateFormat');
- todayDate = moment().format(dateFormat);
-
- btn = $('img.ui-datepicker-trigger');
- todayBtn = $('[data-handler="today"]');
-
- btn.click();
- todayBtn.click();
-
- result = moment(observable()).format(dateFormat);
-
- equal(todayDate, result);
-});
diff --git a/dev/tests/js/JsTestDriver/testsuite/lib/ko/datepicker/index.html b/dev/tests/js/JsTestDriver/testsuite/lib/ko/datepicker/index.html
deleted file mode 100644
index e66e34da43945..0000000000000
--- a/dev/tests/js/JsTestDriver/testsuite/lib/ko/datepicker/index.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
- */
- var list = $('#list');
- list.decorate('list');
- assertTrue($(list.find('li')[0]).hasClass('odd'));
- assertFalse($(list.find('li')[0]).hasClass('even'));
- assertTrue($(list.find('li')[1]).hasClass('even'));
- assertFalse($(list.find('li')[1]).hasClass('odd'));
- assertTrue($(list.find('li')[2]).hasClass('odd'));
- assertFalse($(list.find('li')[2]).hasClass('even'));
- assertTrue($(list.find('li')[3]).hasClass('even'));
- assertFalse($(list.find('li')[3]).hasClass('odd'));
- assertTrue($(list.find('li')[3]).hasClass('last'));
-};
-
-DecoratorTest.prototype.testDecoratorGeneral = function () {
- /*:DOC +=
-
-
- */
- var tableId = '#foo';
- $(tableId).decorate('table');
- assertTrue($(tableId).find('thead tr').hasClass('first'));
- assertTrue($(tableId).find('thead tr').hasClass('last'));
- assertFalse($(tableId).find('thead tr').hasClass('odd'));
- assertFalse($(tableId).find('thead tr').hasClass('even'));
-
- assertTrue($(tableId).find('tfoot tr').hasClass('first'));
- assertTrue($(tableId).find('tfoot tr').hasClass('last'));
- assertFalse($(tableId).find('tfoot tr').hasClass('odd'));
- assertFalse($(tableId).find('tfoot tr').hasClass('even'));
-
- assertFalse($(tableId).find('tfoot tr td').last().hasClass('first'));
- assertTrue($(tableId).find('tfoot tr td').last().hasClass('last'));
- assertFalse($(tableId).find('tfoot tr td').last().hasClass('odd'));
- assertFalse($(tableId).find('tfoot tr td').last().hasClass('even'));
-
- assertTrue($(tableId).find('tbody tr').first().hasClass('first'));
- assertTrue($(tableId).find('tbody tr').first().hasClass('odd'));
- assertFalse($(tableId).find('tbody tr').first().hasClass('last'));
- assertFalse($(tableId).find('tbody tr').first().hasClass('even'));
- assertFalse($(tableId).find('tbody tr').last().hasClass('first'));
- assertFalse($(tableId).find('tbody tr').last().hasClass('odd'));
- assertTrue($(tableId).find('tbody tr').last().hasClass('last'));
- assertTrue($(tableId).find('tbody tr').last().hasClass('even'));
-
- assertFalse($(tableId).find('tbody tr td').last().hasClass('first'));
- assertFalse($(tableId).find('tbody tr td').last().hasClass('odd'));
- assertTrue($(tableId).find('tbody tr td').last().hasClass('last'));
- assertFalse($(tableId).find('tbody tr td').last().hasClass('even'));
-};
-
-DecoratorTest.prototype.testDecoratorDataList = function () {
- /*:DOC +=
-
-
-
- Month
- Savings
-
-
-
-
- Sum
- $180
-
-
- January
- $100
-
-
-
- February
- $80
-
-
- */
- var listId = '#data-list';
- $(listId).decorate('dataList');
- assertTrue($(listId).find('dt').first().hasClass('odd'));
- assertFalse($(listId).find('dt').first().hasClass('even'));
- assertFalse($(listId).find('dt').first().hasClass('last'));
-
- assertTrue($(listId).find('dt').last().hasClass('even'));
- assertFalse($(listId).find('dt').last().hasClass('odd'));
- assertTrue($(listId).find('dt').last().hasClass('last'));
-
- assertTrue($(listId).find('dd').first().hasClass('odd'));
- assertFalse($(listId).find('dd').first().hasClass('even'));
- assertFalse($(listId).find('dd').first().hasClass('last'));
-
- assertTrue($(listId).find('dd').last().hasClass('even'));
- assertFalse($(listId).find('dd').last().hasClass('odd'));
- assertTrue($(listId).find('dd').last().hasClass('last'));
-};
diff --git a/dev/tests/js/JsTestDriver/testsuite/mage/dropdown/index.html b/dev/tests/js/JsTestDriver/testsuite/mage/dropdown/index.html
deleted file mode 100644
index 3d6ed5a7c1d28..0000000000000
--- a/dev/tests/js/JsTestDriver/testsuite/mage/dropdown/index.html
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
- ');
+
+ $('body').append(list);
+ });
+
+ afterEach(function () {
+ $('#' + listId).remove();
+ });
+
+ it('Check correct class decoration', function () {
+ var $list = $('#' + listId);
+
+ $list.decorate('list');
+ expect($list.find('li:first').hasClass('first')).toBe(false);
+ expect($list.find('li:first').hasClass('odd')).toBe(true);
+ expect($list.find('li:last').hasClass('last')).toBe(true);
+ expect($list.find('li:odd').hasClass('even')).toBe(true);
+ expect($list.find('li:even').hasClass('odd')).toBe(true);
+ });
+ });
+
+ describe('"generic" method', function () {
+ var listId = 'testList';
+
+ beforeEach(function () {
+ var list = $('
');
+
+ $('body').append(list);
+ });
+
+ afterEach(function () {
+ $('#' + listId).remove();
+ });
+
+ it('Check correct class decoration with default params', function () {
+ var $list = $('#' + listId);
+
+ $list.find('li').decorate('generic');
+ expect($list.find('li:first').hasClass('first')).toBe(true);
+ expect($list.find('li:first').hasClass('odd')).toBe(true);
+ expect($list.find('li:last').hasClass('last')).toBe(true);
+ expect($list.find('li:odd').hasClass('even')).toBe(true);
+ expect($list.find('li:even').hasClass('odd')).toBe(true);
+ });
+
+ it('Check correct class decoration with custom params', function () {
+ var $list = $('#' + listId);
+
+ $list.find('li').decorate('generic', ['last', 'first']);
+ expect($list.find('li:first').hasClass('first')).toBe(true);
+ expect($list.find('li:first').hasClass('odd')).toBe(false);
+ expect($list.find('li:last').hasClass('last')).toBe(true);
+ expect($list.find('li:odd').hasClass('even')).toBe(false);
+ expect($list.find('li:even').hasClass('odd')).toBe(false);
+ });
+
+ it('Check correct class decoration with empty items', function () {
+ var $list = $('#' + listId);
+
+ $list.find('span').decorate('generic', ['last', 'first']);
+ expect($list.find('li:first').hasClass('first')).toBe(false);
+ expect($list.find('li:first').hasClass('odd')).toBe(false);
+ expect($list.find('li:last').hasClass('last')).toBe(false);
+ expect($list.find('li:odd').hasClass('even')).toBe(false);
+ expect($list.find('li:even').hasClass('odd')).toBe(false);
+ });
+ });
+
+ describe('"table" method', function () {
+ var tableId = 'testTable';
+
+ beforeEach(function () {
+ var table = $('
' +
+ '
');
+
+ $('body').append(table);
+ });
+
+ afterEach(function () {
+ $('#' + tableId).remove();
+ });
+
+ it('Check correct class decoration with default params', function () {
+ var $table = $('#' + tableId);
+
+ $table.decorate('table');
+ expect($table.find('tbody tr:first').hasClass('first')).toBe(true);
+ expect($table.find('tbody tr:first').hasClass('odd')).toBe(true);
+ expect($table.find('tbody tr:odd').hasClass('even')).toBe(true);
+ expect($table.find('tbody tr:even').hasClass('odd')).toBe(true);
+ expect($table.find('tbody tr:last').hasClass('last')).toBe(true);
+ expect($table.find('thead tr:first').hasClass('first')).toBe(true);
+ expect($table.find('thead tr:last').hasClass('last')).toBe(true);
+ expect($table.find('tfoot tr:first').hasClass('first')).toBe(true);
+ expect($table.find('tfoot tr:last').hasClass('last')).toBe(true);
+ expect($table.find('tr td:last').hasClass('last')).toBe(true);
+ expect($table.find('tr td:first').hasClass('first')).toBe(false);
+ });
+
+ it('Check correct class decoration with custom params', function () {
+ var $table = $('#' + tableId);
+
+ $table.decorate('table', {
+ 'tbody': ['first'],
+ 'tbody tr': ['first'],
+ 'thead tr': ['first'],
+ 'tfoot tr': ['last'],
+ 'tr td': ['first']
+ });
+ expect($table.find('tbody:first').hasClass('first')).toBe(true);
+ expect($table.find('tbody tr:first').hasClass('first')).toBe(true);
+ expect($table.find('tbody tr:first').hasClass('odd')).toBe(false);
+ expect($table.find('tbody tr:odd').hasClass('even')).toBe(false);
+ expect($table.find('tbody tr:even').hasClass('odd')).toBe(false);
+ expect($table.find('tbody tr:last').hasClass('last')).toBe(false);
+ expect($table.find('thead tr:first').hasClass('first')).toBe(true);
+ expect($table.find('thead tr:last').hasClass('last')).toBe(false);
+ expect($table.find('tfoot tr:first').hasClass('first')).toBe(false);
+ expect($table.find('tfoot tr:last').hasClass('last')).toBe(true);
+ expect($table.find('tr td:last').hasClass('last')).toBe(false);
+ expect($table.find('tr td:first').hasClass('first')).toBe(true);
+ });
+ });
+
+ describe('"dataList" method', function () {
+ var listId = 'testDataList';
+
+ beforeEach(function () {
+ var list = $(' ' +
+ '' +
+ ' ' +
+ ' ' +
+ ' ' +
+ '>' +
+ ' ' +
+ '');
+
+ $('body').append(list);
+ });
+
+ afterEach(function () {
+ $('#' + listId).remove();
+ });
+
+ it('Check correct class decoration', function () {
+ var $list = $('#' + listId);
+
+ $list.decorate('dataList');
+ expect($list.find('dt:first').hasClass('first')).toBe(false);
+ expect($list.find('dt:first').hasClass('odd')).toBe(true);
+ expect($list.find('dt:odd').hasClass('even')).toBe(true);
+ expect($list.find('dt:even').hasClass('odd')).toBe(true);
+ expect($list.find('dt:last').hasClass('last')).toBe(true);
+ expect($list.find('dd:first').hasClass('first')).toBe(false);
+ expect($list.find('dd:first').hasClass('odd')).toBe(true);
+ expect($list.find('dd:odd').hasClass('even')).toBe(true);
+ expect($list.find('dd:even').hasClass('odd')).toBe(true);
+ expect($list.find('dd:last').hasClass('last')).toBe(true);
+ });
+ });
+
+ describe('Call decorate with fake method', function () {
+ var listId = 'testDataList';
+
+ beforeEach(function () {
+ var list = $('
');
+
+ $('body').append(list);
+ });
+
+ afterEach(function () {
+ $('#' + listId).remove();
+ });
+
+ it('Check error message', function () {
+ var $list = $('#' + listId);
+
+ spyOn($, 'error');
+ $list.decorate('customMethod');
+ expect($.error).toHaveBeenCalledWith('Method customMethod does not exist on jQuery.decorate');
+ });
+ });
+ });
+});
diff --git a/dev/tests/js/jasmine/tests/lib/mage/dropdown.test.js b/dev/tests/js/jasmine/tests/lib/mage/dropdown.test.js
new file mode 100644
index 0000000000000..1d149efe040e0
--- /dev/null
+++ b/dev/tests/js/jasmine/tests/lib/mage/dropdown.test.js
@@ -0,0 +1,357 @@
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/* eslint-disable max-nested-callbacks */
+
+define([
+ 'jquery',
+ 'mage/dropdown'
+], function ($) {
+ 'use strict';
+
+ describe('Test for mage/dropdown jQuery plugin', function () {
+ it('check if dialog opens when the triggerEvent is triggered', function () {
+ var opener = $(''),
+ dialog = $('');
+
+ dialog.dropdownDialog({
+ 'triggerEvent': 'click',
+ 'triggerTarget': opener
+ });
+
+ opener.trigger('click');
+ expect(dialog.dropdownDialog('isOpen')).toBeTruthy();
+
+ dialog.dropdownDialog('destroy');
+
+ dialog.dropdownDialog({
+ 'triggerEvent': null,
+ 'triggerTarget': opener
+ });
+
+ opener.trigger('click');
+ expect(dialog.dropdownDialog('isOpen')).toBeFalsy();
+ dialog.dropdownDialog('destroy');
+ });
+
+ it('check if a specified class is added to the trigger', function () {
+ var opener = $(''),
+ dialog = $('');
+
+ dialog.dropdownDialog({
+ 'triggerClass': 'active',
+ 'triggerTarget': opener
+ });
+
+ dialog.dropdownDialog('open');
+ expect(opener.hasClass('active')).toBeTruthy();
+
+ dialog.dropdownDialog('close');
+ dialog.dropdownDialog('destroy');
+
+ dialog.dropdownDialog({
+ 'triggerClass': null,
+ 'triggerTarget': opener
+ });
+
+ dialog.dropdownDialog('open');
+ expect(opener.hasClass('active')).toBeFalsy();
+
+ dialog.dropdownDialog('close');
+ dialog.dropdownDialog('destroy');
+ });
+
+ it('check if a specified class is added to the element which the dialog appends to', function () {
+ var parent = $(''),
+ dialog = $('');
+
+ dialog.dropdownDialog({
+ 'parentClass': 'active',
+ 'appendTo': parent
+ });
+
+ dialog.dropdownDialog('open');
+ expect(parent.hasClass('active')).toBeTruthy();
+
+ dialog.dropdownDialog('close');
+ dialog.dropdownDialog('destroy');
+
+ dialog.dropdownDialog({
+ 'parentClass': null,
+ 'appendTo': parent
+ });
+
+ dialog.dropdownDialog('open');
+ expect(parent.hasClass('active')).toBeFalsy();
+
+ dialog.dropdownDialog('close');
+ dialog.dropdownDialog('destroy');
+ });
+
+ it('check if a specified class is added to the element that becomes dialog', function () {
+ var dialog = $(''),
+ content;
+
+ dialog.dropdownDialog({
+ 'dialogContentClass': 'active'
+ });
+
+ content = $('.ui-dialog-content');
+ dialog.dropdownDialog('open');
+ expect(content.hasClass('active')).toBeTruthy();
+
+ dialog.dropdownDialog('close');
+ dialog.dropdownDialog('destroy');
+
+ dialog.dropdownDialog({
+ 'dialogContentClass': null
+ });
+
+ dialog.dropdownDialog('open');
+ expect(content.hasClass('active')).toBeFalsy();
+
+ dialog.dropdownDialog('close');
+ dialog.dropdownDialog('destroy');
+ });
+
+ it('check if a specified class is added to dialog', function () {
+ var dialog = $(''),
+ uiClass = '.ui-dialog',
+ ui;
+
+ dialog.dropdownDialog({
+ 'defaultDialogClass': 'custom'
+ });
+
+ ui = $(uiClass);
+ expect(ui.hasClass('custom')).toBeTruthy();
+ expect(ui.hasClass('mage-dropdown-dialog')).toBeFalsy();
+
+ dialog.dropdownDialog('destroy');
+
+ dialog.dropdownDialog({});
+ ui = $(uiClass);
+ expect(ui.hasClass('mage-dropdown-dialog')).toBeTruthy();
+
+ dialog.dropdownDialog('destroy');
+ });
+
+ it('check if the specified trigger actually opens the dialog', function () {
+ var opener = $(''),
+ dialog = $('');
+
+ dialog.dropdownDialog({
+ 'triggerTarget': opener
+ });
+
+ opener.trigger('click');
+ expect(dialog.dropdownDialog('isOpen')).toBeTruthy();
+
+ dialog.dropdownDialog('close');
+ dialog.dropdownDialog('destroy');
+
+ dialog.dropdownDialog({
+ 'triggerTarget': null
+ });
+
+ opener.trigger('click');
+ expect(dialog.dropdownDialog('isOpen')).toBeFalsy();
+
+ dialog.dropdownDialog('destroy');
+ });
+
+ it('check if the dialog gets closed when clicking outside of it', function () {
+ var container = $(''),
+ outside = $('').attr('id', 'outside').appendTo(container),
+ dialog = $('').attr('id', 'dialog').appendTo(container);
+
+ container.appendTo('body');
+
+ dialog.dropdownDialog({
+ 'closeOnClickOutside': true
+ });
+
+ dialog.dropdownDialog('open');
+ outside.trigger('click');
+ expect(dialog.dropdownDialog('isOpen')).toBeFalsy();
+
+ dialog.dropdownDialog('destroy');
+
+ dialog.dropdownDialog({
+ 'closeOnClickOutside': false
+ });
+
+ dialog.dropdownDialog('open');
+ outside.trigger('click');
+ expect(dialog.dropdownDialog('isOpen')).toBeTruthy();
+
+ dialog.dropdownDialog('destroy');
+ });
+
+ it('check if the dialog gets closed when mouse leaves the dialog area', function () {
+ var container = $(''),
+ dialog = $('').attr('id', 'dialog').appendTo(container);
+
+ $('').attr('id', 'outside').appendTo(container);
+ $('').attr('id', 'opener').appendTo(container);
+
+ container.appendTo('body');
+
+ jasmine.clock().install();
+
+ dialog.dropdownDialog({
+ 'closeOnMouseLeave': true
+ });
+
+ dialog.dropdownDialog('open');
+ dialog.trigger('mouseenter');
+ expect(dialog.dropdownDialog('isOpen')).toBeTruthy();
+
+ dialog.trigger('mouseleave');
+
+ jasmine.clock().tick(10);
+
+ expect(dialog.dropdownDialog('isOpen')).toBeFalsy();
+ dialog.dropdownDialog('destroy');
+
+ jasmine.clock().uninstall();
+ });
+
+ it('check if the dialog does not close when mouse leaves the dialog area', function () {
+ var container = $(''),
+ dialog = $('').attr('id', 'dialog').appendTo(container);
+
+ $('').attr('id', 'outside').appendTo(container);
+ $('').attr('id', 'opener').appendTo(container);
+
+ container.appendTo('body');
+
+ jasmine.clock().install();
+
+ dialog.dropdownDialog({
+ 'closeOnMouseLeave': false
+ });
+
+ dialog.dropdownDialog('open');
+ dialog.trigger('mouseenter');
+ dialog.trigger('mouseleave');
+ jasmine.clock().tick(10);
+ expect(dialog.dropdownDialog('isOpen')).toBeTruthy();
+ dialog.dropdownDialog('destroy');
+
+ jasmine.clock().uninstall();
+ });
+
+ it('check if the dialog gets closed with the specified delay', function (done) {
+ var container = $(''),
+ dialog = $('').attr('id', 'dialog').appendTo(container);
+
+ $('').attr('id', 'outside').appendTo(container);
+ $('').attr('id', 'opener').appendTo(container);
+
+ container.appendTo('body');
+
+ dialog.dropdownDialog({
+ 'timeout': 5
+ });
+
+ dialog.dropdownDialog('open');
+ dialog.trigger('mouseenter');
+ dialog.trigger('mouseleave');
+ expect(dialog.dropdownDialog('isOpen')).toBeTruthy();
+
+ setTimeout(function () {
+ expect(dialog.dropdownDialog('isOpen')).toBeFalsy();
+ dialog.dropdownDialog('destroy');
+ done();
+ }, 6);
+ });
+
+ /*
+ * jQuery ui version 1.9.2 belongs to the adminhtml.
+ *
+ * This test will fail on backend since backend's jquery.ui will
+ * add ui-dialog-titlebar class anyway on create.
+ */
+ if ($.ui.version !== '1.9.2') {
+ it('check if the title bar is prevented from being created', function () {
+ var dialog = $(''),
+ uiClass = '.ui-dialog',
+ ui;
+
+ dialog.dropdownDialog({
+ 'createTitleBar': true
+ });
+
+ ui = $(uiClass);
+ expect(ui.find('.ui-dialog-titlebar').length > 0).toBeTruthy();
+
+ dialog.dropdownDialog('destroy');
+
+ dialog.dropdownDialog({
+ 'createTitleBar': false
+ });
+
+ ui = $(uiClass);
+ expect(ui.find('.ui-dialog-titlebar').length <= 0).toBeTruthy();
+
+ dialog.dropdownDialog('destroy');
+ });
+ }
+
+ it('check if the position function gets disabled', function () {
+ var dialog = $(''),
+ uiClass = '.ui-dialog',
+ ui;
+
+ dialog.dropdownDialog({
+ 'autoPosition': false
+ });
+
+ ui = $(uiClass);
+ dialog.dropdownDialog('open');
+ expect(ui.css('top') === 'auto').toBeTruthy();
+
+ dialog.dropdownDialog('destroy');
+
+ dialog.dropdownDialog({
+ 'autoPosition': true
+ });
+
+ ui = $(uiClass);
+ dialog.dropdownDialog('open');
+ expect(ui.css('top') !== '0px').toBeTruthy();
+
+ dialog.dropdownDialog('destroy');
+ });
+
+ it('check if the size function gets disabled', function () {
+ var dialog = $(''),
+ uiClass = '.ui-dialog',
+ ui;
+
+ dialog.dropdownDialog({
+ 'autoSize': true,
+ 'width': '300'
+ });
+
+ ui = $(uiClass);
+ dialog.dropdownDialog('open');
+ expect(ui.css('width') === '300px').toBeTruthy();
+
+ dialog.dropdownDialog('destroy');
+
+ dialog.dropdownDialog({
+ 'autoSize': false,
+ 'width': '300'
+ });
+
+ ui = $(uiClass);
+ dialog.dropdownDialog('open');
+ expect(ui.css('width') === '300px').toBeFalsy();
+
+ dialog.dropdownDialog('destroy');
+ });
+ });
+});
diff --git a/dev/tests/js/jasmine/tests/lib/mage/form.test.js b/dev/tests/js/jasmine/tests/lib/mage/form.test.js
new file mode 100644
index 0000000000000..6202f93da999a
--- /dev/null
+++ b/dev/tests/js/jasmine/tests/lib/mage/form.test.js
@@ -0,0 +1,262 @@
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/* eslint-disable max-nested-callbacks */
+/* jscs:disable jsDoc */
+
+define([
+ 'jquery',
+ 'mage/backend/form'
+], function ($) {
+ 'use strict';
+
+ /*
+ * jQuery ui version 1.9.2 belongs to the adminhtml.
+ *
+ * This test will fail on frontend since mage/backend/form only belongs to backend.
+ */
+ if ($.ui.version === '1.9.2') {
+ describe('Test for mage/form jQuery plugin', function () {
+ var id = 'edit_form',
+ elementId = '#' + id;
+
+ beforeEach(function () {
+ var element = $('');
+
+ element.appendTo('body');
+ });
+
+ afterEach(function () {
+ $(elementId).remove();
+ });
+
+ it('check if form can be initialized', function () {
+ var form = $(elementId).form();
+
+ expect(form.is(':mage-form')).toBeTruthy();
+ });
+
+ it('check get handlers', function () {
+ var form = $(elementId).form(),
+ handlersData = form.form('option', 'handlersData'),
+ handlers = [];
+
+ $.each(handlersData, function (key) {
+ handlers.push(key);
+ });
+ expect(handlers.join(' ')).toBe(form.data('form')._getHandlers().join(' '));
+ });
+
+ it('check store attribute', function () {
+ var form = $(elementId).form(),
+ initialFormAttrs = {
+ action: form.attr('action'),
+ target: form.attr('target'),
+ method: form.attr('method')
+ };
+
+ form.data('form')._storeAttribute('action');
+ form.data('form')._storeAttribute('target');
+ form.data('form')._storeAttribute('method');
+
+ expect(form.data('form').oldAttributes.action).toBe(initialFormAttrs.action);
+ expect(form.data('form').oldAttributes.target).toBe(initialFormAttrs.target);
+ expect(form.data('form').oldAttributes.method).toBe(initialFormAttrs.method);
+ });
+
+ it('check bind', function () {
+ var form = $(elementId).form(),
+ submitted = false,
+ handlersData = form.form('option', 'handlersData');
+
+ form.on('submit', function (e) {
+ submitted = true;
+ e.stopImmediatePropagation();
+ e.preventDefault();
+ });
+
+ $.each(handlersData, function (key) {
+ form.trigger(key);
+ expect(submitted).toBeTruthy();
+ submitted = false;
+ });
+
+ form.off('submit');
+ });
+
+ it('check get action URL', function () {
+ var form = $(elementId).form(),
+ action = form.attr('action'),
+ testUrl = 'new/action/url',
+ testArgs = {
+ args: {
+ arg: 'value'
+ }
+ };
+
+ form.data('form')._storeAttribute('action');
+ expect(form.data('form')._getActionUrl(testArgs)).toBe(action + '/arg/value/');
+ expect(form.data('form')._getActionUrl(testUrl)).toBe(testUrl);
+ expect(form.data('form')._getActionUrl()).toBe(action);
+ });
+
+ it('check process data', function () {
+ var form = $(elementId).form(),
+ initialFormAttrs = {
+ action: form.attr('action'),
+ target: form.attr('target'),
+ method: form.attr('method')
+ },
+ testSimpleData = {
+ action: 'new/action/url',
+ target: '_blank',
+ method: 'POST'
+ },
+ testActionArgsData = {
+ action: {
+ args: {
+ arg: 'value'
+ }
+ }
+ },
+ processedData = form.data('form')._processData(testSimpleData);
+
+ expect(form.data('form').oldAttributes.action).toBe(initialFormAttrs.action);
+ expect(form.data('form').oldAttributes.target).toBe(initialFormAttrs.target);
+ expect(form.data('form').oldAttributes.method).toBe(initialFormAttrs.method);
+ expect(processedData.action).toBe(testSimpleData.action);
+ expect(processedData.target).toBe(testSimpleData.target);
+ expect(processedData.method).toBe(testSimpleData.method);
+
+ form.data('form')._rollback();
+ processedData = form.data('form')._processData(testActionArgsData);
+ form.data('form')._storeAttribute('action');
+ expect(processedData.action).toBe(form.data('form')._getActionUrl(testActionArgsData.action));
+ });
+
+ it('check before submit', function () {
+ var testForm = $('').appendTo('body'),
+ testHandler = {
+ action: {
+ args: {
+ arg1: 'value1'
+ }
+ }
+ },
+ form = $(elementId).form({
+ handlersData: {
+ testHandler: testHandler
+ }
+ }),
+ beforeSubmitData = {
+ action: {
+ args: {
+ arg2: 'value2'
+ }
+ },
+ target: '_blank'
+ },
+ eventData = {
+ method: 'POST'
+ },
+ resultData = $.extend(true, {}, testHandler, beforeSubmitData, eventData);
+
+ form.data('form')._storeAttribute('action');
+ resultData = form.data('form')._processData(resultData);
+ testForm.prop(resultData);
+
+ form.on('beforeSubmit', function (e, data) {
+ $.extend(data, beforeSubmitData);
+ });
+
+ form.on('submit', function (e) {
+ e.stopImmediatePropagation();
+ e.preventDefault();
+ });
+
+ form.data('form')._beforeSubmit('testHandler', eventData);
+ expect(testForm.prop('action')).toBe(form.prop('action'));
+ expect(testForm.prop('target')).toBe(form.prop('target'));
+ expect(testForm.prop('method')).toBe(form.prop('method'));
+ });
+
+ it('check submit', function () {
+ var formSubmitted = false,
+ form = $(elementId).form({
+ handlersData: {
+ save: {}
+ }
+ });
+
+ form.data('form')._storeAttribute('action');
+ form.data('form')._storeAttribute('target');
+ form.data('form')._storeAttribute('method');
+
+ form.on('submit', function (e) {
+ e.preventDefault();
+ e.stopImmediatePropagation();
+ e.preventDefault();
+ formSubmitted = true;
+ }).prop({
+ action: 'new/action/url',
+ target: '_blank',
+ method: 'POST'
+ });
+
+ form.data('form')._submit({
+ type: 'save'
+ });
+
+ expect(form.attr('action')).toBe(form.data('form').oldAttributes.action);
+ expect(form.attr('target')).toBe(form.data('form').oldAttributes.target);
+ expect(form.attr('method')).toBe(form.data('form').oldAttributes.method);
+ expect(formSubmitted).toBeTruthy();
+
+ form.off('submit');
+ });
+
+ it('check build URL', function () {
+ var dataProvider = [
+ {
+ params: ['http://domain.com//', {
+ 'key[one]': 'value 1',
+ 'key2': '# value'
+ }],
+ expected: 'http://domain.com/key[one]/value%201/key2/%23%20value/'
+ },
+ {
+ params: ['http://domain.com', {
+ 'key[one]': 'value 1',
+ 'key2': '# value'
+ }],
+ expected: 'http://domain.com/key[one]/value%201/key2/%23%20value/'
+ },
+ {
+ params: ['http://domain.com?some=param', {
+ 'key[one]': 'value 1',
+ 'key2': '# value'
+ }],
+ expected: 'http://domain.com?some=param&key[one]=value%201&key2=%23%20value'
+ },
+ {
+ params: ['http://domain.com?some=param&', {
+ 'key[one]': 'value 1',
+ 'key2': '# value'
+ }],
+ expected: 'http://domain.com?some=param&key[one]=value%201&key2=%23%20value'
+ }
+ ],
+ method = $.mage.form._proto._buildURL,
+ quantity = dataProvider.length,
+ i = 0;
+
+ expect(quantity).toBeTruthy();
+
+ for (i; i < quantity; i++) {
+ expect(dataProvider[i].expected).toBe(method.apply(null, dataProvider[i].params));
+ }
+ });
+ });
+ }
+});
diff --git a/dev/tests/js/jasmine/tests/lib/mage/loader.test.js b/dev/tests/js/jasmine/tests/lib/mage/loader.test.js
new file mode 100644
index 0000000000000..93dd2ee91902c
--- /dev/null
+++ b/dev/tests/js/jasmine/tests/lib/mage/loader.test.js
@@ -0,0 +1,79 @@
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+/* eslint-disable max-nested-callbacks */
+define([
+ 'jquery',
+ 'mage/loader'
+], function ($) {
+ 'use strict';
+
+ describe('mage/loader', function () {
+ describe('Check loader', function () {
+ var loaderSelector = '#loader';
+
+ beforeEach(function () {
+ var $loader = $('');
+
+ $('body').append($loader);
+ });
+
+ afterEach(function () {
+ $(loaderSelector).remove();
+ $(loaderSelector).loader('destroy');
+ });
+
+ it('Check that loader inited', function () {
+ var $loader = $(loaderSelector).loader({
+ icon: 'icon.gif'
+ });
+
+ $loader.loader('show');
+
+ expect($loader.is(':mage-loader')).toBe(true);
+ expect($loader.find('p').text()).toBe('Please wait...');
+ expect($loader.find('img').prop('src').split('/').pop()).toBe('icon.gif');
+ expect($loader.find('img').prop('alt')).toBe('Loading...');
+ });
+
+ it('Body init', function () {
+ var $loader = $('body').loader();
+
+ $loader.loader('show');
+
+ expect($loader.is(':mage-loader')).toBe(true);
+ $loader.loader('destroy');
+ });
+
+ it('Check show/hide', function () {
+ var $loader = $(loaderSelector).loader(),
+ $loadingMask;
+
+ $loader.loader('show');
+ $loadingMask = $('.loading-mask');
+ expect($loadingMask.is(':visible')).toBe(true);
+
+ $loader.loader('hide');
+ expect($loadingMask.is(':hidden')).toBe(true);
+
+ $loader.loader('show');
+ $loader.trigger('processStop');
+ expect($loadingMask.is(':hidden')).toBe(true);
+ });
+
+ it('Check destroy', function () {
+ var $loader = $(loaderSelector).loader(),
+ $loadingMask;
+
+ $loader.loader('show');
+ $loadingMask = $('.loading-mask');
+ expect($loadingMask.is(':visible')).toBe(true);
+
+ $loader.loader('destroy');
+ expect($loadingMask.is(':visible')).toBe(false);
+ });
+ });
+ });
+});
diff --git a/dev/tests/js/jasmine/tests/lib/mage/menu.test.js b/dev/tests/js/jasmine/tests/lib/mage/menu.test.js
new file mode 100644
index 0000000000000..69d8af4ff3dba
--- /dev/null
+++ b/dev/tests/js/jasmine/tests/lib/mage/menu.test.js
@@ -0,0 +1,110 @@
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+/* eslint-disable max-nested-callbacks */
+define([
+ 'jquery',
+ 'mage/menu',
+ 'text!tests/assets/lib/web/mage/menu.html'
+], function ($, menu, menuTmpl) {
+ 'use strict';
+
+ describe('mage/menu', function () {
+ describe('Menu expanded', function () {
+ var menuSelector = '#menu';
+
+ beforeEach(function () {
+ var $menu = $(menuTmpl);
+
+ $('body').append($menu);
+ });
+
+ afterEach(function () {
+ $(menuSelector).remove();
+ });
+
+ it('Check that menu expanded', function () {
+ var $menu = $(menuSelector),
+ $menuItems = $menu.find('li'),
+ $submenu = $menuItems.find('ul');
+
+ menu.menu({
+ expanded: true
+ }, $menu);
+ expect($submenu.hasClass('expanded')).toBe(true);
+ });
+ });
+
+ describe('Menu hover event', function () {
+ var menuSelector = '#menu',
+ $menu;
+
+ beforeEach(function () {
+ var $menuObject = $(menuTmpl);
+
+ $('body').append($menuObject);
+ $menu = $(menuSelector).menu({
+ delay: 0,
+ showDelay: 0,
+ hideDelay: 0
+ });
+ });
+
+ afterEach(function () {
+ $(menuSelector).remove();
+ });
+
+ it('Check that menu expanded', function (done) {
+ var $menuItem = $menu.find('li.test-menu-item'),
+ $submenu = $menuItem.find('ul');
+
+ $menuItem.trigger('mouseover');
+ setTimeout(function () {
+ expect($submenu.attr('aria-expanded')).toBe('true');
+ $menuItem.trigger('mouseout');
+ setTimeout(function () {
+ expect($submenu.attr('aria-expanded')).toBe('false');
+ done();
+ }, 300);
+ }, 300);
+ });
+ });
+
+ describe('Menu navigation', function () {
+ var menuSelector = '#menu',
+ $menu;
+
+ beforeEach(function () {
+ var $menuObject = $(menuTmpl);
+
+ $('body').append($menuObject);
+ $menu = $(menuSelector).menu();
+ });
+
+ afterEach(function () {
+ $(menuSelector).remove();
+ });
+
+ it('Check max item limit', function () {
+ var $menuItems;
+
+ $menu.navigation({
+ maxItems: 3
+ });
+ $menuItems = $menu.find('li:visible');
+
+ expect($menuItems.length).toBe(4);
+ });
+
+ it('Check that More Menu item will be added', function () {
+ $menu.navigation({
+ responsive: 'onResize'
+ });
+
+ expect($('body').find('.ui-menu-more').length).toBeGreaterThan(0);
+ });
+ });
+ });
+});
diff --git a/dev/tests/js/jasmine/tests/lib/mage/tabs.test.js b/dev/tests/js/jasmine/tests/lib/mage/tabs.test.js
new file mode 100644
index 0000000000000..a6138df073434
--- /dev/null
+++ b/dev/tests/js/jasmine/tests/lib/mage/tabs.test.js
@@ -0,0 +1,93 @@
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+/* eslint-disable max-nested-callbacks */
+define([
+ 'jquery',
+ 'jquery/ui',
+ 'mage/tabs',
+ 'text!tests/assets/lib/web/mage/tabs.html'
+], function ($, ui, tabs, tabsTmpl) {
+ 'use strict';
+
+ describe('mage/tabs', function () {
+ var tabsSelector = '#tabs';
+
+ beforeEach(function () {
+ var $tabs = $(tabsTmpl);
+
+ $('body').append($tabs);
+ });
+
+ afterEach(function () {
+ $(tabsSelector).remove();
+ $(tabsSelector).tabs('destroy');
+ });
+
+ it('Check tabs inited', function () {
+ var $tabs = $(tabsSelector).tabs();
+
+ expect($tabs.is(':mage-tabs')).toBe(true);
+ });
+
+ it('Check tabs collapsible inited', function () {
+ var $title1 = $('#title1'),
+ $title2 = $('#title2');
+
+ $(tabsSelector).tabs();
+
+ expect($title1.is(':mage-collapsible')).toBe(true);
+ expect($title2.is(':mage-collapsible')).toBe(true);
+ });
+
+ it('Check tabs active', function () {
+ var $content1 = $('#content1'),
+ $content2 = $('#content2');
+
+ $(tabsSelector).tabs({
+ active: 1
+ });
+
+ expect($content1.is(':hidden')).toBe(true);
+ expect($content2.is(':visible')).toBe(true);
+ });
+
+ it('Check tabs closing others tabs when one gets activated', function () {
+ var $title2 = $('#title2'),
+ $content1 = $('#content1'),
+ $content2 = $('#content2');
+
+ $(tabsSelector).tabs();
+
+ expect($content1.is(':visible')).toBe(true);
+ expect($content2.is(':hidden')).toBe(true);
+
+ $title2.trigger('click');
+
+ expect($content1.is(':hidden')).toBe(true);
+ expect($content2.is(':visible')).toBe(true);
+ });
+
+ it('Check tabs enable,disable,activate,deactivate options', function () {
+ var $title1 = $('#title1'),
+ $content1 = $('#content1'),
+ $tabs = $(tabsSelector).tabs();
+
+ expect($content1.is(':visible')).toBe(true);
+ $tabs.tabs('deactivate', 0);
+ expect($content1.is(':hidden')).toBe(true);
+ $tabs.tabs('activate', 0);
+ expect($content1.is(':visible')).toBe(true);
+ $tabs.tabs('disable', 0);
+ expect($content1.is(':hidden')).toBe(true);
+ $title1.trigger('click');
+ expect($content1.is(':hidden')).toBe(true);
+ $tabs.tabs('enable', 0);
+ expect($content1.is(':visible')).toBe(true);
+ $title1.trigger('click');
+ expect($content1.is(':visible')).toBe(true);
+ });
+ });
+});
diff --git a/dev/tests/js/jasmine/tests/lib/mage/translate-inline.test.js b/dev/tests/js/jasmine/tests/lib/mage/translate-inline.test.js
new file mode 100644
index 0000000000000..bcdfc4cc59705
--- /dev/null
+++ b/dev/tests/js/jasmine/tests/lib/mage/translate-inline.test.js
@@ -0,0 +1,111 @@
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+/* eslint-disable max-nested-callbacks */
+define([
+ 'jquery',
+ 'mage/translate-inline',
+ 'text!tests/assets/lib/web/mage/translate-inline.html'
+], function ($, TranslateInline, translateTmpl) {
+ 'use strict';
+
+ describe('mage/translate-inline', function () {
+ describe('Check translate', function () {
+ var translateSelector = '[data-role="translate-dialog"]',
+ translateTemplateSelector = '#translate-form-template';
+
+ beforeEach(function () {
+ var translateBlock = $(translateTmpl);
+
+ $('body').append(translateBlock);
+ });
+
+ afterEach(function () {
+ $(translateSelector).remove();
+ $(translateSelector).translateInline('destroy');
+ $(translateTemplateSelector).remove();
+ });
+
+ it('Check that translate inited', function () {
+ var translateInline = $(translateSelector).translateInline();
+
+ expect(translateInline.is(':mage-translateInline')).toBe(true);
+ });
+
+ it('Check that translate hidden on init and visible on trigger', function () {
+ var translateInline = $(translateSelector).translateInline({
+ id: 'dialog-id'
+ }),
+ isDialogHiddenOnInit = translateInline.is(':hidden'),
+ dialogVisibleAfterTriggerEdit;
+
+ translateInline.trigger('edit.editTrigger');
+ dialogVisibleAfterTriggerEdit = translateInline.is(':visible');
+ expect(isDialogHiddenOnInit).toBe(true);
+ expect(dialogVisibleAfterTriggerEdit).toBe(true);
+ });
+
+ it('Check translation form template', function () {
+ var translateFormId = 'translate-form-id',
+ translateFormContent = 'New Template Variable',
+ translateInline = $(translateSelector).translateInline({
+ translateForm: {
+ data: {
+ id: translateFormId,
+ newTemplateVariable: translateFormContent
+ }
+ }
+ }),
+ $translateForm;
+
+ translateInline.trigger('edit.editTrigger');
+ $translateForm = $('#' + translateFormId);
+
+ expect($translateForm.length).toBeGreaterThan(0);
+ expect($translateForm.text()).toBe(translateFormContent);
+ });
+
+ it('Check translation submit', function () {
+ var options = {
+ ajaxUrl: 'www.test.com',
+ area: 'test',
+ translateForm: {
+ template: '',
+ data: {
+ id: 'translate-form-id'
+ }
+ }
+ },
+ expectedEequestData = 'area=test&test=test',
+ translateInline = $(translateSelector).translateInline(options),
+ $submitButton = $('body').find('.action-primary'),
+ originalAjax = $.ajax;
+
+ $.ajax = jasmine.createSpy().and.callFake(function (request) {
+ expect(request.url).toBe(options.ajaxUrl);
+ expect(request.type).toBe('POST');
+ expect(request.data).toBe(expectedEequestData);
+
+ return {
+ complete: jasmine.createSpy()
+ };
+ });
+
+ translateInline.trigger('edit.editTrigger');
+ $submitButton.trigger('click');
+ $.ajax = originalAjax;
+ });
+
+ it('Check translation destroy', function () {
+ var translateInline = $(translateSelector).translateInline();
+
+ translateInline.trigger('edit.editTrigger');
+ expect(translateInline.is(':mage-translateInline')).toBe(true);
+ translateInline.translateInline('destroy');
+ expect(translateInline.is(':mage-translateInline')).toBe(false);
+ });
+ });
+ });
+});
diff --git a/dev/tests/js/jasmine/tests/lib/mage/translate.test.js b/dev/tests/js/jasmine/tests/lib/mage/translate.test.js
new file mode 100644
index 0000000000000..c87cfa227c1aa
--- /dev/null
+++ b/dev/tests/js/jasmine/tests/lib/mage/translate.test.js
@@ -0,0 +1,49 @@
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/* eslint-disable max-nested-callbacks */
+define([
+ 'jquery',
+ 'mage/translate'
+], function ($) {
+ 'use strict';
+
+ describe('Test for mage/translate jQuery plugin', function () {
+ it('works with one string as parameter', function () {
+ $.mage.translate.add('Hello World!');
+ expect('Hello World!').toEqual($.mage.translate.translate('Hello World!'));
+ });
+ it('works with one array as parameter', function () {
+ $.mage.translate.add(['Hello World!', 'Bonjour tout le monde!']);
+ expect('Hello World!').toEqual($.mage.translate.translate('Hello World!'));
+ });
+ it('works with one object as parameter', function () {
+ var translation = {
+ 'Hello World!': 'Bonjour tout le monde!'
+ };
+
+ $.mage.translate.add(translation);
+ expect(translation['Hello World!']).toEqual($.mage.translate.translate('Hello World!'));
+
+ translation = {
+ 'Hello World!': 'Hallo Welt!',
+ 'Some text with symbols!-+"%#*': 'Ein Text mit Symbolen!-+"%#*'
+ };
+
+ $.mage.translate.add(translation);
+ $.each(translation, function (key) {
+ expect(translation[key]).toEqual($.mage.translate.translate(key));
+ });
+ });
+ it('works with two string as parameter', function () {
+ $.mage.translate.add('Hello World!', 'Bonjour tout le monde!');
+ expect('Bonjour tout le monde!').toEqual($.mage.translate.translate('Hello World!'));
+ });
+ it('works with translation alias __', function () {
+ $.mage.translate.add('Hello World!');
+ expect('Hello World!').toEqual($.mage.__('Hello World!'));
+ });
+ });
+
+});
diff --git a/dev/tests/js/jasmine/tests/lib/mage/validation.test.js b/dev/tests/js/jasmine/tests/lib/mage/validation.test.js
index 50931f940c689..1e1203d22a1e3 100644
--- a/dev/tests/js/jasmine/tests/lib/mage/validation.test.js
+++ b/dev/tests/js/jasmine/tests/lib/mage/validation.test.js
@@ -183,4 +183,963 @@ define([
)).toEqual(true);
});
});
+
+ describe('Testing validate-no-html-tags', function () {
+ it('validate-no-html-tags', function () {
+ expect($.validator.methods['validate-no-html-tags']
+ .call($.validator.prototype, '')).toEqual(true);
+ expect($.validator.methods['validate-no-html-tags']
+ .call($.validator.prototype, null)).toEqual(true);
+ expect($.validator.methods['validate-no-html-tags']
+ .call($.validator.prototype, 'abc')).toEqual(true);
+ expect($.validator.methods['validate-no-html-tags']
+ .call($.validator.prototype, '
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+',
+ [['module' => 'Unknown', 'source' => 'unknown_table']]
+ ],
+ [
+ 'SomeModule',
+ '/app/some/path/etc/db_schema.xml',
+ '
',
+ []
+ ],
+ [
+ 'any',
+ '/app/some/path/etc/db_schema.xml',
+ '
',
+ [
+ [
+ 'module' => 'SomeModule',
+ 'type' => \Magento\TestFramework\Dependency\RuleInterface::TYPE_HARD,
+ 'source' => 'some_table',
+ ]
+ ]
+ ],
+ [
+ 'any',
+ '/app/some/path/etc/db_schema.xml',
+ '
+
+