Use jsdom instead of phantomjs for linkifier test

This commit is contained in:
Daniel Imms
2017-02-27 11:00:12 -08:00
parent d0f36e9939
commit 26ebc3d944
5 changed files with 84 additions and 85 deletions
+1
View File
@@ -54,6 +54,7 @@
"gulp-sourcemaps": "1.9.1",
"gulp-typescript": "^3.1.3",
"jsdoc": "3.4.3",
"jsdom": "^9.11.0",
"merge-stream": "^1.0.1",
"node-pty": "^0.4.1",
"nodemon": "1.10.2",
-76
View File
@@ -1,76 +0,0 @@
/**
* @license MIT
*/
import { ITerminal, ILinkifier } from './Interfaces';
declare var assert: Chai.Assert;
declare var Terminal: ITerminal;
// Do not describe tests unless in PhantomJS environment
if (typeof Terminal !== 'undefined') {
const Linkifier = (<any>Terminal).Linkifier;
Linkifier.setTimeBeforeLinkifyForTest(0);
describe('Linkifier', () => {
let container: HTMLElement;
let rows: HTMLElement[];
let linkifier: ILinkifier;
beforeEach(() => {
container = document.createElement('div');
document.querySelector('#xterm').appendChild(container);
rows = [];
linkifier = new Linkifier(rows);
});
afterEach(() => {
while (rows.length) {
container.removeChild(rows.pop());
}
document.querySelector('#xterm').removeChild(container);
});
function addRow(text: string) {
const element = document.createElement('div');
element.textContent = text;
container.appendChild(element);
rows.push(element);
}
function clickElement(element: Node) {
const event = document.createEvent('MouseEvent');
event.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
element.dispatchEvent(event);
}
describe('validationCallback', () => {
it('should enable link if true', done => {
addRow('test');
linkifier.registerLinkMatcher(/test/, () => done(), {
validationCallback: (url, cb) => {
cb(true);
assert.equal((<HTMLElement>rows[0].firstChild).tagName, 'A');
setTimeout(() => clickElement(rows[0].firstChild), 0);
}
});
linkifier.linkifyRow(0);
});
it('should disable link if false', done => {
addRow('test');
linkifier.registerLinkMatcher(/test/, () => assert.fail(), {
validationCallback: (url, cb) => {
cb(false);
assert.equal((<HTMLElement>rows[0].firstChild).tagName, 'A');
setTimeout(() => clickElement(rows[0].firstChild), 0);
}
});
linkifier.linkifyRow(0);
// Allow time for the click to be performed
setTimeout(() => done(), 10);
});
});
});
}
+71
View File
@@ -0,0 +1,71 @@
/**
* @license MIT
*/
import jsdom = require('jsdom');
import { assert } from 'chai';
import { ITerminal, ILinkifier } from './Interfaces';
import { Linkifier } from './Linkifier';
Linkifier.setTimeBeforeLinkifyForTest(0);
describe('Linkifier', () => {
let window: Window;
let document: Document;
let container: HTMLElement;
let rows: HTMLElement[];
let linkifier: ILinkifier;
beforeEach(done => {
rows = [];
jsdom.env('', (err, w) => {
window = w;
document = window.document;
linkifier = new Linkifier(document, rows);
container = document.createElement('div');
document.body.appendChild(container);
done();
});
});
function addRow(text: string) {
const element = document.createElement('div');
element.textContent = text;
container.appendChild(element);
rows.push(element);
}
function clickElement(element: Node) {
const event = document.createEvent('MouseEvent');
event.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
element.dispatchEvent(event);
}
describe('validationCallback', () => {
it('should enable link if true', done => {
addRow('test');
linkifier.registerLinkMatcher(/test/, () => done(), {
validationCallback: (url, cb) => {
cb(true);
assert.equal((<HTMLElement>rows[0].firstChild).tagName, 'A');
setTimeout(() => clickElement(rows[0].firstChild), 0);
}
});
linkifier.linkifyRow(0);
});
it('should disable link if false', done => {
addRow('test');
linkifier.registerLinkMatcher(/test/, () => assert.fail(), {
validationCallback: (url, cb) => {
cb(false);
assert.equal((<HTMLElement>rows[0].firstChild).tagName, 'A');
setTimeout(() => clickElement(rows[0].firstChild), 0);
}
});
linkifier.linkifyRow(0);
// Allow time for the click to be performed
setTimeout(() => done(), 10);
});
});
});
+11 -8
View File
@@ -47,12 +47,14 @@ let TIME_BEFORE_LINKIFY = 200;
* The Linkifier applies links to rows shortly after they have been refreshed.
*/
export class Linkifier {
private _document: Document;
private _rows: HTMLElement[];
private _rowTimeoutIds: number[];
private _linkMatchers: LinkMatcher[];
private _nextLinkMatcherId = HYPERTEXT_LINK_MATCHER_ID;
constructor(rows: HTMLElement[]) {
constructor(document: Document, rows: HTMLElement[]) {
this._document = document;
this._rows = rows;
this._rowTimeoutIds = [];
this._linkMatchers = [];
@@ -169,7 +171,8 @@ export class Linkifier {
const linkElement = this._createAnchorElement(uri, handler);
if (node.textContent.length === uri.length) {
// Matches entire string
if (node.nodeType === Node.TEXT_NODE) {
if (node.nodeType === 3 /*Node.TEXT_NODE*/) {
this._replaceNode(node, linkElement);
} else {
const element = (<HTMLElement>node);
@@ -209,7 +212,7 @@ export class Linkifier {
* @return {HTMLAnchorElement} The link.
*/
private _createAnchorElement(uri: string, handler: LinkMatcherHandler): HTMLAnchorElement {
const element = document.createElement('a');
const element = this._document.createElement('a');
element.textContent = uri;
if (handler) {
element.addEventListener('click', () => {
@@ -249,7 +252,7 @@ export class Linkifier {
*/
private _replaceNodeSubstringWithNode(targetNode: Node, newNode: Node, substring: string, substringIndex: number): void {
let node = targetNode;
if (node.nodeType !== Node.TEXT_NODE) {
if (node.nodeType !== 3/*Node.TEXT_NODE*/) {
node = node.childNodes[0];
}
@@ -265,19 +268,19 @@ export class Linkifier {
if (substringIndex === 0) {
// Replace with <newNode><textnode>
const rightText = fullText.substring(substring.length);
const rightTextNode = document.createTextNode(rightText);
const rightTextNode = this._document.createTextNode(rightText);
this._replaceNode(node, newNode, rightTextNode);
} else if (substringIndex === targetNode.textContent.length - substring.length) {
// Replace with <textnode><newNode>
const leftText = fullText.substring(0, substringIndex);
const leftTextNode = document.createTextNode(leftText);
const leftTextNode = this._document.createTextNode(leftText);
this._replaceNode(node, leftTextNode, newNode);
} else {
// Replace with <textnode><newNode><textnode>
const leftText = fullText.substring(0, substringIndex);
const leftTextNode = document.createTextNode(leftText);
const leftTextNode = this._document.createTextNode(leftText);
const rightText = fullText.substring(substringIndex + substring.length);
const rightTextNode = document.createTextNode(rightText);
const rightTextNode = this._document.createTextNode(rightText);
this._replaceNode(node, leftTextNode, newNode, rightTextNode);
}
}
+1 -1
View File
@@ -612,7 +612,7 @@ Terminal.prototype.open = function(parent) {
this.rowContainer.classList.add('xterm-rows');
this.element.appendChild(this.rowContainer);
this.children = [];
this.linkifier = new Linkifier(this.children);
this.linkifier = new Linkifier(document, this.children);
// Create the container that will hold helpers like the textarea for
// capturing DOM Events. Then produce the helpers.