/**
 * @license
 * Copyright (C) 2016 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 'lodash/lodash.js';
import './gr-diff-processor.js';
import {GrDiffLineType, FILE} from '../gr-diff/gr-diff-line.js';
import {GrDiffGroup, GrDiffGroupType} from '../gr-diff/gr-diff-group.js';

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

suite('gr-diff-processor tests', () => {
  const WHOLE_FILE = -1;
  const loremIpsum =
      'Lorem ipsum dolor sit amet, ei nonumes vituperata ius. ' +
      'Duo  animal omnesque fabellas et. Id has phaedrum dignissim ' +
      'deterruisset, pro ei petentium comprehensam, ut vis solum dicta. ' +
      'Eos cu aliquam labores qualisque, usu postea inermis te, et solum ' +
      'fugit assum per.';

  let element;

  setup(() => {

  });

  suite('not logged in', () => {
    setup(() => {
      element = basicFixture.instantiate();

      element.context = 4;
    });

    test('process loaded content', () => {
      const content = [
        {
          ab: [
            '<!DOCTYPE html>',
            '<meta charset="utf-8">',
          ],
        },
        {
          a: [
            '  Welcome ',
            '  to the wooorld of tomorrow!',
          ],
          b: [
            '  Hello, world!',
          ],
        },
        {
          ab: [
            'Leela: This is the only place the ship can’t hear us, so ',
            'everyone pretend to shower.',
            'Fry: Same as every day. Got it.',
          ],
        },
      ];

      return element.process(content).then(() => {
        const groups = element.groups;

        assert.equal(groups.length, 4);

        let group = groups[0];
        assert.equal(group.type, GrDiffGroupType.BOTH);
        assert.equal(group.lines.length, 1);
        assert.equal(group.lines[0].text, '');
        assert.equal(group.lines[0].beforeNumber, FILE);
        assert.equal(group.lines[0].afterNumber, FILE);

        group = groups[1];
        assert.equal(group.type, GrDiffGroupType.BOTH);
        assert.equal(group.lines.length, 2);

        function beforeNumberFn(l) { return l.beforeNumber; }
        function afterNumberFn(l) { return l.afterNumber; }
        function textFn(l) { return l.text; }

        assert.deepEqual(group.lines.map(beforeNumberFn), [1, 2]);
        assert.deepEqual(group.lines.map(afterNumberFn), [1, 2]);
        assert.deepEqual(group.lines.map(textFn), [
          '<!DOCTYPE html>',
          '<meta charset="utf-8">',
        ]);

        group = groups[2];
        assert.equal(group.type, GrDiffGroupType.DELTA);
        assert.equal(group.lines.length, 3);
        assert.equal(group.adds.length, 1);
        assert.equal(group.removes.length, 2);
        assert.deepEqual(group.removes.map(beforeNumberFn), [3, 4]);
        assert.deepEqual(group.adds.map(afterNumberFn), [3]);
        assert.deepEqual(group.removes.map(textFn), [
          '  Welcome ',
          '  to the wooorld of tomorrow!',
        ]);
        assert.deepEqual(group.adds.map(textFn), [
          '  Hello, world!',
        ]);

        group = groups[3];
        assert.equal(group.type, GrDiffGroupType.BOTH);
        assert.equal(group.lines.length, 3);
        assert.deepEqual(group.lines.map(beforeNumberFn), [5, 6, 7]);
        assert.deepEqual(group.lines.map(afterNumberFn), [4, 5, 6]);
        assert.deepEqual(group.lines.map(textFn), [
          'Leela: This is the only place the ship can’t hear us, so ',
          'everyone pretend to shower.',
          'Fry: Same as every day. Got it.',
        ]);
      });
    });

    test('first group is for file', () => {
      const content = [
        {b: ['foo']},
      ];

      return element.process(content).then(() => {
        const groups = element.groups;

        assert.equal(groups[0].type, GrDiffGroupType.BOTH);
        assert.equal(groups[0].lines.length, 1);
        assert.equal(groups[0].lines[0].text, '');
        assert.equal(groups[0].lines[0].beforeNumber, FILE);
        assert.equal(groups[0].lines[0].afterNumber, FILE);
      });
    });

    suite('context groups', () => {
      test('at the beginning, larger than context', () => {
        element.context = 10;
        const content = [
          {ab: new Array(100)
              .fill('all work and no play make jack a dull boy')},
          {a: ['all work and no play make andybons a dull boy']},
        ];

        return element.process(content).then(() => {
          const groups = element.groups;

          // group[0] is the file group

          assert.equal(groups[1].type, GrDiffGroupType.CONTEXT_CONTROL);
          assert.instanceOf(groups[1].contextGroups[0], GrDiffGroup);
          assert.equal(groups[1].contextGroups[0].lines.length, 90);
          for (const l of groups[1].contextGroups[0].lines) {
            assert.equal(l.text, 'all work and no play make jack a dull boy');
          }

          assert.equal(groups[2].type, GrDiffGroupType.BOTH);
          assert.equal(groups[2].lines.length, 10);
          for (const l of groups[2].lines) {
            assert.equal(l.text, 'all work and no play make jack a dull boy');
          }
        });
      });

      test('at the beginning with skip chunks', async () => {
        element.context = 10;
        const content = [
          {ab: new Array(20)
              .fill('all work and no play make jack a dull boy')},
          {skip: 43900},
          {ab: new Array(30)
              .fill('some other content')},
          {a: ['some other content']},
        ];

        await element.process(content);

        const groups = element.groups;

        // group[0] is the file group

        const commonGroup = groups[1];

        // Hidden context before
        assert.equal(commonGroup.type, GrDiffGroupType.CONTEXT_CONTROL);
        assert.instanceOf(commonGroup.contextGroups[0], GrDiffGroup);
        assert.equal(commonGroup.contextGroups[0].lines.length, 20);
        for (const l of commonGroup.contextGroups[0].lines) {
          assert.equal(l.text, 'all work and no play make jack a dull boy');
        }

        // Skipped group
        const skipGroup = commonGroup.contextGroups[1];
        assert.equal(skipGroup.skip, 43900);
        const expectedRange = {
          left: {start: 21, end: 43920},
          right: {start: 21, end: 43920},
        };
        assert.deepEqual(skipGroup.lineRange, expectedRange);

        // Hidden context after
        assert.equal(commonGroup.contextGroups[2].lines.length, 20);
        for (const l of commonGroup.contextGroups[2].lines) {
          assert.equal(l.text, 'some other content');
        }

        // Displayed lines
        assert.equal(groups[2].type, GrDiffGroupType.BOTH);
        assert.equal(groups[2].lines.length, 10);
        for (const l of groups[2].lines) {
          assert.equal(l.text, 'some other content');
        }
      });

      test('at the beginning, smaller than context', () => {
        element.context = 10;
        const content = [
          {ab: new Array(5)
              .fill('all work and no play make jack a dull boy')},
          {a: ['all work and no play make andybons a dull boy']},
        ];

        return element.process(content).then(() => {
          const groups = element.groups;

          // group[0] is the file group

          assert.equal(groups[1].type, GrDiffGroupType.BOTH);
          assert.equal(groups[1].lines.length, 5);
          for (const l of groups[1].lines) {
            assert.equal(l.text, 'all work and no play make jack a dull boy');
          }
        });
      });

      test('at the end, larger than context', () => {
        element.context = 10;
        const content = [
          {a: ['all work and no play make andybons a dull boy']},
          {ab: new Array(100)
              .fill('all work and no play make jill a dull girl')},
        ];

        return element.process(content).then(() => {
          const groups = element.groups;

          // group[0] is the file group
          // group[1] is the "a" group

          assert.equal(groups[2].type, GrDiffGroupType.BOTH);
          assert.equal(groups[2].lines.length, 10);
          for (const l of groups[2].lines) {
            assert.equal(
                l.text, 'all work and no play make jill a dull girl');
          }

          assert.equal(groups[3].type, GrDiffGroupType.CONTEXT_CONTROL);
          assert.instanceOf(groups[3].contextGroups[0], GrDiffGroup);
          assert.equal(groups[3].contextGroups[0].lines.length, 90);
          for (const l of groups[3].contextGroups[0].lines) {
            assert.equal(
                l.text, 'all work and no play make jill a dull girl');
          }
        });
      });

      test('at the end, smaller than context', () => {
        element.context = 10;
        const content = [
          {a: ['all work and no play make andybons a dull boy']},
          {ab: new Array(5)
              .fill('all work and no play make jill a dull girl')},
        ];

        return element.process(content).then(() => {
          const groups = element.groups;

          // group[0] is the file group
          // group[1] is the "a" group

          assert.equal(groups[2].type, GrDiffGroupType.BOTH);
          assert.equal(groups[2].lines.length, 5);
          for (const l of groups[2].lines) {
            assert.equal(
                l.text, 'all work and no play make jill a dull girl');
          }
        });
      });

      test('for interleaved ab and common: true chunks', () => {
        element.context = 10;
        const content = [
          {a: ['all work and no play make andybons a dull boy']},
          {ab: new Array(3)
              .fill('all work and no play make jill a dull girl')},
          {
            a: new Array(3).fill(
                'all work and no play make jill a dull girl'),
            b: new Array(3).fill(
                '  all work and no play make jill a dull girl'),
            common: true,
          },
          {ab: new Array(3)
              .fill('all work and no play make jill a dull girl')},
          {
            a: new Array(3).fill(
                'all work and no play make jill a dull girl'),
            b: new Array(3).fill(
                '  all work and no play make jill a dull girl'),
            common: true,
          },
          {ab: new Array(3)
              .fill('all work and no play make jill a dull girl')},
        ];

        return element.process(content).then(() => {
          const groups = element.groups;

          // group[0] is the file group
          // group[1] is the "a" group

          // The first three interleaved chunks are completely shown because
          // they are part of the context (3 * 3 <= 10)

          assert.equal(groups[2].type, GrDiffGroupType.BOTH);
          assert.equal(groups[2].lines.length, 3);
          for (const l of groups[2].lines) {
            assert.equal(
                l.text, 'all work and no play make jill a dull girl');
          }

          assert.equal(groups[3].type, GrDiffGroupType.DELTA);
          assert.equal(groups[3].lines.length, 6);
          assert.equal(groups[3].adds.length, 3);
          assert.equal(groups[3].removes.length, 3);
          for (const l of groups[3].removes) {
            assert.equal(
                l.text, 'all work and no play make jill a dull girl');
          }
          for (const l of groups[3].adds) {
            assert.equal(
                l.text, '  all work and no play make jill a dull girl');
          }

          assert.equal(groups[4].type, GrDiffGroupType.BOTH);
          assert.equal(groups[4].lines.length, 3);
          for (const l of groups[4].lines) {
            assert.equal(
                l.text, 'all work and no play make jill a dull girl');
          }

          // The next chunk is partially shown, so it results in two groups

          assert.equal(groups[5].type, GrDiffGroupType.DELTA);
          assert.equal(groups[5].lines.length, 2);
          assert.equal(groups[5].adds.length, 1);
          assert.equal(groups[5].removes.length, 1);
          for (const l of groups[5].removes) {
            assert.equal(
                l.text, 'all work and no play make jill a dull girl');
          }
          for (const l of groups[5].adds) {
            assert.equal(
                l.text, '  all work and no play make jill a dull girl');
          }

          assert.equal(groups[6].type, GrDiffGroupType.CONTEXT_CONTROL);
          assert.equal(groups[6].contextGroups.length, 2);

          assert.equal(groups[6].contextGroups[0].lines.length, 4);
          assert.equal(groups[6].contextGroups[0].removes.length, 2);
          assert.equal(groups[6].contextGroups[0].adds.length, 2);
          for (const l of groups[6].contextGroups[0].removes) {
            assert.equal(
                l.text, 'all work and no play make jill a dull girl');
          }
          for (const l of groups[6].contextGroups[0].adds) {
            assert.equal(
                l.text, '  all work and no play make jill a dull girl');
          }

          // The final chunk is completely hidden
          assert.equal(
              groups[6].contextGroups[1].type,
              GrDiffGroupType.BOTH);
          assert.equal(groups[6].contextGroups[1].lines.length, 3);
          for (const l of groups[6].contextGroups[1].lines) {
            assert.equal(
                l.text, 'all work and no play make jill a dull girl');
          }
        });
      });

      test('in the middle, larger than context', () => {
        element.context = 10;
        const content = [
          {a: ['all work and no play make andybons a dull boy']},
          {ab: new Array(100)
              .fill('all work and no play make jill a dull girl')},
          {a: ['all work and no play make andybons a dull boy']},
        ];

        return element.process(content).then(() => {
          const groups = element.groups;

          // group[0] is the file group
          // group[1] is the "a" group

          assert.equal(groups[2].type, GrDiffGroupType.BOTH);
          assert.equal(groups[2].lines.length, 10);
          for (const l of groups[2].lines) {
            assert.equal(
                l.text, 'all work and no play make jill a dull girl');
          }

          assert.equal(groups[3].type, GrDiffGroupType.CONTEXT_CONTROL);
          assert.instanceOf(groups[3].contextGroups[0], GrDiffGroup);
          assert.equal(groups[3].contextGroups[0].lines.length, 80);
          for (const l of groups[3].contextGroups[0].lines) {
            assert.equal(
                l.text, 'all work and no play make jill a dull girl');
          }

          assert.equal(groups[4].type, GrDiffGroupType.BOTH);
          assert.equal(groups[4].lines.length, 10);
          for (const l of groups[4].lines) {
            assert.equal(
                l.text, 'all work and no play make jill a dull girl');
          }
        });
      });

      test('in the middle, smaller than context', () => {
        element.context = 10;
        const content = [
          {a: ['all work and no play make andybons a dull boy']},
          {ab: new Array(5)
              .fill('all work and no play make jill a dull girl')},
          {a: ['all work and no play make andybons a dull boy']},
        ];

        return element.process(content).then(() => {
          const groups = element.groups;

          // group[0] is the file group
          // group[1] is the "a" group

          assert.equal(groups[2].type, GrDiffGroupType.BOTH);
          assert.equal(groups[2].lines.length, 5);
          for (const l of groups[2].lines) {
            assert.equal(
                l.text, 'all work and no play make jill a dull girl');
          }
        });
      });
    });

    test('in the middle with skip chunks', async () => {
      element.context = 10;
      const content = [
        {a: ['all work and no play make andybons a dull boy']},
        {ab: new Array(20)
            .fill('all work and no play make jill a dull girl')},
        {skip: 60},
        {ab: new Array(20)
            .fill('all work and no play make jill a dull girl')},
        {a: ['all work and no play make andybons a dull boy']},
      ];

      await element.process(content);

      const groups = element.groups;

      // group[0] is the file group
      // group[1] is the chunk with a
      // group[2] is the displayed part of ab before

      const commonGroup = groups[3];

      // Hidden context before
      assert.equal(commonGroup.type, GrDiffGroupType.CONTEXT_CONTROL);
      assert.instanceOf(commonGroup.contextGroups[0], GrDiffGroup);
      assert.equal(commonGroup.contextGroups[0].lines.length, 10);
      for (const l of commonGroup.contextGroups[0].lines) {
        assert.equal(
            l.text, 'all work and no play make jill a dull girl');
      }

      // Skipped group
      const skipGroup = commonGroup.contextGroups[1];
      assert.equal(skipGroup.skip, 60);
      const expectedRange = {
        left: {start: 22, end: 81},
        right: {start: 21, end: 80},
      };
      assert.deepEqual(skipGroup.lineRange, expectedRange);

      // Hidden context after
      assert.equal(commonGroup.contextGroups[2].lines.length, 10);
      for (const l of commonGroup.contextGroups[2].lines) {
        assert.equal(
            l.text, 'all work and no play make jill a dull girl');
      }
      // group[4] is the displayed part of the second ab
    });

    test('break up common diff chunks', () => {
      element.keyLocations = {
        left: {1: true},
        right: {10: true},
      };

      const content = [
        {
          ab: [
            '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.',
          ],
        },
      ];
      const result =
          element._splitCommonChunksWithKeyLocations(content);
      assert.deepEqual(result, [
        {
          ab: ['Copyright (C) 2015 The Android Open Source Project'],
          keyLocation: true,
        },
        {
          ab: [
            '',
            '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, ',
          ],
          keyLocation: false,
        },
        {
          ab: [
            'software distributed under the License is distributed on an '],
          keyLocation: true,
        },
        {
          ab: [
            '"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.',
          ],
          keyLocation: false,
        },
      ]);
    });

    test('breaks down shared chunks w/ whole-file', () => {
      const size = 120 * 2 + 5;
      const content = [{
        ab: _.times(size, () => `${Math.random()}`),
      }];
      element.context = -1;
      const result = element._splitLargeChunks(content);
      assert.equal(result.length, 2);
      assert.deepEqual(result[0].ab, content[0].ab.slice(0, 120));
      assert.deepEqual(result[1].ab, content[0].ab.slice(120));
    });

    test('does not break-down common chunks w/ context', () => {
      const content = [{
        ab: _.times(75, () => `${Math.random()}`),
      }];
      element.context = 4;
      const result =
          element._splitCommonChunksWithKeyLocations(content);
      assert.equal(result.length, 1);
      assert.deepEqual(result[0].ab, content[0].ab);
      assert.isFalse(result[0].keyLocation);
    });

    test('intraline normalization', () => {
      // The content and highlights are in the format returned by the Gerrit
      // REST API.
      let content = [
        '      <section class="summary">',
        '        <gr-linked-text content="' +
            '[[_computeCurrentRevisionMessage(change)]]"></gr-linked-text>',
        '      </section>',
      ];
      let highlights = [
        [31, 34], [42, 26],
      ];

      let results = element._convertIntralineInfos(content,
          highlights);
      assert.deepEqual(results, [
        {
          contentIndex: 0,
          startIndex: 31,
        },
        {
          contentIndex: 1,
          startIndex: 0,
          endIndex: 33,
        },
        {
          contentIndex: 1,
          startIndex: 75,
        },
        {
          contentIndex: 2,
          startIndex: 0,
          endIndex: 6,
        },
      ]);
      const lines = element._linesFromRows(
          GrDiffGroupType.BOTH, content, 0, highlights);
      assert.equal(lines.length, 3);
      assert.isTrue(lines[0].hasIntralineInfo);
      assert.equal(lines[0].highlights.length, 1);
      assert.isTrue(lines[1].hasIntralineInfo);
      assert.equal(lines[1].highlights.length, 2);
      assert.isTrue(lines[2].hasIntralineInfo);
      assert.equal(lines[2].highlights.length, 1);

      content = [
        '        this._path = value.path;',
        '',
        '        // When navigating away from the page, there is a ' +
          'possibility that the',
        '        // patch number is no longer a part of the URL ' +
          '(say when navigating to',
        '        // the top-level change info view) and therefore ' +
          'undefined in `params`.',
        '        if (!this._patchRange.patchNum) {',
      ];
      highlights = [
        [14, 17],
        [11, 70],
        [12, 67],
        [12, 67],
        [14, 29],
      ];
      results = element._convertIntralineInfos(content, highlights);
      assert.deepEqual(results, [
        {
          contentIndex: 0,
          startIndex: 14,
          endIndex: 31,
        },
        {
          contentIndex: 2,
          startIndex: 8,
          endIndex: 78,
        },
        {
          contentIndex: 3,
          startIndex: 11,
          endIndex: 78,
        },
        {
          contentIndex: 4,
          startIndex: 11,
          endIndex: 78,
        },
        {
          contentIndex: 5,
          startIndex: 12,
          endIndex: 41,
        },
      ]);
    });

    test('scrolling pauses rendering', () => {
      const contentRow = {
        ab: [
          '',
          '',
        ],
      };
      const content = _.times(200, _.constant(contentRow));
      sinon.stub(element, 'async');
      element._isScrolling = true;
      element.process(content);
      // Just the files group - no more processing during scrolling.
      assert.equal(element.groups.length, 1);

      element._isScrolling = false;
      element.process(content);
      // More groups have been processed. How many does not matter here.
      assert.isAtLeast(element.groups.length, 2);
    });

    test('image diffs', () => {
      const contentRow = {
        ab: [
          '',
          '',
        ],
      };
      const content = _.times(200, _.constant(contentRow));
      sinon.stub(element, 'async');
      element.process(content, true);
      assert.equal(element.groups.length, 1);

      // Image diffs don't process content, just the 'FILE' line.
      assert.equal(element.groups[0].lines.length, 1);
    });

    suite('_processNext', () => {
      let rows;

      setup(() => {
        rows = loremIpsum.split(' ');
      });

      test('WHOLE_FILE', () => {
        element.context = WHOLE_FILE;
        const state = {
          lineNums: {left: 10, right: 100},
          chunkIndex: 1,
        };
        const chunks = [
          {a: ['foo']},
          {ab: rows},
          {a: ['bar']},
        ];
        const result = element._processNext(state, chunks);

        // Results in one, uncollapsed group with all rows.
        assert.equal(result.groups.length, 1);
        assert.equal(result.groups[0].type, GrDiffGroupType.BOTH);
        assert.equal(result.groups[0].lines.length, rows.length);

        // Line numbers are set correctly.
        assert.equal(
            result.groups[0].lines[0].beforeNumber,
            state.lineNums.left + 1);
        assert.equal(
            result.groups[0].lines[0].afterNumber,
            state.lineNums.right + 1);

        assert.equal(result.groups[0].lines[rows.length - 1].beforeNumber,
            state.lineNums.left + rows.length);
        assert.equal(result.groups[0].lines[rows.length - 1].afterNumber,
            state.lineNums.right + rows.length);
      });

      test('WHOLE_FILE with skip chunks still get collapsed', () => {
        element.context = WHOLE_FILE;
        const lineNums = {left: 10, right: 100};
        const state = {
          lineNums,
          chunkIndex: 1,
        };
        const skip = 10000;
        const chunks = [
          {a: ['foo']},
          {skip},
          {ab: rows},
          {a: ['bar']},
        ];
        const result = element._processNext(state, chunks);
        // Results in one, uncollapsed group with all rows.
        assert.equal(result.groups.length, 1);
        assert.equal(result.groups[0].type, GrDiffGroupType.CONTEXT_CONTROL);

        // Skip and ab group are hidden in the same context control
        assert.equal(result.groups[0].contextGroups.length, 2);
        const [skippedGroup, abGroup] = result.groups[0].contextGroups;

        // Line numbers are set correctly.
        assert.deepEqual(
            skippedGroup.lineRange,
            {
              left: {start: lineNums.left + 1, end: lineNums.left + skip},
              right: {start: lineNums.right + 1, end: lineNums.right + skip},
            });

        assert.deepEqual(
            abGroup.lineRange,
            {
              left: {
                start: lineNums.left + skip + 1,
                end: lineNums.left + skip + rows.length,
              },
              right: {
                start: lineNums.right + skip + 1,
                end: lineNums.right + skip + rows.length,
              },
            });
      });

      test('with context', () => {
        element.context = 10;
        const state = {
          lineNums: {left: 10, right: 100},
          chunkIndex: 1,
        };
        const chunks = [
          {a: ['foo']},
          {ab: rows},
          {a: ['bar']},
        ];
        const result = element._processNext(state, chunks);
        const expectedCollapseSize = rows.length - 2 * element.context;

        assert.equal(result.groups.length, 3, 'Results in three groups');

        // The first and last are uncollapsed context, whereas the middle has
        // a single context-control line.
        assert.equal(result.groups[0].lines.length, element.context);
        assert.equal(result.groups[2].lines.length, element.context);

        // The collapsed group has the hidden lines as its context group.
        assert.equal(result.groups[1].contextGroups[0].lines.length,
            expectedCollapseSize);
      });

      test('first', () => {
        element.context = 10;
        const state = {
          lineNums: {left: 10, right: 100},
          chunkIndex: 0,
        };
        const chunks = [
          {ab: rows},
          {a: ['foo']},
          {a: ['bar']},
        ];
        const result = element._processNext(state, chunks);
        const expectedCollapseSize = rows.length - element.context;

        assert.equal(result.groups.length, 2, 'Results in two groups');

        // Only the first group is collapsed.
        assert.equal(result.groups[1].lines.length, element.context);

        // The collapsed group has the hidden lines as its context group.
        assert.equal(result.groups[0].contextGroups[0].lines.length,
            expectedCollapseSize);
      });

      test('few-rows', () => {
        // Only ten rows.
        rows = rows.slice(0, 10);
        element.context = 10;
        const state = {
          lineNums: {left: 10, right: 100},
          chunkIndex: 0,
        };
        const chunks = [
          {ab: rows},
          {a: ['foo']},
          {a: ['bar']},
        ];
        const result = element._processNext(state, chunks);

        // Results in one uncollapsed group with all rows.
        assert.equal(result.groups.length, 1, 'Results in one group');
        assert.equal(result.groups[0].lines.length, rows.length);
      });

      test('no single line collapse', () => {
        rows = rows.slice(0, 7);
        element.context = 3;
        const state = {
          lineNums: {left: 10, right: 100},
          chunkIndex: 1,
        };
        const chunks = [
          {a: ['foo']},
          {ab: rows},
          {a: ['bar']},
        ];
        const result = element._processNext(state, chunks);

        // Results in one uncollapsed group with all rows.
        assert.equal(result.groups.length, 1, 'Results in one group');
        assert.equal(result.groups[0].lines.length, rows.length);
      });

      suite('with key location', () => {
        let state;
        let chunks;

        setup(() => {
          state = {
            lineNums: {left: 10, right: 100},
          };
          element.context = 10;
          chunks = [
            {ab: rows},
            {ab: ['foo'], keyLocation: true},
            {ab: rows},
          ];
        });

        test('context before', () => {
          state.chunkIndex = 0;
          const result = element._processNext(state, chunks);

          // The first chunk is split into two groups:
          // 1) A context-control, hiding everything but the context before
          //    the key location.
          // 2) The context before the key location.
          // The key location is not processed in this call to _processNext
          assert.equal(result.groups.length, 2);
          // The collapsed group has the hidden lines as its context group.
          assert.equal(result.groups[0].contextGroups[0].lines.length,
              rows.length - element.context);
          assert.equal(result.groups[1].lines.length, element.context);
        });

        test('key location itself', () => {
          state.chunkIndex = 1;
          const result = element._processNext(state, chunks);

          // The second chunk results in a single group, that is just the
          // line with the key location
          assert.equal(result.groups.length, 1);
          assert.equal(result.groups[0].lines.length, 1);
          assert.equal(result.lineDelta.left, 1);
          assert.equal(result.lineDelta.right, 1);
        });

        test('context after', () => {
          state.chunkIndex = 2;
          const result = element._processNext(state, chunks);

          // The last chunk is split into two groups:
          // 1) The context after the key location.
          // 1) A context-control, hiding everything but the context after the
          //    key location.
          assert.equal(result.groups.length, 2);
          assert.equal(result.groups[0].lines.length, element.context);
          // The collapsed group has the hidden lines as its context group.
          assert.equal(result.groups[1].contextGroups[0].lines.length,
              rows.length - element.context);
        });
      });
    });

    suite('gr-diff-processor helpers', () => {
      let rows;

      setup(() => {
        rows = loremIpsum.split(' ');
      });

      test('_linesFromRows', () => {
        const startLineNum = 10;
        let result = element._linesFromRows(GrDiffLineType.ADD, rows,
            startLineNum + 1);

        assert.equal(result.length, rows.length);
        assert.equal(result[0].type, GrDiffLineType.ADD);
        assert.notOk(result[0].hasIntralineInfo);
        assert.equal(result[0].afterNumber, startLineNum + 1);
        assert.notOk(result[0].beforeNumber);
        assert.equal(result[result.length - 1].afterNumber,
            startLineNum + rows.length);
        assert.notOk(result[result.length - 1].beforeNumber);

        result = element._linesFromRows(GrDiffLineType.REMOVE, rows,
            startLineNum + 1);

        assert.equal(result.length, rows.length);
        assert.equal(result[0].type, GrDiffLineType.REMOVE);
        assert.notOk(result[0].hasIntralineInfo);
        assert.equal(result[0].beforeNumber, startLineNum + 1);
        assert.notOk(result[0].afterNumber);
        assert.equal(result[result.length - 1].beforeNumber,
            startLineNum + rows.length);
        assert.notOk(result[result.length - 1].afterNumber);
      });
    });

    suite('_breakdown*', () => {
      test('_breakdownChunk breaks down additions', () => {
        sinon.spy(element, '_breakdown');
        const chunk = {b: ['blah', 'blah', 'blah']};
        const result = element._breakdownChunk(chunk);
        assert.deepEqual(result, [chunk]);
        assert.isTrue(element._breakdown.called);
      });

      test('_breakdownChunk keeps due_to_rebase for broken down additions',
          () => {
            sinon.spy(element, '_breakdown');
            const chunk = {b: ['blah', 'blah', 'blah'], due_to_rebase: true};
            const result = element._breakdownChunk(chunk);
            for (const subResult of result) {
              assert.isTrue(subResult.due_to_rebase);
            }
          });

      test('_breakdownChunk keeps due_to_move for broken down additions',
          () => {
            sinon.spy(element, '_breakdown');
            const chunk = {b: ['blah', 'blah', 'blah'], due_to_move: true};
            const result = element._breakdownChunk(chunk);
            for (const subResult of result) {
              assert.isTrue(subResult.due_to_move);
            }
          });

      test('_breakdown common case', () => {
        const array = 'Lorem ipsum dolor sit amet, suspendisse inceptos'
            .split(' ');
        const size = 3;

        const result = element._breakdown(array, size);

        for (const subResult of result) {
          assert.isAtMost(subResult.length, size);
        }
        const flattened = result
            .reduce((a, b) => a.concat(b), []);
        assert.deepEqual(flattened, array);
      });

      test('_breakdown smaller than size', () => {
        const array = 'Lorem ipsum dolor sit amet, suspendisse inceptos'
            .split(' ');
        const size = 10;
        const expected = [array];

        const result = element._breakdown(array, size);

        assert.deepEqual(result, expected);
      });

      test('_breakdown empty', () => {
        const array = [];
        const size = 10;
        const expected = [];

        const result = element._breakdown(array, size);

        assert.deepEqual(result, expected);
      });
    });
  });

  test('detaching cancels', () => {
    element = basicFixture.instantiate();
    sinon.stub(element, 'cancel');
    element.detached();
    assert(element.cancel.called);
  });
});

