]> git.proxmox.com Git - mirror_xterm.js.git/blobdiff - src/Linkifier.test.ts
Merge pull request #926 from ficristo/search-fix
[mirror_xterm.js.git] / src / Linkifier.test.ts
index 36f825baaf42de448e6f92d240c1e8e0793b237d..132ce5f06e5258780ad48ee18c83f30aff2b0fd4 100644 (file)
@@ -17,6 +17,7 @@ class TestLinkifier extends Linkifier {
 }
 
 describe('Linkifier', () => {
+  let dom: jsdom.JSDOM;
   let window: Window;
   let document: Document;
 
@@ -24,15 +25,20 @@ describe('Linkifier', () => {
   let rows: HTMLElement[];
   let linkifier: TestLinkifier;
 
-  beforeEach(done => {
-    jsdom.env('', (err, w) => {
-      window = w;
-      document = window.document;
-      linkifier = new TestLinkifier();
-      done();
-    });
+  beforeEach(() => {
+    dom = new jsdom.JSDOM('');
+    window = dom.window;
+    document = window.document;
+    linkifier = new TestLinkifier();
   });
 
+  function addRow(html: string) {
+    const element = document.createElement('div');
+    element.innerHTML = html;
+    container.appendChild(element);
+    rows.push(element);
+  }
+
   describe('before attachToDom', () => {
     it('should allow link matcher registration', done => {
       assert.doesNotThrow(() => {
@@ -51,13 +57,6 @@ describe('Linkifier', () => {
       document.body.appendChild(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);
@@ -75,14 +74,63 @@ describe('Linkifier', () => {
     }
 
     describe('http links', () => {
+      function assertLinkifiesEntireRow(uri: string, done: MochaDone) {
+        addRow(uri);
+        linkifier.linkifyRow(0);
+        setTimeout(() => {
+          assert.equal((<HTMLElement>rows[0].firstChild).tagName, 'A');
+          assert.equal((<HTMLElement>rows[0].firstChild).textContent, uri);
+          done();
+        }, 0);
+      }
       it('should allow ~ character in URI path', done => assertLinkifiesEntireRow('http://foo.com/a~b#c~d?e~f', done));
     });
 
+    describe('link matcher', () => {
+      function assertLinkifiesRow(rowText: string, linkMatcherRegex: RegExp, expectedHtml: string, done: MochaDone) {
+        addRow(rowText);
+        linkifier.registerLinkMatcher(linkMatcherRegex, () => {});
+        linkifier.linkifyRow(0);
+        // Allow linkify to happen
+        setTimeout(() => {
+          assert.equal(rows[0].innerHTML, expectedHtml);
+          done();
+        }, 0);
+      }
+      it('should match a single link', done => {
+        assertLinkifiesRow('foo', /foo/, '<a>foo</a>', done);
+      });
+      it('should match a single link at the start of a text node', done => {
+        assertLinkifiesRow('foo bar', /foo/, '<a>foo</a> bar', done);
+      });
+      it('should match a single link in the middle of a text node', done => {
+        assertLinkifiesRow('foo bar baz', /bar/, 'foo <a>bar</a> baz', done);
+      });
+      it('should match a single link at the end of a text node', done => {
+        assertLinkifiesRow('foo bar', /bar/, 'foo <a>bar</a>', done);
+      });
+      it('should match a link after a link at the start of a text node', done => {
+        assertLinkifiesRow('foo bar', /foo|bar/, '<a>foo</a> <a>bar</a>', done);
+      });
+      it('should match a link after a link in the middle of a text node', done => {
+        assertLinkifiesRow('foo bar baz', /bar|baz/, 'foo <a>bar</a> <a>baz</a>', done);
+      });
+      it('should match a link immediately after a link at the end of a text node', done => {
+        assertLinkifiesRow('<span>foo bar</span>baz', /bar|baz/, '<span>foo <a>bar</a></span><a>baz</a>', done);
+      });
+      it('should not duplicate text after a unicode character (wrapped in a span)', done => {
+        // This is a regression test for an issue that came about when using
+        // an oh-my-zsh theme that added the large blue diamond unicode
+        // character (U+1F537) which caused the path to be duplicated. See #642.
+        assertLinkifiesRow('echo \'<span class="xterm-normal-char">🔷</span>foo\'', /foo/, 'echo \'<span class="xterm-normal-char">🔷</span><a>foo</a>\'', done);
+      });
+    });
+
     describe('validationCallback', () => {
       it('should enable link if true', done => {
         addRow('test');
         linkifier.registerLinkMatcher(/test/, () => done(), {
-          validationCallback: (url, cb) => {
+          validationCallback: (url, element, cb) => {
             cb(true);
             assert.equal((<HTMLElement>rows[0].firstChild).tagName, 'A');
             setTimeout(() => clickElement(rows[0].firstChild), 0);
@@ -94,7 +142,7 @@ describe('Linkifier', () => {
       it('should disable link if false', done => {
         addRow('test');
         linkifier.registerLinkMatcher(/test/, () => assert.fail(), {
-          validationCallback: (url, cb) => {
+          validationCallback: (url, element, cb) => {
             cb(false);
             assert.equal((<HTMLElement>rows[0].firstChild).tagName, 'A');
             setTimeout(() => clickElement(rows[0].firstChild), 0);
@@ -104,6 +152,21 @@ describe('Linkifier', () => {
         // Allow time for the click to be performed
         setTimeout(() => done(), 10);
       });
+
+      it('should trigger for multiple link matches on one row', done => {
+        addRow('test test');
+        let count = 0;
+        linkifier.registerLinkMatcher(/test/, () => assert.fail(), {
+          validationCallback: (url, element, cb) => {
+            count += 1;
+            if (count === 2) {
+              done();
+            }
+            cb(false);
+          }
+        });
+        linkifier.linkifyRow(0);
+      });
     });
 
     describe('priority', () => {