Skip to content

Commit

Permalink
Tests: Added .html.test files for replace .js language tests (#3148)
Browse files Browse the repository at this point in the history
  • Loading branch information
RunDevelopment committed Oct 19, 2021
1 parent ae8888a commit 2e834c8
Show file tree
Hide file tree
Showing 20 changed files with 370 additions and 129 deletions.
6 changes: 6 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Expand Up @@ -61,6 +61,7 @@
"mocha": "^6.2.0",
"node-fetch": "^2.6.0",
"npm-run-all": "^4.1.5",
"prettier": "^2.4.1",
"pump": "^3.0.0",
"refa": "^0.9.1",
"regexp-ast-analysis": "^0.2.4",
Expand Down
19 changes: 13 additions & 6 deletions test-suite.html
Expand Up @@ -165,14 +165,21 @@ <h2 id="writing-tests-explaining-the-simplified-token-stream">Explaining the sim
<section id="writing-specific-tests">
<h1>Writing specific tests</h1>

<p>Sometimes, using the token stream tests is not powerful enough. By creating a test file with the file extension <code>.js</code> instead of <code>.test</code>, you can make Prism highlight arbitrary pieces of code and check their HTML results.</p>
<p>Sometimes, using the token stream tests is not powerful enough. By creating a test file with the file extension <code>.html.test</code> instead of <code>.test</code>, you can make Prism highlight arbitrary pieces of code and check their HTML results.</p>
<p>The language is determined by the folder containing the test file lies, as explained in the previous section.</p>
<p>The structure of your test file will look like this, for example:</p>
<pre><code>module.exports = {
'&amp;#x278a;': '&lt;span class="token entity" title="&amp;#x278a;">&amp;amp;#x278a;&lt;/span>',
'&amp;#182;': '&lt;span class="token entity" title="&amp;#182;">&amp;amp;#182;&lt;/span>',
};</code></pre>
<p>The keys are the codes which will be highlighted by Prism. The values are the expected results, as HTML.</p>
<pre><code class="language-html">&amp;amp;
&amp;#x41;

----------------------------------------------------

&lt;span class="token entity named-entity" title="&amp;amp;">&amp;amp;amp;&lt;/span>
&lt;span class="token entity" title="&amp;#x41;">&amp;amp;#x41;&lt;/span>

----------------------------------------------------

This is a comment explaining this test case.
</code></pre>
</section>

<section id="test-runner-tests">
Expand Down
114 changes: 81 additions & 33 deletions tests/helper/test-case.js
Expand Up @@ -2,6 +2,7 @@

const fs = require('fs');
const { assert } = require('chai');
const Prettier = require('prettier');
const PrismLoader = require('./prism-loader');
const TokenStreamTransformer = require('./token-stream-transformer');

Expand Down Expand Up @@ -217,6 +218,81 @@ class TokenizeJSONRunner {
}
}

/**
* @implements {Runner<string>}
*/
class HighlightHTMLRunner {
/**
* @param {Prism} Prism
* @param {string} code
* @param {string} language
* @returns {string}
*/
run(Prism, code, language) {
const env = {
element: {},
language,
grammar: Prism.languages[language],
code,
};

Prism.hooks.run('before-highlight', env);
env.highlightedCode = Prism.highlight(env.code, env.grammar, env.language);
Prism.hooks.run('before-insert', env);
env.element.innerHTML = env.highlightedCode;
Prism.hooks.run('after-highlight', env);
Prism.hooks.run('complete', env);

return env.highlightedCode;
}
/**
* @param {string} actual
* @returns {string}
*/
print(actual) {
return Prettier.format(actual, {
printWidth: 100,
tabWidth: 4,
useTabs: true,
htmlWhitespaceSensitivity: 'ignore',
filepath: 'fake.html',
});
}
/**
* @param {string} actual
* @param {string} expected
* @returns {boolean}
*/
isEqual(actual, expected) {
return this.normalize(actual) === this.normalize(expected);
}
/**
* @param {string} actual
* @param {string} expected
* @param {(firstDifference: number) => string} message
* @returns {void}
*/
assertEqual(actual, expected, message) {
// We don't calculate the index of the first difference because it's difficult.
assert.deepEqual(this.normalize(actual), this.normalize(expected), message(0));
}

/**
* Normalizes the given HTML by removing all leading spaces and trailing spaces. Line breaks will also be normalized
* to enable good diffing.
*
* @param {string} html
* @returns {string}
*/
normalize(html) {
return html
.replace(/</g, '\n<')
.replace(/>/g, '>\n')
.replace(/[ \t]*[\r\n]\s*/g, '\n')
.trim();
}
}


