Skip to content

Commit

Permalink
Tests: Additional checks for Prism functions (#1803)
Browse files Browse the repository at this point in the history
This adds additional checks for `extend` and `insertBefore` under `Prism.languages`.
  • Loading branch information
RunDevelopment committed Mar 24, 2019
1 parent 29a30c6 commit c3e74ea
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 5 deletions.
20 changes: 20 additions & 0 deletions tests/checks/extend.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const { testFunction } = require('./../helper/check-functionality');

function extendTest(id, redef) {
const details = `\nextend("${id}", ${redef})`;

// type checks
if (typeof id !== 'string') {
throw new TypeError(`The id argument has to be a 'string'.` + details);
}
if (typeof redef !== 'object') {
throw new TypeError(`The redef argument has to be an 'object'.` + details);
}


if (!(id in Prism.languages)) {
throw new Error(`Cannot extend '${id}' because it is not defined in Prism.languages.`);
}
}

testFunction('extend', Prism.languages, extendTest);
32 changes: 32 additions & 0 deletions tests/checks/insert-before.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
const { testFunction } = require('./../helper/check-functionality');

function insertBeforeTest(inside, before, insert, root) {
const details = `\ninsertBefore("${inside}", "${before}", ${insert}, ${root})`;

// type checks
if (typeof inside !== 'string') {
throw new TypeError(`The inside argument has to be a 'string'.` + details);
}
if (typeof before !== 'string') {
throw new TypeError(`The before argument has to be a 'string'.` + details);
}
if (typeof insert !== 'object') {
throw new TypeError(`The insert argument has to be an 'object'.` + details);
}
if (root && typeof root !== 'object') {
throw new TypeError(`The root argument has to be an 'object' if defined.` + details);
}


root = root || Prism.languages;
var grammar = root[inside];

if (typeof grammar !== 'object') {
throw new Error(`The grammar "${inside}" has to be an 'object' not '${typeof grammar}'.`);
}
if (!(before in grammar)) {
throw new Error(`"${before}" has to be a key of the grammar "${inside}".`);
}
}

testFunction('insertBefore', Prism.languages, insertBeforeTest);
13 changes: 13 additions & 0 deletions tests/helper/check-functionality.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
"use strict";

module.exports = {
testFunction(name, object, tester) {
const func = object[name];

object[name] = function () {
tester.apply(this, arguments);
return func.apply(this, arguments);
};
}

}
58 changes: 53 additions & 5 deletions tests/helper/prism-loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

const fs = require("fs");
const vm = require("vm");
const { getAllFiles } = require("./test-discovery");
const components = require("../../components");
const languagesCatalog = components.languages;

Expand Down Expand Up @@ -70,7 +71,7 @@ module.exports = {
}

// load the language itself
const languageSource = this.loadFileSource(language);
const languageSource = this.loadComponentSource(language);
context.Prism = this.runFileWithContext(languageSource, { Prism: context.Prism }).Prism;
context.loadedLanguages.push(language);

Expand All @@ -85,8 +86,32 @@ module.exports = {
* @returns {Prism}
*/
createEmptyPrism() {
const coreSource = this.loadFileSource("core");
const coreSource = this.loadComponentSource("core");
const context = this.runFileWithContext(coreSource);

for (const testSource of this.getChecks().map(src => this.loadFileSource(src))) {
context.Prism = this.runFileWithContext(testSource, {
Prism: context.Prism,
/**
* A pseudo require function for the checks.
*
* This function will behave like the regular `require` in real modules when called form a check file.
*
* @param {string} id The id of relative path to require.
*/
require(id) {
if (id.startsWith('./')) {
// We have to rewrite relative paths starting with './'
return require('./../checks/' + id.substr(2));
} else {
// This might be an id like 'mocha' or 'fs' or a relative path starting with '../'.
// In both cases we don't have to change anything.
return require(id);
}
}
}).Prism;
}

return context.Prism;
},

Expand All @@ -101,14 +126,37 @@ module.exports = {


/**
* Loads the given file source as string
* Loads the given component's file source as string
*
* @private
* @param {string} name
* @returns {string}
*/
loadFileSource(name) {
return this.fileSourceCache[name] = this.fileSourceCache[name] || fs.readFileSync(__dirname + "/../../components/prism-" + name + ".js", "utf8");
loadComponentSource(name) {
return this.loadFileSource(__dirname + "/../../components/prism-" + name + ".js");
},

/**
* Loads the given file source as string
*
* @private
* @param {string} src
* @returns {string}
*/
loadFileSource(src) {
return this.fileSourceCache[src] = this.fileSourceCache[src] || fs.readFileSync(src, "utf8");
},


checkCache: null,

/**
* Returns a list of files which add additional checks to Prism functions.
*
* @returns {ReadonlyArray<string>}
*/
getChecks() {
return this.checkCache = this.checkCache || getAllFiles(__dirname + "/../checks");
},


Expand Down

0 comments on commit c3e74ea

Please sign in to comment.