/**
 * @license
 * Copyright 2016 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import '../../../test/common-test-setup';
import './gr-diff-processor';
import {GrDiffLine} from '../gr-diff/gr-diff-line';
import {GrDiffGroup, GrDiffGroupType} from '../gr-diff/gr-diff-group';
import {GrDiffProcessor, ProcessingOptions, State} from './gr-diff-processor';
import {DiffContent} from '../../../types/diff';
import {assert} from '@open-wc/testing';
import {FILE, GrDiffLineType} from '../../../api/diff';
import {FULL_CONTEXT} from '../gr-diff/gr-diff-utils';

suite('gr-diff-processor tests', () => {
  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 processor: GrDiffProcessor;
  let options: ProcessingOptions = {
    context: 4,
  };

  setup(() => {});

  suite('not logged in', () => {
    setup(() => {
      options = {context: 4};
      processor = new GrDiffProcessor(options);
    });

    test('process loaded content', async () => {
      const content: DiffContent[] = [
        {
          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.',
          ],
        },
      ];

      const groups = await processor.process(content);
      groups.shift(); // remove portedThreadsWithoutRangeGroup
      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: GrDiffLine) {
        return l.beforeNumber;
      }
      function afterNumberFn(l: GrDiffLine) {
        return l.afterNumber;
      }
      function textFn(l: GrDiffLine) {
        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', async () => {
      const content = [{b: ['foo']}];

      const groups = await processor.process(content);
      groups.shift(); // remove portedThreadsWithoutRangeGroup

      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', async () => {
      test('at the beginning, larger than context', async () => {
        options.context = 10;
        processor = new GrDiffProcessor(options);
        const content = [
          {
            ab: Array.from<string>({length: 100}).fill(
              'all work and no play make jack a dull boy'
            ),
          },
          {a: ['all work and no play make andybons a dull boy']},
        ];

        const groups = await processor.process(content);
        // group[0] is the LOST group
        // group[1] is the FILE group

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

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

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

        const groups = await processor.process(content);
        groups.shift(); // remove portedThreadsWithoutRangeGroup

        // 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_line: 21, end_line: 43920},
          right: {start_line: 21, end_line: 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', async () => {
        options.context = 10;
        processor = new GrDiffProcessor(options);
        const content = [
          {
            ab: Array.from<string>({length: 5}).fill(
              'all work and no play make jack a dull boy'
            ),
          },
          {a: ['all work and no play make andybons a dull boy']},
        ];

        const groups = await processor.process(content);
        groups.shift(); // remove portedThreadsWithoutRangeGroup

        // 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', async () => {
        options.context = 10;
        processor = new GrDiffProcessor(options);
        const content = [
          {a: ['all work and no play make andybons a dull boy']},
          {
            ab: Array.from<string>({length: 100}).fill(
              'all work and no play make jill a dull girl'
            ),
          },
        ];

        const groups = await processor.process(content);
        groups.shift(); // remove portedThreadsWithoutRangeGroup

        // 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', async () => {
        options.context = 10;
        const content = [
          {a: ['all work and no play make andybons a dull boy']},
          {
            ab: Array.from<string>({length: 5}).fill(
              'all work and no play make jill a dull girl'
            ),
          },
        ];

        const groups = await processor.process(content);
        groups.shift(); // remove portedThreadsWithoutRangeGroup

        // 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', async () => {
        options.context = 10;
        processor = new GrDiffProcessor(options);
        const content = [
          {a: ['all work and no play make andybons a dull boy']},
          {
            ab: Array.from<string>({length: 3}).fill(
              'all work and no play make jill a dull girl'
            ),
          },
          {
            a: Array.from<string>({length: 3}).fill(
              'all work and no play make jill a dull girl'
            ),
            b: Array.from<string>({length: 3}).fill(
              '  all work and no play make jill a dull girl'
            ),
            common: true,
          },
          {
            ab: Array.from<string>({length: 3}).fill(
              'all work and no play make jill a dull girl'
            ),
          },
          {
            a: Array.from<string>({length: 3}).fill(
              'all work and no play make jill a dull girl'
            ),
            b: Array.from<string>({length: 3}).fill(
              '  all work and no play make jill a dull girl'
            ),
            common: true,
          },
          {
            ab: Array.from<string>({length: 3}).fill(
              'all work and no play make jill a dull girl'
            ),
          },
        ];

        const groups = await processor.process(content);
        groups.shift(); // remove portedThreadsWithoutRangeGroup

        // 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', async () => {
        options.context = 10;
        processor = new GrDiffProcessor(options);
        const content = [
          {a: ['all work and no play make andybons a dull boy']},
          {
            ab: Array.from<string>({length: 100}).fill(
              'all work and no play make jill a dull girl'
            ),
          },
          {a: ['all work and no play make andybons a dull boy']},
        ];

        const groups = await processor.process(content);
        groups.shift(); // remove portedThreadsWithoutRangeGroup

        // 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', async () => {
        options.context = 10;
        processor = new GrDiffProcessor(options);
        const content = [
          {a: ['all work and no play make andybons a dull boy']},
          {
            ab: Array.from<string>({length: 5}).fill(
              'all work and no play make jill a dull girl'
            ),
          },
          {a: ['all work and no play make andybons a dull boy']},
        ];

        const groups = await processor.process(content);
        groups.shift(); // remove portedThreadsWithoutRangeGroup

        // 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 () => {
      options.context = 10;
      processor = new GrDiffProcessor(options);
      const content = [
        {a: ['all work and no play make andybons a dull boy']},
        {
          ab: Array.from<string>({length: 20}).fill(
            'all work and no play make jill a dull girl'
          ),
        },
        {skip: 60},
        {
          ab: Array.from<string>({length: 20}).fill(
            'all work and no play make jill a dull girl'
          ),
        },
        {a: ['all work and no play make andybons a dull boy']},
      ];

      const groups = await processor.process(content);
      groups.shift(); // remove portedThreadsWithoutRangeGroup

      // 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_line: 22, end_line: 81},
        right: {start_line: 21, end_line: 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('works with skip === 0', async () => {
      options.context = 3;
      processor = new GrDiffProcessor(options);
      const content = [
        {
          skip: 0,
        },
        {
          b: [
            '/**',
            ' * @license',
            ' * Copyright 2015 Google LLC',
            ' * SPDX-License-Identifier: Apache-2.0',
            ' */',
            "import '../../../test/common-test-setup';",
          ],
        },
      ];
      await processor.process(content);
    });

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

      const content = [
        {
          ab: [
            'copy',
            '',
            'asdf',
            'qwer',
            'zxcv',
            '',
            'http',
            '',
            'vbnm',
            'dfgh',
            'yuio',
            'sdfg',
            '1234',
          ],
        },
      ];
      const result = processor.splitCommonChunksWithKeyLocations(content);
      assert.deepEqual(result, [
        {
          ab: ['copy'],
          keyLocation: true,
        },
        {
          ab: ['', 'asdf', 'qwer', 'zxcv', '', 'http', '', 'vbnm'],
          keyLocation: false,
        },
        {
          ab: ['dfgh'],
          keyLocation: true,
        },
        {
          ab: ['yuio', 'sdfg', '1234'],
          keyLocation: false,
        },
      ]);
    });

    test('breaks down shared chunks w/ whole-file', () => {
      const maxGroupSize = 128;
      const size = maxGroupSize * 2 + 5;
      const ab = Array(size)
        .fill(0)
        .map(() => `${Math.random()}`);
      const content = [{ab}];
      processor.context = FULL_CONTEXT;
      const result = processor.splitLargeChunks(content);
      assert.equal(result.length, 2);
      assert.deepEqual(result[0].ab, content[0].ab.slice(0, maxGroupSize));
      assert.deepEqual(result[1].ab, content[0].ab.slice(maxGroupSize));
    });

    test('breaks down added chunks', () => {
      const maxGroupSize = 128;
      const size = maxGroupSize * 2 + 5;
      const content = Array(size)
        .fill(0)
        .map(() => `${Math.random()}`);
      processor.context = 5;
      const splitContent = processor
        .splitLargeChunks([{a: [], b: content}])
        .map(r => r.b);
      assert.equal(splitContent.length, 3);
      assert.deepEqual(splitContent[0], content.slice(0, 5));
      assert.deepEqual(splitContent[1], content.slice(5, maxGroupSize + 5));
      assert.deepEqual(splitContent[2], content.slice(maxGroupSize + 5));
    });

    test('breaks down removed chunks', () => {
      const maxGroupSize = 128;
      const size = maxGroupSize * 2 + 5;
      const content = Array(size)
        .fill(0)
        .map(() => `${Math.random()}`);
      processor.context = 5;
      const splitContent = processor
        .splitLargeChunks([{a: content, b: []}])
        .map(r => r.a);
      assert.equal(splitContent.length, 3);
      assert.deepEqual(splitContent[0], content.slice(0, 5));
      assert.deepEqual(splitContent[1], content.slice(5, maxGroupSize + 5));
      assert.deepEqual(splitContent[2], content.slice(maxGroupSize + 5));
    });

    test('does not break down moved chunks', () => {
      const size = 120 * 2 + 5;
      const content = Array(size)
        .fill(0)
        .map(() => `${Math.random()}`);
      processor.context = 5;
      const splitContent = processor
        .splitLargeChunks([
          {
            a: content,
            b: [],
            move_details: {changed: false, range: {start: 1, end: 1}},
          },
        ])
        .map(r => r.a);
      assert.equal(splitContent.length, 1);
      assert.deepEqual(splitContent[0], content);
    });

    test('does not break-down common chunks w/ context', () => {
      const ab = Array(75)
        .fill(0)
        .map(() => `${Math.random()}`);
      const content = [{ab}];
      processor.context = 4;
      const result = processor.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-formatted-text content="' +
          '[[_computeCurrentRevisionMessage(change)]]"></gr-formatted-text>',
        '      </section>',
      ];
      let highlights = [
        [31, 34],
        [42, 26],
      ];

      let results = processor.convertIntralineInfos(content, highlights);
      assert.deepEqual(results, [
        {
          contentIndex: 0,
          startIndex: 31,
        },
        {
          contentIndex: 1,
          startIndex: 0,
          endIndex: 33,
        },
        {
          contentIndex: 1,
          endIndex: 101,
          startIndex: 75,
        },
      ]);
      const lines = processor.linesFromRows(
        GrDiffLineType.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, 0);

      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 = processor.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,
        },
      ]);

      content = ['🙈 a', '🙉 b', '🙊 c'];
      highlights = [[2, 7]];
      results = processor.convertIntralineInfos(content, highlights);
      assert.deepEqual(results, [
        {
          contentIndex: 0,
          startIndex: 2,
        },
        {
          contentIndex: 1,
          startIndex: 0,
        },
        {
          contentIndex: 2,
          startIndex: 0,
          endIndex: 1,
        },
      ]);
    });

    test('isScrolling paused', async () => {
      const content = Array(200).fill({ab: ['', '']});
      processor.isScrolling = true;
      const promise = processor.process(content);
      processor.isScrolling = false;
      const groups = await promise;
      assert.isAtLeast(groups.length, 3);
    });

    test('image diffs', async () => {
      const content = Array(200).fill({ab: ['', '']});
      options.isBinary = true;
      processor = new GrDiffProcessor(options);
      const groups = await processor.process(content);
      assert.equal(groups.length, 2);

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

    suite('processNext', () => {
      let rows: string[];

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

      test('FULL_CONTEXT', () => {
        processor.context = FULL_CONTEXT;
        const state: State = {
          lineNums: {left: 10, right: 100},
          chunkIndex: 1,
        };
        const chunks = [{a: ['foo']}, {ab: rows}, {a: ['bar']}];
        const result = processor.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('FULL_CONTEXT with skip chunks still get collapsed', () => {
        processor.context = FULL_CONTEXT;
        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 = processor.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_line: lineNums.left + 1,
            end_line: lineNums.left + skip,
          },
          right: {
            start_line: lineNums.right + 1,
            end_line: lineNums.right + skip,
          },
        });

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

      test('with context', () => {
        processor.context = 10;
        const state = {
          lineNums: {left: 10, right: 100},
          chunkIndex: 1,
        };
        const chunks = [{a: ['foo']}, {ab: rows}, {a: ['bar']}];
        const result = processor.processNext(state, chunks);
        const expectedCollapseSize = rows.length - 2 * processor.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, processor.context);
        assert.equal(result.groups[2].lines.length, processor.context);

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

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

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

        // Only the first group is collapsed.
        assert.equal(result.groups[1].lines.length, processor.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);
        processor.context = 10;
        const state = {
          lineNums: {left: 10, right: 100},
          chunkIndex: 0,
        };
        const chunks = [{ab: rows}, {a: ['foo']}, {a: ['bar']}];
        const result = processor.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);
        processor.context = 3;
        const state = {
          lineNums: {left: 10, right: 100},
          chunkIndex: 1,
        };
        const chunks = [{a: ['foo']}, {ab: rows}, {a: ['bar']}];
        const result = processor.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: State;
        let chunks: DiffContent[];

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

        test('context before', () => {
          state.chunkIndex = 0;
          const result = processor.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 - processor.context
          );
          assert.equal(result.groups[1].lines.length, processor.context);
        });

        test('key location itself', () => {
          state.chunkIndex = 1;
          const result = processor.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 = processor.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, processor.context);
          // The collapsed group has the hidden lines as its context group.
          assert.equal(
            result.groups[1].contextGroups[0].lines.length,
            rows.length - processor.context
          );
        });
      });
    });

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

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

      test('linesFromRows', () => {
        const startLineNum = 10;
        let result = processor.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 = processor.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', () => {
        const breakdownSpy = sinon.spy(processor, 'breakdown');
        const chunk = {b: ['blah', 'blah', 'blah']};
        const result = processor.breakdownChunk(chunk);
        assert.deepEqual(result, [chunk]);
        assert.isTrue(breakdownSpy.called);
      });

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

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

        const result = processor.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 = processor.breakdown(array, size);

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

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

        const result = processor.breakdown(array, size);

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