/**
 * @license
 * Copyright 2016 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import * as sinon from 'sinon';
import '../../../test/common-test-setup';
import './gr-diff-highlight';
import {getTextOffset} from './gr-range-normalizer';
import {assert, fixture, fixtureCleanup, html} from '@open-wc/testing';
import {DiffBuilderInterface, GrDiffHighlight} from './gr-diff-highlight';
import {Side} from '../../../api/diff';
import {SinonStubbedMember} from 'sinon';
import {queryAndAssert} from '../../../utils/common-util';
import {
  getDataFromCommentThreadEl,
  GrDiffThreadElement,
} from '../gr-diff/gr-diff-utils';
import {
  stubElement,
  waitQueryAndAssert,
  waitUntil,
} from '../../../test/test-utils';
import {GrSelectionActionBox} from '../gr-selection-action-box/gr-selection-action-box';
import {DiffModel, DiffState} from '../gr-diff-model/gr-diff-model';

// Splitting long lines in html into shorter rows breaks tests:
// zero-length text nodes and new lines are not expected in some places

/* prettier-ignore */
const diffTable = html`
  <table id="diffTable">
    <tbody class="section both">
      <tr class="diff-row side-by-side" left-type="both" right-type="both">
        <td class="left lineNum" data-value="1"></td>
        <td class="content both"><div class="contentText">[1] Nam cum ad me in Cumanum salutandi causa uterque venisset,</div></td>
        <td class="right lineNum" data-value="1"></td>
        <td class="content both"><div class="contentText">[1] Nam cum ad me in Cumanum salutandi causa uterque</div></td>
      </tr>
    </tbody>

    <tbody class="section delta">
      <tr class="diff-row side-by-side" left-type="remove" right-type="add">
        <td class="left lineNum" data-value="2"></td>
        <!-- Next tag is formatted to eliminate zero-length text nodes. -->
        <td class="content remove"><div class="contentText">na💢ti <hl class="foo range generated_id314">te, inquit</hl>, sumus<hl class="bar">aliquando</hl> otiosum, <hl>certe</hl> a<hl><span class="tab-indicator" style="tab-size:8;"> </span></hl>udiam, <hl>quid</hl> sit,<span class="tab-indicator" style="tab-size:8;"> </span>quod<hl>Epicurum</hl></div></td>
        <td class="right lineNum" data-value="2"></td>
        <!-- Next tag is formatted to eliminate zero-length text nodes. -->
        <td class="content add"><div class="contentText">nacti , <hl>,</hl> sumus<hl><span class="tab-indicator" style="tab-size:8;"> </span></hl>otiosum,<span class="tab-indicator" style="tab-size:8;"> </span> audiam,sit, quod</div></td>
      </tr>
    </tbody>

    <tbody class="section both">
      <tr class="diff-row side-by-side" left-type="both" right-type="both">
        <td class="left lineNum" data-value="138"></td>
        <td class="content both"><div class="contentText">[14] Nam cum ad me in Cumanum salutandi causa uterque venisset,</div></td>
        <td class="right lineNum" data-value="119"></td>
        <td class="content both"><div class="contentText">[14] Nam cum ad me in Cumanum salutandi causa uterque venisset,</div></td>
      </tr>
    </tbody>

    <tbody class="section delta">
      <tr class="diff-row side-by-side" left-type="remove" right-type="add">
        <td class="left lineNum" data-value="140"></td>
        <!-- Next tag is formatted to eliminate zero-length text nodes. -->
        <td class="content remove"><div class="contentText"><!-- a comment node -->na💢ti <hl class="foo">te, inquit</hl>, sumus <hl class="bar">aliquando</hl> otiosum, <hl>certe</hl> a <hl><span class="tab-indicator" style="tab-size:8;">\u0009</span></hl>udiam, <hl>quid</hl> sit, <span class="tab-indicator" style="tab-size:8;">\u0009</span>quod <hl>Epicurum</hl></div><div class="comment-thread">
          [Yet another random diff thread content here]
        </div></td>
        <td class="right lineNum" data-value="120"></td>
        <!-- Next tag is formatted to eliminate zero-length text nodes. -->
        <td class="content add"><div class="contentText">nacti , <hl>,</hl> sumus <hl><span class="tab-indicator" style="tab-size:8;">\u0009</span></hl> otiosum,  <span class="tab-indicator" style="tab-size:8;">\u0009</span> audiam,  sit, quod</div></td>
      </tr>
    </tbody>

    <tbody class="section both">
      <tr class="diff-row side-by-side" left-type="both" right-type="both">
        <td class="left lineNum" data-value="141"></td>
        <td class="content both"><div class="contentText">nam et<hl><span class="tab-indicator" style="tab-size:8;"> </span></hl>complectitur<span class="tab-indicator" style="tab-size:8;"></span>verbis, quod vult, et dicit plane, quod intellegam;</div></td>
        <td class="right lineNum" data-value="130"></td>
        <td class="content both"><div class="contentText">nam et complectitur verbis, quod vult, et dicit plane, quodintellegam;</div></td>
      </tr>
    </tbody>

    <tbody class="section contextControl">
      <tr
        class="diff-row side-by-side"
        left-type="contextControl"
        right-type="contextControl"
      >
        <td class="left contextLineNum"></td>
        <td>
          <gr-button>+10↑</gr-button>
          -
          <gr-button>Show 21 common lines</gr-button>
          -
          <gr-button>+10↓</gr-button>
        </td>
        <td class="right contextLineNum"></td>
        <td>
          <gr-button>+10↑</gr-button>
          -
          <gr-button>Show 21 common lines</gr-button>
          -
          <gr-button>+10↓</gr-button>
        </td>
      </tr>
    </tbody>

    <tbody class="section delta total">
      <tr class="diff-row side-by-side" left-type="blank" right-type="add">
        <td class="left"></td>
        <td class="blank"></td>
        <td class="right lineNum" data-value="146"></td>
        <td class="content add"><div class="contentText">[17] Quid igitur est? inquit; audire enim cupio, quid non probes. Principio, inquam,</div></td>
      </tr>
    </tbody>

    <tbody class="section both">
      <tr class="diff-row side-by-side" left-type="both" right-type="both">
        <td class="left lineNum" data-value="165"></td>
        <td class="content both"><div class="contentText"></div></td>
        <td class="right lineNum" data-value="147"></td>
        <td class="content both"><div class="contentText">in physicis, <hl><span class="tab-indicator" style="tab-size:8;"> </span></hl>quibus maxime gloriatur, primum totus est alienus. Democritea dicit</div></td>
      </tr>
    </tbody>
  </table>
`;

