diff --git a/tests/helper/prism-loader.js b/tests/helper/prism-loader.js index 3257485a5f..cb7780d243 100644 --- a/tests/helper/prism-loader.js +++ b/tests/helper/prism-loader.js @@ -1,9 +1,9 @@ "use strict"; -var fs = require("fs"); -var vm = require("vm"); -var components = require("../../components"); -var languagesCatalog = components.languages; +const fs = require("fs"); +const vm = require("vm"); +const components = require("../../components"); +const languagesCatalog = components.languages; module.exports = { @@ -14,8 +14,8 @@ module.exports = { * @param {string|string[]} languages * @returns {Prism} */ - createInstance: function (languages) { - var context = { + createInstance(languages) { + let context = { loadedLanguages: [], Prism: this.createEmptyPrism() }; @@ -33,16 +33,14 @@ module.exports = { * @param {{loadedLanguages: string[], Prism: Prism}} context * @returns {{loadedLanguages: string[], Prism: Prism}} */ - loadLanguages: function (languages, context) { + loadLanguages(languages, context) { if (typeof languages === 'string') { languages = [languages]; } - var self = this; - - languages.forEach(function (language) { - context = self.loadLanguage(language, context); - }); + for (const language of languages) { + context = this.loadLanguage(language, context); + } return context; }, @@ -56,7 +54,7 @@ module.exports = { * @param {{loadedLanguages: string[], Prism: Prism}} context * @returns {{loadedLanguages: string[], Prism: Prism}} */ - loadLanguage: function (language, context) { + loadLanguage(language, context) { if (!languagesCatalog[language]) { throw new Error("Language '" + language + "' not found."); } @@ -72,8 +70,8 @@ module.exports = { } // load the language itself - var languageSource = this.loadFileSource(language); - context.Prism = this.runFileWithContext(languageSource, {Prism: context.Prism}).Prism; + const languageSource = this.loadFileSource(language); + context.Prism = this.runFileWithContext(languageSource, { Prism: context.Prism }).Prism; context.loadedLanguages.push(language); return context; @@ -86,9 +84,9 @@ module.exports = { * @private * @returns {Prism} */ - createEmptyPrism: function () { - var coreSource = this.loadFileSource("core"); - var context = this.runFileWithContext(coreSource); + createEmptyPrism() { + const coreSource = this.loadFileSource("core"); + const context = this.runFileWithContext(coreSource); return context.Prism; }, @@ -109,7 +107,7 @@ module.exports = { * @param {string} name * @returns {string} */ - loadFileSource: function (name) { + loadFileSource(name) { return this.fileSourceCache[name] = this.fileSourceCache[name] || fs.readFileSync(__dirname + "/../../components/prism-" + name + ".js", "utf8"); }, @@ -119,12 +117,11 @@ module.exports = { * * @private * @param {string} fileSource - * @param {*} [context] + * @param {*} [context={}] * * @returns {*} */ - runFileWithContext: function (fileSource, context) { - context = context || {}; + runFileWithContext(fileSource, context = {}) { vm.runInNewContext(fileSource, context); return context; } diff --git a/tests/helper/test-case.js b/tests/helper/test-case.js index e4e5739941..8ba4dc60fc 100644 --- a/tests/helper/test-case.js +++ b/tests/helper/test-case.js @@ -1,9 +1,9 @@ "use strict"; -var fs = require("fs"); -var assert = require("chai").assert; -var PrismLoader = require("./prism-loader"); -var TokenStreamTransformer = require("./token-stream-transformer"); +const fs = require("fs"); +const { assert } = require("chai"); +const PrismLoader = require("./prism-loader"); +const TokenStreamTransformer = require("./token-stream-transformer"); /** * Handles parsing of a test case file. @@ -32,7 +32,6 @@ var TokenStreamTransformer = require("./token-stream-transformer"); * the test case will later be marked as failed. * * - * @type {{runTestCase: Function, transformCompiledTokenStream: Function, parseTestCaseFile: Function}} */ module.exports = { @@ -52,18 +51,18 @@ module.exports = { * @param {string} filePath * @param {boolean} [pretty=false] */ - runTestCase: function (languageIdentifier, filePath, pretty) { - var testCase = this.parseTestCaseFile(filePath); - var usedLanguages = this.parseLanguageNames(languageIdentifier); + runTestCase(languageIdentifier, filePath, pretty = false) { + const testCase = this.parseTestCaseFile(filePath); + const usedLanguages = this.parseLanguageNames(languageIdentifier); if (null === testCase) { throw new Error("Test case file has invalid format (or the provided token stream is invalid JSON), please read the docs."); } - var Prism = PrismLoader.createInstance(usedLanguages.languages); + const Prism = PrismLoader.createInstance(usedLanguages.languages); // the first language is the main language to highlight - var mainLanguageGrammar = Prism.languages[usedLanguages.mainLanguage]; - var env = { + const mainLanguageGrammar = Prism.languages[usedLanguages.mainLanguage]; + const env = { code: testCase.testSource, grammar: mainLanguageGrammar, language: usedLanguages.mainLanguage @@ -71,22 +70,30 @@ module.exports = { Prism.hooks.run('before-tokenize', env); env.tokens = Prism.tokenize(env.code, env.grammar); Prism.hooks.run('after-tokenize', env); - var compiledTokenStream = env.tokens; - - var simplifiedTokenStream = TokenStreamTransformer.simplify(compiledTokenStream); - - var tzd = JSON.stringify(simplifiedTokenStream); - var exp = JSON.stringify(testCase.expectedTokenStream); - var i = 0; var j = 0; var diff = ""; - while (j < tzd.length) { if (exp[i] != tzd[j] || i == exp.length) diff += tzd[j]; else i++; j++; } + const compiledTokenStream = env.tokens; + + const simplifiedTokenStream = TokenStreamTransformer.simplify(compiledTokenStream); + + const tzd = JSON.stringify(simplifiedTokenStream); + const exp = JSON.stringify(testCase.expectedTokenStream); + let i = 0; + let j = 0; + let diff = ""; + while (j < tzd.length) { + if (exp[i] != tzd[j] || i == exp.length) + diff += tzd[j]; + else + i++; + j++; + } const tokenStreamStr = pretty ? TokenStreamTransformer.prettyprint(simplifiedTokenStream) : tzd; - var message = "\nToken Stream: \n" + tokenStreamStr + + const message = "\nToken Stream: \n" + tokenStreamStr + "\n-----------------------------------------\n" + "Expected Token Stream: \n" + exp + "\n-----------------------------------------\n" + diff; - var result = assert.deepEqual(simplifiedTokenStream, testCase.expectedTokenStream, testCase.comment + message); + const result = assert.deepEqual(simplifiedTokenStream, testCase.expectedTokenStream, testCase.comment + message); }, @@ -100,13 +107,13 @@ module.exports = { * * @returns {{languages: string[], mainLanguage: string}} */ - parseLanguageNames: function (languageIdentifier) { - var languages = languageIdentifier.split("+"); - var mainLanguage = null; + parseLanguageNames(languageIdentifier) { + let languages = languageIdentifier.split("+"); + let mainLanguage = null; languages = languages.map( function (language) { - var pos = language.indexOf("!"); + const pos = language.indexOf("!"); if (-1 < pos) { if (mainLanguage) { @@ -139,12 +146,12 @@ module.exports = { * @param {string} filePath * @returns {{testSource: string, expectedTokenStream: Array.>, comment:string?}|null} */ - parseTestCaseFile: function (filePath) { - var testCaseSource = fs.readFileSync(filePath, "utf8"); - var testCaseParts = testCaseSource.split(/^-{10,}\w*$/m); + parseTestCaseFile(filePath) { + const testCaseSource = fs.readFileSync(filePath, "utf8"); + const testCaseParts = testCaseSource.split(/^-{10,}\w*$/m); try { - var testCase = { + const testCase = { testSource: testCaseParts[0].trim(), expectedTokenStream: JSON.parse(testCaseParts[1]), comment: null @@ -172,14 +179,14 @@ module.exports = { * @param {string} languageIdentifier * @param {object} codes */ - runTestsWithHooks: function (languageIdentifier, codes) { - var usedLanguages = this.parseLanguageNames(languageIdentifier); - var Prism = PrismLoader.createInstance(usedLanguages.languages); + runTestsWithHooks(languageIdentifier, codes) { + const usedLanguages = this.parseLanguageNames(languageIdentifier); + const Prism = PrismLoader.createInstance(usedLanguages.languages); // the first language is the main language to highlight - for (var code in codes) { + for (const code in codes) { if (codes.hasOwnProperty(code)) { - var env = { + const env = { element: {}, language: usedLanguages.mainLanguage, grammar: Prism.languages[usedLanguages.mainLanguage], diff --git a/tests/helper/test-discovery.js b/tests/helper/test-discovery.js index b2aade1ad5..b13f902103 100644 --- a/tests/helper/test-discovery.js +++ b/tests/helper/test-discovery.js @@ -1,7 +1,7 @@ "use strict"; -var fs = require("fs"); -var path = require("path"); +const fs = require("fs"); +const path = require("path"); module.exports = { @@ -12,15 +12,13 @@ module.exports = { * @param {string} rootDir * @returns {Object.} */ - loadAllTests: function (rootDir) { - var testSuite = {}; - var self = this; + loadAllTests(rootDir) { + /** @type {Object.} */ + const testSuite = {}; - this.getAllDirectories(rootDir).forEach( - function (language) { - testSuite[language] = self.getAllFiles(path.join(rootDir, language)); - } - ); + for (const language of this.getAllDirectories(rootDir)) { + testSuite[language] = this.getAllFiles(path.join(rootDir, language)); + } return testSuite; }, @@ -32,15 +30,13 @@ module.exports = { * @param {string|string[]} languages * @returns {Object.} */ - loadSomeTests: function (rootDir, languages) { - var testSuite = {}; - var self = this; + loadSomeTests(rootDir, languages) { + /** @type {Object.} */ + const testSuite = {}; - this.getSomeDirectories(rootDir, languages).forEach( - function (language) { - testSuite[language] = self.getAllFiles(path.join(rootDir, language)); - } - ); + for (const language of this.getSomeDirectories(rootDir, languages)) { + testSuite[language] = this.getAllFiles(path.join(rootDir, language)); + } return testSuite; }, @@ -53,12 +49,10 @@ module.exports = { * @param {string} src * @returns {Array.} */ - getAllDirectories: function (src) { - return fs.readdirSync(src).filter( - function (file) { - return fs.statSync(path.join(src, file)).isDirectory(); - } - ); + getAllDirectories(src) { + return fs.readdirSync(src).filter(file => { + return fs.statSync(path.join(src, file)).isDirectory(); + }); }, /** @@ -69,13 +63,10 @@ module.exports = { * @param {string|string[]} languages * @returns {Array.} */ - getSomeDirectories: function (src, languages) { - var self = this; - return fs.readdirSync(src).filter( - function (file) { - return fs.statSync(path.join(src, file)).isDirectory() && self.directoryMatches(file, languages); - } - ); + getSomeDirectories(src, languages) { + return fs.readdirSync(src).filter(file => { + return fs.statSync(path.join(src, file)).isDirectory() && this.directoryMatches(file, languages); + }); }, /** @@ -83,14 +74,12 @@ module.exports = { * @param {string} directory * @param {string|string[]} languages */ - directoryMatches: function (directory, languages) { + directoryMatches(directory, languages) { if (!Array.isArray(languages)) { languages = [languages]; } - var dirLanguages = directory.split(/!?\+!?/); - return dirLanguages.some(function (lang) { - return languages.indexOf(lang) >= 0; - }); + const dirLanguages = directory.split(/!?\+!?/); + return dirLanguages.some(lang => languages.indexOf(lang) >= 0); }, @@ -101,15 +90,13 @@ module.exports = { * @param {string} src * @returns {Array.} */ - getAllFiles: function (src) { - return fs.readdirSync(src).filter( - function (fileName) { + getAllFiles(src) { + return fs.readdirSync(src) + .filter(fileName => { return fs.statSync(path.join(src, fileName)).isFile(); - } - ).map( - function (fileName) { + }) + .map(fileName => { return path.join(src, fileName); - } - ); + }); } }; diff --git a/tests/helper/token-stream-transformer.js b/tests/helper/token-stream-transformer.js index 36c2c25e88..35ee96cafc 100644 --- a/tests/helper/token-stream-transformer.js +++ b/tests/helper/token-stream-transformer.js @@ -2,6 +2,12 @@ module.exports = { + /** + * @typedef TokenStreamItem + * @property {string} type + * @property {string | TokenStreamItem | Array} content + */ + /** * Simplifies the token stream to ease the matching with the expected token stream. * @@ -9,15 +15,14 @@ module.exports = { * * In arrays each value is transformed individually * * Values that are empty (empty arrays or strings only containing whitespace) * - * - * @param {Array} tokenStream - * @returns {Array} + * @param {string | TokenStreamItem | Array} tokenStream + * @returns {Array>} */ - simplify: function (tokenStream) { + simplify(tokenStream) { if (Array.isArray(tokenStream)) { return tokenStream - .map(this.simplify.bind(this)) - .filter(function (value) { + .map(value => this.simplify(value)) + .filter(value => { return !(Array.isArray(value) && !value.length) && !(typeof value === "string" && !value.trim().length); }); } @@ -31,7 +36,7 @@ module.exports = { /** * - * @param {ReadonlyArray} tokenStream + * @param {ReadonlyArray>} tokenStream * @param {number} [indentationLevel=0] */ prettyprint(tokenStream, indentationLevel = 1) { diff --git a/tests/run.js b/tests/run.js index 11b6dbed85..11c036d956 100644 --- a/tests/run.js +++ b/tests/run.js @@ -1,21 +1,20 @@ +// @ts-check "use strict"; -var TestDiscovery = require("./helper/test-discovery"); -var TestCase = require("./helper/test-case"); -var path = require("path"); -var argv = require("yargs").argv; +const TestDiscovery = require("./helper/test-discovery"); +const TestCase = require("./helper/test-case"); +const path = require("path"); +const { argv } = require("yargs"); -var testSuite; -if (argv.language) { - testSuite = TestDiscovery.loadSomeTests(__dirname + "/languages", argv.language); -} else { - // load complete test suite - testSuite = TestDiscovery.loadAllTests(__dirname + "/languages"); -} +const testSuite = + (argv.language) + ? TestDiscovery.loadSomeTests(__dirname + "/languages", argv.language) + // load complete test suite + : TestDiscovery.loadAllTests(__dirname + "/languages"); const pretty = 'pretty' in argv; // define tests for all tests in all languages in the test suite -for (var language in testSuite) { +for (const language in testSuite) { if (!testSuite.hasOwnProperty(language)) { continue; } @@ -24,23 +23,17 @@ for (var language in testSuite) { describe("Testing language '" + language + "'", function () { this.timeout(10000); - testFiles.forEach( - function (filePath) { - var fileName = path.basename(filePath, path.extname(filePath)); - - it("– should pass test case '" + fileName + "'", - function () { - - if (path.extname(filePath) === '.test') { - TestCase.runTestCase(language, filePath, pretty); - } else { - TestCase.runTestsWithHooks(language, require(filePath)); - } - - } - ); - } - ); + for (const filePath of testFiles) { + const fileName = path.basename(filePath, path.extname(filePath)); + + it("– should pass test case '" + fileName + "'", function () { + if (path.extname(filePath) === '.test') { + TestCase.runTestCase(language, filePath, pretty); + } else { + TestCase.runTestsWithHooks(language, require(filePath)); + } + }); + } }); })(language, testSuite[language]); -} \ No newline at end of file +} diff --git a/tests/testrunner-tests.js b/tests/testrunner-tests.js index 24ad32cd8a..03e6fc53a0 100644 --- a/tests/testrunner-tests.js +++ b/tests/testrunner-tests.js @@ -1,166 +1,143 @@ "use strict"; -var assert = require("chai").assert; -var TokenStreamTransformer = require("./helper/token-stream-transformer"); -var TestCase = require("./helper/test-case"); - - -//region Token Stream Transformer -describe("The token stream transformer", - function () { - it("should handle all kinds of simple transformations", - function () { - var tokens = [ - {type: "type", content: "content"}, - "string" - ]; - - var expected = [ - ["type", "content"], - "string" - ]; - - assert.deepEqual(TokenStreamTransformer.simplify(tokens), expected); - } - ); +const { assert } = require("chai"); +const TokenStreamTransformer = require("./helper/token-stream-transformer"); +const TestCase = require("./helper/test-case"); + + +describe("The token stream transformer", function () { + + it("should handle all kinds of simple transformations", function () { + const tokens = [ + { type: "type", content: "content" }, + "string" + ]; + + const expected = [ + ["type", "content"], + "string" + ]; + + assert.deepEqual(TokenStreamTransformer.simplify(tokens), expected); + }); - it("should handle nested structures", - function () { - var tokens = [ + it("should handle nested structures", function () { + const tokens = [ + { + type: "type", + content: [ { - type: "type", + type: "insideType", content: [ - { - type: "insideType", content: - [ - {type: "insideInsideType", content: "content"} - ] - } + { type: "insideInsideType", content: "content" } ] } - ]; + ] + } + ]; - var expected = [ - ["type", [ - ["insideType", [ - ["insideInsideType", "content"] - ]] - ]] - ]; + const expected = [ + ["type", [ + ["insideType", [ + ["insideInsideType", "content"] + ]] + ]] + ]; - assert.deepEqual(TokenStreamTransformer.simplify(tokens), expected); - } - ); + assert.deepEqual(TokenStreamTransformer.simplify(tokens), expected); + }); - it("should strip empty tokens", - function () { - var tokenStream = [ - "", - "\r\n", - "\t", - " " - ]; + it("should strip empty tokens", function () { + const tokenStream = [ + "", + "\r\n", + "\t", + " " + ]; - var expectedSimplified = []; + const expectedSimplified = []; - assert.deepEqual(TokenStreamTransformer.simplify(tokenStream), expectedSimplified); - } - ); + assert.deepEqual(TokenStreamTransformer.simplify(tokenStream), expectedSimplified); + }); - it("should strip empty token tree branches", - function () { - var tokenStream = [ - { - type: "type", - content: [ - ["", ""], - "", - {type: "nested", content: [""]} - ] - }, - [[[[[[[""]]]]]]] - ]; + it("should strip empty token tree branches", function () { + const tokenStream = [ + { + type: "type", + content: [ + ["", ""], + "", + { type: "nested", content: [""] } + ] + }, + [[[[[[[""]]]]]]] + ]; - var expectedSimplified = [ - ["type", [ - ["nested", []] - ]] - ]; + const expectedSimplified = [ + ["type", [ + ["nested", []] + ]] + ]; - assert.deepEqual(TokenStreamTransformer.simplify(tokenStream), expectedSimplified); - } - ); + assert.deepEqual(TokenStreamTransformer.simplify(tokenStream), expectedSimplified); + }); + + + it("should ignore all properties in tokens except value and content", function () { + const tokenStream = [ + { type: "type", content: "content", alias: "alias" } + ]; - it("should ignore all properties in tokens except value and content", - function () { + const expectedSimplified = [ + ["type", "content"] + ]; - var tokenStream = [ - {type: "type", content: "content", alias: "alias"} - ]; + assert.deepEqual(TokenStreamTransformer.simplify(tokenStream), expectedSimplified); + }); +}); - var expectedSimplified = [ - ["type", "content"] - ]; +describe("The language name parsing", function () { - assert.deepEqual(TokenStreamTransformer.simplify(tokenStream), expectedSimplified); + it("should use the last language as the main language if no language is specified", function () { + assert.deepEqual( + TestCase.parseLanguageNames("a"), + { + languages: ["a"], + mainLanguage: "a" } ); - } -); -//endregion - - -//region Language name parsing -describe("The language name parsing", - function () { - it("should use the last language as the main language if no language is specified", - function () { - assert.deepEqual( - TestCase.parseLanguageNames("a"), - { - languages: ["a"], - mainLanguage: "a" - } - ); - assert.deepEqual( - TestCase.parseLanguageNames("a+b+c"), - { - languages: ["a", "b", "c"], - mainLanguage: "c" - } - ); + assert.deepEqual( + TestCase.parseLanguageNames("a+b+c"), + { + languages: ["a", "b", "c"], + mainLanguage: "c" } ); + }); - it("should use the specified language as main language", - function () { - assert.deepEqual( - TestCase.parseLanguageNames("a+b!+c"), - { - languages: ["a", "b", "c"], - mainLanguage: "b" - } - ); + it("should use the specified language as main language", function () { + assert.deepEqual( + TestCase.parseLanguageNames("a+b!+c"), + { + languages: ["a", "b", "c"], + mainLanguage: "b" } ); + }); - it("should throw an error if there are multiple main languages", - function () { - assert.throw( - function () { - TestCase.parseLanguageNames("a+b!+c!"); - }, - "There are multiple main languages defined." - ); - } + it("should throw an error if there are multiple main languages", function () { + assert.throw( + () => { + TestCase.parseLanguageNames("a+b!+c!"); + }, + "There are multiple main languages defined." ); - } -); -//endregion + }); +});