/**
 * @license
 * Copyright 2016 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import '../../../test/common-test-setup-karma';
import {
  createConfig,
  createDiff,
  createEmptyDiff,
} from '../../../test/test-data-generators';
import './gr-diff-builder-element';
import {queryAndAssert, stubBaseUrl, waitUntil} from '../../../test/test-utils';
import {GrAnnotation} from '../gr-diff-highlight/gr-annotation';
import {GrDiffLine, GrDiffLineType} from '../gr-diff/gr-diff-line';
import {GrDiffBuilderSideBySide} from './gr-diff-builder-side-by-side';
import {
  DiffContent,
  DiffInfo,
  DiffLayer,
  DiffPreferencesInfo,
  DiffViewMode,
  Side,
} from '../../../api/diff';
import {stubRestApi} from '../../../test/test-utils';
import {GrDiffBuilderLegacy} from './gr-diff-builder-legacy';
import {waitForEventOnce} from '../../../utils/event-util';
import {GrDiffBuilderElement} from './gr-diff-builder-element';
import {createDefaultDiffPrefs} from '../../../constants/constants';
import {KeyLocations} from '../gr-diff-processor/gr-diff-processor';
import {BlameInfo} from '../../../types/common';
import {fixture, html} from '@open-wc/testing';
import {EventType} from '../../../types/events';

const DEFAULT_PREFS = createDefaultDiffPrefs();

suite('gr-diff-builder tests', () => {
  let element: GrDiffBuilderElement;
  let builder: GrDiffBuilderLegacy;
  let diffTable: HTMLTableElement;

  const LINE_BREAK_HTML = '<span class="gr-diff br"></span>';
  const WBR_HTML = '<wbr class="gr-diff">';

  const setBuilderPrefs = (prefs: Partial<DiffPreferencesInfo>) => {
    builder = new GrDiffBuilderSideBySide(
      createEmptyDiff(),
      {...createDefaultDiffPrefs(), ...prefs},
      diffTable
    );
  };

  const line = (text: string) => {
    const line = new GrDiffLine(GrDiffLineType.BOTH);
    line.text = text;
    return line;
  };

  setup(async () => {
    diffTable = await fixture(html`<table id="diffTable"></table>`);
    element = new GrDiffBuilderElement();
    element.diffElement = diffTable;
    stubRestApi('getLoggedIn').returns(Promise.resolve(false));
    stubRestApi('getProjectConfig').returns(Promise.resolve(createConfig()));
    stubBaseUrl('/r');
    setBuilderPrefs({});
  });

  test('line_length applied with <wbr> if line_wrapping is true', () => {
    setBuilderPrefs({line_wrapping: true, tab_size: 4, line_length: 50});
    const text = 'a'.repeat(51);
    const expected = 'a'.repeat(50) + WBR_HTML + 'a';
    const result = builder.createTextEl(null, line(text)).firstElementChild
      ?.innerHTML;
    assert.equal(result, expected);
  });

  test('line_length applied with line break if line_wrapping is false', () => {
    setBuilderPrefs({line_wrapping: false, tab_size: 4, line_length: 50});
    const text = 'a'.repeat(51);
    const expected = 'a'.repeat(50) + LINE_BREAK_HTML + 'a';
    const result = builder.createTextEl(null, line(text)).firstElementChild
      ?.innerHTML;
    assert.equal(result, expected);
  });

  [DiffViewMode.UNIFIED, DiffViewMode.SIDE_BY_SIDE].forEach(mode => {
    test(`line_length used for regular files under ${mode}`, () => {
      element.path = '/a.txt';
      element.viewMode = mode;
      element.diff = createEmptyDiff();
      element.prefs = {
        ...createDefaultDiffPrefs(),
        tab_size: 4,
        line_length: 50,
      };
      builder = element.getDiffBuilder() as GrDiffBuilderLegacy;
      assert.equal(builder._prefs.line_length, 50);
    });

    test(`line_length ignored for commit msg under ${mode}`, () => {
      element.path = '/COMMIT_MSG';
      element.viewMode = mode;
      element.diff = createEmptyDiff();
      element.prefs = {
        ...createDefaultDiffPrefs(),
        tab_size: 4,
        line_length: 50,
      };
      builder = element.getDiffBuilder() as GrDiffBuilderLegacy;
      assert.equal(builder._prefs.line_length, 72);
    });
  });

  test('createTextEl linewrap with tabs', () => {
    setBuilderPrefs({tab_size: 4, line_length: 10});
    const text = '\t'.repeat(7) + '!';
    const el = builder.createTextEl(null, line(text));
    assert.equal(el.innerText, text);
    // With line length 10 and tab size 4, there should be a line break
    // after every two tabs.
    const newlineEl = el.querySelector('.contentText > .br');
    assert.isOk(newlineEl);
    assert.equal(
      el.querySelector('.contentText .tab:nth-child(2)')?.nextSibling,
      newlineEl
    );
  });

  test('_handlePreferenceError throws with invalid preference', () => {
    element.prefs = {...createDefaultDiffPrefs(), tab_size: 0};
    assert.throws(() => element.getDiffBuilder());
  });

  test('_handlePreferenceError triggers alert and javascript error', () => {
    const errorStub = sinon.stub();
    diffTable.addEventListener(EventType.SHOW_ALERT, errorStub);
    assert.throws(() => element.handlePreferenceError('tab size'));
    assert.equal(
      errorStub.lastCall.args[0].detail.message,
      "The value of the 'tab size' user preference is invalid. " +
        'Fix in diff preferences'
    );
  });

  suite('intraline differences', () => {
    let el: HTMLElement;
    let str: string;
    let annotateElementSpy: sinon.SinonSpy;
    let layer: DiffLayer;
    const lineNumberEl = document.createElement('td');

    function slice(str: string, start: number, end?: number) {
      return Array.from(str).slice(start, end).join('');
    }

    setup(async () => {
      el = await fixture(html`
        <div>Lorem ipsum dolor sit amet, suspendisse inceptos vehicula</div>
      `);
      str = el.textContent ?? '';
      annotateElementSpy = sinon.spy(GrAnnotation, 'annotateElement');
      layer = element.createIntralineLayer();
    });

    test('annotate no highlights', () => {
      layer.annotate(el, lineNumberEl, line(str), Side.LEFT);

      // The content is unchanged.
      assert.isFalse(annotateElementSpy.called);
      assert.equal(el.childNodes.length, 1);
      assert.instanceOf(el.childNodes[0], Text);
      assert.equal(str, el.childNodes[0].textContent);
    });

    test('annotate with highlights', () => {
      const l = line(str);
      l.highlights = [
        {contentIndex: 0, startIndex: 6, endIndex: 12},
        {contentIndex: 0, startIndex: 18, endIndex: 22},
      ];
      const str0 = slice(str, 0, 6);
      const str1 = slice(str, 6, 12);
      const str2 = slice(str, 12, 18);
      const str3 = slice(str, 18, 22);
      const str4 = slice(str, 22);

      layer.annotate(el, lineNumberEl, l, Side.LEFT);

      assert.isTrue(annotateElementSpy.called);
      assert.equal(el.childNodes.length, 5);

      assert.instanceOf(el.childNodes[0], Text);
      assert.equal(el.childNodes[0].textContent, str0);

      assert.notInstanceOf(el.childNodes[1], Text);
      assert.equal(el.childNodes[1].textContent, str1);

      assert.instanceOf(el.childNodes[2], Text);
      assert.equal(el.childNodes[2].textContent, str2);

      assert.notInstanceOf(el.childNodes[3], Text);
      assert.equal(el.childNodes[3].textContent, str3);

      assert.instanceOf(el.childNodes[4], Text);
      assert.equal(el.childNodes[4].textContent, str4);
    });

    test('annotate without endIndex', () => {
      const l = line(str);
      l.highlights = [{contentIndex: 0, startIndex: 28}];

      const str0 = slice(str, 0, 28);
      const str1 = slice(str, 28);

      layer.annotate(el, lineNumberEl, l, Side.LEFT);

      assert.isTrue(annotateElementSpy.called);
      assert.equal(el.childNodes.length, 2);

      assert.instanceOf(el.childNodes[0], Text);
      assert.equal(el.childNodes[0].textContent, str0);

      assert.notInstanceOf(el.childNodes[1], Text);
      assert.equal(el.childNodes[1].textContent, str1);
    });

    test('annotate ignores empty highlights', () => {
      const l = line(str);
      l.highlights = [{contentIndex: 0, startIndex: 28, endIndex: 28}];

      layer.annotate(el, lineNumberEl, l, Side.LEFT);

      assert.isFalse(annotateElementSpy.called);
      assert.equal(el.childNodes.length, 1);
    });

    test('annotate handles unicode', () => {
      // Put some unicode into the string:
      str = str.replace(/\s/g, '💢');
      el.textContent = str;
      const l = line(str);
      l.highlights = [{contentIndex: 0, startIndex: 6, endIndex: 12}];

      const str0 = slice(str, 0, 6);
      const str1 = slice(str, 6, 12);
      const str2 = slice(str, 12);

      layer.annotate(el, lineNumberEl, l, Side.LEFT);

      assert.isTrue(annotateElementSpy.called);
      assert.equal(el.childNodes.length, 3);

      assert.instanceOf(el.childNodes[0], Text);
      assert.equal(el.childNodes[0].textContent, str0);

      assert.notInstanceOf(el.childNodes[1], Text);
      assert.equal(el.childNodes[1].textContent, str1);

      assert.instanceOf(el.childNodes[2], Text);
      assert.equal(el.childNodes[2].textContent, str2);
    });

    test('annotate handles unicode w/o endIndex', () => {
      // Put some unicode into the string:
      str = str.replace(/\s/g, '💢');
      el.textContent = str;

      const l = line(str);
      l.highlights = [{contentIndex: 0, startIndex: 6}];

      const str0 = slice(str, 0, 6);
      const str1 = slice(str, 6);

      layer.annotate(el, lineNumberEl, l, Side.LEFT);

      assert.isTrue(annotateElementSpy.called);
      assert.equal(el.childNodes.length, 2);

      assert.instanceOf(el.childNodes[0], Text);
      assert.equal(el.childNodes[0].textContent, str0);

      assert.notInstanceOf(el.childNodes[1], Text);
      assert.equal(el.childNodes[1].textContent, str1);
    });
  });

  suite('tab indicators', () => {
    let layer: DiffLayer;
    const lineNumberEl = document.createElement('td');

    setup(() => {
      element.showTabs = true;
      layer = element.createTabIndicatorLayer();
    });

    test('does nothing with empty line', () => {
      const l = line('');
      const el = document.createElement('div');
      const annotateElementStub = sinon.stub(GrAnnotation, 'annotateElement');

      layer.annotate(el, lineNumberEl, l, Side.LEFT);

      assert.isFalse(annotateElementStub.called);
    });

    test('does nothing with no tabs', () => {
      const str = 'lorem ipsum no tabs';
      const l = line(str);
      const el = document.createElement('div');
      el.textContent = str;
      const annotateElementStub = sinon.stub(GrAnnotation, 'annotateElement');

      layer.annotate(el, lineNumberEl, l, Side.LEFT);

      assert.isFalse(annotateElementStub.called);
    });

    test('annotates tab at beginning', () => {
      const str = '\tlorem upsum';
      const l = line(str);
      const el = document.createElement('div');
      el.textContent = str;
      const annotateElementStub = sinon.stub(GrAnnotation, 'annotateElement');

      layer.annotate(el, lineNumberEl, l, Side.LEFT);

      assert.equal(annotateElementStub.callCount, 1);
      const args = annotateElementStub.getCalls()[0].args;
      assert.equal(args[0], el);
      assert.equal(args[1], 0, 'offset of tab indicator');
      assert.equal(args[2], 1, 'length of tab indicator');
      assert.include(args[3], 'tab-indicator');
    });

    test('does not annotate when disabled', () => {
      element.showTabs = false;

      const str = '\tlorem upsum';
      const l = line(str);
      const el = document.createElement('div');
      el.textContent = str;
      const annotateElementStub = sinon.stub(GrAnnotation, 'annotateElement');

      layer.annotate(el, lineNumberEl, l, Side.LEFT);

      assert.isFalse(annotateElementStub.called);
    });

    test('annotates multiple in beginning', () => {
      const str = '\t\tlorem upsum';
      const l = line(str);
      const el = document.createElement('div');
      el.textContent = str;
      const annotateElementStub = sinon.stub(GrAnnotation, 'annotateElement');

      layer.annotate(el, lineNumberEl, l, Side.LEFT);

      assert.equal(annotateElementStub.callCount, 2);

      let args = annotateElementStub.getCalls()[0].args;
      assert.equal(args[0], el);
      assert.equal(args[1], 0, 'offset of tab indicator');
      assert.equal(args[2], 1, 'length of tab indicator');
      assert.include(args[3], 'tab-indicator');

      args = annotateElementStub.getCalls()[1].args;
      assert.equal(args[0], el);
      assert.equal(args[1], 1, 'offset of tab indicator');
      assert.equal(args[2], 1, 'length of tab indicator');
      assert.include(args[3], 'tab-indicator');
    });

    test('annotates intermediate tabs', () => {
      const str = 'lorem\tupsum';
      const l = line(str);
      const el = document.createElement('div');
      el.textContent = str;
      const annotateElementStub = sinon.stub(GrAnnotation, 'annotateElement');

      layer.annotate(el, lineNumberEl, l, Side.LEFT);

      assert.equal(annotateElementStub.callCount, 1);
      const args = annotateElementStub.getCalls()[0].args;
      assert.equal(args[0], el);
      assert.equal(args[1], 5, 'offset of tab indicator');
      assert.equal(args[2], 1, 'length of tab indicator');
      assert.include(args[3], 'tab-indicator');
    });
  });

  suite('layers', () => {
    let initialLayersCount = 0;
    let withLayerCount = 0;
    setup(() => {
      const layers: DiffLayer[] = [];
      element.layers = layers;
      element.showTrailingWhitespace = true;
      element.setupAnnotationLayers();
      initialLayersCount = element.layersInternal.length;
    });

    test('no layers', () => {
      element.setupAnnotationLayers();
      assert.equal(element.layersInternal.length, initialLayersCount);
    });

    suite('with layers', () => {
      const layers: DiffLayer[] = [{annotate: () => {}}, {annotate: () => {}}];
      setup(() => {
        element.layers = layers;
        element.showTrailingWhitespace = true;
        element.setupAnnotationLayers();
        withLayerCount = element.layersInternal.length;
      });
      test('with layers', () => {
        element.setupAnnotationLayers();
        assert.equal(element.layersInternal.length, withLayerCount);
        assert.equal(initialLayersCount + layers.length, withLayerCount);
      });
    });
  });

  suite('trailing whitespace', () => {
    let layer: DiffLayer;
    const lineNumberEl = document.createElement('td');

    setup(() => {
      element.showTrailingWhitespace = true;
      layer = element.createTrailingWhitespaceLayer();
    });

    test('does nothing with empty line', () => {
      const l = line('');
      const el = document.createElement('div');
      const annotateElementStub = sinon.stub(GrAnnotation, 'annotateElement');
      layer.annotate(el, lineNumberEl, l, Side.LEFT);
      assert.isFalse(annotateElementStub.called);
    });

    test('does nothing with no trailing whitespace', () => {
      const str = 'lorem ipsum blah blah';
      const l = line(str);
      const el = document.createElement('div');
      el.textContent = str;
      const annotateElementStub = sinon.stub(GrAnnotation, 'annotateElement');
      layer.annotate(el, lineNumberEl, l, Side.LEFT);
      assert.isFalse(annotateElementStub.called);
    });

    test('annotates trailing spaces', () => {
      const str = 'lorem ipsum   ';
      const l = line(str);
      const el = document.createElement('div');
      el.textContent = str;
      const annotateElementStub = sinon.stub(GrAnnotation, 'annotateElement');
      layer.annotate(el, lineNumberEl, l, Side.LEFT);
      assert.isTrue(annotateElementStub.called);
      assert.equal(annotateElementStub.lastCall.args[1], 11);
      assert.equal(annotateElementStub.lastCall.args[2], 3);
    });

    test('annotates trailing tabs', () => {
      const str = 'lorem ipsum\t\t\t';
      const l = line(str);
      const el = document.createElement('div');
      el.textContent = str;
      const annotateElementStub = sinon.stub(GrAnnotation, 'annotateElement');
      layer.annotate(el, lineNumberEl, l, Side.LEFT);
      assert.isTrue(annotateElementStub.called);
      assert.equal(annotateElementStub.lastCall.args[1], 11);
      assert.equal(annotateElementStub.lastCall.args[2], 3);
    });

    test('annotates mixed trailing whitespace', () => {
      const str = 'lorem ipsum\t \t';
      const l = line(str);
      const el = document.createElement('div');
      el.textContent = str;
      const annotateElementStub = sinon.stub(GrAnnotation, 'annotateElement');
      layer.annotate(el, lineNumberEl, l, Side.LEFT);
      assert.isTrue(annotateElementStub.called);
      assert.equal(annotateElementStub.lastCall.args[1], 11);
      assert.equal(annotateElementStub.lastCall.args[2], 3);
    });

    test('unicode preceding trailing whitespace', () => {
      const str = '💢\t';
      const l = line(str);
      const el = document.createElement('div');
      el.textContent = str;
      const annotateElementStub = sinon.stub(GrAnnotation, 'annotateElement');
      layer.annotate(el, lineNumberEl, l, Side.LEFT);
      assert.isTrue(annotateElementStub.called);
      assert.equal(annotateElementStub.lastCall.args[1], 1);
      assert.equal(annotateElementStub.lastCall.args[2], 1);
    });

    test('does not annotate when disabled', () => {
      element.showTrailingWhitespace = false;
      const str = 'lorem upsum\t \t ';
      const l = line(str);
      const el = document.createElement('div');
      el.textContent = str;
      const annotateElementStub = sinon.stub(GrAnnotation, 'annotateElement');
      layer.annotate(el, lineNumberEl, l, Side.LEFT);
      assert.isFalse(annotateElementStub.called);
    });
  });

  suite('rendering text, images and binary files', () => {
    let processStub: sinon.SinonStub;
    let keyLocations: KeyLocations;
    let content: DiffContent[] = [];

    setup(() => {
      element.viewMode = 'SIDE_BY_SIDE';
      processStub = sinon
        .stub(element.processor, 'process')
        .returns(Promise.resolve());
      keyLocations = {left: {}, right: {}};
      element.prefs = {
        ...DEFAULT_PREFS,
        context: -1,
        syntax_highlighting: true,
      };
      content = [
        {
          a: ['all work and no play make andybons a dull boy'],
          b: ['elgoog elgoog elgoog'],
        },
        {
          ab: [
            'Non eram nescius, Brute, cum, quae summis ingeniis ',
            'exquisitaque doctrina philosophi Graeco sermone tractavissent',
          ],
        },
      ];
    });

    test('text', async () => {
      element.diff = {...createEmptyDiff(), content};
      element.render(keyLocations);
      await waitForEventOnce(diffTable, 'render-content');
      assert.isTrue(processStub.calledOnce);
      assert.isFalse(processStub.lastCall.args[1]);
    });

    test('image', async () => {
      element.diff = {...createEmptyDiff(), content, binary: true};
      element.isImageDiff = true;
      element.render(keyLocations);
      await waitForEventOnce(diffTable, 'render-content');
      assert.isTrue(processStub.calledOnce);
      assert.isTrue(processStub.lastCall.args[1]);
    });

    test('binary', async () => {
      element.diff = {...createEmptyDiff(), content, binary: true};
      element.render(keyLocations);
      await waitForEventOnce(diffTable, 'render-content');
      assert.isTrue(processStub.calledOnce);
      assert.isTrue(processStub.lastCall.args[1]);
    });
  });

  suite('rendering', () => {
    let content: DiffContent[];
    let outputEl: HTMLTableElement;
    let keyLocations: KeyLocations;
    let addColumnsStub: sinon.SinonStub;
    let dispatchStub: sinon.SinonStub;
    let builder: GrDiffBuilderSideBySide;

    setup(() => {
      const prefs = {...DEFAULT_PREFS};
      content = [
        {
          a: ['all work and no play make andybons a dull boy'],
          b: ['elgoog elgoog elgoog'],
        },
        {
          ab: [
            'Non eram nescius, Brute, cum, quae summis ingeniis ',
            'exquisitaque doctrina philosophi Graeco sermone tractavissent',
          ],
        },
      ];
      dispatchStub = sinon.stub(diffTable, 'dispatchEvent');
      outputEl = element.diffElement!;
      keyLocations = {left: {}, right: {}};
      sinon.stub(element, 'getDiffBuilder').callsFake(() => {
        builder = new GrDiffBuilderSideBySide(
          {...createEmptyDiff(), content},
          prefs,
          outputEl
        );
        addColumnsStub = sinon.stub(builder, 'addColumns');
        builder.buildSectionElement = function (group) {
          const section = document.createElement('stub');
          section.style.display = 'block';
          section.textContent = group.lines.reduce(
            (acc, line) => acc + line.text,
            ''
          );
          return section;
        };
        return builder;
      });
      element.diff = {...createEmptyDiff(), content};
      element.prefs = prefs;
      element.render(keyLocations);
    });

    test('addColumns is called', () => {
      assert.isTrue(addColumnsStub.called);
    });

    test('getGroupsByLineRange one line', () => {
      const section = outputEl.querySelector<HTMLElement>(
        'stub:nth-of-type(3)'
      );
      const groups = builder.getGroupsByLineRange(1, 1, Side.LEFT);
      assert.equal(groups.length, 1);
      assert.strictEqual(groups[0].element, section);
    });

    test('getGroupsByLineRange over diff', () => {
      const section = [
        outputEl.querySelector<HTMLElement>('stub:nth-of-type(3)'),
        outputEl.querySelector<HTMLElement>('stub:nth-of-type(4)'),
      ];
      const groups = builder.getGroupsByLineRange(1, 2, Side.LEFT);
      assert.equal(groups.length, 2);
      assert.strictEqual(groups[0].element, section[0]);
      assert.strictEqual(groups[1].element, section[1]);
    });

    test('render-start and render-content are fired', async () => {
      await waitUntil(() => dispatchStub.callCount >= 1);
      let firedEventTypes = dispatchStub.getCalls().map(c => c.args[0].type);
      assert.include(firedEventTypes, 'render-start');

      await waitUntil(() => dispatchStub.callCount >= 2);
      firedEventTypes = dispatchStub.getCalls().map(c => c.args[0].type);
      assert.include(firedEventTypes, 'render-content');
    });

    test('cancel cancels the processor', () => {
      const processorCancelStub = sinon.stub(element.processor, 'cancel');
      element.cancel();
      assert.isTrue(processorCancelStub.called);
    });
  });

  suite('context hiding and expanding', () => {
    let dispatchStub: sinon.SinonStub;

    setup(async () => {
      dispatchStub = sinon.stub(diffTable, 'dispatchEvent');
      element.diff = {
        ...createEmptyDiff(),
        content: [
          {ab: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(i => `unchanged ${i}`)},
          {a: ['before'], b: ['after']},
          {ab: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(i => `unchanged ${10 + i}`)},
        ],
      };
      element.viewMode = DiffViewMode.SIDE_BY_SIDE;

      const keyLocations: KeyLocations = {left: {}, right: {}};
      element.prefs = {
        ...DEFAULT_PREFS,
        context: 1,
      };
      element.render(keyLocations);
      // Make sure all listeners are installed.
      await element.untilGroupsRendered();
    });

    test('hides lines behind two context controls', () => {
      const contextControls = diffTable.querySelectorAll('gr-context-controls');
      assert.equal(contextControls.length, 2);

      const diffRows = diffTable.querySelectorAll('.diff-row');
      // The first two are LOST and FILE line
      assert.equal(diffRows.length, 2 + 1 + 1 + 1);
      assert.include(diffRows[2].textContent, 'unchanged 10');
      assert.include(diffRows[3].textContent, 'before');
      assert.include(diffRows[3].textContent, 'after');
      assert.include(diffRows[4].textContent, 'unchanged 11');
    });

    test('clicking +x common lines expands those lines', () => {
      const contextControls = diffTable.querySelectorAll('gr-context-controls');
      const topExpandCommonButton =
        contextControls[0].shadowRoot?.querySelectorAll<HTMLElement>(
          '.showContext'
        )[0];
      assert.isOk(topExpandCommonButton);
      assert.include(topExpandCommonButton!.textContent, '+9 common lines');
      topExpandCommonButton!.click();
      const diffRows = diffTable.querySelectorAll('.diff-row');
      // The first two are LOST and FILE line
      assert.equal(diffRows.length, 2 + 10 + 1 + 1);
      assert.include(diffRows[2].textContent, 'unchanged 1');
      assert.include(diffRows[3].textContent, 'unchanged 2');
      assert.include(diffRows[4].textContent, 'unchanged 3');
      assert.include(diffRows[5].textContent, 'unchanged 4');
      assert.include(diffRows[6].textContent, 'unchanged 5');
      assert.include(diffRows[7].textContent, 'unchanged 6');
      assert.include(diffRows[8].textContent, 'unchanged 7');
      assert.include(diffRows[9].textContent, 'unchanged 8');
      assert.include(diffRows[10].textContent, 'unchanged 9');
      assert.include(diffRows[11].textContent, 'unchanged 10');
      assert.include(diffRows[12].textContent, 'before');
      assert.include(diffRows[12].textContent, 'after');
      assert.include(diffRows[13].textContent, 'unchanged 11');
    });

    test('unhideLine shows the line with context', async () => {
      dispatchStub.reset();
      element.unhideLine(4, Side.LEFT);

      const diffRows = diffTable.querySelectorAll('.diff-row');
      // The first two are LOST and FILE line
      // Lines 3-5 (Line 4 plus 1 context in each direction) will be expanded
      // Because context expanders do not hide <3 lines, lines 1-2 will also
      // be shown.
      // Lines 6-9 continue to be hidden
      assert.equal(diffRows.length, 2 + 5 + 1 + 1 + 1);
      assert.include(diffRows[2].textContent, 'unchanged 1');
      assert.include(diffRows[3].textContent, 'unchanged 2');
      assert.include(diffRows[4].textContent, 'unchanged 3');
      assert.include(diffRows[5].textContent, 'unchanged 4');
      assert.include(diffRows[6].textContent, 'unchanged 5');
      assert.include(diffRows[7].textContent, 'unchanged 10');
      assert.include(diffRows[8].textContent, 'before');
      assert.include(diffRows[8].textContent, 'after');
      assert.include(diffRows[9].textContent, 'unchanged 11');

      await element.untilGroupsRendered();
      const firedEventTypes = dispatchStub.getCalls().map(c => c.args[0].type);
      assert.include(firedEventTypes, 'render-content');
    });
  });

  suite('mock-diff', () => {
    let builder: GrDiffBuilderSideBySide;
    let diff: DiffInfo;
    let keyLocations: KeyLocations;

    setup(() => {
      element.viewMode = DiffViewMode.SIDE_BY_SIDE;
      diff = createDiff();
      element.diff = diff;

      keyLocations = {left: {}, right: {}};

      element.prefs = {
        ...createDefaultDiffPrefs(),
        line_length: 80,
        show_tabs: true,
        tab_size: 4,
      };
      element.render(keyLocations);
      builder = element.builder as GrDiffBuilderSideBySide;
    });

    test('aria-labels on added line numbers', () => {
      const deltaLineNumberButton = diffTable.querySelectorAll(
        '.lineNumButton.right'
      )[5];

      assert.isOk(deltaLineNumberButton);
      assert.equal(deltaLineNumberButton.getAttribute('aria-label'), '5 added');
    });

    test('aria-labels on removed line numbers', () => {
      const deltaLineNumberButton = diffTable.querySelectorAll(
        '.lineNumButton.left'
      )[10];

      assert.isOk(deltaLineNumberButton);
      assert.equal(
        deltaLineNumberButton.getAttribute('aria-label'),
        '10 removed'
      );
    });

    test('getContentByLine', () => {
      let actual: HTMLElement | null;

      actual = builder.getContentByLine(2, Side.LEFT);
      assert.equal(actual?.textContent, diff.content[0].ab?.[1]);

      actual = builder.getContentByLine(2, Side.RIGHT);
      assert.equal(actual?.textContent, diff.content[0].ab?.[1]);

      actual = builder.getContentByLine(5, Side.LEFT);
      assert.equal(actual?.textContent, diff.content[2].ab?.[0]);

      actual = builder.getContentByLine(5, Side.RIGHT);
      assert.equal(actual?.textContent, diff.content[1].b?.[0]);
    });

    test('getContentTdByLineEl works both with button and td', () => {
      const diffRow = diffTable.querySelectorAll('tr.diff-row')[2];

      const lineNumTdLeft = queryAndAssert(diffRow, 'td.lineNum.left');
      const lineNumButtonLeft = queryAndAssert(lineNumTdLeft, 'button');
      const contentTdLeft = diffRow.querySelectorAll('.content')[0];

      const lineNumTdRight = queryAndAssert(diffRow, 'td.lineNum.right');
      const lineNumButtonRight = queryAndAssert(lineNumTdRight, 'button');
      const contentTdRight = diffRow.querySelectorAll('.content')[1];

      assert.equal(element.getContentTdByLineEl(lineNumTdLeft), contentTdLeft);
      assert.equal(
        element.getContentTdByLineEl(lineNumButtonLeft),
        contentTdLeft
      );
      assert.equal(
        element.getContentTdByLineEl(lineNumTdRight),
        contentTdRight
      );
      assert.equal(
        element.getContentTdByLineEl(lineNumButtonRight),
        contentTdRight
      );
    });

    test('findLinesByRange', () => {
      const lines: GrDiffLine[] = [];
      const elems: HTMLElement[] = [];
      const start = 6;
      const end = 10;
      const count = end - start + 1;

      builder.findLinesByRange(start, end, Side.RIGHT, lines, elems);

      assert.equal(lines.length, count);
      assert.equal(elems.length, count);

      for (let i = 0; i < 5; i++) {
        assert.instanceOf(lines[i], GrDiffLine);
        assert.equal(lines[i].afterNumber, start + i);
        assert.instanceOf(elems[i], HTMLElement);
        assert.equal(lines[i].text, elems[i].textContent);
      }
    });

    test('renderContentByRange', () => {
      const spy = sinon.spy(builder, 'createTextEl');
      const start = 9;
      const end = 14;
      const count = end - start + 1;

      builder.renderContentByRange(start, end, Side.LEFT);

      assert.equal(spy.callCount, count);
      spy.getCalls().forEach((call, i: number) => {
        assert.equal(call.args[1].beforeNumber, start + i);
      });
    });

    test('renderContentByRange non-existent elements', () => {
      const spy = sinon.spy(builder, 'createTextEl');

      sinon
        .stub(builder, 'getLineNumberEl')
        .returns(document.createElement('div'));
      sinon
        .stub(builder, 'findLinesByRange')
        .callsFake((_1, _2, _3, lines, elements) => {
          // Add a line and a corresponding element.
          lines?.push(new GrDiffLine(GrDiffLineType.BOTH));
          const tr = document.createElement('tr');
          const td = document.createElement('td');
          const el = document.createElement('div');
          tr.appendChild(td);
          td.appendChild(el);
          elements?.push(el);

          // Add 2 lines without corresponding elements.
          lines?.push(new GrDiffLine(GrDiffLineType.BOTH));
          lines?.push(new GrDiffLine(GrDiffLineType.BOTH));
        });

      builder.renderContentByRange(1, 10, Side.LEFT);
      // Should be called only once because only one line had a corresponding
      // element.
      assert.equal(spy.callCount, 1);
    });

    test('getLineNumberEl side-by-side left', () => {
      const contentEl = builder.getContentByLine(
        5,
        Side.LEFT,
        element.diffElement as HTMLTableElement
      );
      assert.isOk(contentEl);
      const lineNumberEl = builder.getLineNumberEl(contentEl!, Side.LEFT);
      assert.isOk(lineNumberEl);
      assert.isTrue(lineNumberEl!.classList.contains('lineNum'));
      assert.isTrue(lineNumberEl!.classList.contains(Side.LEFT));
    });

    test('getLineNumberEl side-by-side right', () => {
      const contentEl = builder.getContentByLine(
        5,
        Side.RIGHT,
        element.diffElement as HTMLTableElement
      );
      assert.isOk(contentEl);
      const lineNumberEl = builder.getLineNumberEl(contentEl!, Side.RIGHT);
      assert.isOk(lineNumberEl);
      assert.isTrue(lineNumberEl!.classList.contains('lineNum'));
      assert.isTrue(lineNumberEl!.classList.contains(Side.RIGHT));
    });

    test('getLineNumberEl unified left', async () => {
      // Re-render as unified:
      element.viewMode = 'UNIFIED_DIFF';
      element.render(keyLocations);
      builder = element.builder as GrDiffBuilderSideBySide;

      const contentEl = builder.getContentByLine(
        5,
        Side.LEFT,
        element.diffElement as HTMLTableElement
      );
      assert.isOk(contentEl);
      const lineNumberEl = builder.getLineNumberEl(contentEl!, Side.LEFT);
      assert.isOk(lineNumberEl);
      assert.isTrue(lineNumberEl!.classList.contains('lineNum'));
      assert.isTrue(lineNumberEl!.classList.contains(Side.LEFT));
    });

    test('getLineNumberEl unified right', async () => {
      // Re-render as unified:
      element.viewMode = 'UNIFIED_DIFF';
      element.render(keyLocations);
      builder = element.builder as GrDiffBuilderSideBySide;

      const contentEl = builder.getContentByLine(
        5,
        Side.RIGHT,
        element.diffElement as HTMLTableElement
      );
      assert.isOk(contentEl);
      const lineNumberEl = builder.getLineNumberEl(contentEl!, Side.RIGHT);
      assert.isOk(lineNumberEl);
      assert.isTrue(lineNumberEl!.classList.contains('lineNum'));
      assert.isTrue(lineNumberEl!.classList.contains(Side.RIGHT));
    });

    test('getNextContentOnSide side-by-side left', () => {
      const startElem = builder.getContentByLine(
        5,
        Side.LEFT,
        element.diffElement as HTMLTableElement
      );
      assert.isOk(startElem);
      const expectedStartString = diff.content[2].ab?.[0];
      const expectedNextString = diff.content[2].ab?.[1];
      assert.equal(startElem!.textContent, expectedStartString);

      const nextElem = builder.getNextContentOnSide(startElem!, Side.LEFT);
      assert.isOk(nextElem);
      assert.equal(nextElem!.textContent, expectedNextString);
    });

    test('getNextContentOnSide side-by-side right', () => {
      const startElem = builder.getContentByLine(
        5,
        Side.RIGHT,
        element.diffElement as HTMLTableElement
      );
      const expectedStartString = diff.content[1].b?.[0];
      const expectedNextString = diff.content[1].b?.[1];
      assert.isOk(startElem);
      assert.equal(startElem!.textContent, expectedStartString);

      const nextElem = builder.getNextContentOnSide(startElem!, Side.RIGHT);
      assert.isOk(nextElem);
      assert.equal(nextElem!.textContent, expectedNextString);
    });

    test('getNextContentOnSide unified left', async () => {
      // Re-render as unified:
      element.viewMode = 'UNIFIED_DIFF';
      element.render(keyLocations);
      builder = element.builder as GrDiffBuilderSideBySide;

      const startElem = builder.getContentByLine(
        5,
        Side.LEFT,
        element.diffElement as HTMLTableElement
      );
      const expectedStartString = diff.content[2].ab?.[0];
      const expectedNextString = diff.content[2].ab?.[1];
      assert.isOk(startElem);
      assert.equal(startElem!.textContent, expectedStartString);

      const nextElem = builder.getNextContentOnSide(startElem!, Side.LEFT);
      assert.isOk(nextElem);
      assert.equal(nextElem!.textContent, expectedNextString);
    });

    test('getNextContentOnSide unified right', async () => {
      // Re-render as unified:
      element.viewMode = 'UNIFIED_DIFF';
      element.render(keyLocations);
      builder = element.builder as GrDiffBuilderSideBySide;

      const startElem = builder.getContentByLine(
        5,
        Side.RIGHT,
        element.diffElement as HTMLTableElement
      );
      const expectedStartString = diff.content[1].b?.[0];
      const expectedNextString = diff.content[1].b?.[1];
      assert.isOk(startElem);
      assert.equal(startElem!.textContent, expectedStartString);

      const nextElem = builder.getNextContentOnSide(startElem!, Side.RIGHT);
      assert.isOk(nextElem);
      assert.equal(nextElem!.textContent, expectedNextString);
    });
  });

  suite('blame', () => {
    let mockBlame: BlameInfo[];

    setup(() => {
      mockBlame = [
        {
          author: 'test-author',
          time: 314,
          commit_msg: 'test-commit-message',
          id: 'commit 1',
          ranges: [
            {start: 1, end: 2},
            {start: 10, end: 16},
          ],
        },
        {
          author: 'test-author',
          time: 314,
          commit_msg: 'test-commit-message',
          id: 'commit 2',
          ranges: [
            {start: 4, end: 10},
            {start: 17, end: 32},
          ],
        },
      ];
    });

    test('setBlame attempts to render each blamed line', () => {
      const getBlameStub = sinon
        .stub(builder, 'getBlameTdByLine')
        .returns(undefined);
      builder.setBlame(mockBlame);
      assert.equal(getBlameStub.callCount, 32);
    });

    test('getBlameCommitForBaseLine', () => {
      sinon.stub(builder, 'getBlameTdByLine').returns(undefined);
      builder.setBlame(mockBlame);
      assert.isOk(builder.getBlameCommitForBaseLine(1));
      assert.equal(builder.getBlameCommitForBaseLine(1)?.id, 'commit 1');

      assert.isOk(builder.getBlameCommitForBaseLine(11));
      assert.equal(builder.getBlameCommitForBaseLine(11)?.id, 'commit 1');

      assert.isOk(builder.getBlameCommitForBaseLine(32));
      assert.equal(builder.getBlameCommitForBaseLine(32)?.id, 'commit 2');

      assert.isUndefined(builder.getBlameCommitForBaseLine(33));
    });

    test('getBlameCommitForBaseLine w/o blame returns null', () => {
      assert.isUndefined(builder.getBlameCommitForBaseLine(1));
      assert.isUndefined(builder.getBlameCommitForBaseLine(11));
      assert.isUndefined(builder.getBlameCommitForBaseLine(31));
    });

    test('createBlameCell', () => {
      const mockBlameInfo = {
        time: 1576155200,
        id: '1234567890',
        author: 'Clark Kent',
        commit_msg: 'Testing Commit',
        ranges: [{start: 4, end: 10}],
      };
      const getBlameStub = sinon
        .stub(builder, 'getBlameCommitForBaseLine')
        .returns(mockBlameInfo);
      const line = new GrDiffLine(GrDiffLineType.BOTH);
      line.beforeNumber = 3;
      line.afterNumber = 5;

      const result = builder.createBlameCell(line.beforeNumber);

      assert.isTrue(getBlameStub.calledWithExactly(3));
      assert.equal(result.getAttribute('data-line-number'), '3');
      assert.dom.equal(
        result,
        /* HTML */ `
          <span class="gr-diff">
            <a class="blameDate gr-diff" href="/r/q/1234567890"> 12/12/2019 </a>
            <span class="blameAuthor gr-diff">Clark</span>
            <gr-hovercard class="gr-diff">
              <span class="blameHoverCard gr-diff">
                Commit 1234567890<br />
                Author: Clark Kent<br />
                Date: 12/12/2019<br />
                <br />
                Testing Commit
              </span>
            </gr-hovercard>
          </span>
        `
      );
    });
  });
});
