blob: f83253eee86a3167b7722ecf4dd3c2b726877ec2 [file] [log] [blame]
<!DOCTYPE html>
<!--
@license
Copyright (C) 2018 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</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="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-diff-host.html">
<script>void(0);</script>
<test-fixture id="basic">
<template>
<gr-diff-host></gr-diff-host>
</template>
</test-fixture>
<script>
suite('gr-diff-host tests', () => {
let element;
let sandbox;
setup(() => {
sandbox = sinon.sandbox.create();
element = fixture('basic');
});
teardown(() => {
sandbox.restore();
});
test('reload() cancels before network resolves', () => {
const cancelStub = sandbox.stub(element.$.diff, 'cancel');
// Stub the network calls into requests that never resolve.
sandbox.stub(element, '_getDiff', () => new Promise(() => {}));
element.reload();
assert.isTrue(cancelStub.called);
});
suite('not logged in', () => {
setup(() => {
const getLoggedInPromise = Promise.resolve(false);
stub('gr-rest-api-interface', {
getLoggedIn() { return getLoggedInPromise; },
});
element = fixture('basic');
return getLoggedInPromise;
});
test('reload() loads files weblinks', () => {
const weblinksStub = sandbox.stub(Gerrit.Nav, '_generateWeblinks')
.returns({name: 'stubb', url: '#s'});
sandbox.stub(element.$.restAPI, 'getDiff').returns(Promise.resolve({
content: [],
}));
element.projectName = 'test-project';
element.path = 'test-path';
element.commitRange = {baseCommit: 'test-base', commit: 'test-commit'};
element.patchRange = {};
return element.reload().then(() => {
assert.isTrue(weblinksStub.calledTwice);
assert.isTrue(weblinksStub.firstCall.calledWith({
commit: 'test-base',
file: 'test-path',
options: {
weblinks: undefined,
},
repo: 'test-project',
type: Gerrit.Nav.WeblinkType.FILE}));
assert.isTrue(weblinksStub.secondCall.calledWith({
commit: 'test-commit',
file: 'test-path',
options: {
weblinks: undefined,
},
repo: 'test-project',
type: Gerrit.Nav.WeblinkType.FILE}));
assert.deepEqual(element.filesWeblinks, {
meta_a: [{name: 'stubb', url: '#s'}],
meta_b: [{name: 'stubb', url: '#s'}],
});
});
});
test('_getDiff handles null diff responses', done => {
stub('gr-rest-api-interface', {
getDiff() { return Promise.resolve(null); },
});
element.changeNum = 123;
element.patchRange = {basePatchNum: 1, patchNum: 2};
element.path = 'file.txt';
element._getDiff().then(done);
});
test('reload resolves on error', () => {
const onErrStub = sandbox.stub(element, '_handleGetDiffError');
const error = {ok: false, status: 500};
sandbox.stub(element.$.restAPI, 'getDiff',
(changeNum, basePatchNum, patchNum, path, onErr) => {
onErr(error);
});
return element.reload().then(() => {
assert.isTrue(onErrStub.calledOnce);
});
});
suite('_handleGetDiffError', () => {
let serverErrorStub;
let pageErrorStub;
setup(() => {
serverErrorStub = sinon.stub();
element.addEventListener('server-error', serverErrorStub);
pageErrorStub = sinon.stub();
element.addEventListener('page-error', pageErrorStub);
});
test('page error on HTTP-409', () => {
element._handleGetDiffError({status: 409});
assert.isTrue(serverErrorStub.calledOnce);
assert.isFalse(pageErrorStub.called);
assert.isNotOk(element._errorMessage);
});
test('server error on non-HTTP-409', () => {
element._handleGetDiffError({status: 500});
assert.isFalse(serverErrorStub.called);
assert.isTrue(pageErrorStub.calledOnce);
assert.isNotOk(element._errorMessage);
});
test('error message if showLoadFailure', () => {
element.showLoadFailure = true;
element._handleGetDiffError({status: 500, statusText: 'Failure!'});
assert.isFalse(serverErrorStub.called);
assert.isFalse(pageErrorStub.called);
assert.equal(element._errorMessage,
'Encountered error when loading the diff: 500 Failure!');
});
});
suite('image diffs', () => {
let mockFile1;
let mockFile2;
setup(() => {
mockFile1 = {
body: 'Qk06AAAAAAAAADYAAAAoAAAAAQAAAP////8BACAAAAAAAAAAAAATCwAAE' +
'wsAAAAAAAAAAAAAAAAA/w==',
type: 'image/bmp',
};
mockFile2 = {
body: 'Qk06AAAAAAAAADYAAAAoAAAAAQAAAP////8BACAAAAAAAAAAAAATCwAAE' +
'wsAAAAAAAAAAAAA/////w==',
type: 'image/bmp',
};
sandbox.stub(element.$.restAPI,
'getB64FileContents',
(changeId, patchNum, path, opt_parentIndex) => {
return Promise.resolve(opt_parentIndex === 1 ? mockFile1 :
mockFile2);
});
element.patchRange = {basePatchNum: 'PARENT', patchNum: 1};
element.comments = {left: [], right: []};
});
test('renders image diffs with same file name', done => {
const mockDiff = {
meta_a: {name: 'carrot.jpg', content_type: 'image/jpeg', lines: 66},
meta_b: {name: 'carrot.jpg', content_type: 'image/jpeg',
lines: 560},
intraline_status: 'OK',
change_type: 'MODIFIED',
diff_header: [
'diff --git a/carrot.jpg b/carrot.jpg',
'index 2adc47d..f9c2f2c 100644',
'--- a/carrot.jpg',
'+++ b/carrot.jpg',
'Binary files differ',
],
content: [{skip: 66}],
binary: true,
};
sandbox.stub(element.$.restAPI, 'getDiff')
.returns(Promise.resolve(mockDiff));
const rendered = () => {
// Recognizes that it should be an image diff.
assert.isTrue(element.isImageDiff);
assert.instanceOf(
element.$.diff.$.diffBuilder._builder, GrDiffBuilderImage);
// Left image rendered with the parent commit's version of the file.
const leftImage =
element.$.diff.$.diffTable.querySelector('td.left img');
const leftLabel =
element.$.diff.$.diffTable.querySelector('td.left label');
const leftLabelContent = leftLabel.querySelector('.label');
const leftLabelName = leftLabel.querySelector('.name');
const rightImage =
element.$.diff.$.diffTable.querySelector('td.right img');
const rightLabel = element.$.diff.$.diffTable.querySelector(
'td.right label');
const rightLabelContent = rightLabel.querySelector('.label');
const rightLabelName = rightLabel.querySelector('.name');
assert.isNotOk(rightLabelName);
assert.isNotOk(leftLabelName);
let leftLoaded = false;
let rightLoaded = false;
leftImage.addEventListener('load', () => {
assert.isOk(leftImage);
assert.equal(leftImage.getAttribute('src'),
'data:image/bmp;base64, ' + mockFile1.body);
assert.equal(leftLabelContent.textContent, '1×1 image/bmp');
leftLoaded = true;
if (rightLoaded) {
element.removeEventListener('render', rendered);
done();
}
});
rightImage.addEventListener('load', () => {
assert.isOk(rightImage);
assert.equal(rightImage.getAttribute('src'),
'data:image/bmp;base64, ' + mockFile2.body);
assert.equal(rightLabelContent.textContent, '1×1 image/bmp');
rightLoaded = true;
if (leftLoaded) {
element.removeEventListener('render', rendered);
done();
}
});
};
element.addEventListener('render', rendered);
element.$.restAPI.getDiffPreferences().then(prefs => {
element.prefs = prefs;
element.reload();
});
});
test('renders image diffs with a different file name', done => {
const mockDiff = {
meta_a: {name: 'carrot.jpg', content_type: 'image/jpeg', lines: 66},
meta_b: {name: 'carrot2.jpg', content_type: 'image/jpeg',
lines: 560},
intraline_status: 'OK',
change_type: 'MODIFIED',
diff_header: [
'diff --git a/carrot.jpg b/carrot2.jpg',
'index 2adc47d..f9c2f2c 100644',
'--- a/carrot.jpg',
'+++ b/carrot2.jpg',
'Binary files differ',
],
content: [{skip: 66}],
binary: true,
};
sandbox.stub(element.$.restAPI, 'getDiff')
.returns(Promise.resolve(mockDiff));
const rendered = () => {
// Recognizes that it should be an image diff.
assert.isTrue(element.isImageDiff);
assert.instanceOf(
element.$.diff.$.diffBuilder._builder, GrDiffBuilderImage);
// Left image rendered with the parent commit's version of the file.
const leftImage =
element.$.diff.$.diffTable.querySelector('td.left img');
const leftLabel =
element.$.diff.$.diffTable.querySelector('td.left label');
const leftLabelContent = leftLabel.querySelector('.label');
const leftLabelName = leftLabel.querySelector('.name');
const rightImage =
element.$.diff.$.diffTable.querySelector('td.right img');
const rightLabel = element.$.diff.$.diffTable.querySelector(
'td.right label');
const rightLabelContent = rightLabel.querySelector('.label');
const rightLabelName = rightLabel.querySelector('.name');
assert.isOk(rightLabelName);
assert.isOk(leftLabelName);
assert.equal(leftLabelName.textContent, mockDiff.meta_a.name);
assert.equal(rightLabelName.textContent, mockDiff.meta_b.name);
let leftLoaded = false;
let rightLoaded = false;
leftImage.addEventListener('load', () => {
assert.isOk(leftImage);
assert.equal(leftImage.getAttribute('src'),
'data:image/bmp;base64, ' + mockFile1.body);
assert.equal(leftLabelContent.textContent, '1×1 image/bmp');
leftLoaded = true;
if (rightLoaded) {
element.removeEventListener('render', rendered);
done();
}
});
rightImage.addEventListener('load', () => {
assert.isOk(rightImage);
assert.equal(rightImage.getAttribute('src'),
'data:image/bmp;base64, ' + mockFile2.body);
assert.equal(rightLabelContent.textContent, '1×1 image/bmp');
rightLoaded = true;
if (leftLoaded) {
element.removeEventListener('render', rendered);
done();
}
});
};
element.addEventListener('render', rendered);
element.$.restAPI.getDiffPreferences().then(prefs => {
element.prefs = prefs;
element.reload();
});
});
test('renders added image', done => {
const mockDiff = {
meta_b: {name: 'carrot.jpg', content_type: 'image/jpeg',
lines: 560},
intraline_status: 'OK',
change_type: 'ADDED',
diff_header: [
'diff --git a/carrot.jpg b/carrot.jpg',
'index 0000000..f9c2f2c 100644',
'--- /dev/null',
'+++ b/carrot.jpg',
'Binary files differ',
],
content: [{skip: 66}],
binary: true,
};
sandbox.stub(element.$.restAPI, 'getDiff')
.returns(Promise.resolve(mockDiff));
element.addEventListener('render', () => {
// Recognizes that it should be an image diff.
assert.isTrue(element.isImageDiff);
assert.instanceOf(
element.$.diff.$.diffBuilder._builder, GrDiffBuilderImage);
const leftImage =
element.$.diff.$.diffTable.querySelector('td.left img');
const rightImage =
element.$.diff.$.diffTable.querySelector('td.right img');
assert.isNotOk(leftImage);
assert.isOk(rightImage);
done();
});
element.$.restAPI.getDiffPreferences().then(prefs => {
element.prefs = prefs;
element.reload();
});
});
test('renders removed image', done => {
const mockDiff = {
meta_a: {name: 'carrot.jpg', content_type: 'image/jpeg',
lines: 560},
intraline_status: 'OK',
change_type: 'DELETED',
diff_header: [
'diff --git a/carrot.jpg b/carrot.jpg',
'index f9c2f2c..0000000 100644',
'--- a/carrot.jpg',
'+++ /dev/null',
'Binary files differ',
],
content: [{skip: 66}],
binary: true,
};
sandbox.stub(element.$.restAPI, 'getDiff')
.returns(Promise.resolve(mockDiff));
element.addEventListener('render', () => {
// Recognizes that it should be an image diff.
assert.isTrue(element.isImageDiff);
assert.instanceOf(
element.$.diff.$.diffBuilder._builder, GrDiffBuilderImage);
const leftImage =
element.$.diff.$.diffTable.querySelector('td.left img');
const rightImage =
element.$.diff.$.diffTable.querySelector('td.right img');
assert.isOk(leftImage);
assert.isNotOk(rightImage);
done();
});
element.$.restAPI.getDiffPreferences().then(prefs => {
element.prefs = prefs;
element.reload();
});
});
test('does not render disallowed image type', done => {
const mockDiff = {
meta_a: {name: 'carrot.jpg', content_type: 'image/jpeg-evil',
lines: 560},
intraline_status: 'OK',
change_type: 'DELETED',
diff_header: [
'diff --git a/carrot.jpg b/carrot.jpg',
'index f9c2f2c..0000000 100644',
'--- a/carrot.jpg',
'+++ /dev/null',
'Binary files differ',
],
content: [{skip: 66}],
binary: true,
};
mockFile1.type = 'image/jpeg-evil';
sandbox.stub(element.$.restAPI, 'getDiff')
.returns(Promise.resolve(mockDiff));
element.addEventListener('render', () => {
// Recognizes that it should be an image diff.
assert.isTrue(element.isImageDiff);
assert.instanceOf(
element.$.diff.$.diffBuilder._builder, GrDiffBuilderImage);
const leftImage =
element.$.diff.$.diffTable.querySelector('td.left img');
assert.isNotOk(leftImage);
done();
});
element.$.restAPI.getDiffPreferences().then(prefs => {
element.prefs = prefs;
element.reload();
});
});
});
});
test('delegates cancel()', () => {
const stub = sandbox.stub(element.$.diff, 'cancel');
element.reload();
assert.isTrue(stub.calledOnce);
assert.equal(stub.lastCall.args.length, 0);
});
test('delegates getCursorStops()', () => {
const returnValue = [document.createElement('b')];
const stub = sandbox.stub(element.$.diff, 'getCursorStops')
.returns(returnValue);
assert.equal(element.getCursorStops(), returnValue);
assert.isTrue(stub.calledOnce);
assert.equal(stub.lastCall.args.length, 0);
});
test('delegates isRangeSelected()', () => {
const returnValue = true;
const stub = sandbox.stub(element.$.diff, 'isRangeSelected')
.returns(returnValue);
assert.equal(element.isRangeSelected(), returnValue);
assert.isTrue(stub.calledOnce);
assert.equal(stub.lastCall.args.length, 0);
});
test('delegates toggleLeftDiff()', () => {
const stub = sandbox.stub(element.$.diff, 'toggleLeftDiff');
element.toggleLeftDiff();
assert.isTrue(stub.calledOnce);
assert.equal(stub.lastCall.args.length, 0);
});
suite('blame', () => {
setup(() => {
element = fixture('basic');
});
test('clearBlame', () => {
element._blame = [];
const setBlameSpy = sandbox.spy(element.$.diff.$.diffBuilder, 'setBlame');
element.clearBlame();
assert.isNull(element._blame);
assert.isTrue(setBlameSpy.calledWithExactly(null));
assert.equal(element.isBlameLoaded, false);
});
test('loadBlame', () => {
const mockBlame = [{id: 'commit id', ranges: [{start: 1, end: 2}]}];
const showAlertStub = sinon.stub();
element.addEventListener('show-alert', showAlertStub);
const getBlameStub = sandbox.stub(element.$.restAPI, 'getBlame')
.returns(Promise.resolve(mockBlame));
element.changeNum = 42;
element.patchRange = {patchNum: 5, basePatchNum: 4};
element.path = 'foo/bar.baz';
return element.loadBlame().then(() => {
assert.isTrue(getBlameStub.calledWithExactly(
42, 5, 'foo/bar.baz', true));
assert.isFalse(showAlertStub.called);
assert.equal(element._blame, mockBlame);
assert.equal(element.isBlameLoaded, true);
});
});
test('loadBlame empty', () => {
const mockBlame = [];
const showAlertStub = sinon.stub();
element.addEventListener('show-alert', showAlertStub);
sandbox.stub(element.$.restAPI, 'getBlame')
.returns(Promise.resolve(mockBlame));
element.changeNum = 42;
element.patchRange = {patchNum: 5, basePatchNum: 4};
element.path = 'foo/bar.baz';
return element.loadBlame()
.then(() => {
assert.isTrue(false, 'Promise should not resolve');
})
.catch(() => {
assert.isTrue(showAlertStub.calledOnce);
assert.isNull(element._blame);
assert.equal(element.isBlameLoaded, false);
});
});
});
test('delegates getThreadEls()', () => {
const returnValue = [document.createElement('b')];
const stub = sandbox.stub(element.$.diff, 'getThreadEls')
.returns(returnValue);
assert.equal(element.getThreadEls(), returnValue);
assert.isTrue(stub.calledOnce);
assert.equal(stub.lastCall.args.length, 0);
});
test('delegates addDraftAtLine(el)', () => {
const param0 = document.createElement('b');
const stub = sandbox.stub(element.$.diff, 'addDraftAtLine');
element.addDraftAtLine(param0);
assert.isTrue(stub.calledOnce);
assert.equal(stub.lastCall.args.length, 1);
assert.equal(stub.lastCall.args[0], param0);
});
test('delegates clearDiffContent()', () => {
const stub = sandbox.stub(element.$.diff, 'clearDiffContent');
element.clearDiffContent();
assert.isTrue(stub.calledOnce);
assert.equal(stub.lastCall.args.length, 0);
});
test('delegates expandAllContext()', () => {
const stub = sandbox.stub(element.$.diff, 'expandAllContext');
element.expandAllContext();
assert.isTrue(stub.calledOnce);
assert.equal(stub.lastCall.args.length, 0);
});
test('passes in changeNum', () => {
const value = '12345';
element.changeNum = value;
assert.equal(element.$.diff.changeNum, value);
});
test('passes in noAutoRender', () => {
const value = true;
element.noAutoRender = value;
assert.equal(element.$.diff.noAutoRender, value);
});
test('passes in patchRange', () => {
const value = {patchNum: 'foo', basePatchNum: 'bar'};
element.patchRange = value;
assert.equal(element.$.diff.patchRange, value);
});
test('passes in path', () => {
const value = 'some/file/path';
element.path = value;
assert.equal(element.$.diff.path, value);
});
test('passes in prefs', () => {
const value = {};
element.prefs = value;
assert.equal(element.$.diff.prefs, value);
});
test('passes in projectConfig', () => {
const value = {};
element.projectConfig = value;
assert.equal(element.$.diff.projectConfig, value);
});
test('passes in changeNum', () => {
const value = '12345';
element.changeNum = value;
assert.equal(element.$.diff.changeNum, value);
});
test('passes in projectName', () => {
const value = 'Gerrit';
element.projectName = value;
assert.equal(element.$.diff.projectName, value);
});
test('passes in displayLine', () => {
const value = true;
element.displayLine = value;
assert.equal(element.$.diff.displayLine, value);
});
test('passes in commitRange', () => {
const value = {};
element.commitRange = value;
assert.equal(element.$.diff.commitRange, value);
});
test('passes in hidden', () => {
const value = true;
element.hidden = value;
assert.equal(element.$.diff.hidden, value);
assert.isNotNull(element.getAttribute('hidden'));
});
test('passes in noRenderOnPrefsChange', () => {
const value = true;
element.noRenderOnPrefsChange = value;
assert.equal(element.$.diff.noRenderOnPrefsChange, value);
});
test('passes in comments', () => {
const value = {left: [], right: []};
element.comments = value;
assert.equal(element.$.diff.comments, value);
});
test('passes in lineWrapping', () => {
const value = true;
element.lineWrapping = value;
assert.equal(element.$.diff.lineWrapping, value);
});
test('passes in viewMode', () => {
const value = 'SIDE_BY_SIDE';
element.viewMode = value;
assert.equal(element.$.diff.viewMode, value);
});
test('passes in lineOfInterest', () => {
const value = {number: 123, leftSide: true};
element.lineOfInterest = value;
assert.equal(element.$.diff.lineOfInterest, value);
});
suite('_reportDiff', () => {
let reportStub;
setup(() => {
element = fixture('basic');
element.patchRange = {basePatchNum: 1};
reportStub = sandbox.stub(element.$.reporting, 'reportInteraction');
});
test('null and content-less', () => {
element._reportDiff(null);
assert.isFalse(reportStub.called);
element._reportDiff({});
assert.isFalse(reportStub.called);
});
test('diff w/ no delta', () => {
const diff = {
content: [
{ab: ['foo', 'bar']},
{ab: ['baz', 'foo']},
],
};
element._reportDiff(diff);
assert.isTrue(reportStub.calledOnce);
assert.equal(reportStub.lastCall.args[0], 'rebase-percent-zero');
assert.isUndefined(reportStub.lastCall.args[1]);
});
test('diff w/ no rebase delta', () => {
const diff = {
content: [
{ab: ['foo', 'bar']},
{a: ['baz', 'foo']},
{ab: ['foo', 'bar']},
{a: ['baz', 'foo'], b: ['bar', 'baz']},
{ab: ['foo', 'bar']},
{b: ['baz', 'foo']},
{ab: ['foo', 'bar']},
],
};
element._reportDiff(diff);
assert.isTrue(reportStub.calledOnce);
assert.equal(reportStub.lastCall.args[0], 'rebase-percent-zero');
assert.isUndefined(reportStub.lastCall.args[1]);
});
test('diff w/ some rebase delta', () => {
const diff = {
content: [
{ab: ['foo', 'bar']},
{a: ['baz', 'foo'], due_to_rebase: true},
{ab: ['foo', 'bar']},
{a: ['baz', 'foo'], b: ['bar', 'baz']},
{ab: ['foo', 'bar']},
{b: ['baz', 'foo'], due_to_rebase: true},
{ab: ['foo', 'bar']},
{a: ['baz', 'foo']},
],
};
element._reportDiff(diff);
assert.isTrue(reportStub.calledOnce);
assert.equal(reportStub.lastCall.args[0], 'rebase-percent-nonzero');
assert.strictEqual(reportStub.lastCall.args[1], 50);
});
test('diff w/ all rebase delta', () => {
const diff = {content: [{
a: ['foo', 'bar'],
b: ['baz', 'foo'],
due_to_rebase: true,
}]};
element._reportDiff(diff);
assert.isTrue(reportStub.calledOnce);
assert.equal(reportStub.lastCall.args[0], 'rebase-percent-nonzero');
assert.strictEqual(reportStub.lastCall.args[1], 100);
});
test('diff against parent event', () => {
element.patchRange.basePatchNum = 'PARENT';
const diff = {content: [{
a: ['foo', 'bar'],
b: ['baz', 'foo'],
}]};
element._reportDiff(diff);
assert.isTrue(reportStub.calledOnce);
assert.equal(reportStub.lastCall.args[0], 'diff-against-parent');
assert.isUndefined(reportStub.lastCall.args[1]);
});
});
suite('_translateChunksToIgnore', () => {
let content;
setup(() => {
content = [
{ab: ['one', 'two']},
{a: ['three'], b: ['different three']},
{b: ['four']},
{ab: ['five', 'six']},
{a: ['seven']},
{ab: ['eight', 'nine']},
];
});
test('does nothing to unmarked diff', () => {
assert.deepEqual(element._translateChunksToIgnore({content}),
{content});
});
test('merges marked delta chunk', () => {
content[1].common = true;
assert.deepEqual(element._translateChunksToIgnore({content}), {
content: [
{ab: ['one', 'two', 'different three']},
{b: ['four']},
{ab: ['five', 'six']},
{a: ['seven']},
{ab: ['eight', 'nine']},
],
});
});
test('merges marked addition chunk', () => {
content[2].common = true;
assert.deepEqual(element._translateChunksToIgnore({content}), {
content: [
{ab: ['one', 'two']},
{a: ['three'], b: ['different three']},
{ab: ['four', 'five', 'six']},
{a: ['seven']},
{ab: ['eight', 'nine']},
],
});
});
test('merges multiple marked delta', () => {
content[1].common = true;
content[2].common = true;
assert.deepEqual(element._translateChunksToIgnore({content}), {
content: [
{ab: ['one', 'two', 'different three', 'four', 'five', 'six']},
{a: ['seven']},
{ab: ['eight', 'nine']},
],
});
});
test('marked deletion chunks are omitted', () => {
content[4].common = true;
assert.deepEqual(element._translateChunksToIgnore({content}), {
content: [
{ab: ['one', 'two']},
{a: ['three'], b: ['different three']},
{b: ['four']},
{ab: ['five', 'six', 'eight', 'nine']},
],
});
});
test('marked deltas can start shared chunks', () => {
content[0] = {a: ['one'], b: ['two'], common: true};
assert.deepEqual(element._translateChunksToIgnore({content}), {
content: [
{ab: ['two']},
{a: ['three'], b: ['different three']},
{b: ['four']},
{ab: ['five', 'six']},
{a: ['seven']},
{ab: ['eight', 'nine']},
],
});
});
});
});
</script>