]> git.proxmox.com Git - mirror_xterm.js.git/blob - src/Linkifier.test.ts
More tests
[mirror_xterm.js.git] / src / Linkifier.test.ts
1 /**
2 * @license MIT
3 */
4 import jsdom = require('jsdom');
5 import { assert } from 'chai';
6 import { ITerminal, ILinkifier } from './Interfaces';
7 import { Linkifier } from './Linkifier';
8 import { LinkMatcher } from './Types';
9
10 class TestLinkifier extends Linkifier {
11 constructor(document: Document, rows: HTMLElement[]) {
12 Linkifier.TIME_BEFORE_LINKIFY = 0;
13 super(document, rows);
14 }
15
16 public get linkMatchers(): LinkMatcher[] { return this._linkMatchers; }
17 }
18
19 describe('Linkifier', () => {
20 let window: Window;
21 let document: Document;
22
23 let container: HTMLElement;
24 let rows: HTMLElement[];
25 let linkifier: TestLinkifier;
26
27 beforeEach(done => {
28 rows = [];
29 jsdom.env('', (err, w) => {
30 window = w;
31 document = window.document;
32 linkifier = new TestLinkifier(document, rows);
33 container = document.createElement('div');
34 document.body.appendChild(container);
35 done();
36 });
37 });
38
39 function addRow(html: string) {
40 const element = document.createElement('div');
41 element.innerHTML = html;
42 container.appendChild(element);
43 rows.push(element);
44 }
45
46 function clickElement(element: Node) {
47 const event = document.createEvent('MouseEvent');
48 event.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
49 element.dispatchEvent(event);
50 }
51
52 describe('http links', () => {
53 function assertLinkifiesEntireRow(uri: string, done: MochaDone) {
54 addRow(uri);
55 linkifier.linkifyRow(0);
56 setTimeout(() => {
57 assert.equal((<HTMLElement>rows[0].firstChild).tagName, 'A');
58 assert.equal((<HTMLElement>rows[0].firstChild).textContent, uri);
59 done();
60 }, 0);
61 }
62 it('should allow ~ character in URI path', done => assertLinkifiesEntireRow('http://foo.com/a~b#c~d?e~f', done));
63 });
64
65 describe('link matcher', () => {
66 function assertLinkifiesRow(rowText: string, linkMatcherRegex: RegExp, expectedHtml: string, done: MochaDone) {
67 addRow(rowText);
68 linkifier.registerLinkMatcher(linkMatcherRegex, () => {});
69 linkifier.linkifyRow(0);
70 // Allow linkify to happen
71 setTimeout(() => {
72 assert.equal(rows[0].innerHTML, expectedHtml);
73 done();
74 }, 0);
75 }
76 it('should match a single link', done => {
77 assertLinkifiesRow('foo', /foo/, '<a>foo</a>', done);
78 });
79 it('should match a single link at the start of a text node', done => {
80 assertLinkifiesRow('foo bar', /foo/, '<a>foo</a> bar', done);
81 });
82 it('should match a single link in the middle of a text node', done => {
83 assertLinkifiesRow('foo bar baz', /bar/, 'foo <a>bar</a> baz', done);
84 });
85 it('should match a single link at the end of a text node', done => {
86 assertLinkifiesRow('foo bar', /bar/, 'foo <a>bar</a>', done);
87 });
88 it('should match a link after a link at the start of a text node', done => {
89 assertLinkifiesRow('foo bar', /foo|bar/, '<a>foo</a> <a>bar</a>', done);
90 });
91 it('should match a link after a link in the middle of a text node', done => {
92 assertLinkifiesRow('foo bar baz', /bar|baz/, 'foo <a>bar</a> <a>baz</a>', done);
93 });
94 it('should match a link immediately after a link at the end of a text node', done => {
95 assertLinkifiesRow('<span>foo bar</span>baz', /bar|baz/, '<span>foo <a>bar</a></span><a>baz</a>', done);
96 });
97 });
98
99 describe('validationCallback', () => {
100 it('should enable link if true', done => {
101 addRow('test');
102 linkifier.registerLinkMatcher(/test/, () => done(), {
103 validationCallback: (url, cb) => {
104 cb(true);
105 assert.equal((<HTMLElement>rows[0].firstChild).tagName, 'A');
106 setTimeout(() => clickElement(rows[0].firstChild), 0);
107 }
108 });
109 linkifier.linkifyRow(0);
110 });
111
112 it('should disable link if false', done => {
113 addRow('test');
114 linkifier.registerLinkMatcher(/test/, () => assert.fail(), {
115 validationCallback: (url, cb) => {
116 cb(false);
117 assert.equal((<HTMLElement>rows[0].firstChild).tagName, 'A');
118 setTimeout(() => clickElement(rows[0].firstChild), 0);
119 }
120 });
121 linkifier.linkifyRow(0);
122 // Allow time for the click to be performed
123 setTimeout(() => done(), 10);
124 });
125
126 it('should trigger for multiple link matches on one row', done => {
127 addRow('test test');
128 let count = 0;
129 linkifier.registerLinkMatcher(/test/, () => assert.fail(), {
130 validationCallback: (url, cb) => {
131 count += 1;
132 if (count === 2) {
133 done();
134 }
135 cb(false);
136 }
137 });
138 linkifier.linkifyRow(0);
139 });
140 });
141
142 describe('priority', () => {
143 it('should order the list from highest priority to lowest #1', () => {
144 const aId = linkifier.registerLinkMatcher(/a/, () => {}, { priority: 1 });
145 const bId = linkifier.registerLinkMatcher(/b/, () => {}, { priority: -1 });
146 assert.deepEqual(linkifier.linkMatchers.map(lm => lm.id), [aId, 0, bId]);
147 });
148
149 it('should order the list from highest priority to lowest #2', () => {
150 const aId = linkifier.registerLinkMatcher(/a/, () => {}, { priority: -1 });
151 const bId = linkifier.registerLinkMatcher(/b/, () => {}, { priority: 1 });
152 assert.deepEqual(linkifier.linkMatchers.map(lm => lm.id), [bId, 0, aId]);
153 });
154
155 it('should order items of equal priority in the order they are added', () => {
156 const aId = linkifier.registerLinkMatcher(/a/, () => {}, { priority: 0 });
157 const bId = linkifier.registerLinkMatcher(/b/, () => {}, { priority: 0 });
158 assert.deepEqual(linkifier.linkMatchers.map(lm => lm.id), [0, aId, bId]);
159 });
160 });
161 });