suite('gr-diff-highlight', () => {
  suite('comment events', () => {
    let threadEl: GrDiffThreadElement;
    let hlRange: HTMLElement;
    let element: GrDiffHighlight;
    let diff: HTMLElement;
    let builder: DiffBuilderInterface;

    setup(async () => {
      diff = await fixture<HTMLTableElement>(diffTable);
      builder = {
        getContentTdByLineEl: sinon.stub(),
        diffModel: new DiffModel(document),
      };
      element = new GrDiffHighlight();
      element.init(diff, builder);
      hlRange = queryAndAssert(diff, 'hl.range.generated_id314');

      threadEl = document.createElement(
        'div'
      ) as unknown as GrDiffThreadElement;
      threadEl.className = 'comment-thread';
      threadEl.rootId = 'id314';
      threadEl.setAttribute('line-num', '12');
      threadEl.setAttribute('diff-side', 'right');
      diff.appendChild(threadEl);
    });

    teardown(() => {
      element.cleanup();
      threadEl.remove();
    });

    test('comment-thread-mouseenter toggles rangeHoverHighlight class', async () => {
      assert.isFalse(hlRange.classList.contains('rangeHoverHighlight'));
      threadEl.dispatchEvent(
        new CustomEvent('comment-thread-mouseenter', {
          detail: getDataFromCommentThreadEl(threadEl),
          bubbles: true,
          composed: true,
        })
      );
      await waitUntil(() => hlRange.classList.contains('rangeHoverHighlight'));
      assert.isTrue(hlRange.classList.contains('rangeHoverHighlight'));
    });

    test('comment-thread-mouseleave toggles rangeHoverHighlight class', async () => {
      hlRange.classList.add('rangeHoverHighlight');
      threadEl.dispatchEvent(
        new CustomEvent('comment-thread-mouseleave', {
          detail: getDataFromCommentThreadEl(threadEl),
          bubbles: true,
          composed: true,
        })
      );
      await waitUntil(() => !hlRange.classList.contains('rangeHoverHighlight'));
      assert.isFalse(hlRange.classList.contains('rangeHoverHighlight'));
    });

    test(`create-range-comment for range when create-comment-requested
          is fired`, () => {
      const removeActionBoxStub = sinon.stub(element, 'removeActionBox');
      const range = {
        start_line: 7,
        start_character: 11,
        end_line: 24,
        end_character: 42,
      };
      element.selectedRange = {side: Side.LEFT, range};
      const createCommentStub = sinon.stub(
        builder.diffModel,
        'createCommentOnRange'
      );

      diff.dispatchEvent(new CustomEvent('create-comment-requested'));

      assert.isTrue(createCommentStub.called);
      assert.deepEqual(createCommentStub.lastCall.args[0], range);
      assert.equal(createCommentStub.lastCall.args[1], Side.LEFT);
      assert.isTrue(removeActionBoxStub.called);
    });
  });

  suite('selection', () => {
    let element: GrDiffHighlight;
    let diff: HTMLElement;
    let getContentTdByLineElStub: SinonStubbedMember<
      DiffBuilderInterface['getContentTdByLineEl']
    >;
    let contentStubs;

    setup(async () => {
      diff = await fixture<HTMLTableElement>(diffTable);
      const builder: DiffBuilderInterface = {
        getContentTdByLineEl: () => undefined,
        diffModel: new DiffModel(document),
      };
      getContentTdByLineElStub = sinon.stub(builder, 'getContentTdByLineEl');
      element = new GrDiffHighlight();
      element.init(diff, builder);
      contentStubs = [];
      stubElement('gr-selection-action-box', 'placeAbove');
      stubElement('gr-selection-action-box', 'placeBelow');
    });

    teardown(() => {
      fixtureCleanup();
      element.cleanup();
      contentStubs = null;
      document.getSelection()!.removeAllRanges();
    });

    const stubContent = (line: number, side: Side) => {
      const contentTd = diff.querySelector(
        `.${side}.lineNum[data-value="${line}"] ~ .content`
      );
      if (!contentTd) assert.fail('content td not found');
      const contentText = contentTd.querySelector('.contentText');
      const lineEl =
        diff.querySelector(`.${side}.lineNum[data-value="${line}"]`) ??
        undefined;
      contentStubs.push({
        lineEl,
        contentTd,
        contentText,
      });
      getContentTdByLineElStub.withArgs(lineEl).returns(contentTd);
      return contentText;
    };

    const emulateSelection = (
      startNode: Node,
      startOffset: number,
      endNode: Node,
      endOffset: number
    ) => {
      const selection = document.getSelection();
      if (!selection) assert.fail('no selection');
      selection.removeAllRanges();
      const range = document.createRange();
      range.setStart(startNode, startOffset);
      range.setEnd(endNode, endOffset);
      selection.addRange(range);
      element.handleSelection(selection, false);
    };

    test('single first line', () => {
      const content = stubContent(1, Side.RIGHT);
      sinon.spy(element, 'positionActionBox');
      if (!content?.firstChild) assert.fail('content first child not found');
      emulateSelection(content.firstChild, 5, content.firstChild, 12);
      const actionBox = diff.querySelector('gr-selection-action-box');
      if (!actionBox) assert.fail('action box not found');
      assert.isTrue(actionBox.positionBelow);
    });

    test('multiline starting on first line', () => {
      const startContent = stubContent(1, Side.RIGHT);
      const endContent = stubContent(2, Side.RIGHT);
      sinon.spy(element, 'positionActionBox');
      if (!startContent?.firstChild) {
        assert.fail('first child of start content not found');
      }
      if (!endContent?.lastChild) {
        assert.fail('last child of end content not found');
      }
      emulateSelection(startContent.firstChild, 10, endContent.lastChild, 7);
      const actionBox = diff.querySelector('gr-selection-action-box');
      if (!actionBox) assert.fail('action box not found');
      assert.isTrue(actionBox.positionBelow);
    });

    test('single line', async () => {
      const content = stubContent(138, Side.LEFT);
      sinon.spy(element, 'positionActionBox');
      if (!content?.firstChild) assert.fail('content first child not found');
      emulateSelection(content.firstChild, 5, content.firstChild, 12);
      const actionBox = await waitQueryAndAssert<GrSelectionActionBox>(
        diff,
        'gr-selection-action-box'
      );
      if (!element.selectedRange) assert.fail('no range selected');
      const {range, side} = element.selectedRange;
      assert.deepEqual(range, {
        start_line: 138,
        start_character: 5,
        end_line: 138,
        end_character: 12,
      });
      assert.equal(side, Side.LEFT);
      assert.notOk(actionBox.positionBelow);
    });

    test('actionBox properties populated correctly', async () => {
      const content = stubContent(138, Side.LEFT);
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      const diffModel = (element as any).diffBuilder.diffModel;
      const getStateStub = sinon.stub(diffModel, 'getState').returns({
        path: 'foo/bar.txt',
      } as unknown as DiffState);

      if (!content?.firstChild) assert.fail('content first child not found');
      emulateSelection(content.firstChild, 5, content.firstChild, 12);

      const actionBox = await waitQueryAndAssert<GrSelectionActionBox>(
        diff,
        'gr-selection-action-box'
      );

      assert.isDefined(actionBox.getSelectionContext);
      const context = await actionBox.getSelectionContext();
      assert.equal(context.path, 'foo/bar.txt');
      assert.equal(context.side, Side.LEFT);
      assert.deepEqual(context.range, {
        start_line: 138,
        start_character: 5,
        end_line: 138,
        end_character: 12,
      });
      assert.equal(context.text, 'Nam cum');
      getStateStub.restore();
    });

    test('multiline', () => {
      const startContent = stubContent(119, Side.RIGHT);
      const endContent = stubContent(120, Side.RIGHT);
      sinon.spy(element, 'positionActionBox');
      if (!startContent?.firstChild) {
        assert.fail('first child of start content not found');
      }
      if (!endContent?.lastChild) {
        assert.fail('last child of end content');
      }
      emulateSelection(startContent.firstChild, 10, endContent.lastChild, 7);
      const actionBox = diff.querySelector('gr-selection-action-box');
      if (!actionBox) assert.fail('action box not found');
      if (!element.selectedRange) assert.fail('no range selected');
      const {range, side} = element.selectedRange;
      assert.deepEqual(range, {
        start_line: 119,
        start_character: 10,
        end_line: 120,
        end_character: 36,
      });
      assert.equal(side, Side.RIGHT);
      assert.notOk(actionBox.positionBelow);
    });

    test('multiple ranges aka firefox implementation', () => {
      const startContent = stubContent(119, Side.RIGHT);
      const endContent = stubContent(120, Side.RIGHT);
      if (!startContent?.firstChild) {
        assert.fail('first child of start content not found');
      }
      if (!endContent?.lastChild) {
        assert.fail('last child of end content');
      }

      const startRange = document.createRange();
      startRange.setStart(startContent.firstChild, 10);
      startRange.setEnd(startContent.firstChild, 11);

      const endRange = document.createRange();
      endRange.setStart(endContent.lastChild, 6);
      endRange.setEnd(endContent.lastChild, 7);

      const getRangeAtStub = sinon.stub();
      getRangeAtStub
        .onFirstCall()
        .returns(startRange)
        .onSecondCall()
        .returns(endRange);
      const selection = {
        rangeCount: 2,
        getRangeAt: getRangeAtStub,
        removeAllRanges: sinon.stub(),
      } as unknown as Selection;
      element.handleSelection(selection, false);
      if (!element.selectedRange) assert.fail('no range selected');
      const {range} = element.selectedRange;
      assert.deepEqual(range, {
        start_line: 119,
        start_character: 10,
        end_line: 120,
        end_character: 36,
      });
    });

    test('multiline grow end highlight over tabs', () => {
      const startContent = stubContent(119, Side.RIGHT);
      const endContent = stubContent(120, Side.RIGHT);
      if (!startContent?.firstChild) {
        assert.fail('first child of start content not found');
      }
      if (!endContent?.firstChild) {
        assert.fail('first child of end content not found');
      }
      emulateSelection(startContent.firstChild, 10, endContent.firstChild, 2);
      if (!element.selectedRange) assert.fail('no range selected');
      const {range, side} = element.selectedRange;
      assert.deepEqual(range, {
        start_line: 119,
        start_character: 10,
        end_line: 120,
        end_character: 2,
      });
      assert.equal(side, Side.RIGHT);
    });

    test('collapsed', () => {
      const content = stubContent(138, Side.LEFT);
      if (!content?.firstChild) {
        assert.fail('first child of content not found');
      }
      emulateSelection(content.firstChild, 5, content.firstChild, 5);
      const sel = document.getSelection();
      if (!sel) assert.fail('no selection');
      assert.isOk(sel.getRangeAt(0).startContainer);
      assert.isFalse(!!element.selectedRange);
    });

    test('starts inside hl', () => {
      const content = stubContent(140, Side.LEFT);
      if (!content) {
        assert.fail('content not found');
      }
      const hl = content.querySelector('.foo');
      if (!hl?.firstChild) {
        assert.fail('first child of hl element not found');
      }
      if (!hl?.nextSibling) {
        assert.fail('next sibling of hl element not found');
      }
      emulateSelection(hl.firstChild, 2, hl.nextSibling, 7);
      if (!element.selectedRange) assert.fail('no range selected');
      const {range, side} = element.selectedRange;
      assert.deepEqual(range, {
        start_line: 140,
        start_character: 8,
        end_line: 140,
        end_character: 23,
      });
      assert.equal(side, Side.LEFT);
    });

    test('ends inside hl', () => {
      const content = stubContent(140, Side.LEFT);
      if (!content) assert.fail('content not found');
      const hl = content.querySelector('.bar');
      if (!hl) assert.fail('hl inside content not found');
      if (!hl.previousSibling) assert.fail('previous sibling not found');
      if (!hl.firstChild) assert.fail('first child not found');
      emulateSelection(hl.previousSibling, 2, hl.firstChild, 3);
      if (!element.selectedRange) assert.fail('no range selected');
      const {range} = element.selectedRange;
      assert.deepEqual(range, {
        start_line: 140,
        start_character: 18,
        end_line: 140,
        end_character: 27,
      });
    });

    test('multiple hl', () => {
      const content = stubContent(140, Side.LEFT);
      if (!content) assert.fail('content not found');
      if (!content.firstChild) assert.fail('first child not found');
      const hl = content.querySelectorAll('hl')[4];
      if (!hl) assert.fail('hl not found');
      if (!hl.firstChild) assert.fail('first child of hl not found');
      emulateSelection(content.firstChild, 2, hl.firstChild, 2);
      if (!element.selectedRange) assert.fail('no range selected');
      const {range, side} = element.selectedRange;
      assert.deepEqual(range, {
        start_line: 140,
        start_character: 2,
        end_line: 140,
        end_character: 61,
      });
      assert.equal(side, Side.LEFT);
    });

    test('starts outside of diff', () => {
      const contentText = stubContent(140, Side.LEFT);
      if (!contentText) assert.fail('content not found');
      if (!contentText.firstChild) assert.fail('child not found');
      const contentTd = contentText.parentElement;
      if (!contentTd) assert.fail('content td not found');
      if (!contentTd.parentElement) assert.fail('parent of td not found');

      emulateSelection(contentTd.parentElement, 0, contentText.firstChild, 2);
      assert.isFalse(!!element.selectedRange);
    });

    test('ends outside of diff', () => {
      const content = stubContent(140, Side.LEFT);
      if (!content) assert.fail('content not found');
      if (!content.firstChild) assert.fail('child not found');
      if (!content.nextElementSibling) assert.fail('sibling not found');
      if (!content.nextElementSibling.firstChild) {
        assert.fail('sibling child not found');
      }
      emulateSelection(
        content.nextElementSibling.firstChild,
        2,
        content.firstChild,
        2
      );
      assert.isFalse(!!element.selectedRange);
    });

    test('starts and ends on different sides', () => {
      const startContent = stubContent(140, Side.LEFT);
      const endContent = stubContent(130, Side.RIGHT);
      if (!startContent?.firstChild) {
        assert.fail('first child of start content not found');
      }
      if (!endContent?.firstChild) {
        assert.fail('first child of end content not found');
      }
      emulateSelection(startContent.firstChild, 2, endContent.firstChild, 2);
      assert.isFalse(!!element.selectedRange);
    });

    test('starts in comment thread element', () => {
      const startContent = stubContent(140, Side.LEFT);
      if (!startContent?.parentElement) {
        assert.fail('parent el of start content not found');
      }
      const comment =
        startContent.parentElement.querySelector('.comment-thread');
      if (!comment?.firstChild) {
        assert.fail('first child of comment not found');
      }
      const endContent = stubContent(141, Side.LEFT);
      if (!endContent?.firstChild) {
        assert.fail('first child of end content not found');
      }
      emulateSelection(comment.firstChild, 2, endContent.firstChild, 4);
      if (!element.selectedRange) assert.fail('no range selected');
      const {range, side} = element.selectedRange;
      assert.deepEqual(range, {
        start_line: 140,
        start_character: 83,
        end_line: 141,
        end_character: 4,
      });
      assert.equal(side, Side.LEFT);
    });

    test('ends in comment thread element', () => {
      const content = stubContent(140, Side.LEFT);
      if (!content?.firstChild) {
        assert.fail('first child of content not found');
      }
      if (!content?.parentElement) {
        assert.fail('parent element of content not found');
      }
      const comment = content.parentElement.querySelector('.comment-thread');
      if (!comment?.firstChild) {
        assert.fail('first child of comment element not found');
      }
      emulateSelection(content.firstChild, 4, comment.firstChild, 1);
      if (!element.selectedRange) assert.fail('no range selected');
      const {range, side} = element.selectedRange;
      assert.deepEqual(range, {
        start_line: 140,
        start_character: 4,
        end_line: 140,
        end_character: 83,
      });
      assert.equal(side, Side.LEFT);
    });

    test('starts in context element', () => {
      const contextControl = diff
        .querySelector('.contextControl')!
        .querySelector('gr-button');
      if (!contextControl) assert.fail('context control not found');
      const content = stubContent(146, Side.RIGHT);
      if (!content) assert.fail('content not found');
      if (!content.firstChild) assert.fail('content child not found');
      emulateSelection(contextControl, 0, content.firstChild, 7);
      // TODO (viktard): Select nearest line.
      assert.isFalse(!!element.selectedRange);
    });

    test('ends in context element', () => {
      const contextControl = diff
        .querySelector('.contextControl')!
        .querySelector('gr-button');
      if (!contextControl) {
        assert.fail('context control element not found');
      }
      const content = stubContent(141, Side.LEFT);
      if (!content?.firstChild) {
        assert.fail('first child of content element not found');
      }
      emulateSelection(content.firstChild, 2, contextControl, 1);
      // TODO (viktard): Select nearest line.
      assert.isFalse(!!element.selectedRange);
    });

    test('selection containing context element', () => {
      const startContent = stubContent(130, Side.RIGHT);
      const endContent = stubContent(146, Side.RIGHT);
      if (!startContent?.firstChild) {
        assert.fail('first child of start content not found');
      }
      if (!endContent?.firstChild) {
        assert.fail('first child of end content not found');
      }
      emulateSelection(startContent.firstChild, 3, endContent.firstChild, 14);
      if (!element.selectedRange) assert.fail('no range selected');
      const {range, side} = element.selectedRange;
      assert.deepEqual(range, {
        start_line: 130,
        start_character: 3,
        end_line: 146,
        end_character: 14,
      });
      assert.equal(side, Side.RIGHT);
    });

    test('ends at a tab', () => {
      const content = stubContent(140, Side.LEFT);
      if (!content?.firstChild) {
        assert.fail('first child of content element not found');
      }
      const span = content.querySelector('span');
      if (!span) assert.fail('span element not found');
      emulateSelection(content.firstChild, 1, span, 0);
      if (!element.selectedRange) assert.fail('no range selected');
      const {range, side} = element.selectedRange;
      assert.deepEqual(range, {
        start_line: 140,
        start_character: 1,
        end_line: 140,
        end_character: 51,
      });
      assert.equal(side, Side.LEFT);
    });

    test('starts at a tab', () => {
      const content = stubContent(140, Side.LEFT);
      if (!content) assert.fail('content element not found');
      emulateSelection(
        content.querySelectorAll('hl')[3],
        0,
        content.querySelectorAll('span')[1].nextSibling!,
        1
      );
      if (!element.selectedRange) assert.fail('no range selected');
      const {range, side} = element.selectedRange;
      assert.deepEqual(range, {
        start_line: 140,
        start_character: 51,
        end_line: 140,
        end_character: 71,
      });
      assert.equal(side, Side.LEFT);
    });

    test('properly accounts for syntax highlighting', () => {
      const content = stubContent(140, Side.LEFT);
      if (!content) assert.fail('content element not found');
      emulateSelection(
        content.querySelectorAll('hl')[3],
        0,
        content.querySelectorAll('span')[1],
        0
      );
      if (!element.selectedRange) assert.fail('no range selected');
      const {range, side} = element.selectedRange;
      assert.deepEqual(range, {
        start_line: 140,
        start_character: 51,
        end_line: 140,
        end_character: 69,
      });
      assert.equal(side, Side.LEFT);
    });

    test('GrRangeNormalizer.getTextOffset computes text offset', () => {
      let content = stubContent(140, Side.LEFT);
      if (!content) assert.fail('content element not found');
      if (!content.lastChild) assert.fail('last child of content not found');
      let child = content.lastChild.lastChild;
      if (!child) assert.fail('last child of last child of content not found');
      let result = getTextOffset(content, child);
      assert.equal(result, 75);
      content = stubContent(146, Side.RIGHT);
      if (!content) assert.fail('content element not found');
      child = content.lastChild;
      if (!child) assert.fail('child element not found');
      result = getTextOffset(content, child);
      assert.equal(result, 0);
    });

    test('fixTripleClickSelection', () => {
      const startContent = stubContent(119, Side.RIGHT);
      const endContent = stubContent(120, Side.RIGHT);
      if (!startContent?.firstChild) {
        assert.fail('first child of start content not found');
      }
      if (!endContent) assert.fail('end content not found');
      if (!endContent.firstChild) assert.fail('first child not found');
      emulateSelection(startContent.firstChild, 0, endContent.firstChild, 0);
      if (!element.selectedRange) assert.fail('no range selected');
      const {range, side} = element.selectedRange;
      assert.deepEqual(range, {
        start_line: 119,
        start_character: 0,
        end_line: 119,
        end_character: element.getLength(startContent),
      });
      assert.equal(side, Side.RIGHT);
    });
  });
});
