blob: c8446f02b3408c08b90eded1a79c41267c5d2eea [file] [log] [blame]
/**
* @license
* Copyright 2016 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import '../../../test/common-test-setup';
import {GrDiffLine, BLANK_LINE} from './gr-diff-line';
import {
GrDiffGroup,
GrDiffGroupType,
hideInContextControl,
} from './gr-diff-group';
import {assert} from '@open-wc/testing';
import {FILE, GrDiffLineType, LOST, Side} from '../../../api/diff';
suite('gr-diff-group tests', () => {
test('delta line pairs', () => {
const l1 = new GrDiffLine(GrDiffLineType.ADD, 0, 128);
const l2 = new GrDiffLine(GrDiffLineType.ADD, 0, 129);
const l3 = new GrDiffLine(GrDiffLineType.REMOVE, 64, 0);
let group = new GrDiffGroup({
type: GrDiffGroupType.DELTA,
lines: [l1, l2, l3],
});
assert.deepEqual(group.lines, [l1, l2, l3]);
assert.deepEqual(group.adds, [l1, l2]);
assert.deepEqual(group.removes, [l3]);
assert.deepEqual(group.lineRange, {
left: {start_line: 64, end_line: 64},
right: {start_line: 128, end_line: 129},
});
let pairs = group.getSideBySidePairs();
assert.deepEqual(pairs, [
{left: l3, right: l1},
{left: BLANK_LINE, right: l2},
]);
group = new GrDiffGroup({type: GrDiffGroupType.DELTA, lines: [l1, l2, l3]});
assert.deepEqual(group.lines, [l1, l2, l3]);
assert.deepEqual(group.adds, [l1, l2]);
assert.deepEqual(group.removes, [l3]);
pairs = group.getSideBySidePairs();
assert.deepEqual(pairs, [
{left: l3, right: l1},
{left: BLANK_LINE, right: l2},
]);
});
test('group must have lines', () => {
try {
new GrDiffGroup({type: GrDiffGroupType.BOTH});
} catch (e) {
// expected
return;
}
assert.fail('a standard diff group cannot be empty');
});
test('group/header line pairs', () => {
const l1 = new GrDiffLine(GrDiffLineType.BOTH, 64, 128);
const l2 = new GrDiffLine(GrDiffLineType.BOTH, 65, 129);
const l3 = new GrDiffLine(GrDiffLineType.BOTH, 66, 130);
const group = new GrDiffGroup({
type: GrDiffGroupType.BOTH,
lines: [l1, l2, l3],
});
assert.deepEqual(group.lines, [l1, l2, l3]);
assert.deepEqual(group.adds, []);
assert.deepEqual(group.removes, []);
assert.deepEqual(group.lineRange, {
left: {start_line: 64, end_line: 66},
right: {start_line: 128, end_line: 130},
});
const pairs = group.getSideBySidePairs();
assert.deepEqual(pairs, [
{left: l1, right: l1},
{left: l2, right: l2},
{left: l3, right: l3},
]);
});
test('adding delta lines to non-delta group', () => {
const l1 = new GrDiffLine(GrDiffLineType.ADD);
const l2 = new GrDiffLine(GrDiffLineType.REMOVE);
const l3 = new GrDiffLine(GrDiffLineType.BOTH);
assert.throws(
() => new GrDiffGroup({type: GrDiffGroupType.BOTH, lines: [l1, l2, l3]})
);
});
suite('hideInContextControl', () => {
let groups: GrDiffGroup[];
let groupsWithDelta: GrDiffGroup[];
let groupsWithWhiteSpaceOnlyChange: GrDiffGroup[];
setup(() => {
groups = [
new GrDiffGroup({
type: GrDiffGroupType.BOTH,
lines: [
new GrDiffLine(GrDiffLineType.BOTH, 5, 7),
new GrDiffLine(GrDiffLineType.BOTH, 6, 8),
new GrDiffLine(GrDiffLineType.BOTH, 7, 9),
],
}),
new GrDiffGroup({
type: GrDiffGroupType.BOTH,
lines: [
new GrDiffLine(GrDiffLineType.BOTH, 8, 10),
new GrDiffLine(GrDiffLineType.BOTH, 9, 11),
new GrDiffLine(GrDiffLineType.BOTH, 10, 12),
new GrDiffLine(GrDiffLineType.BOTH, 11, 13),
],
}),
new GrDiffGroup({
type: GrDiffGroupType.BOTH,
lines: [
new GrDiffLine(GrDiffLineType.BOTH, 12, 14),
new GrDiffLine(GrDiffLineType.BOTH, 13, 15),
new GrDiffLine(GrDiffLineType.BOTH, 14, 16),
],
}),
];
groupsWithWhiteSpaceOnlyChange = [
groups[0],
new GrDiffGroup({
type: GrDiffGroupType.DELTA,
lines: [
new GrDiffLine(GrDiffLineType.REMOVE, 8),
new GrDiffLine(GrDiffLineType.ADD, 0, 10),
new GrDiffLine(GrDiffLineType.REMOVE, 9),
new GrDiffLine(GrDiffLineType.ADD, 0, 11),
new GrDiffLine(GrDiffLineType.REMOVE, 10),
new GrDiffLine(GrDiffLineType.ADD, 0, 12),
new GrDiffLine(GrDiffLineType.REMOVE, 11),
new GrDiffLine(GrDiffLineType.ADD, 0, 13),
],
ignoredWhitespaceOnly: true,
}),
groups[2],
];
groupsWithDelta = [
groups[0],
new GrDiffGroup({
type: GrDiffGroupType.DELTA,
lines: [
new GrDiffLine(GrDiffLineType.REMOVE, 8),
new GrDiffLine(GrDiffLineType.ADD, 0, 10),
new GrDiffLine(GrDiffLineType.REMOVE, 9),
new GrDiffLine(GrDiffLineType.ADD, 0, 11),
new GrDiffLine(GrDiffLineType.REMOVE, 10),
new GrDiffLine(GrDiffLineType.ADD, 0, 12),
new GrDiffLine(GrDiffLineType.REMOVE, 11),
new GrDiffLine(GrDiffLineType.ADD, 0, 13),
],
}),
groups[2],
];
});
test('hides hidden groups in context control', () => {
const collapsedGroups = hideInContextControl(groups, 3, 7);
assert.equal(collapsedGroups.length, 3);
assert.equal(collapsedGroups[0], groups[0]);
assert.equal(collapsedGroups[1].type, GrDiffGroupType.CONTEXT_CONTROL);
assert.equal(collapsedGroups[1].contextGroups.length, 1);
assert.equal(collapsedGroups[1].contextGroups[0], groups[1]);
assert.equal(collapsedGroups[2], groups[2]);
});
test('does not hides when split is at delta group in context control', () => {
const collapsedGroups = hideInContextControl(groupsWithDelta, 3, 7);
assert.equal(collapsedGroups.length, 3);
assert.equal(collapsedGroups[0], groupsWithDelta[0]);
assert.equal(collapsedGroups[1], groupsWithDelta[1]);
assert.equal(collapsedGroups[2], groupsWithDelta[2]);
});
test('splits partially hidden groups', () => {
const collapsedGroups = hideInContextControl(groups, 4, 8);
assert.equal(collapsedGroups.length, 4);
assert.equal(collapsedGroups[0], groups[0]);
assert.equal(collapsedGroups[1].type, GrDiffGroupType.BOTH);
assert.deepEqual(collapsedGroups[1].lines, [groups[1].lines[0]]);
assert.equal(collapsedGroups[2].type, GrDiffGroupType.CONTEXT_CONTROL);
assert.equal(collapsedGroups[2].contextGroups.length, 2);
assert.equal(
collapsedGroups[2].contextGroups[0].type,
GrDiffGroupType.BOTH
);
assert.deepEqual(
collapsedGroups[2].contextGroups[0].lines,
groups[1].lines.slice(1)
);
assert.equal(
collapsedGroups[2].contextGroups[1].type,
GrDiffGroupType.BOTH
);
assert.deepEqual(collapsedGroups[2].contextGroups[1].lines, [
groups[2].lines[0],
]);
assert.equal(collapsedGroups[3].type, GrDiffGroupType.BOTH);
assert.deepEqual(collapsedGroups[3].lines, groups[2].lines.slice(1));
});
test('splits partially hidden common delta groups', () => {
const collapsedGroups = hideInContextControl(
groupsWithWhiteSpaceOnlyChange,
4,
8
);
assert.equal(collapsedGroups.length, 4);
assert.equal(collapsedGroups[0], groupsWithWhiteSpaceOnlyChange[0]);
assert.equal(collapsedGroups[1].type, GrDiffGroupType.DELTA);
assert.deepEqual(collapsedGroups[1].adds, [
groupsWithWhiteSpaceOnlyChange[1].adds[0],
]);
assert.deepEqual(collapsedGroups[1].removes, [
groupsWithWhiteSpaceOnlyChange[1].removes[0],
]);
assert.equal(collapsedGroups[2].type, GrDiffGroupType.CONTEXT_CONTROL);
assert.equal(collapsedGroups[2].contextGroups.length, 2);
assert.equal(
collapsedGroups[2].contextGroups[0].type,
GrDiffGroupType.DELTA
);
assert.deepEqual(
collapsedGroups[2].contextGroups[0].adds,
groupsWithWhiteSpaceOnlyChange[1].adds.slice(1)
);
assert.deepEqual(
collapsedGroups[2].contextGroups[0].removes,
groupsWithWhiteSpaceOnlyChange[1].removes.slice(1)
);
assert.equal(
collapsedGroups[2].contextGroups[1].type,
GrDiffGroupType.BOTH
);
assert.deepEqual(collapsedGroups[2].contextGroups[1].lines, [
groupsWithWhiteSpaceOnlyChange[2].lines[0],
]);
assert.equal(collapsedGroups[3].type, GrDiffGroupType.BOTH);
assert.deepEqual(
collapsedGroups[3].lines,
groupsWithWhiteSpaceOnlyChange[2].lines.slice(1)
);
});
suite('with skip chunks', () => {
setup(() => {
const skipGroup = new GrDiffGroup({
type: GrDiffGroupType.BOTH,
skip: 60,
offsetLeft: 8,
offsetRight: 10,
});
groups = [
new GrDiffGroup({
type: GrDiffGroupType.BOTH,
lines: [
new GrDiffLine(GrDiffLineType.BOTH, 5, 7),
new GrDiffLine(GrDiffLineType.BOTH, 6, 8),
new GrDiffLine(GrDiffLineType.BOTH, 7, 9),
],
}),
skipGroup,
new GrDiffGroup({
type: GrDiffGroupType.BOTH,
lines: [
new GrDiffLine(GrDiffLineType.BOTH, 68, 70),
new GrDiffLine(GrDiffLineType.BOTH, 69, 71),
new GrDiffLine(GrDiffLineType.BOTH, 70, 72),
],
}),
];
});
test('refuses to split skip group when closer to before', () => {
const collapsedGroups = hideInContextControl(groups, 4, 10);
assert.deepEqual(groups, collapsedGroups);
});
});
test('groups unchanged if the hidden range is empty', () => {
assert.deepEqual(hideInContextControl(groups, 0, 0), groups);
});
test('groups unchanged if there is only 1 line to hide', () => {
assert.deepEqual(hideInContextControl(groups, 3, 4), groups);
});
});
suite('isTotal', () => {
test('is total for add', () => {
const lines = [];
for (let idx = 0; idx < 10; idx++) {
lines.push(new GrDiffLine(GrDiffLineType.ADD));
}
const group = new GrDiffGroup({type: GrDiffGroupType.DELTA, lines});
assert.isTrue(group.isTotal());
});
test('is total for remove', () => {
const lines = [];
for (let idx = 0; idx < 10; idx++) {
lines.push(new GrDiffLine(GrDiffLineType.REMOVE));
}
const group = new GrDiffGroup({type: GrDiffGroupType.DELTA, lines});
assert.isTrue(group.isTotal());
});
test('not total for non-delta', () => {
const lines = [];
for (let idx = 0; idx < 10; idx++) {
lines.push(new GrDiffLine(GrDiffLineType.BOTH));
}
const group = new GrDiffGroup({type: GrDiffGroupType.DELTA, lines});
assert.isFalse(group.isTotal());
});
});
suite('startLine', () => {
test('DELTA', () => {
const lines: GrDiffLine[] = [];
lines.push(new GrDiffLine(GrDiffLineType.BOTH, 3, 4));
const group = new GrDiffGroup({type: GrDiffGroupType.DELTA, lines});
assert.equal(group.startLine(Side.LEFT), 3);
assert.equal(group.startLine(Side.RIGHT), 4);
});
test('CONTEXT CONTROL', () => {
const lines: GrDiffLine[] = [];
lines.push(new GrDiffLine(GrDiffLineType.BOTH, 3, 4));
const delta = new GrDiffGroup({type: GrDiffGroupType.DELTA, lines});
const group = new GrDiffGroup({
type: GrDiffGroupType.CONTEXT_CONTROL,
contextGroups: [delta],
});
assert.equal(group.startLine(Side.LEFT), 3);
assert.equal(group.startLine(Side.RIGHT), 4);
});
test('SKIP', () => {
const group = new GrDiffGroup({
type: GrDiffGroupType.BOTH,
skip: 10,
offsetLeft: 3,
offsetRight: 6,
});
assert.equal(group.startLine(Side.LEFT), 3);
assert.equal(group.startLine(Side.RIGHT), 6);
const group2 = new GrDiffGroup({
type: GrDiffGroupType.BOTH,
skip: 0,
offsetLeft: 3,
offsetRight: 6,
});
assert.equal(group2.startLine(Side.LEFT), 3);
assert.equal(group2.startLine(Side.RIGHT), 6);
});
test('FILE', () => {
const lines: GrDiffLine[] = [];
lines.push(new GrDiffLine(GrDiffLineType.BOTH, FILE, FILE));
const group = new GrDiffGroup({type: GrDiffGroupType.DELTA, lines});
assert.equal(group.startLine(Side.LEFT), FILE);
assert.equal(group.startLine(Side.RIGHT), FILE);
});
test('LOST', () => {
const lines: GrDiffLine[] = [];
lines.push(new GrDiffLine(GrDiffLineType.BOTH, LOST, LOST));
const group = new GrDiffGroup({type: GrDiffGroupType.DELTA, lines});
assert.equal(group.startLine(Side.LEFT), LOST);
assert.equal(group.startLine(Side.RIGHT), LOST);
});
});
});