blob: 5429f5206550751b372ca6087841e2edc25a5762 [file] [log] [blame]
<!DOCTYPE html>
<!--
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="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
<script src="../../../bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../bower_components/iron-test-helpers/iron-test-helpers.html">
<link rel="import" href="gr-diff-processor.html">
<script>void(0);</script>
<test-fixture id="basic">
<template>
<gr-diff-processor></gr-diff-processor>
</template>
</test-fixture>
<script>
suite('gr-diff-processor tests', function() {
var WHOLE_FILE = -1;
var 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.';
var element;
var sandbox;
setup(function() {
sandbox = sinon.sandbox.create();
});
teardown(function() {
sandbox.restore();
});
suite('not logged in', function() {
setup(function() {
element = fixture('basic');
element.context = 4;
});
test('process loaded content', function(done) {
var 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.',
]
},
];
element.process(content).then(function() {
var groups = element.groups;
assert.equal(groups.length, 4);
var 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.',
]);
done();
});
});
test('insert context groups', function(done) {
var content = [
{ab: []},
{a: ['all work and no play make andybons a dull boy']},
{ab: []},
{b: ['elgoog elgoog elgoog']},
{ab: []},
];
for (var i = 0; i < 100; i++) {
content[0].ab.push('all work and no play make jack a dull boy');
content[4].ab.push('all work and no play make jill a dull girl');
}
for (var i = 0; i < 5; i++) {
content[2].ab.push('no tv and no beer make homer go crazy');
}
var context = 10;
element.context = context;
element.process(content).then(function() {
var 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);
assert.equal(groups[1].type, GrDiffGroup.Type.CONTEXT_CONTROL);
assert.instanceOf(groups[1].lines[0].contextGroup, GrDiffGroup);
assert.equal(groups[1].lines[0].contextGroup.lines.length, 90);
groups[1].lines[0].contextGroup.lines.forEach(function(l) {
assert.equal(l.text, content[0].ab[0]);
});
assert.equal(groups[2].type, GrDiffGroup.Type.BOTH);
assert.equal(groups[2].lines.length, context);
groups[2].lines.forEach(function(l) {
assert.equal(l.text, content[0].ab[0]);
});
assert.equal(groups[3].type, GrDiffGroup.Type.DELTA);
assert.equal(groups[3].lines.length, 1);
assert.equal(groups[3].removes.length, 1);
assert.equal(groups[3].removes[0].text,
'all work and no play make andybons a dull boy');
assert.equal(groups[4].type, GrDiffGroup.Type.BOTH);
assert.equal(groups[4].lines.length, 5);
groups[4].lines.forEach(function(l) {
assert.equal(l.text, content[2].ab[0]);
});
assert.equal(groups[5].type, GrDiffGroup.Type.DELTA);
assert.equal(groups[5].lines.length, 1);
assert.equal(groups[5].adds.length, 1);
assert.equal(groups[5].adds[0].text, 'elgoog elgoog elgoog');
assert.equal(groups[6].type, GrDiffGroup.Type.BOTH);
assert.equal(groups[6].lines.length, context);
groups[6].lines.forEach(function(l) {
assert.equal(l.text, content[4].ab[0]);
});
assert.equal(groups[7].type, GrDiffGroup.Type.CONTEXT_CONTROL);
assert.instanceOf(groups[7].lines[0].contextGroup, GrDiffGroup);
assert.equal(groups[7].lines[0].contextGroup.lines.length, 90);
groups[7].lines[0].contextGroup.lines.forEach(function(l) {
assert.equal(l.text, content[4].ab[0]);
});
done();
});
});
test('insert context groups', function(done) {
var content = [
{a: ['all work and no play make andybons a dull boy']},
{ab: []},
{b: ['elgoog elgoog elgoog']},
];
for (var i = 0; i < 50; i++) {
content[1].ab.push('no tv and no beer make homer go crazy');
}
var context = 10;
element.context = context;
element.process(content).then(function() {
var 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);
assert.equal(groups[1].type, GrDiffGroup.Type.DELTA);
assert.equal(groups[1].lines.length, 1);
assert.equal(groups[1].removes.length, 1);
assert.equal(groups[1].removes[0].text,
'all work and no play make andybons a dull boy');
assert.equal(groups[2].type, GrDiffGroup.Type.BOTH);
assert.equal(groups[2].lines.length, context);
groups[2].lines.forEach(function(l) {
assert.equal(l.text, content[1].ab[0]);
});
assert.equal(groups[3].type, GrDiffGroup.Type.CONTEXT_CONTROL);
assert.instanceOf(groups[3].lines[0].contextGroup, GrDiffGroup);
assert.equal(groups[3].lines[0].contextGroup.lines.length, 30);
groups[3].lines[0].contextGroup.lines.forEach(function(l) {
assert.equal(l.text, content[1].ab[0]);
});
assert.equal(groups[4].type, GrDiffGroup.Type.BOTH);
assert.equal(groups[4].lines.length, context);
groups[4].lines.forEach(function(l) {
assert.equal(l.text, content[1].ab[0]);
});
assert.equal(groups[5].type, GrDiffGroup.Type.DELTA);
assert.equal(groups[5].lines.length, 1);
assert.equal(groups[5].adds.length, 1);
assert.equal(groups[5].adds[0].text, 'elgoog elgoog elgoog');
done();
});
});
test('break up common diff chunks', function() {
element.keyLocations = {
left: {1: true},
right: {10: true},
};
var lineNums = {left: 0, right: 0};
var 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.',
]
}
];
var result = element._splitCommonGroupsWithComments(content, lineNums);
assert.deepEqual(result, [
{
ab: ['Copyright (C) 2015 The Android Open Source Project'],
},
{
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, ',
]
},
{
ab: [
'software distributed under the License is distributed on an '],
},
{
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.',
]
}
]);
});
test('breaks-down shared chunks w/ whole-file', function() {
var lineNums = {left: 0, right: 0};
var content = [{
ab: _.times(75, function() { return '' + Math.random(); }),
}];
element.context = -1;
var result = element._splitCommonGroupsWithComments(content, lineNums);
assert.equal(result.length, 2);
assert.deepEqual(result[0].ab, content[0].ab.slice(0, 5));
assert.deepEqual(result[1].ab, content[0].ab.slice(5));
});
test('does not break-down shared chunks w/ context', function() {
var lineNums = {left: 0, right: 0};
var content = [{
ab: _.times(75, function() { return '' + Math.random(); }),
}];
element.context = 4;
var result = element._splitCommonGroupsWithComments(content, lineNums);
assert.deepEqual(result, content);
});
test('intraline normalization', function() {
// The content and highlights are in the format returned by the Gerrit
// REST API.
var content = [
' <section class="summary">',
' <gr-linked-text content="' +
'[[_computeCurrentRevisionMessage(change)]]"></gr-linked-text>',
' </section>',
];
var highlights = [
[31, 34], [42, 26]
];
var results = element._normalizeIntralineHighlights(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._normalizeIntralineHighlights(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', function() {
var contentRow = {
ab: [
'<!DOCTYPE html>',
'<meta charset="utf-8">',
]
};
var content = _.times(200, _.constant(contentRow));
sandbox.stub(element, 'async');
element._isScrolling = true;
element.process(content);
assert.equal(element.groups.length, 1);
element._isScrolling = false;
element.process(content);
assert.equal(element.groups.length, 33);
});
suite('gr-diff-processor helpers', function() {
var rows;
setup(function() {
rows = loremIpsum.split(' ');
});
test('_sharedGroupsFromRows WHOLE_FILE', function() {
var context = WHOLE_FILE;
var lineNumbers = {left: 10, right: 100};
var result = element._sharedGroupsFromRows(
rows, context, lineNumbers.left, lineNumbers.right, null);
// Results in one, uncollapsed group with all rows.
assert.equal(result.length, 1);
assert.equal(result[0].type, GrDiffGroup.Type.BOTH);
assert.equal(result[0].lines.length, rows.length);
// Line numbers are set correctly.
assert.equal(result[0].lines[0].beforeNumber, lineNumbers.left + 1);
assert.equal(result[0].lines[0].afterNumber, lineNumbers.right + 1);
assert.equal(result[0].lines[rows.length - 1].beforeNumber,
lineNumbers.left + rows.length);
assert.equal(result[0].lines[rows.length - 1].afterNumber,
lineNumbers.right + rows.length);
});
test('_sharedGroupsFromRows context', function() {
var context = 10;
var result = element._sharedGroupsFromRows(
rows, context, 10, 100, null);
var expectedCollapseSize = rows.length - 2 * context;
assert.equal(result.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[0].lines.length, context);
assert.equal(result[1].lines.length, 1);
assert.equal(result[2].lines.length, context);
// The collapsed group has the hidden lines as its context group.
assert.equal(result[1].lines[0].contextGroup.lines.length,
expectedCollapseSize);
});
test('_sharedGroupsFromRows first', function() {
var context = 10;
var result = element._sharedGroupsFromRows(
rows, context, 10, 100, 'first');
var expectedCollapseSize = rows.length - context;
assert.equal(result.length, 2, 'Results in two groups');
// Only the first group is collapsed.
assert.equal(result[0].lines.length, 1);
assert.equal(result[1].lines.length, context);
// The collapsed group has the hidden lines as its context group.
assert.equal(result[0].lines[0].contextGroup.lines.length,
expectedCollapseSize);
});
test('_sharedGroupsFromRows few-rows', function() {
// Only ten rows.
rows = rows.slice(0, 10);
var context = 10;
var result = element._sharedGroupsFromRows(
rows, context, 10, 100, 'first');
// Results in one uncollapsed group with all rows.
assert.equal(result.length, 1, 'Results in one group');
assert.equal(result[0].lines.length, rows.length);
});
test('_sharedGroupsFromRows no single line collapse', function() {
rows = rows.slice(0, 7);
var context = 3;
var result = element._sharedGroupsFromRows(
rows, context, 10, 100);
// Results in one uncollapsed group with all rows.
assert.equal(result.length, 1, 'Results in one group');
assert.equal(result[0].lines.length, rows.length);
});
test('_deltaLinesFromRows', function() {
var startLineNum = 10;
var result = element._deltaLinesFromRows(GrDiffLine.Type.ADD, rows,
startLineNum);
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._deltaLinesFromRows(GrDiffLine.Type.REMOVE, rows,
startLineNum);
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*', function() {
test('_breakdownGroup breaks down additions', function() {
sandbox.spy(element, '_breakdown');
var chunk = {b: ['blah', 'blah', 'blah']};
var result = element._breakdownGroup(chunk);
assert.deepEqual(result, [chunk]);
assert.isTrue(element._breakdown.called);
});
test('_breakdown common case', function() {
var array = 'Lorem ipsum dolor sit amet, suspendisse inceptos'
.split(' ');
var size = 3;
var result = element._breakdown(array, size);
result.forEach(function(subResult) {
assert.isAtMost(subResult.length, size);
});
var flattened = result
.reduce(function(a, b) { return a.concat(b); }, []);
assert.deepEqual(flattened, array);
});
test('_breakdown smaller than size', function() {
var array = 'Lorem ipsum dolor sit amet, suspendisse inceptos'
.split(' ');
var size = 10;
var expected = [array];
var result = element._breakdown(array, size);
assert.deepEqual(result, expected);
});
test('_breakdown empty', function() {
var array = [];
var size = 10;
var expected = [];
var result = element._breakdown(array, size);
assert.deepEqual(result, expected);
});
});
});
test('detaching cancels', function() {
element = fixture('basic');
sandbox.stub(element, 'cancel');
element.detached();
assert(element.cancel.called);
});
});
</script>