Merge "Allow multiple threads per line, with different ranges"
This commit is contained in:
@@ -84,9 +84,9 @@
|
||||
row.appendChild(action);
|
||||
} else {
|
||||
var textEl = this._createTextEl(line, side);
|
||||
var threadEl = this._commentThreadForLine(line, side);
|
||||
if (threadEl) {
|
||||
textEl.appendChild(threadEl);
|
||||
var threadGroupEl = this._commentThreadGroupForLine(line, side);
|
||||
if (threadGroupEl) {
|
||||
textEl.appendChild(threadGroupEl);
|
||||
}
|
||||
row.appendChild(textEl);
|
||||
}
|
||||
|
||||
@@ -73,9 +73,9 @@
|
||||
row.appendChild(action);
|
||||
} else {
|
||||
var textEl = this._createTextEl(line);
|
||||
var threadEl = this._commentThreadForLine(line);
|
||||
if (threadEl) {
|
||||
textEl.appendChild(threadEl);
|
||||
var threadGroupEl = this._commentThreadGroupForLine(line);
|
||||
if (threadGroupEl) {
|
||||
textEl.appendChild(threadGroupEl);
|
||||
}
|
||||
row.appendChild(textEl);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ limitations under the License.
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer.html">
|
||||
<link rel="import" href="../../core/gr-reporting/gr-reporting.html">
|
||||
<link rel="import" href="../gr-diff-comment-thread/gr-diff-comment-thread.html">
|
||||
<link rel="import" href="../gr-diff-comment-thread-group/gr-diff-comment-thread-group.html">
|
||||
<link rel="import" href="../gr-diff-processor/gr-diff-processor.html">
|
||||
<link rel="import" href="../gr-ranged-comment-layer/gr-ranged-comment-layer.html">
|
||||
<link rel="import" href="../gr-syntax-layer/gr-syntax-layer.html">
|
||||
@@ -177,38 +178,6 @@ limitations under the License.
|
||||
parseInt(lineEl.getAttribute('data-value'), 10) : null;
|
||||
},
|
||||
|
||||
renderLineRange: function(startLine, endLine, opt_side) {
|
||||
var groups =
|
||||
this._builder.getGroupsByLineRange(startLine, endLine, opt_side);
|
||||
groups.forEach(function(group) {
|
||||
var newElement = this._builder.buildSectionElement(group);
|
||||
var oldElement = group.element;
|
||||
|
||||
// Transfer comment threads from existing section to new one.
|
||||
var threads = Polymer.dom(newElement).querySelectorAll(
|
||||
'gr-diff-comment-thread');
|
||||
threads.forEach(function(threadEl) {
|
||||
var lineEl = this.getLineElByChild(threadEl, oldElement);
|
||||
if (!lineEl) { // New comment thread.
|
||||
return;
|
||||
}
|
||||
var side = this.getSideByLineEl(lineEl);
|
||||
var line = lineEl.getAttribute('data-value');
|
||||
var oldThreadEl =
|
||||
this.getCommentThreadByLine(line, side, oldElement);
|
||||
threadEl.parentNode.replaceChild(oldThreadEl, threadEl);
|
||||
}, this);
|
||||
|
||||
// Replace old group elements with new ones.
|
||||
group.element.parentNode.replaceChild(newElement, group.element);
|
||||
group.element = newElement;
|
||||
}, this);
|
||||
|
||||
this.async(function() {
|
||||
this.fire('render');
|
||||
}, 1);
|
||||
},
|
||||
|
||||
getContentByLine: function(lineNumber, opt_side, opt_root) {
|
||||
return this._builder.getContentByLine(lineNumber, opt_side, opt_root);
|
||||
},
|
||||
@@ -233,27 +202,15 @@ limitations under the License.
|
||||
return result;
|
||||
},
|
||||
|
||||
getCommentThreadByLine: function(lineNumber, opt_side, opt_root) {
|
||||
var content = this.getContentByLine(lineNumber, opt_side, opt_root);
|
||||
return this.getCommentThreadByContentEl(content);
|
||||
},
|
||||
|
||||
getCommentThreadByContentEl: function(contentEl) {
|
||||
if (contentEl.classList.contains('contentText')) {
|
||||
contentEl = contentEl.parentElement;
|
||||
}
|
||||
return contentEl.querySelector('gr-diff-comment-thread');
|
||||
},
|
||||
|
||||
getSideByLineEl: function(lineEl) {
|
||||
return lineEl.classList.contains(GrDiffBuilder.Side.RIGHT) ?
|
||||
GrDiffBuilder.Side.RIGHT : GrDiffBuilder.Side.LEFT;
|
||||
},
|
||||
|
||||
createCommentThread: function(changeNum, patchNum, path, side,
|
||||
createCommentThreadGroup: function(changeNum, patchNum, path, side,
|
||||
projectConfig) {
|
||||
return this._builder.createCommentThread(changeNum, patchNum, path,
|
||||
side, projectConfig);
|
||||
return this._builder.createCommentThreadGroup(changeNum, patchNum,
|
||||
path, side, projectConfig);
|
||||
},
|
||||
|
||||
emitGroup: function(group, sectionEl) {
|
||||
|
||||
@@ -332,18 +332,21 @@
|
||||
return result;
|
||||
};
|
||||
|
||||
GrDiffBuilder.prototype.createCommentThread = function(changeNum, patchNum,
|
||||
path, side, projectConfig) {
|
||||
var threadEl = document.createElement('gr-diff-comment-thread');
|
||||
threadEl.changeNum = changeNum;
|
||||
threadEl.patchNum = patchNum;
|
||||
threadEl.path = path;
|
||||
threadEl.side = side;
|
||||
threadEl.projectConfig = projectConfig;
|
||||
return threadEl;
|
||||
GrDiffBuilder.prototype.createCommentThreadGroup =
|
||||
function(changeNum, patchNum, path, side, projectConfig, range) {
|
||||
var threadGroupEl =
|
||||
document.createElement('gr-diff-comment-thread-group');
|
||||
threadGroupEl.changeNum = changeNum;
|
||||
threadGroupEl.patchNum = patchNum;
|
||||
threadGroupEl.path = path;
|
||||
threadGroupEl.side = side;
|
||||
threadGroupEl.projectConfig = projectConfig;
|
||||
threadGroupEl.range = range;
|
||||
return threadGroupEl;
|
||||
};
|
||||
|
||||
GrDiffBuilder.prototype._commentThreadForLine = function(line, opt_side) {
|
||||
GrDiffBuilder.prototype._commentThreadGroupForLine =
|
||||
function(line, opt_side) {
|
||||
var comments = this._getCommentsForLine(this._comments, line, opt_side);
|
||||
if (!comments || comments.length === 0) {
|
||||
return null;
|
||||
@@ -359,17 +362,17 @@
|
||||
patchNum = this._comments.meta.patchRange.basePatchNum;
|
||||
}
|
||||
}
|
||||
var threadEl = this.createCommentThread(
|
||||
var threadGroupEl = this.createCommentThreadGroup(
|
||||
this._comments.meta.changeNum,
|
||||
patchNum,
|
||||
this._comments.meta.path,
|
||||
side,
|
||||
this._comments.meta.projectConfig);
|
||||
threadEl.comments = comments;
|
||||
threadGroupEl.comments = comments;
|
||||
if (opt_side) {
|
||||
threadEl.setAttribute('data-side', opt_side);
|
||||
threadGroupEl.setAttribute('data-side', opt_side);
|
||||
}
|
||||
return threadEl;
|
||||
return threadGroupEl;
|
||||
};
|
||||
|
||||
GrDiffBuilder.prototype._createLineEl = function(line, number, type,
|
||||
|
||||
@@ -214,7 +214,7 @@ limitations under the License.
|
||||
GrDiffBuilder.Side.RIGHT), [{id: 'r5', line: 5}]);
|
||||
});
|
||||
|
||||
test('comment thread creation', function() {
|
||||
test('comment thread group creation', function() {
|
||||
var l3 = {id: 'l3', line: 3, updated: '2016-08-09 00:42:32.000000000'};
|
||||
var l5 = {id: 'l5', line: 5, updated: '2016-08-09 00:42:32.000000000'};
|
||||
var r5 = {id: 'r5', line: 5, updated: '2016-08-09 00:42:32.000000000'};
|
||||
@@ -233,51 +233,55 @@ limitations under the License.
|
||||
right: [r5],
|
||||
};
|
||||
|
||||
function checkThreadProps(threadEl, patchNum, side, comments) {
|
||||
assert.equal(threadEl.changeNum, '42');
|
||||
assert.equal(threadEl.patchNum, patchNum);
|
||||
assert.equal(threadEl.path, '/path/to/foo');
|
||||
assert.equal(threadEl.side, side);
|
||||
assert.deepEqual(threadEl.projectConfig, {foo: 'bar'});
|
||||
assert.deepEqual(threadEl.comments, comments);
|
||||
function checkThreadGroupProps(threadGroupEl, patchNum, side, comments) {
|
||||
assert.equal(threadGroupEl.changeNum, '42');
|
||||
assert.equal(threadGroupEl.patchNum, patchNum);
|
||||
assert.equal(threadGroupEl.path, '/path/to/foo');
|
||||
assert.equal(threadGroupEl.side, side);
|
||||
assert.deepEqual(threadGroupEl.projectConfig, {foo: 'bar'});
|
||||
assert.deepEqual(threadGroupEl.comments, comments);
|
||||
}
|
||||
|
||||
var line = new GrDiffLine(GrDiffLine.Type.BOTH);
|
||||
line.beforeNumber = 5;
|
||||
line.afterNumber = 5;
|
||||
var threadEl = builder._commentThreadForLine(line);
|
||||
checkThreadProps(threadEl, '3', 'REVISION', [l5, r5]);
|
||||
var threadGroupEl = builder._commentThreadGroupForLine(line);
|
||||
checkThreadGroupProps(threadGroupEl, '3', 'REVISION', [l5, r5]);
|
||||
|
||||
threadEl = builder._commentThreadForLine(line, GrDiffBuilder.Side.RIGHT);
|
||||
checkThreadProps(threadEl, '3', 'REVISION', [r5]);
|
||||
threadGroupEl =
|
||||
builder._commentThreadGroupForLine(line, GrDiffBuilder.Side.RIGHT);
|
||||
checkThreadGroupProps(threadGroupEl, '3', 'REVISION', [r5]);
|
||||
|
||||
threadEl = builder._commentThreadForLine(line, GrDiffBuilder.Side.LEFT);
|
||||
checkThreadProps(threadEl, '3', 'PARENT', [l5]);
|
||||
threadGroupEl =
|
||||
builder._commentThreadGroupForLine(line, GrDiffBuilder.Side.LEFT);
|
||||
checkThreadGroupProps(threadGroupEl, '3', 'PARENT', [l5]);
|
||||
|
||||
builder._comments.meta.patchRange.basePatchNum = '1';
|
||||
|
||||
threadEl = builder._commentThreadForLine(line);
|
||||
checkThreadProps(threadEl, '3', 'REVISION', [l5, r5]);
|
||||
threadGroupEl = builder._commentThreadGroupForLine(line);
|
||||
checkThreadGroupProps(threadGroupEl, '3', 'REVISION', [l5, r5]);
|
||||
|
||||
threadEl = builder._commentThreadForLine(line, GrDiffBuilder.Side.LEFT);
|
||||
checkThreadProps(threadEl, '1', 'REVISION', [l5]);
|
||||
threadEl =
|
||||
builder._commentThreadGroupForLine(line, GrDiffBuilder.Side.LEFT);
|
||||
checkThreadGroupProps(threadEl, '1', 'REVISION', [l5]);
|
||||
|
||||
threadEl = builder._commentThreadForLine(line, GrDiffBuilder.Side.RIGHT);
|
||||
checkThreadProps(threadEl, '3', 'REVISION', [r5]);
|
||||
threadGroupEl =
|
||||
builder._commentThreadGroupForLine(line, GrDiffBuilder.Side.RIGHT);
|
||||
checkThreadGroupProps(threadGroupEl, '3', 'REVISION', [r5]);
|
||||
|
||||
builder._comments.meta.patchRange.basePatchNum = 'PARENT';
|
||||
|
||||
line = new GrDiffLine(GrDiffLine.Type.REMOVE);
|
||||
line.beforeNumber = 5;
|
||||
line.afterNumber = 5;
|
||||
threadEl = builder._commentThreadForLine(line);
|
||||
checkThreadProps(threadEl, '3', 'PARENT', [l5, r5]);
|
||||
threadGroupEl = builder._commentThreadGroupForLine(line);
|
||||
checkThreadGroupProps(threadGroupEl, '3', 'PARENT', [l5, r5]);
|
||||
|
||||
line = new GrDiffLine(GrDiffLine.Type.ADD);
|
||||
line.beforeNumber = 3;
|
||||
line.afterNumber = 5;
|
||||
threadEl = builder._commentThreadForLine(line);
|
||||
checkThreadProps(threadEl, '3', 'REVISION', [l3, r5]);
|
||||
threadGroupEl = builder._commentThreadGroupForLine(line);
|
||||
checkThreadGroupProps(threadGroupEl, '3', 'REVISION', [l3, r5]);
|
||||
});
|
||||
|
||||
suite('_isTotal', function() {
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
<!--
|
||||
Copyright (C) 2017 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.
|
||||
-->
|
||||
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer.html">
|
||||
<link rel="import" href="../gr-diff-comment-thread/gr-diff-comment-thread.html">
|
||||
|
||||
<dom-module id="gr-diff-comment-thread-group">
|
||||
<template>
|
||||
<style>
|
||||
:host {
|
||||
display: block;
|
||||
white-space: normal;
|
||||
}
|
||||
</style>
|
||||
<template is="dom-repeat" items="[[_threadGroups]]"
|
||||
as="thread">
|
||||
<gr-diff-comment-thread
|
||||
comments="[[thread.comments]]"
|
||||
change-num="[[changeNum]]"
|
||||
location-range="[[thread.locationRange]]"
|
||||
patch-num="[[patchNum]]"
|
||||
path="[[path]]"
|
||||
side="[[side]]"
|
||||
project-config="[[projectConfig]]"></gr-diff-comment-thread>
|
||||
</template>
|
||||
</template>
|
||||
<script src="gr-diff-comment-thread-group.js"></script>
|
||||
</dom-module>
|
||||
@@ -0,0 +1,119 @@
|
||||
// Copyright (C) 2017 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.
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
Polymer({
|
||||
is: 'gr-diff-comment-thread-group',
|
||||
|
||||
properties: {
|
||||
changeNum: String,
|
||||
comments: {
|
||||
type: Array,
|
||||
value: function() { return []; },
|
||||
},
|
||||
patchNum: String,
|
||||
projectConfig: Object,
|
||||
range: Object,
|
||||
side: {
|
||||
type: String,
|
||||
value: 'REVISION',
|
||||
},
|
||||
_threadGroups: {
|
||||
type: Array,
|
||||
value: function() { return []; },
|
||||
},
|
||||
},
|
||||
|
||||
observers: [
|
||||
'_commentsChanged(comments.*)',
|
||||
],
|
||||
|
||||
addNewThread: function(locationRange) {
|
||||
this.push('_threadGroups', {
|
||||
comments: [],
|
||||
locationRange: locationRange,
|
||||
});
|
||||
},
|
||||
|
||||
removeThread: function(locationRange) {
|
||||
for (var i = 0; i < this._threadGroups.length; i++) {
|
||||
if (this._threadGroups[i].locationRange === locationRange) {
|
||||
this.splice('_threadGroups', i, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
getThreadForRange: function(rangeToCheck) {
|
||||
var threads = [].filter.call(
|
||||
Polymer.dom(this.root).querySelectorAll('gr-diff-comment-thread'),
|
||||
function(thread) {
|
||||
return thread.locationRange === rangeToCheck;
|
||||
});
|
||||
if (threads.length === 1) {
|
||||
return threads[0];
|
||||
}
|
||||
},
|
||||
|
||||
_commentsChanged: function() {
|
||||
this._threadGroups = this._getThreadGroups(this.comments);
|
||||
},
|
||||
|
||||
_sortByDate: function(threadGroups) {
|
||||
if (!threadGroups.length) { return; }
|
||||
return threadGroups.sort(function(a, b) {
|
||||
return a.start_datetime > b.start_datetime;
|
||||
});
|
||||
},
|
||||
|
||||
_calculateLocationRange: function(range) {
|
||||
return 'range-' + range.start_line + '-' +
|
||||
range.start_character + '-' +
|
||||
range.end_line + '-' +
|
||||
range.end_character;
|
||||
},
|
||||
|
||||
_getThreadGroups: function(comments) {
|
||||
var threadGroups = {};
|
||||
|
||||
comments.forEach(function(comment) {
|
||||
var locationRange;
|
||||
if (!comment.range) {
|
||||
locationRange = 'line';
|
||||
} else {
|
||||
locationRange = this._calculateLocationRange(comment.range);
|
||||
}
|
||||
|
||||
if (threadGroups[locationRange]) {
|
||||
threadGroups[locationRange].comments.push(comment);
|
||||
} else {
|
||||
threadGroups[locationRange] = {
|
||||
start_datetime: comment.updated,
|
||||
comments: [comment],
|
||||
locationRange: locationRange,
|
||||
};
|
||||
}
|
||||
}.bind(this));
|
||||
|
||||
var threadGroupArr = [];
|
||||
var threadGroupKeys = Object.keys(threadGroups);
|
||||
threadGroupKeys.forEach(function(threadGroupKey) {
|
||||
threadGroupArr.push(threadGroups[threadGroupKey]);
|
||||
});
|
||||
|
||||
return this._sortByDate(threadGroupArr);
|
||||
},
|
||||
});
|
||||
})();
|
||||
@@ -0,0 +1,199 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Copyright (C) 2017 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-comment-thread-group</title>
|
||||
|
||||
<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
|
||||
<script src="../../../bower_components/web-component-tester/browser.js"></script>
|
||||
<script src="../../../scripts/util.js"></script>
|
||||
|
||||
<link rel="import" href="../../../bower_components/iron-test-helpers/iron-test-helpers.html">
|
||||
<link rel="import" href="gr-diff-comment-thread-group.html">
|
||||
|
||||
<test-fixture id="basic">
|
||||
<template>
|
||||
<gr-diff-comment-thread-group></gr-diff-comment-thread-group>
|
||||
</template>
|
||||
</test-fixture>
|
||||
|
||||
<script>
|
||||
suite('gr-diff-comment-thread-group tests', function() {
|
||||
var element;
|
||||
var sandbox;
|
||||
|
||||
setup(function() {
|
||||
sandbox = sinon.sandbox.create();
|
||||
stub('gr-rest-api-interface', {
|
||||
getLoggedIn: function() { return Promise.resolve(false); },
|
||||
});
|
||||
element = fixture('basic');
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
test('_getThreadGroups', function() {
|
||||
var comments = [
|
||||
{
|
||||
id: 'sallys_confession',
|
||||
message: 'i like you, jack',
|
||||
updated: '2015-12-23 15:00:20.396000000',
|
||||
}, {
|
||||
id: 'jacks_reply',
|
||||
message: 'i like you, too',
|
||||
updated: '2015-12-24 15:00:20.396000000',
|
||||
},
|
||||
];
|
||||
|
||||
var expectedThreadGroups = [
|
||||
{
|
||||
start_datetime: '2015-12-23 15:00:20.396000000',
|
||||
comments: [{
|
||||
id: 'sallys_confession',
|
||||
message: 'i like you, jack',
|
||||
updated: '2015-12-23 15:00:20.396000000',
|
||||
}, {
|
||||
id: 'jacks_reply',
|
||||
message: 'i like you, too',
|
||||
updated: '2015-12-24 15:00:20.396000000',
|
||||
}],
|
||||
locationRange: 'line',
|
||||
},
|
||||
];
|
||||
|
||||
assert.deepEqual(element._getThreadGroups(comments),
|
||||
expectedThreadGroups);
|
||||
|
||||
comments.push({
|
||||
id: 'betsys_confession',
|
||||
message: 'i like you, jack',
|
||||
updated: '2015-12-24 15:00:10.396000000',
|
||||
range: {
|
||||
start_line: 1,
|
||||
start_character: 1,
|
||||
end_line: 1,
|
||||
end_character: 2,
|
||||
}
|
||||
});
|
||||
|
||||
expectedThreadGroups = [
|
||||
{
|
||||
start_datetime: '2015-12-23 15:00:20.396000000',
|
||||
comments: [{
|
||||
id: 'sallys_confession',
|
||||
message: 'i like you, jack',
|
||||
updated: '2015-12-23 15:00:20.396000000',
|
||||
}, {
|
||||
id: 'jacks_reply',
|
||||
message: 'i like you, too',
|
||||
updated: '2015-12-24 15:00:20.396000000',
|
||||
}],
|
||||
locationRange: 'line',
|
||||
},
|
||||
{
|
||||
start_datetime: '2015-12-24 15:00:10.396000000',
|
||||
comments: [{
|
||||
id: 'betsys_confession',
|
||||
message: 'i like you, jack',
|
||||
updated: '2015-12-24 15:00:10.396000000',
|
||||
range: {
|
||||
start_line: 1,
|
||||
start_character: 1,
|
||||
end_line: 1,
|
||||
end_character: 2,
|
||||
},
|
||||
}],
|
||||
locationRange: 'range-1-1-1-2',
|
||||
},
|
||||
];
|
||||
|
||||
assert.deepEqual(element._getThreadGroups(comments),
|
||||
expectedThreadGroups);
|
||||
});
|
||||
|
||||
test('_sortByDate', function() {
|
||||
var threadGroups = expectedThreadGroups = [
|
||||
{
|
||||
start_datetime: '2015-12-23 15:00:20.396000000',
|
||||
comments: [],
|
||||
locationRange: 'line',
|
||||
},
|
||||
{
|
||||
start_datetime: '2015-12-22 15:00:10.396000000',
|
||||
comments: [],
|
||||
locationRange: 'range-1-1-1-2',
|
||||
},
|
||||
];
|
||||
|
||||
var expectedResult = expectedThreadGroups = [
|
||||
{
|
||||
start_datetime: '2015-12-22 15:00:10.396000000',
|
||||
comments: [],
|
||||
locationRange: 'range-1-1-1-2',
|
||||
},{
|
||||
start_datetime: '2015-12-23 15:00:20.396000000',
|
||||
comments: [],
|
||||
locationRange: 'line',
|
||||
},
|
||||
];
|
||||
|
||||
assert.deepEqual(element._sortByDate(threadGroups), expectedResult);
|
||||
});
|
||||
|
||||
test('_calculateLocationRange', function() {
|
||||
var range = {
|
||||
start_line: 1,
|
||||
start_character: 2,
|
||||
end_line: 3,
|
||||
end_character: 4,
|
||||
};
|
||||
assert.equal(element._calculateLocationRange(range), 'range-1-2-3-4');
|
||||
});
|
||||
|
||||
test('thread groups are updated when comments change', function() {
|
||||
var commentsChangedStub = sandbox.stub(element, '_commentsChanged');
|
||||
element.comments = [];
|
||||
element.comments.push({
|
||||
id: 'sallys_confession',
|
||||
message: 'i like you, jack',
|
||||
updated: '2015-12-23 15:00:20.396000000',
|
||||
});
|
||||
assert(commentsChangedStub.called);
|
||||
});
|
||||
|
||||
test('addNewThread', function() {
|
||||
var locationRange = 'range-1-2-3-4';
|
||||
element._threadGroups = [{locationRange: 'line'}];
|
||||
element.addNewThread(locationRange);
|
||||
assert(element._threadGroups.length, 2);
|
||||
});
|
||||
|
||||
test('removeThread', function() {
|
||||
var locationRange = 'range-1-2-3-4';
|
||||
element._threadGroups = [
|
||||
{locationRange: 'range-1-2-3-4', comments: []},
|
||||
{locationRange: 'line', comments: []}
|
||||
];
|
||||
flushAsynchronousOperations();
|
||||
element.removeThread(locationRange);
|
||||
flushAsynchronousOperations();
|
||||
assert(element._threadGroups.length, 1);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@@ -32,6 +32,7 @@
|
||||
type: Array,
|
||||
value: function() { return []; },
|
||||
},
|
||||
locationRange: String,
|
||||
keyEventTarget: {
|
||||
type: Object,
|
||||
value: function() { return document.body; },
|
||||
|
||||
@@ -163,27 +163,10 @@ limitations under the License.
|
||||
getContentsByLineRange: sandbox.stub().returns([]),
|
||||
getLineElByChild: sandbox.stub().returns({}),
|
||||
getSideByLineEl: sandbox.stub().returns('other-side'),
|
||||
renderLineRange: sandbox.stub(),
|
||||
};
|
||||
element._cachedDiffBuilder = builder;
|
||||
});
|
||||
|
||||
test('ignores thread discard for line comment', function(done) {
|
||||
element.fire('thread-discard', {lastComment: {}});
|
||||
flush(function() {
|
||||
assert.isFalse(builder.renderLineRange.called);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('ignores comment discard for line comment', function(done) {
|
||||
element.fire('comment-discard', {comment: {}});
|
||||
flush(function() {
|
||||
assert.isFalse(builder.renderLineRange.called);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('comment-mouse-over from line comments is ignored', function() {
|
||||
sandbox.stub(element, 'set');
|
||||
element.fire('comment-mouse-over', {comment: {}});
|
||||
|
||||
@@ -232,7 +232,8 @@
|
||||
var contentEl = contentText.parentElement;
|
||||
var patchNum = this._getPatchNumByLineAndContent(lineEl, contentEl);
|
||||
var side = this._getSideByLineAndContent(lineEl, contentEl);
|
||||
var threadEl = this._getOrCreateThreadAtLine(contentEl, patchNum, side);
|
||||
var threadEl =
|
||||
this._getOrCreateThreadAtLineRange(contentEl, patchNum, side, range);
|
||||
|
||||
threadEl.addDraft(line, range);
|
||||
},
|
||||
@@ -242,20 +243,43 @@
|
||||
var contentEl = contentText.parentElement;
|
||||
var patchNum = this._getPatchNumByLineAndContent(lineEl, contentEl);
|
||||
var side = this._getSideByLineAndContent(lineEl, contentEl);
|
||||
var threadEl = this._getOrCreateThreadAtLine(contentEl, patchNum, side);
|
||||
var threadEl =
|
||||
this._getOrCreateThreadAtLineRange(contentEl, patchNum, side);
|
||||
|
||||
threadEl.addOrEditDraft(opt_lineNum);
|
||||
},
|
||||
|
||||
_getOrCreateThreadAtLine: function(contentEl, patchNum, side) {
|
||||
var threadEl = contentEl.querySelector('gr-diff-comment-thread');
|
||||
_getThreadForRange: function(threadGroupEl, rangeToCheck) {
|
||||
return threadGroupEl.getThreadForRange(rangeToCheck);
|
||||
},
|
||||
|
||||
if (!threadEl) {
|
||||
threadEl = this.$.diffBuilder.createCommentThread(
|
||||
this.changeNum, patchNum, this.path, side, this.projectConfig);
|
||||
contentEl.appendChild(threadEl);
|
||||
_getThreadGroupForLine: function(contentEl) {
|
||||
return contentEl.querySelector('gr-diff-comment-thread-group');
|
||||
},
|
||||
|
||||
_getOrCreateThreadAtLineRange: function(contentEl, patchNum, side, range) {
|
||||
var rangeToCheck = range ?
|
||||
'range-' +
|
||||
range.startLine + '-' +
|
||||
range.startChar + '-' +
|
||||
range.endLine + '-' +
|
||||
range.endChar : 'line';
|
||||
|
||||
// Check if thread group exists.
|
||||
var threadGroupEl = this._getThreadGroupForLine(contentEl);
|
||||
if (!threadGroupEl) {
|
||||
threadGroupEl = this.$.diffBuilder.createCommentThreadGroup(
|
||||
this.changeNum, patchNum, this.path, side, this.projectConfig);
|
||||
contentEl.appendChild(threadGroupEl);
|
||||
}
|
||||
|
||||
var threadEl = this._getThreadForRange(threadGroupEl, rangeToCheck);
|
||||
|
||||
if (!threadEl) {
|
||||
threadGroupEl.addNewThread(rangeToCheck);
|
||||
Polymer.dom.flush();
|
||||
threadEl = this._getThreadForRange(threadGroupEl, rangeToCheck);
|
||||
}
|
||||
return threadEl;
|
||||
},
|
||||
|
||||
@@ -281,7 +305,7 @@
|
||||
|
||||
_handleThreadDiscard: function(e) {
|
||||
var el = Polymer.dom(e).rootTarget;
|
||||
el.parentNode.removeChild(el);
|
||||
el.parentNode.removeThread(el.locationRange);
|
||||
},
|
||||
|
||||
_handleCommentDiscard: function(e) {
|
||||
|
||||
@@ -34,6 +34,15 @@ limitations under the License.
|
||||
<script>
|
||||
suite('gr-diff tests', function() {
|
||||
var element;
|
||||
var sandbox;
|
||||
|
||||
setup(function() {
|
||||
sandbox = sinon.sandbox.create();
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
suite('not logged in', function() {
|
||||
setup(function() {
|
||||
@@ -57,22 +66,20 @@ limitations under the License.
|
||||
|
||||
test('displayLine class added called when displayLine is true',
|
||||
function() {
|
||||
var spy = sinon.spy(element, '_computeContainerClass');
|
||||
var spy = sandbox.spy(element, '_computeContainerClass');
|
||||
element.displayLine = true;
|
||||
assert.isTrue(spy.called);
|
||||
assert.isTrue(
|
||||
element.$$('.diffContainer').classList.contains('displayLine'));
|
||||
spy.restore();
|
||||
});
|
||||
|
||||
test('get drafts', function(done) {
|
||||
element.patchRange = {basePatchNum: 0, patchNum: 0};
|
||||
|
||||
var getDraftsStub = sinon.stub(element.$.restAPI, 'getDiffDrafts');
|
||||
var getDraftsStub = sandbox.stub(element.$.restAPI, 'getDiffDrafts');
|
||||
element._getDiffDrafts().then(function(result) {
|
||||
assert.deepEqual(result, {baseComments: [], comments: []});
|
||||
sinon.assert.notCalled(getDraftsStub);
|
||||
getDraftsStub.restore();
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -80,18 +87,17 @@ limitations under the License.
|
||||
test('get robot comments', function(done) {
|
||||
element.patchRange = {basePatchNum: 0, patchNum: 0};
|
||||
|
||||
var getDraftsStub = sinon.stub(element.$.restAPI,
|
||||
var getDraftsStub = sandbox.stub(element.$.restAPI,
|
||||
'getDiffRobotComments');
|
||||
element._getDiffDrafts().then(function(result) {
|
||||
assert.deepEqual(result, {baseComments: [], comments: []});
|
||||
sinon.assert.notCalled(getDraftsStub);
|
||||
getDraftsStub.restore();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('loads files weblinks', function(done) {
|
||||
var diffStub = sinon.stub(element.$.restAPI, 'getDiff').returns(
|
||||
var diffStub = sandbox.stub(element.$.restAPI, 'getDiff').returns(
|
||||
Promise.resolve({
|
||||
meta_a: {
|
||||
web_links: 'foo',
|
||||
@@ -108,7 +114,6 @@ limitations under the License.
|
||||
});
|
||||
done();
|
||||
});
|
||||
diffStub.restore();
|
||||
});
|
||||
|
||||
test('remove comment', function() {
|
||||
@@ -211,6 +216,53 @@ limitations under the License.
|
||||
}));
|
||||
});
|
||||
|
||||
test('thread groups', function() {
|
||||
var contentEl = document.createElement('div');
|
||||
var rangeToCheck = 'line';
|
||||
var patchNum = 1;
|
||||
var side = 'PARENT';
|
||||
var range = {
|
||||
startLine: 1,
|
||||
startChar: 1,
|
||||
endLine: 1,
|
||||
endChar: 2,
|
||||
};
|
||||
|
||||
sandbox.stub(element.$.diffBuilder, 'createCommentThreadGroup',
|
||||
function() {
|
||||
return document.createElement('gr-diff-comment-thread-group');
|
||||
});
|
||||
|
||||
// No thread groups.
|
||||
assert.isNotOk(element._getThreadGroupForLine(contentEl));
|
||||
|
||||
// A thread group gets created.
|
||||
assert.isOk(
|
||||
element._getOrCreateThreadAtLineRange(contentEl, patchNum, side));
|
||||
|
||||
// Try to fetch a thread with a different range.
|
||||
range = {
|
||||
startLine: 1,
|
||||
startChar: 1,
|
||||
endLine: 1,
|
||||
endChar: 3,
|
||||
};
|
||||
|
||||
assert.isOk(element._getOrCreateThreadAtLineRange(
|
||||
contentEl, patchNum, side, range));
|
||||
// The new thread group can be fetched.
|
||||
assert.isOk(element._getThreadGroupForLine(contentEl));
|
||||
|
||||
assert.equal(contentEl.querySelectorAll(
|
||||
'gr-diff-comment-thread-group').length, 1);
|
||||
|
||||
var threadGroup = contentEl.querySelector(
|
||||
'gr-diff-comment-thread-group');
|
||||
var threadLength = Polymer.dom(threadGroup.root).
|
||||
querySelectorAll('gr-diff-comment-thread').length;
|
||||
assert.equal(threadLength, 2);
|
||||
});
|
||||
|
||||
test('renders image diffs', function(done) {
|
||||
var mockDiff = {
|
||||
meta_a: {name: 'carrot.jpg', content_type: 'image/jpeg', lines: 66},
|
||||
@@ -261,19 +313,19 @@ limitations under the License.
|
||||
var mockComments = {baseComments: [], comments: []};
|
||||
|
||||
var stubs = [];
|
||||
stubs.push(sinon.stub(element, '_getDiff',
|
||||
stubs.push(sandbox.stub(element, '_getDiff',
|
||||
function() { return Promise.resolve(mockDiff); }));
|
||||
stubs.push(sinon.stub(element.$.restAPI, 'getCommitInfo',
|
||||
stubs.push(sandbox.stub(element.$.restAPI, 'getCommitInfo',
|
||||
function() { return Promise.resolve(mockCommit); }));
|
||||
stubs.push(sinon.stub(element.$.restAPI,
|
||||
stubs.push(sandbox.stub(element.$.restAPI,
|
||||
'getCommitFileContents',
|
||||
function() { return Promise.resolve(mockFile1); }));
|
||||
stubs.push(sinon.stub(element.$.restAPI,
|
||||
stubs.push(sandbox.stub(element.$.restAPI,
|
||||
'getChangeFileContents',
|
||||
function() { return Promise.resolve(mockFile2); }));
|
||||
stubs.push(sinon.stub(element.$.restAPI, '_getDiffComments',
|
||||
stubs.push(sandbox.stub(element.$.restAPI, '_getDiffComments',
|
||||
function() { return Promise.resolve(mockComments); }));
|
||||
stubs.push(sinon.stub(element.$.restAPI, 'getDiffDrafts',
|
||||
stubs.push(sandbox.stub(element.$.restAPI, 'getDiffDrafts',
|
||||
function() { return Promise.resolve(mockComments); }));
|
||||
|
||||
element.patchRange = {basePatchNum: 'PARENT', patchNum: 1};
|
||||
@@ -297,7 +349,6 @@ limitations under the License.
|
||||
|
||||
// Cleanup.
|
||||
element.removeEventListener('render', rendered);
|
||||
stubs.forEach(function(stub) { stub.restore(); });
|
||||
|
||||
done();
|
||||
};
|
||||
@@ -339,17 +390,15 @@ limitations under the License.
|
||||
var content = document.createElement('div');
|
||||
var lineEl = document.createElement('div');
|
||||
|
||||
var selectStub = sinon.stub(element, '_selectLine');
|
||||
var getLineStub = sinon.stub(element.$.diffBuilder, 'getLineElByChild',
|
||||
function() { return lineEl; });
|
||||
var selectStub = sandbox.stub(element, '_selectLine');
|
||||
var getLineStub = sandbox.stub(element.$.diffBuilder,
|
||||
'getLineElByChild', function() { return lineEl; });
|
||||
|
||||
content.className = 'content';
|
||||
content.addEventListener('click', function(e) {
|
||||
element._handleTap(e);
|
||||
assert.isTrue(selectStub.called);
|
||||
assert.equal(selectStub.lastCall.args[0], lineEl);
|
||||
selectStub.restore();
|
||||
getLineStub.restore();
|
||||
done();
|
||||
});
|
||||
content.click();
|
||||
@@ -383,11 +432,10 @@ limitations under the License.
|
||||
baseComments: [{id: 'foo'}],
|
||||
comments: [{id: 'bar'}],
|
||||
};
|
||||
var getDraftsStub = sinon.stub(element.$.restAPI, 'getDiffDrafts',
|
||||
var getDraftsStub = sandbox.stub(element.$.restAPI, 'getDiffDrafts',
|
||||
function() { return Promise.resolve(draftsResponse); });
|
||||
element._getDiffDrafts().then(function(result) {
|
||||
assert.deepEqual(result, draftsResponse);
|
||||
getDraftsStub.restore();
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -403,7 +451,7 @@ limitations under the License.
|
||||
{id: 'c2'},
|
||||
],
|
||||
};
|
||||
var diffCommentsStub = sinon.stub(element, '_getDiffComments',
|
||||
var diffCommentsStub = sandbox.stub(element, '_getDiffComments',
|
||||
function() { return Promise.resolve(comments); });
|
||||
|
||||
var drafts = {
|
||||
@@ -417,7 +465,7 @@ limitations under the License.
|
||||
],
|
||||
};
|
||||
|
||||
var diffDraftsStub = sinon.stub(element, '_getDiffDrafts',
|
||||
var diffDraftsStub = sandbox.stub(element, '_getDiffDrafts',
|
||||
function() { return Promise.resolve(drafts); });
|
||||
|
||||
var robotComments = {
|
||||
@@ -431,8 +479,9 @@ limitations under the License.
|
||||
],
|
||||
};
|
||||
|
||||
var diffRobotCommentStub = sinon.stub(element, '_getDiffRobotComments',
|
||||
function() { return Promise.resolve(robotComments); });
|
||||
var diffRobotCommentStub = sandbox.stub(element,
|
||||
'_getDiffRobotComments', function() {
|
||||
return Promise.resolve(robotComments); });
|
||||
|
||||
element.changeNum = '42';
|
||||
element.patchRange = {
|
||||
@@ -471,9 +520,6 @@ limitations under the License.
|
||||
],
|
||||
});
|
||||
|
||||
diffCommentsStub.restore();
|
||||
diffDraftsStub.restore();
|
||||
diffRobotCommentStub.restore();
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -534,9 +580,8 @@ limitations under the License.
|
||||
element.patchRange = element._comments.meta.patchRange;
|
||||
element.path = element._comments.meta.path;
|
||||
|
||||
var stub = sinon.stub(element, 'reload', function() {
|
||||
var stub = sandbox.stub(element, 'reload', function() {
|
||||
assert.isTrue(stub.called);
|
||||
stub.restore();
|
||||
done();
|
||||
});
|
||||
var spy = sinon.spy(element, '_handleShowDiff');
|
||||
|
||||
@@ -53,6 +53,7 @@ limitations under the License.
|
||||
'core/gr-search-bar/gr-search-bar_test.html',
|
||||
'diff/gr-diff-builder/gr-diff-builder_test.html',
|
||||
'diff/gr-diff-comment-thread/gr-diff-comment-thread_test.html',
|
||||
'diff/gr-diff-comment-thread-group/gr-diff-comment-thread-group_test.html',
|
||||
'diff/gr-diff-comment/gr-diff-comment_test.html',
|
||||
'diff/gr-diff-cursor/gr-diff-cursor_test.html',
|
||||
'diff/gr-diff-highlight/gr-annotation_test.html',
|
||||
|
||||
Reference in New Issue
Block a user