<!DOCTYPE html>
<!--
@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.
-->

<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-diff-processor test</title>

<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>

<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
<script src="/components/wct-browser-legacy/browser.js"></script>

<test-fixture id="basic">
  <template>
    <gr-diff-processor></gr-diff-processor>
  </template>
</test-fixture>

<script type="module">
import '../../../test/common-test-setup.js';
import './gr-diff-processor.js';
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;
  let sandbox;

  setup(() => {
    sandbox = sinon.sandbox.create();
  });

  teardown(() => {
    sandbox.restore();
  });

  suite('not logged in', () => {
    setup(() => {
      element = fixture('basic');

      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, GrDiffGroup.Type.BOTH);
        assert.equal(group.lines.length, 1);
        assert.equal(group.lines[0].text, '');
        assert.equal(group.lines[0].beforeNumber, GrDiffLine.FILE);
        assert.equal(group.lines[0].afterNumber, GrDiffLine.FILE);

        group = groups[1];
        assert.equal(group.type, GrDiffGroup.Type.BOTH);
        assert.equal(group.lines.length, 2);
        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, GrDiffGroup.Type.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, GrDiffGroup.Type.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, GrDiffGroup.Type.BOTH);
        assert.equal(groups[0].lines.length, 1);
        assert.equal(groups[0].lines[0].text, '');
        assert.equal(groups[0].lines[0].beforeNumber, GrDiffLine.FILE);
        assert.equal(groups[0].lines[0].afterNumber, GrDiffLine.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, GrDiffGroup.Type.CONTEXT_CONTROL);
          assert.instanceOf(groups[1].lines[0].contextGroups[0], GrDiffGroup);
          assert.equal(groups[1].lines[0].contextGroups[0].lines.length, 90);
          for (const l of groups[1].lines[0].contextGroups[0].lines) {
            assert.equal(l.text, 'all work and no play make jack a dull boy');
          }

          assert.equal(groups[2].type, GrDiffGroup.Type.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, 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, GrDiffGroup.Type.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, GrDiffGroup.Type.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, GrDiffGroup.Type.CONTEXT_CONTROL);
          assert.instanceOf(groups[3].lines[0].contextGroups[0], GrDiffGroup);
          assert.equal(groups[3].lines[0].contextGroups[0].lines.length, 90);
          for (const l of groups[3].lines[0].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, GrDiffGroup.Type.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, GrDiffGroup.Type.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, GrDiffGroup.Type.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, GrDiffGroup.Type.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, GrDiffGroup.Type.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, GrDiffGroup.Type.CONTEXT_CONTROL);
          assert.equal(groups[6].lines[0].contextGroups.length, 2);

          assert.equal(groups[6].lines[0].contextGroups[0].lines.length, 4);
          assert.equal(groups[6].lines[0].contextGroups[0].removes.length, 2);
          assert.equal(groups[6].lines[0].contextGroups[0].adds.length, 2);
          for (const l of groups[6].lines[0].contextGroups[0].removes) {
            assert.equal(
                l.text, 'all work and no play make jill a dull girl');
          }
          for (const l of groups[6].lines[0].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].lines[0].contextGroups[1].type,
              GrDiffGroup.Type.BOTH);
          assert.equal(groups[6].lines[0].contextGroups[1].lines.length, 3);
          for (const l of groups[6].lines[0].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, GrDiffGroup.Type.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, GrDiffGroup.Type.CONTEXT_CONTROL);
          assert.instanceOf(groups[3].lines[0].contextGroups[0], GrDiffGroup);
          assert.equal(groups[3].lines[0].contextGroups[0].lines.length, 80);
          for (const l of groups[3].lines[0].contextGroups[0].lines) {
            assert.equal(
                l.text, 'all work and no play make jill a dull girl');
          }

          assert.equal(groups[4].type, GrDiffGroup.Type.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, GrDiffGroup.Type.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('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,
        },
      ]);

      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: [
          '<!DOCTYPE html>',
          '<meta charset="utf-8">',
        ],
      };
      const content = _.times(200, _.constant(contentRow));
      sandbox.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: [
          '<!DOCTYPE html>',
          '<meta charset="utf-8">',
        ],
      };
      const content = _.times(200, _.constant(contentRow));
      sandbox.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, GrDiffGroup.Type.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('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[1].lines.length, 1);
        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].lines[0].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[0].lines.length, 1);
        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].lines[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);
          assert.equal(result.groups[0].lines.length, 1);
          // The collapsed group has the hidden lines as its context group.
          assert.equal(result.groups[0].lines[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);
          assert.equal(result.groups[1].lines.length, 1);
          // The collapsed group has the hidden lines as its context group.
          assert.equal(result.groups[1].lines[0].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(GrDiffLine.Type.ADD, rows,
            startLineNum + 1);

        assert.equal(result.length, rows.length);
        assert.equal(result[0].type, GrDiffLine.Type.ADD);
        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(GrDiffLine.Type.REMOVE, rows,
            startLineNum + 1);

        assert.equal(result.length, rows.length);
        assert.equal(result[0].type, GrDiffLine.Type.REMOVE);
        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', () => {
        sandbox.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',
          () => {
            sandbox.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('_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 = fixture('basic');
    sandbox.stub(element, 'cancel');
    element.detached();
    assert(element.cancel.called);
  });
});
</script>
