From 09ac826a32d4ca0a176db60c5d0643a7c48f16c0 Mon Sep 17 00:00:00 2001 From: Guillaume Grossetie Date: Mon, 19 Nov 2018 16:39:19 +0100 Subject: [PATCH] Adds unit tests to the Keep Markup plugin --- package.json | 3 +- plugins/keep-markup/prism-keep-markup.js | 4 +- plugins/keep-markup/prism-keep-markup.min.js | 2 +- tests/plugins/keep-markup/test.js | 92 ++++++++++++++++++++ 4 files changed, 97 insertions(+), 4 deletions(-) create mode 100644 tests/plugins/keep-markup/test.js diff --git a/package.json b/package.json index b4e616bde9..dce27e1364 100755 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "main": "prism.js", "style": "themes/prism.css", "scripts": { - "test": "mocha tests/testrunner-tests.js && mocha tests/run.js" + "test": "mocha tests/testrunner-tests.js && mocha tests/run.js && mocha tests/plugins/**/*.js" }, "repository": { "type": "git", @@ -29,6 +29,7 @@ "gulp-rename": "^1.2.0", "gulp-replace": "^1.0.0", "gulp-uglify": "^3.0.1", + "jsdom": "^13.0.0", "mocha": "^6.0.0", "pump": "^3.0.0", "yargs": "^13.2.2" diff --git a/plugins/keep-markup/prism-keep-markup.js b/plugins/keep-markup/prism-keep-markup.js index bc136c6720..3f87089930 100644 --- a/plugins/keep-markup/prism-keep-markup.js +++ b/plugins/keep-markup/prism-keep-markup.js @@ -1,4 +1,4 @@ -(function () { +(function (self, document) { if (typeof self === 'undefined' || !self.Prism || !self.document || !document.createRange) { return; @@ -96,4 +96,4 @@ env.highlightedCode = env.element.innerHTML; } }); -}()); +}(self, document)); diff --git a/plugins/keep-markup/prism-keep-markup.min.js b/plugins/keep-markup/prism-keep-markup.min.js index 5d072e920a..a0fa98adb8 100644 --- a/plugins/keep-markup/prism-keep-markup.min.js +++ b/plugins/keep-markup/prism-keep-markup.min.js @@ -1 +1 @@ -"undefined"!=typeof self&&self.Prism&&self.document&&document.createRange&&(Prism.plugins.KeepMarkup=!0,Prism.hooks.add("before-highlight",function(e){if(e.element.children.length){var a=0,s=[],l=function(e,n){var o={};n||(o.clone=e.cloneNode(!1),o.posOpen=a,s.push(o));for(var t=0,d=e.childNodes.length;tn.node.posOpen&&(n.nodeStart=d,n.nodeStartPos=n.node.posOpen-n.pos),n.nodeStart&&n.pos+d.data.length>=n.node.posClose&&(n.nodeEnd=d,n.nodeEndPos=n.node.posClose-n.pos),n.pos+=d.data.length);if(n.nodeStart&&n.nodeEnd){var r=document.createRange();return r.setStart(n.nodeStart,n.nodeStartPos),r.setEnd(n.nodeEnd,n.nodeEndPos),n.node.clone.appendChild(r.extractContents()),r.insertNode(n.node.clone),r.detach(),!1}}return!0};n.keepMarkup.forEach(function(e){a(n.element,{node:e,pos:0})}),n.highlightedCode=n.element.innerHTML}})); \ No newline at end of file +"undefined"!=typeof self&&self.Prism&&self.document&&document.createRange&&(Prism.plugins.KeepMarkup=!0,Prism.hooks.add("before-highlight",function(e){if(e.element.children.length){var a=0,s=[],l=function(e,n){var o={};n||(o.clone=e.cloneNode(!1),o.posOpen=a,s.push(o));for(var t=0,d=e.childNodes.length;tn.node.posOpen&&(n.nodeStart=d,n.nodeStartPos=n.node.posOpen-n.pos),n.nodeStart&&n.pos+d.data.length>=n.node.posClose&&(n.nodeEnd=d,n.nodeEndPos=n.node.posClose-n.pos),n.pos+=d.data.length);if(n.nodeStart&&n.nodeEnd){var r=document.createRange();return r.setStart(n.nodeStart,n.nodeStartPos),r.setEnd(n.nodeEnd,n.nodeEndPos),n.node.clone.appendChild(r.extractContents()),r.insertNode(n.node.clone),r.detach(),!1}}return!0};n.keepMarkup.forEach(function(e){a(n.element,{node:e,pos:0})}),n.highlightedCode=n.element.innerHTML}})); diff --git a/tests/plugins/keep-markup/test.js b/tests/plugins/keep-markup/test.js new file mode 100644 index 0000000000..bb0e78b34b --- /dev/null +++ b/tests/plugins/keep-markup/test.js @@ -0,0 +1,92 @@ +const expect = require('chai').expect; +const jsdom = require('jsdom') +const { JSDOM } = jsdom + +require('../../../prism') +// fake DOM +global.self = {} +global.self.Prism = Prism +global.document = {} +document.createRange = function () { +} +global.self.document = document + +require('../../../plugins/keep-markup/prism-keep-markup') + +describe('Prism Keep Markup Plugin', function () { + + function execute (code) { + const start = []; + const end = []; + const nodes = []; + document.createRange = function () { + return { + setStart: function (node, offset) { + start.push({ node, offset }) + }, + setEnd: function (node, offset) { + end.push({ node, offset }) + }, + extractContents: function () { + return new JSDOM('').window.document.createTextNode('') + }, + insertNode: function (node) { + nodes.push(node) + }, + detach: function () { + } + } + } + const beforeHighlight = Prism.hooks.all['before-highlight'][0] + const afterHighlight = Prism.hooks.all['after-highlight'][0] + const env = { + element: new JSDOM(code).window.document.getElementsByTagName('code')[0], + language: "javascript" + } + beforeHighlight(env) + afterHighlight(env) + return { start, end, nodes } + } + + it('should keep markup', function () { + const result = execute(`xay`) + expect(result.start.length).to.equal(1) + expect(result.end.length).to.equal(1) + expect(result.nodes.length).to.equal(1) + expect(result.nodes[0].nodeName).to.equal('SPAN') + }) + it('should preserve markup order', function () { + const result = execute(`xy`) + expect(result.start.length).to.equal(2) + expect(result.start[0].offset).to.equal(0) + expect(result.start[0].node.textContent).to.equal('y') + expect(result.start[1].offset).to.equal(0) + expect(result.start[1].node.textContent).to.equal('y') + expect(result.end.length).to.equal(2) + expect(result.end[0].offset).to.equal(0) + expect(result.end[0].node.textContent).to.equal('y') + expect(result.end[1].offset).to.equal(0) + expect(result.end[1].node.textContent).to.equal('y') + expect(result.nodes.length).to.equal(2) + expect(result.nodes[0].nodeName).to.equal('A') + expect(result.nodes[1].nodeName).to.equal('B') + }) + it('should keep last markup', function () { + const result = execute(`xya`) + expect(result.start.length).to.equal(1) + expect(result.end.length).to.equal(1) + expect(result.nodes.length).to.equal(1) + expect(result.nodes[0].nodeName).to.equal('SPAN') + }) + // The markup is removed if it's the last element and the element's name is a single letter: a(nchor), b(old), i(talic)... + // https://github.com/PrismJS/prism/issues/1618 + /* + it('should keep last single letter empty markup', function () { + const result = execute(`xy`) + expect(result.start.length).to.equal(1) + expect(result.end.length).to.equal(1) + expect(result.nodes.length).to.equal(1) + expect(result.nodes[0].nodeName).to.equal('A') + }) + */ +})