From ac593e928f96d8eaa0f5ae7ea5b3538ab9da2720 Mon Sep 17 00:00:00 2001
From: Ruslan Kabalin
Date: Thu, 21 Feb 2019 00:00:18 +0000
Subject: [PATCH 1/2] mustache_lint: Test partials with stray tags.
Stray tags are those that got strict parent requirement, e.g. you can't
use ... without wrapping it in tag.
---
tests/1-mustache_lint.bats | 21 +++++++-
tests/fixtures/31-mustache_lint-partial.patch | 53 +++++++++++++++++++
2 files changed, 72 insertions(+), 2 deletions(-)
create mode 100644 tests/fixtures/31-mustache_lint-partial.patch
diff --git a/tests/1-mustache_lint.bats b/tests/1-mustache_lint.bats
index d6ade39a..e7312eb4 100755
--- a/tests/1-mustache_lint.bats
+++ b/tests/1-mustache_lint.bats
@@ -76,7 +76,6 @@ setup () {
# Assert result
assert_failure
- assert_output --partial "NPM installed validator found."
assert_output --partial "Running mustache lint from $GIT_PREVIOUS_COMMIT to $GIT_COMMIT"
assert_output --partial "lib/templates/linting.mustache - WARNING: HTML Validation error, line 2: End tag “p” seen, but there were open elements. (ello World
Hello )"
@@ -100,6 +99,24 @@ setup () {
assert_output --partial "No mustache problems found"
}
+@test "mustache_lint: Partial contains elements with strict parent requirement" {
+ # Set up.
+ git_apply_fixture 31-mustache_lint-partial.patch
+ export GIT_PREVIOUS_COMMIT=$FIXTURE_HASH_BEFORE
+ export GIT_COMMIT=$FIXTURE_HASH_AFTER
+
+ ci_run mustache_lint/mustache_lint.sh
+
+ # Assert result
+ assert_success
+ # We should not have a validation warning about stray tags.
+ refute_output --partial "lib/templates/linting.mustache - WARNING: HTML Validation error, line 2: Stray start tag “td”."
+ refute_output --partial "lib/templates/linting.mustache - WARNING: HTML Validation error, line 2: Stray end tag “td”."
+
+ assert_output --partial "lib/templates/linting.mustache - OK: Mustache rendered html succesfully"
+ assert_output --partial "No mustache problems found"
+}
+
@test "mustache_lint: Full HTML page doesn't get embeded in body" {
# Set up.
git_apply_fixture 31-mustache_lint-full-html-body.patch
@@ -110,7 +127,7 @@ setup () {
# Assert result
assert_success
- # We should not have a vlidation warning about multiple 'html' tags.
+ # We should not have a validation warning about multiple 'html' tags.
refute_output --partial 'Stray start tag “html”.'
assert_output --partial "lib/templates/full-html-page.mustache - OK: Mustache rendered html succesfully"
diff --git a/tests/fixtures/31-mustache_lint-partial.patch b/tests/fixtures/31-mustache_lint-partial.patch
new file mode 100644
index 00000000..153a60ac
--- /dev/null
+++ b/tests/fixtures/31-mustache_lint-partial.patch
@@ -0,0 +1,53 @@
+From 21dcf559cc7850d03729f7679e2f1ce87db5cb4c Mon Sep 17 00:00:00 2001
+From: Ruslan Kabalin
+Date: Fri, 18 Jan 2019 18:26:08 +0000
+Subject: [PATCH] MDL-56504 mustache: fixture for partial problem detection
+
+---
+ lib/templates/linting.mustache | 35 +++++++++++++++++++++++++++++++++++
+ 1 file changed, 35 insertions(+)
+ create mode 100644 lib/templates/linting.mustache
+
+diff --git a/lib/templates/linting.mustache b/lib/templates/linting.mustache
+new file mode 100644
+index 00000000000..dffe9239d92
+--- /dev/null
++++ b/lib/templates/linting.mustache
+@@ -0,0 +1,35 @@
++{{!
++ This file is part of Moodle - http://moodle.org/
++
++ Moodle is free software: you can redistribute it and/or modify
++ it under the terms of the GNU General Public License as published by
++ the Free Software Foundation, either version 3 of the License, or
++ (at your option) any later version.
++
++ Moodle is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ GNU General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with Moodle. If not, see .
++}}
++{{!
++ @template core/linting
++
++ A test for for mustache linting tests.
++
++ Classes required for JS:
++ * none
++
++ Data attributes required for JS:
++ * none
++
++ Context variables required for this template:
++ * none
++
++ Example context (json):
++ {
++ }
++}}
++| Hello World |
+--
+2.11.0
From 8523227bbe5656d11abe6e3768b638b977d518c6 Mon Sep 17 00:00:00 2001
From: Ruslan Kabalin
Date: Thu, 21 Feb 2019 00:02:27 +0000
Subject: [PATCH 2/2] mustache_lint: Wrap stray tags into valid parent.
Attempt to fix a partial template containing elements with a strict
parent requirements.
---
mustache_lint/mustache_lint.php | 59 ++++++++++++++++++++++++++++-----
1 file changed, 51 insertions(+), 8 deletions(-)
diff --git a/mustache_lint/mustache_lint.php b/mustache_lint/mustache_lint.php
index a1ac17c1..f7ef9301 100644
--- a/mustache_lint/mustache_lint.php
+++ b/mustache_lint/mustache_lint.php
@@ -192,16 +192,59 @@ function print_message($severity, $mesage) {
}
/**
- * Wrap the template content in a html5 wrapper and validate it
+ * Fix partials and wrap the template content in a html5 wrapper.
+ *
+ * There could be the case when partial template got elements that have a strict
+ * parent element requirement. We can wrap most obvious elements into correct parent,
+ * assuming the partial template is "balanced" i.e. contain equal number of start
+ * and end tags (though, if it is not equial, the partial template will fail
+ * validation anyway). This partial fixing wrapper will not be required if we
+ * find a way to exclude partials from linting at some point (MDL-56504).
+ *
+ * @param string $content the raw template as string.
+ * @return string $wrappedcontent
*/
-function check_html_validation($content) {
- if (strpos($content, '') === false) {
- // Primative detection if we have full html body, if not, wrap it.
- // (This isn't bulletproof, obviously).
- $wrappedcontent = "Validate\n{$content}\n";
- } else {
- $wrappedcontent = $content;
+function wrap_content($content) {
+ // Primitive detection if we have full html body, if not, we need to wrap it.
+ if (strpos($content, '')) {
+ return $content;
+ }
+
+ // Mapping of child elements to their required parent elements.
+ $reqparent = [
+ // List.
+ 'li' => 'ul',
+ // Table.
+ 'td' => 'tr',
+ 'th' => 'tr',
+ 'tr' => 'table',
+ 'thead' => 'table',
+ 'tbody' => 'table',
+ 'tfoot' => 'table',
+ // Definition list.
+ 'dd' => 'dl',
+ 'dt' => 'dl',
+ ];
+
+ // Determine if the first element has strict parent element requirement and wrap it if necessary.
+ // Iterate through, as further wrapping may be needed.
+ while (preg_match('@^<(' . join('|', array_keys($reqparent)) . ')[^>]*>@is', trim($content), $matches)) {
+ $parent = $reqparent[$matches[1]];
+ $content = "<{$parent}>\n{$content}\n{$parent}>";
}
+
+ // Wrap in html5 body.
+ $wrappedcontent = "Validate\n{$content}\n";
+ return $wrappedcontent;
+}
+
+/**
+ * Validate template content.
+ */
+function check_html_validation($content) {
+ // We need to wrap template content first.
+ $wrappedcontent = wrap_content($content);
+ // And then call validator.
$response = validate_html($wrappedcontent);
if (!$response || !isset($response->messages)) {