module.exports = {
TestCaseFile,
Expand All @@ -238,7 +314,11 @@ module.exports = {
* @param {"none" | "insert" | "update"} updateMode
*/
runTestCase(languageIdentifier, filePath, updateMode) {
this.runTestCaseWithRunner(languageIdentifier, filePath, updateMode, new TokenizeJSONRunner());
if (/\.html\.test$/i.test(filePath)) {
this.runTestCaseWithRunner(languageIdentifier, filePath, updateMode, new HighlightHTMLRunner());
} else {
this.runTestCaseWithRunner(languageIdentifier, filePath, updateMode, new TokenizeJSONRunner());
}
},

/**
Expand Down Expand Up @@ -347,38 +427,6 @@ module.exports = {
mainLanguage: mainLanguage
};
},

/**
* Runs the given pieces of codes and asserts their result.
*
* Code is provided as the key and expected result as the value.
*
* @param {string} languageIdentifier
* @param {object} codes
*/
runTestsWithHooks(languageIdentifier, codes) {
const usedLanguages = this.parseLanguageNames(languageIdentifier);
const Prism = PrismLoader.createInstance(usedLanguages.languages);
// the first language is the main language to highlight

for (const code in codes) {
if (codes.hasOwnProperty(code)) {
const env = {
element: {},
language: usedLanguages.mainLanguage,
grammar: Prism.languages[usedLanguages.mainLanguage],
code: code
};
Prism.hooks.run('before-highlight', env);
env.highlightedCode = Prism.highlight(env.code, env.grammar, env.language);
Prism.hooks.run('before-insert', env);
env.element.innerHTML = env.highlightedCode;
Prism.hooks.run('after-highlight', env);
Prism.hooks.run('complete', env);
assert.equal(env.highlightedCode, codes[code]);
}
}
}
};

/**
Expand Down
4 changes: 1 addition & 3 deletions tests/helper/test-discovery.js
Expand Up @@ -3,8 +3,6 @@
const fs = require('fs');
const path = require('path');

const SUPPORTED_TEST_FILE_EXT = new Set(['.js', '.test']);

module.exports = {

/**
Expand Down Expand Up @@ -95,7 +93,7 @@ module.exports = {
getAllFiles(src) {
return fs.readdirSync(src)
.filter(fileName => {
return SUPPORTED_TEST_FILE_EXT.has(path.extname(fileName))
return path.extname(fileName) === '.test'
&& fs.statSync(path.join(src, fileName)).isFile();
})
.map(fileName => {
Expand Down
7 changes: 7 additions & 0 deletions tests/languages/asciidoc/entity_feature.html.test
@@ -0,0 +1,7 @@
&#x278a;
&#182;

----------------------------------------------------

<span class="token entity" title="&#x278a;">&amp;#x278a;</span>
<span class="token entity" title="&#182;">&amp;#182;</span>
4 changes: 0 additions & 4 deletions tests/languages/asciidoc/entity_feature.js

This file was deleted.

15 changes: 15 additions & 0 deletions tests/languages/groovy/issue1049.html.test
@@ -0,0 +1,15 @@
"&amp;"
"&amp;&amp;"
"&lt;"
"&lt;&lt;"
"&amp;lt;"
"&gt;"

----------------------------------------------------

<span class="token string gstring">"&amp;amp;"</span>
<span class="token string gstring">"&amp;amp;&amp;amp;"</span>
<span class="token string gstring">"&amp;lt;"</span>
<span class="token string gstring">"&amp;lt;&amp;lt;"</span>
<span class="token string gstring">"&amp;amp;lt;"</span>
<span class="token string gstring">"&amp;gt;"</span>
8 changes: 0 additions & 8 deletions tests/languages/groovy/issue1049.js

This file was deleted.

133 changes: 133 additions & 0 deletions tests/languages/groovy/string-interpolation_feature.html.test
@@ -0,0 +1,133 @@
// Double quoted: interpolation
"$foo"
"${42}"

// Triple double quoted: interpolation
"""$foo"""
"""${42}"""

// Slashy string: interpolation
/$foo/
/${42}/

// Dollar slashy string: interpolation
$/$foo/$
$/${42}/$

// Double quoted: no interpolation (escaped)
"\$foo \${42}"

// Triple double quoted: no interpolation (escaped)
"""\$foo \${42}"""

// Slashy string: no interpolation (escaped)
/\$foo \${42}/

// Dollar slashy string: no interpolation (escaped)
$/$$foo $${42}/$

// Single quoted string: no interpolation
'$foo ${42}'

// Triple single quoted string: no interpolation
'''$foo ${42}'''

----------------------------------------------------

<span class="token comment">// Double quoted: interpolation</span>
<span class="token string gstring">
"
<span class="token expression">
<span class="token punctuation">$</span>
foo
</span>
"
</span>
<span class="token string gstring">
"
<span class="token expression">
<span class="token punctuation">$</span>
<span class="token punctuation">{</span>
<span class="token number">42</span>
<span class="token punctuation">}</span>
</span>
"
</span>

<span class="token comment">// Triple double quoted: interpolation</span>
<span class="token string gstring">
"""
<span class="token expression">
<span class="token punctuation">$</span>
foo
</span>
"""
</span>
<span class="token string gstring">
"""
<span class="token expression">
<span class="token punctuation">$</span>
<span class="token punctuation">{</span>
<span class="token number">42</span>
<span class="token punctuation">}</span>
</span>
"""
</span>

<span class="token comment">// Slashy string: interpolation</span>
<span class="token string regex">
/
<span class="token expression">
<span class="token punctuation">$</span>
foo
</span>
/
</span>
<span class="token string regex">
/
<span class="token expression">
<span class="token punctuation">$</span>
<span class="token punctuation">{</span>
<span class="token number">42</span>
<span class="token punctuation">}</span>
</span>
/
</span>

<span class="token comment">// Dollar slashy string: interpolation</span>
<span class="token string gstring">
$/
<span class="token expression">
<span class="token punctuation">$</span>
foo
</span>
/$
</span>
<span class="token string gstring">
$/
<span class="token expression">
<span class="token punctuation">$</span>
<span class="token punctuation">{</span>
<span class="token number">42</span>
<span class="token punctuation">}</span>
</span>
/$
</span>

<span class="token comment">// Double quoted: no interpolation (escaped)</span>
<span class="token string gstring">"\$foo \${42}"</span>

<span class="token comment">// Triple double quoted: no interpolation (escaped)</span>
<span class="token string gstring">"""\$foo \${42}"""</span>

<span class="token comment">// Slashy string: no interpolation (escaped)</span>
<span class="token string regex">/\$foo \${42}/</span>

<span class="token comment">// Dollar slashy string: no interpolation (escaped)</span>
<span class="token string gstring">$/$$foo $${42}/$</span>

<span class="token comment">// Single quoted string: no interpolation</span>
<span class="token string">'$foo ${42}'</span>

<span class="token comment">// Triple single quoted string: no interpolation</span>
<span class="token string">'''$foo ${42}'''</span>

0 comments on commit 2e834c8

Please sign in to comment.