/**
 * @license
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import '../../../test/common-test-setup-karma.js';
import {getMockDiffResponse} from '../../../test/mocks/diff-response.js';
import './gr-diff.js';
import {GrDiffBuilderImage} from '../gr-diff-builder/gr-diff-builder-image.js';
import {getComputedStyleValue} from '../../../utils/dom-util.js';
import {_setHiddenScroll} from '../../../scripts/hiddenscroll.js';
import {runA11yAudit} from '../../../test/a11y-test-utils.js';
import '@polymer/paper-button/paper-button.js';
import {stubRestApi} from '../../../test/test-utils.js';

const basicFixture = fixtureFromElement('gr-diff');

suite('gr-diff a11y test', () => {
  test('audit', async () => {
    await runA11yAudit(basicFixture);
  });
});

suite('gr-diff tests', () => {
  let element;

  const MINIMAL_PREFS = {tab_size: 2, line_length: 80};

  setup(() => {

  });

  suite('selectionchange event handling', () => {
    const emulateSelection = function() {
      document.dispatchEvent(new CustomEvent('selectionchange'));
    };

    setup(() => {
      element = basicFixture.instantiate();
      sinon.stub(element.$.highlights, 'handleSelectionChange');
    });

    test('enabled if logged in', () => {
      element.loggedIn = true;
      emulateSelection();
      assert.isTrue(element.$.highlights.handleSelectionChange.called);
    });

    test('ignored if logged out', () => {
      element.loggedIn = false;
      emulateSelection();
      assert.isFalse(element.$.highlights.handleSelectionChange.called);
    });
  });

  test('cancel', () => {
    element = basicFixture.instantiate();
    const cancelStub = sinon.stub(element.$.diffBuilder, 'cancel');
    element.cancel();
    assert.isTrue(cancelStub.calledOnce);
  });

  test('line limit with line_wrapping', () => {
    element = basicFixture.instantiate();
    element.prefs = {...MINIMAL_PREFS, line_wrapping: true};
    flush();
    assert.equal(getComputedStyleValue('--line-limit', element), '80ch');
  });

  test('line limit without line_wrapping', () => {
    element = basicFixture.instantiate();
    element.prefs = {...MINIMAL_PREFS, line_wrapping: false};
    flush();
    assert.isNotOk(getComputedStyleValue('--line-limit', element));
  });

  suite('not logged in', () => {
    setup(() => {
      const getLoggedInPromise = Promise.resolve(false);
      stubRestApi('getLoggedIn').returns(getLoggedInPromise);
      element = basicFixture.instantiate();
      return getLoggedInPromise;
    });

    test('toggleLeftDiff', () => {
      element.toggleLeftDiff();
      assert.isTrue(element.classList.contains('no-left'));
      element.toggleLeftDiff();
      assert.isFalse(element.classList.contains('no-left'));
    });

    test('view does not start with displayLine classList', () => {
      assert.isFalse(
          element.shadowRoot
              .querySelector('.diffContainer')
              .classList
              .contains('displayLine'));
    });

    test('displayLine class added called when displayLine is true', () => {
      const spy = sinon.spy(element, '_computeContainerClass');
      element.displayLine = true;
      assert.isTrue(spy.called);
      assert.isTrue(
          element.shadowRoot
              .querySelector('.diffContainer')
              .classList
              .contains('displayLine'));
    });

    test('thread groups', () => {
      const contentEl = document.createElement('div');

      element.changeNum = 123;
      element.patchRange = {basePatchNum: 1, patchNum: 2};
      element.path = 'file.txt';

      element.$.diffBuilder._builder = element.$.diffBuilder._getDiffBuilder(
          getMockDiffResponse(), {...MINIMAL_PREFS});

      // No thread groups.
      assert.isNotOk(element._getThreadGroupForLine(contentEl));

      // A thread group gets created.
      const threadGroupEl = element._getOrCreateThreadGroup(contentEl);
      assert.isOk(threadGroupEl);

      // The new thread group can be fetched.
      assert.isOk(element._getThreadGroupForLine(contentEl));

      assert.equal(contentEl.querySelectorAll('.thread-group').length, 1);
    });

    suite('image diffs', () => {
      let mockFile1;
      let mockFile2;
      setup(() => {
        mockFile1 = {
          body: 'Qk06AAAAAAAAADYAAAAoAAAAAQAAAP////8BACAAAAAAAAAAAAATCwAAE' +
          'wsAAAAAAAAAAAAAAAAA/w==',
          type: 'image/bmp',
        };
        mockFile2 = {
          body: 'Qk06AAAAAAAAADYAAAAoAAAAAQAAAP////8BACAAAAAAAAAAAAATCwAAE' +
          'wsAAAAAAAAAAAAA/////w==',
          type: 'image/bmp',
        };

        element.patchRange = {basePatchNum: 'PARENT', patchNum: 1};
        element.isImageDiff = true;
        element.prefs = {
          context: 10,
          cursor_blink_rate: 0,
          font_size: 12,
          ignore_whitespace: 'IGNORE_NONE',
          intraline_difference: true,
          line_length: 100,
          line_wrapping: false,
          show_line_endings: true,
          show_tabs: true,
          show_whitespace_errors: true,
          syntax_highlighting: true,
          tab_size: 8,
          theme: 'DEFAULT',
        };
      });

      test('renders image diffs with same file name', done => {
        const rendered = () => {
          // Recognizes that it should be an image diff.
          assert.isTrue(element.isImageDiff);
          assert.instanceOf(
              element.$.diffBuilder._builder, GrDiffBuilderImage);

          // Left image rendered with the parent commit's version of the file.
          const leftImage = element.$.diffTable.querySelector('td.left img');
          const leftLabel =
              element.$.diffTable.querySelector('td.left label');
          const leftLabelContent = leftLabel.querySelector('.label');
          const leftLabelName = leftLabel.querySelector('.name');

          const rightImage =
              element.$.diffTable.querySelector('td.right img');
          const rightLabel = element.$.diffTable.querySelector(
              'td.right label');
          const rightLabelContent = rightLabel.querySelector('.label');
          const rightLabelName = rightLabel.querySelector('.name');

          assert.isNotOk(rightLabelName);
          assert.isNotOk(leftLabelName);

          let leftLoaded = false;
          let rightLoaded = false;

          leftImage.addEventListener('load', () => {
            assert.isOk(leftImage);
            assert.equal(leftImage.getAttribute('src'),
                'data:image/bmp;base64, ' + mockFile1.body);
            assert.equal(leftLabelContent.textContent, '1\u00d71 image/bmp');// \u00d7 - '×'
            leftLoaded = true;
            if (rightLoaded) {
              element.removeEventListener('render', rendered);
              done();
            }
          });

          rightImage.addEventListener('load', () => {
            assert.isOk(rightImage);
            assert.equal(rightImage.getAttribute('src'),
                'data:image/bmp;base64, ' + mockFile2.body);
            assert.equal(rightLabelContent.textContent, '1\u00d71 image/bmp');// \u00d7 - '×'

            rightLoaded = true;
            if (leftLoaded) {
              element.removeEventListener('render', rendered);
              done();
            }
          });
        };

        element.addEventListener('render', rendered);

        element.baseImage = mockFile1;
        element.revisionImage = mockFile2;
        element.diff = {
          meta_a: {name: 'carrot.jpg', content_type: 'image/jpeg', lines: 66},
          meta_b: {name: 'carrot.jpg', content_type: 'image/jpeg',
            lines: 560},
          intraline_status: 'OK',
          change_type: 'MODIFIED',
          diff_header: [
            'diff --git a/carrot.jpg b/carrot.jpg',
            'index 2adc47d..f9c2f2c 100644',
            '--- a/carrot.jpg',
            '+++ b/carrot.jpg',
            'Binary files differ',
          ],
          content: [{skip: 66}],
          binary: true,
        };
      });

      test('renders image diffs with a different file name', done => {
        const mockDiff = {
          meta_a: {name: 'carrot.jpg', content_type: 'image/jpeg', lines: 66},
          meta_b: {name: 'carrot2.jpg', content_type: 'image/jpeg',
            lines: 560},
          intraline_status: 'OK',
          change_type: 'MODIFIED',
          diff_header: [
            'diff --git a/carrot.jpg b/carrot2.jpg',
            'index 2adc47d..f9c2f2c 100644',
            '--- a/carrot.jpg',
            '+++ b/carrot2.jpg',
            'Binary files differ',
          ],
          content: [{skip: 66}],
          binary: true,
        };

        const rendered = () => {
          // Recognizes that it should be an image diff.
          assert.isTrue(element.isImageDiff);
          assert.instanceOf(
              element.$.diffBuilder._builder, GrDiffBuilderImage);

          // Left image rendered with the parent commit's version of the file.
          const leftImage = element.$.diffTable.querySelector('td.left img');
          const leftLabel =
              element.$.diffTable.querySelector('td.left label');
          const leftLabelContent = leftLabel.querySelector('.label');
          const leftLabelName = leftLabel.querySelector('.name');

          const rightImage =
              element.$.diffTable.querySelector('td.right img');
          const rightLabel = element.$.diffTable.querySelector(
              'td.right label');
          const rightLabelContent = rightLabel.querySelector('.label');
          const rightLabelName = rightLabel.querySelector('.name');

          assert.isOk(rightLabelName);
          assert.isOk(leftLabelName);
          assert.equal(leftLabelName.textContent, mockDiff.meta_a.name);
          assert.equal(rightLabelName.textContent, mockDiff.meta_b.name);

          let leftLoaded = false;
          let rightLoaded = false;

          leftImage.addEventListener('load', () => {
            assert.isOk(leftImage);
            assert.equal(leftImage.getAttribute('src'),
                'data:image/bmp;base64, ' + mockFile1.body);
            assert.equal(leftLabelContent.textContent, '1\u00d71 image/bmp');// \u00d7 - '×'
            leftLoaded = true;
            if (rightLoaded) {
              element.removeEventListener('render', rendered);
              done();
            }
          });

          rightImage.addEventListener('load', () => {
            assert.isOk(rightImage);
            assert.equal(rightImage.getAttribute('src'),
                'data:image/bmp;base64, ' + mockFile2.body);
            assert.equal(rightLabelContent.textContent, '1\u00d71 image/bmp');// \u00d7 - '×'

            rightLoaded = true;
            if (leftLoaded) {
              element.removeEventListener('render', rendered);
              done();
            }
          });
        };

        element.addEventListener('render', rendered);

        element.baseImage = mockFile1;
        element.baseImage._name = mockDiff.meta_a.name;
        element.revisionImage = mockFile2;
        element.revisionImage._name = mockDiff.meta_b.name;
        element.diff = mockDiff;
      });

      test('renders added image', done => {
        const mockDiff = {
          meta_b: {name: 'carrot.jpg', content_type: 'image/jpeg',
            lines: 560},
          intraline_status: 'OK',
          change_type: 'ADDED',
          diff_header: [
            'diff --git a/carrot.jpg b/carrot.jpg',
            'index 0000000..f9c2f2c 100644',
            '--- /dev/null',
            '+++ b/carrot.jpg',
            'Binary files differ',
          ],
          content: [{skip: 66}],
          binary: true,
        };

        function rendered() {
          // Recognizes that it should be an image diff.
          assert.isTrue(element.isImageDiff);
          assert.instanceOf(
              element.$.diffBuilder._builder, GrDiffBuilderImage);

          const leftImage = element.$.diffTable.querySelector('td.left img');
          const rightImage = element.$.diffTable.querySelector('td.right img');

          assert.isNotOk(leftImage);
          assert.isOk(rightImage);
          done();
          element.removeEventListener('render', rendered);
        }
        element.addEventListener('render', rendered);

        element.revisionImage = mockFile2;
        element.diff = mockDiff;
      });

      test('renders removed image', done => {
        const mockDiff = {
          meta_a: {name: 'carrot.jpg', content_type: 'image/jpeg',
            lines: 560},
          intraline_status: 'OK',
          change_type: 'DELETED',
          diff_header: [
            'diff --git a/carrot.jpg b/carrot.jpg',
            'index f9c2f2c..0000000 100644',
            '--- a/carrot.jpg',
            '+++ /dev/null',
            'Binary files differ',
          ],
          content: [{skip: 66}],
          binary: true,
        };

        function rendered() {
          // Recognizes that it should be an image diff.
          assert.isTrue(element.isImageDiff);
          assert.instanceOf(
              element.$.diffBuilder._builder, GrDiffBuilderImage);

          const leftImage = element.$.diffTable.querySelector('td.left img');
          const rightImage = element.$.diffTable.querySelector('td.right img');

          assert.isOk(leftImage);
          assert.isNotOk(rightImage);
          done();
          element.removeEventListener('render', rendered);
        }
        element.addEventListener('render', rendered);

        element.baseImage = mockFile1;
        element.diff = mockDiff;
      });

      test('does not render disallowed image type', done => {
        const mockDiff = {
          meta_a: {name: 'carrot.jpg', content_type: 'image/jpeg-evil',
            lines: 560},
          intraline_status: 'OK',
          change_type: 'DELETED',
          diff_header: [
            'diff --git a/carrot.jpg b/carrot.jpg',
            'index f9c2f2c..0000000 100644',
            '--- a/carrot.jpg',
            '+++ /dev/null',
            'Binary files differ',
          ],
          content: [{skip: 66}],
          binary: true,
        };
        mockFile1.type = 'image/jpeg-evil';

        function rendered() {
          // Recognizes that it should be an image diff.
          assert.isTrue(element.isImageDiff);
          assert.instanceOf(
              element.$.diffBuilder._builder, GrDiffBuilderImage);
          const leftImage = element.$.diffTable.querySelector('td.left img');
          assert.isNotOk(leftImage);
          done();
          element.removeEventListener('render', rendered);
        }
        element.addEventListener('render', rendered);

        element.baseImage = mockFile1;
        element.diff = mockDiff;
      });
    });

    test('_handleTap lineNum', done => {
      const addDraftStub = sinon.stub(element, 'addDraftAtLine');
      const el = document.createElement('div');
      el.className = 'lineNum';
      el.addEventListener('click', e => {
        element._handleTap(e);
        assert.isTrue(addDraftStub.called);
        assert.equal(addDraftStub.lastCall.args[0], el);
        done();
      });
      el.click();
    });

    test('_handleTap context', done => {
      const showContextStub =
          sinon.stub(element.$.diffBuilder, 'showContext');
      const el = document.createElement('div');
      el.className = 'showContext';
      el.addEventListener('click', e => {
        element._handleTap(e);
        assert.isTrue(showContextStub.called);
        done();
      });
      el.click();
    });

    test('_handleTap content', done => {
      const content = document.createElement('div');
      const lineEl = document.createElement('div');

      const selectStub = sinon.stub(element, '_selectLine');
      sinon.stub(element.$.diffBuilder, 'getLineElByChild')
          .callsFake(() => lineEl);

      content.className = 'content';
      content.addEventListener('click', e => {
        element._handleTap(e);
        assert.isTrue(selectStub.called);
        assert.equal(selectStub.lastCall.args[0], lineEl);
        done();
      });
      content.click();
    });

    suite('getCursorStops', () => {
      function setupDiff() {
        element.diff = getMockDiffResponse();
        element.prefs = {
          context: 10,
          tab_size: 8,
          font_size: 12,
          line_length: 100,
          cursor_blink_rate: 0,
          line_wrapping: false,
          intraline_difference: true,
          show_line_endings: true,
          show_tabs: true,
          show_whitespace_errors: true,
          syntax_highlighting: true,
          theme: 'DEFAULT',
          ignore_whitespace: 'IGNORE_NONE',
        };

        element._renderDiffTable();
        element._setLoading(false);
        flush();
      }

      test('getCursorStops returns [] when hidden and noAutoRender', () => {
        element.noAutoRender = true;
        setupDiff();
        element.hidden = true;
        assert.equal(element.getCursorStops().length, 0);
      });

      test('getCursorStops', () => {
        setupDiff();
        const ROWS = 48;
        const FILE_ROW = 1;
        assert.equal(element.getCursorStops().length, ROWS + FILE_ROW);
      });
    });

    test('adds .hiddenscroll', () => {
      _setHiddenScroll(true);
      element.displayLine = true;
      assert.include(element.shadowRoot
          .querySelector('.diffContainer').className, 'hiddenscroll');
    });
  });

  suite('logged in', () => {
    let fakeLineEl;
    setup(() => {
      element = basicFixture.instantiate();
      element.loggedIn = true;
      element.patchRange = {};

      fakeLineEl = {
        getAttribute: sinon.stub().returns(42),
        classList: {
          contains: sinon.stub().returns(true),
        },
      };
    });

    test('addDraftAtLine', () => {
      sinon.stub(element, '_selectLine');
      sinon.stub(element, '_createComment');
      element.addDraftAtLine(fakeLineEl);
      assert.isTrue(element._createComment
          .calledWithExactly(fakeLineEl, 42));
    });

    test('adds long range comment chip', async () => {
      const range = {
        start_line: 1,
        end_line: 7,
        start_character: 0,
        end_character: 0,
      };
      const threadEl = document.createElement('div');
      threadEl.className = 'comment-thread';
      threadEl.setAttribute('diff-side', 'right');
      threadEl.setAttribute('line-num', 1);
      threadEl.setAttribute('range', JSON.stringify(range));
      threadEl.setAttribute('slot', 'right-1');
      const content = [{
        a: [],
        b: [],
      }, {
        ab: Array(8).fill('text'),
      }];
      setupSampleDiff({content});

      element.appendChild(threadEl);
      await flush();

      assert.deepEqual(
          element.querySelector('gr-ranged-comment-chip').range, range);
    });

    test('no duplicate range chip for same thread', async () => {
      const range = {
        start_line: 1,
        end_line: 7,
        start_character: 0,
        end_character: 0,
      };
      const threadEl = document.createElement('div');
      threadEl.className = 'comment-thread';
      threadEl.setAttribute('diff-side', 'right');
      threadEl.setAttribute('line-num', 1);
      threadEl.setAttribute('range', JSON.stringify(range));
      threadEl.setAttribute('slot', 'right-1');
      const firstChip = document.createElement('gr-ranged-comment-chip');
      firstChip.range = range;
      firstChip.setAttribute('threadElRootId', threadEl.rootId);
      firstChip.setAttribute('slot', 'right-1');
      const content = [{
        a: [],
        b: [],
      }, {
        ab: Array(8).fill('text'),
      }];
      setupSampleDiff({content});

      element.appendChild(firstChip);
      await flush();
      element._handleRenderContent();
      await flush();
      element.appendChild(threadEl);
      await flush();

      assert.equal(
          element.querySelectorAll('gr-ranged-comment-chip').length, 1);
    });

    test('removes long range comment chip when comment is discarded',
        async () => {
          const range = {
            start_line: 1,
            end_line: 7,
            start_character: 0,
            end_character: 0,
          };
          const threadEl = document.createElement('div');
          threadEl.className = 'comment-thread';
          threadEl.setAttribute('diff-side', 'right');
          threadEl.setAttribute('line-num', 1);
          threadEl.setAttribute('range', JSON.stringify(range));
          threadEl.setAttribute('slot', 'right-1');
          const content = [{
            a: [],
            b: [],
          }, {
            ab: Array(8).fill('text'),
          }];
          setupSampleDiff({content});
          element.appendChild(threadEl);
          await flush();

          threadEl.remove();
          await flush();

          assert.isEmpty(element.querySelectorAll('gr-ranged-comment-chip'));
        });

    suite('change in preferences', () => {
      setup(() => {
        element.diff = {
          meta_a: {name: 'carrot.jpg', content_type: 'image/jpeg', lines: 66},
          meta_b: {name: 'carrot.jpg', content_type: 'image/jpeg',
            lines: 560},
          diff_header: [],
          intraline_status: 'OK',
          change_type: 'MODIFIED',
          content: [{skip: 66}],
        };
        element.flushDebouncer('renderDiffTable');
      });

      test('change in preferences re-renders diff', () => {
        sinon.stub(element, '_renderDiffTable');
        element.prefs = {
          ...MINIMAL_PREFS, time_format: 'HHMM_12'};
        element.flushDebouncer('renderDiffTable');
        assert.isTrue(element._renderDiffTable.called);
      });

      test('adding/removing property in preferences re-renders diff', () => {
        const stub = sinon.stub(element, '_renderDiffTable');
        const newPrefs1 = {...MINIMAL_PREFS,
          line_wrapping: true};
        element.prefs = newPrefs1;
        element.flushDebouncer('renderDiffTable');
        assert.isTrue(element._renderDiffTable.called);
        stub.reset();

        const newPrefs2 = {...newPrefs1};
        delete newPrefs2.line_wrapping;
        element.prefs = newPrefs2;
        element.flushDebouncer('renderDiffTable');
        assert.isTrue(element._renderDiffTable.called);
      });

      test('change in preferences does not re-renders diff with ' +
          'noRenderOnPrefsChange', () => {
        sinon.stub(element, '_renderDiffTable');
        element.noRenderOnPrefsChange = true;
        element.prefs = {
          ...MINIMAL_PREFS, time_format: 'HHMM_12'};
        element.flushDebouncer('renderDiffTable');
        assert.isFalse(element._renderDiffTable.called);
      });
    });
  });

  suite('diff header', () => {
    setup(() => {
      element = basicFixture.instantiate();
      element.diff = {
        meta_a: {name: 'carrot.jpg', content_type: 'image/jpeg', lines: 66},
        meta_b: {name: 'carrot.jpg', content_type: 'image/jpeg',
          lines: 560},
        diff_header: [],
        intraline_status: 'OK',
        change_type: 'MODIFIED',
        content: [{skip: 66}],
      };
    });

    test('hidden', () => {
      assert.equal(element._diffHeaderItems.length, 0);
      element.push('diff.diff_header', 'diff --git a/test.jpg b/test.jpg');
      assert.equal(element._diffHeaderItems.length, 0);
      element.push('diff.diff_header', 'index 2adc47d..f9c2f2c 100644');
      assert.equal(element._diffHeaderItems.length, 0);
      element.push('diff.diff_header', '--- a/test.jpg');
      assert.equal(element._diffHeaderItems.length, 0);
      element.push('diff.diff_header', '+++ b/test.jpg');
      assert.equal(element._diffHeaderItems.length, 0);
      element.push('diff.diff_header', 'test');
      assert.equal(element._diffHeaderItems.length, 1);
      flush();

      assert.equal(element.$.diffHeader.textContent.trim(), 'test');
    });

    test('binary files', () => {
      element.diff.binary = true;
      assert.equal(element._diffHeaderItems.length, 0);
      element.push('diff.diff_header', 'diff --git a/test.jpg b/test.jpg');
      assert.equal(element._diffHeaderItems.length, 0);
      element.push('diff.diff_header', 'test');
      assert.equal(element._diffHeaderItems.length, 1);
      element.push('diff.diff_header', 'Binary files differ');
      assert.equal(element._diffHeaderItems.length, 1);
    });
  });

  suite('safety and bypass', () => {
    let renderStub;

    setup(() => {
      element = basicFixture.instantiate();
      renderStub = sinon.stub(element.$.diffBuilder, 'render').callsFake(
          () => {
            element.$.diffBuilder.dispatchEvent(
                new CustomEvent('render', {bubbles: true, composed: true}));
            return Promise.resolve({});
          });
      sinon.stub(element, 'getDiffLength').returns(10000);
      element.diff = getMockDiffResponse();
      element.noRenderOnPrefsChange = true;
    });

    test('large render w/ context = 10', done => {
      element.prefs = {...MINIMAL_PREFS, context: 10};
      function rendered() {
        assert.isTrue(renderStub.called);
        assert.isFalse(element._showWarning);
        done();
        element.removeEventListener('render', rendered);
      }
      element.addEventListener('render', rendered);
      element._renderDiffTable();
    });

    test('large render w/ whole file and bypass', done => {
      element.prefs = {...MINIMAL_PREFS, context: -1};
      element._safetyBypass = 10;
      function rendered() {
        assert.isTrue(renderStub.called);
        assert.isFalse(element._showWarning);
        done();
        element.removeEventListener('render', rendered);
      }
      element.addEventListener('render', rendered);
      element._renderDiffTable();
    });

    test('large render w/ whole file and no bypass', done => {
      element.prefs = {...MINIMAL_PREFS, context: -1};
      function rendered() {
        assert.isFalse(renderStub.called);
        assert.isTrue(element._showWarning);
        done();
        element.removeEventListener('render', rendered);
      }
      element.addEventListener('render', rendered);
      element._renderDiffTable();
    });
  });

  suite('blame', () => {
    setup(() => {
      element = basicFixture.instantiate();
    });

    test('unsetting', () => {
      element.blame = [];
      const setBlameSpy = sinon.spy(element.$.diffBuilder, 'setBlame');
      element.classList.add('showBlame');
      element.blame = null;
      assert.isTrue(setBlameSpy.calledWithExactly(null));
      assert.isFalse(element.classList.contains('showBlame'));
    });

    test('setting', () => {
      element.blame = [{id: 'commit id', ranges: [{start: 1, end: 2}]}];
      assert.isTrue(element.classList.contains('showBlame'));
    });
  });

  suite('trailing newline warnings', () => {
    const NO_NEWLINE_BASE = 'No newline at end of base file.';
    const NO_NEWLINE_REVISION = 'No newline at end of revision file.';

    const getWarning = element =>
      element.shadowRoot.querySelector('.newlineWarning').textContent;

    setup(() => {
      element = basicFixture.instantiate();
      element.showNewlineWarningLeft = false;
      element.showNewlineWarningRight = false;
    });

    test('shows combined warning if both sides set to warn', () => {
      element.showNewlineWarningLeft = true;
      element.showNewlineWarningRight = true;
      assert.include(getWarning(element),
          NO_NEWLINE_BASE + ' \u2014 ' + NO_NEWLINE_REVISION);// \u2014 - '—'
    });

    suite('showNewlineWarningLeft', () => {
      test('show warning if true', () => {
        element.showNewlineWarningLeft = true;
        assert.include(getWarning(element), NO_NEWLINE_BASE);
      });

      test('hide warning if false', () => {
        element.showNewlineWarningLeft = false;
        assert.notInclude(getWarning(element), NO_NEWLINE_BASE);
      });

      test('hide warning if undefined', () => {
        element.showNewlineWarningLeft = undefined;
        assert.notInclude(getWarning(element), NO_NEWLINE_BASE);
      });
    });

    suite('showNewlineWarningRight', () => {
      test('show warning if true', () => {
        element.showNewlineWarningRight = true;
        assert.include(getWarning(element), NO_NEWLINE_REVISION);
      });

      test('hide warning if false', () => {
        element.showNewlineWarningRight = false;
        assert.notInclude(getWarning(element), NO_NEWLINE_REVISION);
      });

      test('hide warning if undefined', () => {
        element.showNewlineWarningRight = undefined;
        assert.notInclude(getWarning(element), NO_NEWLINE_REVISION);
      });
    });

    test('_computeNewlineWarningClass', () => {
      const hidden = 'newlineWarning hidden';
      const shown = 'newlineWarning';
      assert.equal(element._computeNewlineWarningClass(null, true), hidden);
      assert.equal(element._computeNewlineWarningClass('foo', true), hidden);
      assert.equal(element._computeNewlineWarningClass(null, false), hidden);
      assert.equal(element._computeNewlineWarningClass('foo', false), shown);
    });

    test('_prefsEqual', () => {
      element = basicFixture.instantiate();
      assert.isTrue(element._prefsEqual(null, null));
      assert.isTrue(element._prefsEqual({}, {}));
      assert.isTrue(element._prefsEqual({x: 1}, {x: 1}));
      assert.isTrue(
          element._prefsEqual({x: 1, abc: 'def'}, {x: 1, abc: 'def'}));
      const somePref = {abc: 'def', p: true};
      assert.isTrue(element._prefsEqual(somePref, somePref));

      assert.isFalse(element._prefsEqual({}, null));
      assert.isFalse(element._prefsEqual(null, {}));
      assert.isFalse(element._prefsEqual({x: 1}, {x: 2}));
      assert.isFalse(element._prefsEqual({x: 1, y: 'abc'}, {x: 1, y: 'abcd'}));
      assert.isFalse(element._prefsEqual({x: 1, y: 'abc'}, {x: 1}));
      assert.isFalse(element._prefsEqual({x: 1}, {x: 1, y: 'abc'}));
    });
  });

  suite('key locations', () => {
    let renderStub;

    setup(() => {
      element = basicFixture.instantiate();
      element.prefs = {};
      renderStub = sinon.stub(element.$.diffBuilder, 'render')
          .returns(new Promise(() => {}));
    });

    test('lineOfInterest is a key location', () => {
      element.lineOfInterest = {number: 789, leftSide: true};
      element._renderDiffTable();
      assert.isTrue(renderStub.called);
      assert.deepEqual(renderStub.lastCall.args[0], {
        left: {789: true},
        right: {},
      });
    });

    test('line comments are key locations', () => {
      const threadEl = document.createElement('div');
      threadEl.className = 'comment-thread';
      threadEl.setAttribute('diff-side', 'right');
      threadEl.setAttribute('line-num', 3);
      element.appendChild(threadEl);
      flush();

      element._renderDiffTable();
      assert.isTrue(renderStub.called);
      assert.deepEqual(renderStub.lastCall.args[0], {
        left: {},
        right: {3: true},
      });
    });

    test('file comments are key locations', () => {
      const threadEl = document.createElement('div');
      threadEl.className = 'comment-thread';
      threadEl.setAttribute('diff-side', 'left');
      element.appendChild(threadEl);
      flush();

      element._renderDiffTable();
      assert.isTrue(renderStub.called);
      assert.deepEqual(renderStub.lastCall.args[0], {
        left: {FILE: true},
        right: {},
      });
    });
  });
  const setupSampleDiff = function(params) {
    const {ignore_whitespace, content} = params;
    // binary can't be undefined, use false if not set
    const binary = params.binary || false;
    element = basicFixture.instantiate();
    element.prefs = {
      ignore_whitespace: ignore_whitespace || 'IGNORE_ALL',
      context: 10,
      cursor_blink_rate: 0,
      font_size: 12,
      intraline_difference: true,
      line_length: 100,
      line_wrapping: false,
      show_line_endings: true,
      show_tabs: true,
      show_whitespace_errors: true,
      syntax_highlighting: true,
      tab_size: 8,
      theme: 'DEFAULT',
    };
    element.diff = {
      intraline_status: 'OK',
      change_type: 'MODIFIED',
      diff_header: [
        'diff --git a/carrot.js b/carrot.js',
        'index 2adc47d..f9c2f2c 100644',
        '--- a/carrot.js',
        '+++ b/carrot.jjs',
        'file differ',
      ],
      content,
      binary,
    };
    element._renderDiffTable();
    flush();
  };

  test('clear diff table content as soon as diff changes', () => {
    const content = [{
      a: ['all work and no play make andybons a dull boy'],
    }, {
      b: [
        'Non eram nescius, Brute, cum, quae summis ingeniis ',
      ],
    }];
    function assertDiffTableWithContent() {
      assert.isTrue(element.$.diffTable.innerText.includes(content[0].a));
    }
    setupSampleDiff({content});
    assertDiffTableWithContent();
    element.diff = {...element.diff};
    // immediately cleaned up
    assert.equal(element.$.diffTable.innerHTML, '');
    element._renderDiffTable();
    flush();
    // rendered again
    assertDiffTableWithContent();
  });

  suite('selection test', () => {
    test('user-select set correctly on side-by-side view', () => {
      const 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',
        ],
      }];
      setupSampleDiff({content});
      flush();
      const diffLine = element.shadowRoot.querySelectorAll('.contentText')[2];
      assert.equal(getComputedStyle(diffLine).userSelect, 'none');
      // click to mark it as selected
      MockInteractions.tap(diffLine);
      assert.equal(getComputedStyle(diffLine).userSelect, 'text');
    });

    test('user-select set correctly on unified view', () => {
      const 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',
        ],
      }];
      setupSampleDiff({content});
      element.viewMode = 'UNIFIED_DIFF';
      flush();
      const diffLine = element.shadowRoot.querySelectorAll('.contentText')[2];
      assert.equal(getComputedStyle(diffLine).userSelect, 'none');
      MockInteractions.tap(diffLine);
      assert.equal(getComputedStyle(diffLine).userSelect, 'text');
    });
  });

  suite('whitespace changes only message', () => {
    test('show the message if ignore_whitespace is criteria matches', () => {
      setupSampleDiff({content: [{skip: 100}]});
      assert.isTrue(element.showNoChangeMessage(
          /* loading= */ false,
          element.prefs,
          element._diffLength,
          element.diff
      ));
    });

    test('do not show the message for binary files', () => {
      setupSampleDiff({content: [{skip: 100}], binary: true});
      assert.isFalse(element.showNoChangeMessage(
          /* loading= */ false,
          element.prefs,
          element._diffLength,
          element.diff
      ));
    });

    test('do not show the message if still loading', () => {
      setupSampleDiff({content: [{skip: 100}]});
      assert.isFalse(element.showNoChangeMessage(
          /* loading= */ true,
          element.prefs,
          element._diffLength,
          element.diff
      ));
    });

    test('do not show the message if contains valid changes', () => {
      const 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',
        ],
      }];
      setupSampleDiff({content});
      assert.equal(element._diffLength, 3);
      assert.isFalse(element.showNoChangeMessage(
          /* loading= */ false,
          element.prefs,
          element._diffLength,
          element.diff
      ));
    });

    test('do not show message if ignore whitespace is disabled', () => {
      const 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',
        ],
      }];
      setupSampleDiff({ignore_whitespace: 'IGNORE_NONE', content});
      assert.isFalse(element.showNoChangeMessage(
          /* loading= */ false,
          element.prefs,
          element._diffLength,
          element.diff
      ));
    });
  });

  test('getDiffLength', () => {
    const diff = getMockDiffResponse();
    assert.equal(element.getDiffLength(diff), 52);
  });

  test('`render` event has contentRendered field in detail', done => {
    element = basicFixture.instantiate();
    element.prefs = {};
    sinon.stub(element.$.diffBuilder, 'render')
        .returns(Promise.resolve());
    element.addEventListener('render', event => {
      assert.isTrue(event.detail.contentRendered);
      done();
    });
    element._renderDiffTable();
  });

  test('_prefsEqual', () => {
    element = basicFixture.instantiate();
    assert.isTrue(element._prefsEqual(null, null));
    assert.isTrue(element._prefsEqual({}, {}));
    assert.isTrue(element._prefsEqual({x: 1}, {x: 1}));
    assert.isTrue(element._prefsEqual({x: 1, abc: 'def'}, {x: 1, abc: 'def'}));
    const somePref = {abc: 'def', p: true};
    assert.isTrue(element._prefsEqual(somePref, somePref));

    assert.isFalse(element._prefsEqual({}, null));
    assert.isFalse(element._prefsEqual(null, {}));
    assert.isFalse(element._prefsEqual({x: 1}, {x: 2}));
    assert.isFalse(element._prefsEqual({x: 1, y: 'abc'}, {x: 1, y: 'abcd'}));
    assert.isFalse(element._prefsEqual({x: 1, y: 'abc'}, {x: 1}));
    assert.isFalse(element._prefsEqual({x: 1}, {x: 1, y: 'abc'}));
  });
});
