blob: b5ce128836d21f7524b1ce2748065b97a91ac59f [file] [log] [blame]
/**
* @license
* Copyright 2017 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import '../../../test/common-test-setup';
import {ChangeComments} from './gr-comment-api';
import {
isInRevisionOfPatchRange,
isInBaseOfPatchRange,
isDraftThread,
isUnresolved,
createCommentThreads,
DraftInfo,
CommentThread,
} from '../../../utils/comment-util';
import {
createDraft,
createComment,
createChangeComments,
createCommentThread,
createFileInfo,
createRobotComment,
} from '../../../test/test-data-generators';
import {CommentSide, FileInfoStatus} from '../../../constants/constants';
import {
BasePatchSetNum,
CommentInfo,
PARENT,
PatchRange,
PatchSetNum,
PathToCommentsInfoMap,
RevisionPatchSetNum,
RobotCommentInfo,
Timestamp,
UrlEncodedCommentId,
} from '../../../types/common';
import {stubRestApi} from '../../../test/test-utils';
import {assert} from '@open-wc/testing';
suite('ChangeComments tests', () => {
let changeComments: ChangeComments;
suite('_changeComment methods', () => {
setup(() => {
stubRestApi('getDiffComments').resolves({});
stubRestApi('getDiffRobotComments').resolves({});
stubRestApi('getDiffDrafts').resolves({});
});
suite('ported comments', () => {
let portedComments: PathToCommentsInfoMap;
const comment1: CommentInfo = {
...createComment(),
unresolved: true,
id: '1' as UrlEncodedCommentId,
line: 136,
patch_set: 2 as RevisionPatchSetNum,
range: {
start_line: 1,
start_character: 1,
end_line: 1,
end_character: 1,
},
};
const comment2: CommentInfo = {
...createComment(),
patch_set: 2 as RevisionPatchSetNum,
id: '2' as UrlEncodedCommentId,
line: 5,
};
const comment3: CommentInfo = {
...createComment(),
side: CommentSide.PARENT,
line: 10,
unresolved: true,
};
const comment4: CommentInfo = {
...comment3,
parent: -2,
};
const draft1: DraftInfo = {
...createDraft(),
id: 'db977012_e1f13828' as UrlEncodedCommentId,
line: 4,
patch_set: 2 as RevisionPatchSetNum,
};
const draft2: DraftInfo = {
...createDraft(),
id: '503008e2_0ab203ee' as UrlEncodedCommentId,
line: 11,
unresolved: true,
// slightly larger timestamp so it's sorted higher
updated: '2018-02-13 22:49:48.018000001' as Timestamp,
patch_set: 2 as RevisionPatchSetNum,
};
setup(() => {
portedComments = {
'karma.conf.js': [
{
...comment1,
patch_set: 4 as RevisionPatchSetNum,
range: {
start_line: 136,
start_character: 16,
end_line: 136,
end_character: 29,
},
},
],
};
changeComments = new ChangeComments(
{
/* comments */
'karma.conf.js': [
// resolved comment that will not be ported over
comment2,
// original comment that will be ported over to patchset 4
comment1,
],
},
{} /* robot comments */,
{} /* drafts */,
portedComments,
{} /* ported drafts */
);
});
test('threads containing ported comment are returned', () => {
assert.equal(changeComments.getAllThreadsForChange().length, 2);
const portedThreads = changeComments._getPortedCommentThreads(
{path: 'karma.conf.js'},
{patchNum: 4 as RevisionPatchSetNum, basePatchNum: PARENT}
);
assert.equal(portedThreads.length, 1);
// check that the location of the thread matches the ported comment
assert.equal(portedThreads[0].patchNum, 4 as RevisionPatchSetNum);
assert.deepEqual(portedThreads[0].range, {
start_line: 136,
start_character: 16,
end_line: 136,
end_character: 29,
});
// thread ported over if comparing patchset 1 vs patchset 4
assert.equal(
changeComments._getPortedCommentThreads(
{path: 'karma.conf.js'},
{
patchNum: 4 as RevisionPatchSetNum,
basePatchNum: 1 as BasePatchSetNum,
}
).length,
1
);
// verify ported thread is not returned if original thread will be
// shown
// original thread attached to right side
assert.equal(
changeComments._getPortedCommentThreads(
{path: 'karma.conf.js'},
{patchNum: 2 as RevisionPatchSetNum, basePatchNum: PARENT}
).length,
0
);
assert.equal(
changeComments._getPortedCommentThreads(
{path: 'karma.conf.js'},
{
patchNum: 2 as RevisionPatchSetNum,
basePatchNum: 1 as BasePatchSetNum,
}
).length,
0
);
// original thread attached to left side
assert.equal(
changeComments._getPortedCommentThreads(
{path: 'karma.conf.js'},
{
patchNum: 3 as RevisionPatchSetNum,
basePatchNum: 2 as BasePatchSetNum,
}
).length,
0
);
});
test('threads without any ported comment are filtered out', () => {
changeComments = new ChangeComments(
{
/* comments */
// comment that is not ported over
'karma.conf.js': [comment2],
},
{} /* robot comments */,
{
/* drafts */ 'karma.conf.js': [draft2],
},
// comment1 that is ported over but does not have any thread
// that has a comment that matches it
portedComments,
{} /* ported drafts */
);
assert.equal(
createCommentThreads(
changeComments.getAllCommentsForPath('karma.conf.js')
).length,
1
);
assert.equal(
changeComments._getPortedCommentThreads(
{path: 'karma.conf.js'},
{patchNum: 4 as RevisionPatchSetNum, basePatchNum: PARENT}
).length,
0
);
});
test('comments with side=PARENT are ported over', () => {
changeComments = new ChangeComments(
{
/* comments */
// comment left on Base
'karma.conf.js': [comment3],
},
{} /* robot comments */,
{
/* drafts */ 'karma.conf.js': [draft2],
},
{
/* ported comments */
'karma.conf.js': [
{
...comment3,
line: 31,
patch_set: 4 as RevisionPatchSetNum,
},
],
},
{} /* ported drafts */
);
const portedThreads = changeComments._getPortedCommentThreads(
{path: 'karma.conf.js'},
{patchNum: 4 as RevisionPatchSetNum, basePatchNum: PARENT}
);
assert.equal(portedThreads.length, 1);
assert.equal(portedThreads[0].line, 31);
assert.equal(
changeComments._getPortedCommentThreads(
{path: 'karma.conf.js'},
{
patchNum: 4 as RevisionPatchSetNum,
basePatchNum: -2 as BasePatchSetNum,
}
).length,
0
);
assert.equal(
changeComments._getPortedCommentThreads(
{path: 'karma.conf.js'},
{
patchNum: 4 as RevisionPatchSetNum,
basePatchNum: 2 as BasePatchSetNum,
}
).length,
0
);
});
test('comments left on merge parent is not ported over', () => {
changeComments = new ChangeComments(
{
/* comments */
// comment left on Base
'karma.conf.js': [comment4],
},
{} /* robot comments */,
{
/* drafts */ 'karma.conf.js': [draft2],
},
{
/* ported comments */
'karma.conf.js': [
{
...comment4,
line: 31,
patch_set: 4 as RevisionPatchSetNum,
},
],
},
{} /* ported drafts */
);
const portedThreads = changeComments._getPortedCommentThreads(
{path: 'karma.conf.js'},
{patchNum: 4 as RevisionPatchSetNum, basePatchNum: PARENT}
);
assert.equal(portedThreads.length, 0);
assert.equal(
changeComments._getPortedCommentThreads(
{path: 'karma.conf.js'},
{
patchNum: 4 as RevisionPatchSetNum,
basePatchNum: -2 as BasePatchSetNum,
}
).length,
0
);
assert.equal(
changeComments._getPortedCommentThreads(
{path: 'karma.conf.js'},
{
patchNum: 4 as RevisionPatchSetNum,
basePatchNum: 2 as BasePatchSetNum,
}
).length,
0
);
});
test('ported comments contribute to comment count', () => {
const fileInfo = createFileInfo();
assert.equal(
changeComments.computeCommentsString(
{basePatchNum: PARENT, patchNum: 2 as RevisionPatchSetNum},
'karma.conf.js',
fileInfo
),
'2 comments (1 unresolved)'
);
// comment1 is ported over to patchset 4
assert.equal(
changeComments.computeCommentsString(
{basePatchNum: PARENT, patchNum: 4 as RevisionPatchSetNum},
'karma.conf.js',
fileInfo
),
'1 comment (1 unresolved)'
);
});
test('drafts are ported over', () => {
changeComments = new ChangeComments(
{} /* comments */,
{} /* robotComments */,
{
/* drafts */
// draft1: resolved draft that will be ported over to ps 4
// draft2: unresolved draft that will be ported over to ps 4
'karma.conf.js': [draft1, draft2],
},
{} /* ported comments */,
{
/* ported drafts */
'karma.conf.js': [
{
...draft1,
line: 5,
patch_set: 4 as RevisionPatchSetNum,
},
{
...draft2,
line: 31,
patch_set: 4 as RevisionPatchSetNum,
},
],
}
);
const portedThreads = changeComments._getPortedCommentThreads(
{path: 'karma.conf.js'},
{patchNum: 4 as RevisionPatchSetNum, basePatchNum: PARENT}
);
// resolved draft is ported over
assert.equal(portedThreads.length, 2);
assert.equal(portedThreads[0].line, 5);
assert.isTrue(isDraftThread(portedThreads[0]));
assert.isFalse(isUnresolved(portedThreads[0]));
// unresolved draft is ported over
assert.equal(portedThreads[1].line, 31);
assert.isTrue(isDraftThread(portedThreads[1]));
assert.isTrue(isUnresolved(portedThreads[1]));
assert.equal(
createCommentThreads(
changeComments.getAllCommentsForPath('karma.conf.js')
).length,
0
);
});
});
test('_isInBaseOfPatchRange', () => {
const comment: {
patch_set?: PatchSetNum;
side?: CommentSide;
parent?: number;
} = {patch_set: 1 as PatchSetNum};
const patchRange = {
basePatchNum: 1 as BasePatchSetNum,
patchNum: 2 as RevisionPatchSetNum,
};
assert.isTrue(isInBaseOfPatchRange(comment, patchRange));
patchRange.basePatchNum = PARENT;
assert.isFalse(isInBaseOfPatchRange(comment, patchRange));
comment.side = CommentSide.PARENT;
assert.isFalse(isInBaseOfPatchRange(comment, patchRange));
comment.patch_set = 2 as PatchSetNum;
assert.isTrue(isInBaseOfPatchRange(comment, patchRange));
patchRange.basePatchNum = -2 as BasePatchSetNum;
comment.side = CommentSide.PARENT;
comment.parent = 1;
assert.isFalse(isInBaseOfPatchRange(comment, patchRange));
comment.parent = 2;
assert.isTrue(isInBaseOfPatchRange(comment, patchRange));
});
test('isInRevisionOfPatchRange', () => {
const comment: {
patch_set?: PatchSetNum;
side?: CommentSide;
} = {patch_set: 123 as PatchSetNum};
const patchRange: PatchRange = {
basePatchNum: 122 as BasePatchSetNum,
patchNum: 124 as RevisionPatchSetNum,
};
assert.isFalse(isInRevisionOfPatchRange(comment, patchRange));
patchRange.patchNum = 123 as RevisionPatchSetNum;
assert.isTrue(isInRevisionOfPatchRange(comment, patchRange));
comment.side = CommentSide.PARENT;
assert.isFalse(isInRevisionOfPatchRange(comment, patchRange));
});
suite('comment ranges and paths', () => {
const comments = [
{
...createRobotComment(),
id: '01' as UrlEncodedCommentId,
patch_set: 2 as RevisionPatchSetNum,
path: 'file/one',
side: CommentSide.PARENT,
line: 1,
updated: makeTime(1),
range: {
start_line: 1,
start_character: 2,
end_line: 2,
end_character: 2,
},
},
{
...createRobotComment(),
id: '02' as UrlEncodedCommentId,
in_reply_to: '04' as UrlEncodedCommentId,
patch_set: 2 as RevisionPatchSetNum,
path: 'file/one',
unresolved: true,
line: 1,
updated: makeTime(3),
},
{
...createComment(),
id: '03' as UrlEncodedCommentId,
patch_set: 2 as RevisionPatchSetNum,
path: 'file/one',
side: CommentSide.PARENT,
line: 2,
updated: makeTime(1),
},
{
...createComment(),
id: '04' as UrlEncodedCommentId,
patch_set: 2 as RevisionPatchSetNum,
path: 'file/one',
line: 1,
updated: makeTime(1),
},
{
...createComment(),
id: '05' as UrlEncodedCommentId,
patch_set: 2 as RevisionPatchSetNum,
line: 2,
updated: makeTime(1),
},
{
...createComment(),
id: '06' as UrlEncodedCommentId,
patch_set: 3 as RevisionPatchSetNum,
line: 2,
updated: makeTime(1),
},
{
...createComment(),
id: '07' as UrlEncodedCommentId,
patch_set: 2 as RevisionPatchSetNum,
side: CommentSide.PARENT,
unresolved: false,
line: 1,
updated: makeTime(1),
},
{
...createComment(),
id: '08' as UrlEncodedCommentId,
patch_set: 2 as RevisionPatchSetNum,
side: CommentSide.PARENT,
unresolved: true,
in_reply_to: '07' as UrlEncodedCommentId,
line: 1,
updated: makeTime(1),
},
{
...createComment(),
id: '09' as UrlEncodedCommentId,
patch_set: 3 as RevisionPatchSetNum,
line: 1,
updated: makeTime(1),
},
{
...createComment(),
id: '10' as UrlEncodedCommentId,
patch_set: 5 as RevisionPatchSetNum,
side: CommentSide.PARENT,
line: 1,
updated: makeTime(1),
},
{
...createComment(),
id: '11' as UrlEncodedCommentId,
patch_set: 5 as RevisionPatchSetNum,
line: 1,
updated: makeTime(1),
},
{
...createDraft(),
id: '12' as UrlEncodedCommentId,
patch_set: 2 as RevisionPatchSetNum,
side: CommentSide.PARENT,
line: 1,
updated: makeTime(3),
path: 'file/one',
},
{
...createDraft(),
id: '13' as UrlEncodedCommentId,
in_reply_to: '04' as UrlEncodedCommentId,
patch_set: 2 as RevisionPatchSetNum,
line: 1,
// Draft gets lower timestamp than published comment, because we
// want to test that the draft still gets sorted to the end.
updated: makeTime(2),
path: 'file/one',
},
{
...createDraft(),
id: '14' as UrlEncodedCommentId,
patch_set: 3 as RevisionPatchSetNum,
line: 1,
path: 'file/two',
updated: makeTime(3),
},
] as const;
const drafts: {[path: string]: DraftInfo[]} = {
'file/one': [comments[11], comments[12]],
'file/two': [comments[13]],
};
const robotComments: {[path: string]: RobotCommentInfo[]} = {
'file/one': [comments[0], comments[1]],
};
const commentsByFile: PathToCommentsInfoMap = {
'file/one': [comments[2], comments[3]],
'file/two': [comments[4], comments[5]],
'file/three': [comments[6], comments[7], comments[8]],
'file/four': [comments[9], comments[10]],
};
function makeTime(mins: number) {
return `2013-02-26 15:0${mins}:43.986000000` as Timestamp;
}
setup(() => {
changeComments = new ChangeComments(
commentsByFile,
robotComments,
drafts,
{} /* portedComments */,
{} /* portedDrafts */
);
});
test('getPaths', () => {
const patchRange: PatchRange = {
basePatchNum: 1 as BasePatchSetNum,
patchNum: 4 as RevisionPatchSetNum,
};
let paths = changeComments.getPaths(patchRange);
assert.equal(Object.keys(paths).length, 0);
patchRange.basePatchNum = PARENT;
patchRange.patchNum = 3 as RevisionPatchSetNum;
paths = changeComments.getPaths(patchRange);
assert.notProperty(paths, 'file/one');
assert.property(paths, 'file/two');
assert.property(paths, 'file/three');
assert.notProperty(paths, 'file/four');
patchRange.patchNum = 2 as RevisionPatchSetNum;
paths = changeComments.getPaths(patchRange);
assert.property(paths, 'file/one');
assert.property(paths, 'file/two');
assert.property(paths, 'file/three');
assert.notProperty(paths, 'file/four');
paths = changeComments.getPaths();
assert.property(paths, 'file/one');
assert.property(paths, 'file/two');
assert.property(paths, 'file/three');
assert.property(paths, 'file/four');
});
test('getCommentsForPath', () => {
const patchRange: PatchRange = {
basePatchNum: 1 as BasePatchSetNum,
patchNum: 3 as RevisionPatchSetNum,
};
let path = 'file/one';
let comments = changeComments.getCommentsForPath(path, patchRange);
assert.equal(
comments.filter(c => isInBaseOfPatchRange(c, patchRange)).length,
0
);
assert.equal(
comments.filter(c => isInRevisionOfPatchRange(c, patchRange)).length,
0
);
path = 'file/two';
comments = changeComments.getCommentsForPath(path, patchRange);
assert.equal(
comments.filter(c => isInBaseOfPatchRange(c, patchRange)).length,
0
);
assert.equal(
comments.filter(c => isInRevisionOfPatchRange(c, patchRange)).length,
2
);
patchRange.basePatchNum = 2 as BasePatchSetNum;
comments = changeComments.getCommentsForPath(path, patchRange);
assert.equal(
comments.filter(c => isInBaseOfPatchRange(c, patchRange)).length,
1
);
assert.equal(
comments.filter(c => isInRevisionOfPatchRange(c, patchRange)).length,
2
);
patchRange.basePatchNum = PARENT;
path = 'file/three';
comments = changeComments.getCommentsForPath(path, patchRange);
assert.equal(
comments.filter(c => isInBaseOfPatchRange(c, patchRange)).length,
0
);
assert.equal(
comments.filter(c => isInRevisionOfPatchRange(c, patchRange)).length,
1
);
});
test('getAllCommentsForPath', () => {
let path = 'file/one';
let comments = changeComments.getAllCommentsForPath(path);
assert.equal(comments.length, 4);
path = 'file/two';
comments = changeComments.getAllCommentsForPath(path, 2 as PatchSetNum);
assert.equal(comments.length, 1);
const aCopyOfComments = changeComments.getAllCommentsForPath(
path,
2 as PatchSetNum
);
assert.deepEqual(comments, aCopyOfComments);
assert.notEqual(comments[0], aCopyOfComments[0]);
});
test('getAllDraftsForPath', () => {
const path = 'file/one';
const drafts = changeComments.getAllDraftsForPath(path);
assert.equal(drafts.length, 2);
});
test('computeUnresolvedNum', () => {
assert.equal(
changeComments.computeUnresolvedNum({
patchNum: 2 as PatchSetNum,
path: 'file/one',
}),
0
);
assert.equal(
changeComments.computeUnresolvedNum({
patchNum: 1 as PatchSetNum,
path: 'file/one',
}),
0
);
assert.equal(
changeComments.computeUnresolvedNum({
patchNum: 2 as PatchSetNum,
path: 'file/three',
}),
1
);
});
test('computeUnresolvedNum w/ non-linear thread', () => {
const comments: PathToCommentsInfoMap = {
path: [
{
id: '9c6ba3c6_28b7d467' as UrlEncodedCommentId,
patch_set: 1 as RevisionPatchSetNum,
updated: '2018-02-28 14:41:13.000000000' as Timestamp,
unresolved: true,
},
{
id: '3df7b331_0bead405' as UrlEncodedCommentId,
patch_set: 1 as RevisionPatchSetNum,
in_reply_to: '1c346623_ab85d14a' as UrlEncodedCommentId,
updated: '2018-02-28 23:07:55.000000000' as Timestamp,
unresolved: false,
},
{
id: '6153dce6_69958d1e' as UrlEncodedCommentId,
patch_set: 1 as RevisionPatchSetNum,
in_reply_to: '9c6ba3c6_28b7d467' as UrlEncodedCommentId,
updated: '2018-02-28 17:11:31.000000000' as Timestamp,
unresolved: true,
},
{
id: '1c346623_ab85d14a' as UrlEncodedCommentId,
patch_set: 1 as RevisionPatchSetNum,
in_reply_to: '9c6ba3c6_28b7d467' as UrlEncodedCommentId,
updated: '2018-02-28 23:01:39.000000000' as Timestamp,
unresolved: false,
},
],
};
changeComments = new ChangeComments(comments, {}, {}, {});
assert.equal(
changeComments.computeUnresolvedNum(
{patchNum: 1 as PatchSetNum},
true
),
0
);
});
test('computeCommentsString', () => {
const changeComments = createChangeComments();
const parentTo1: PatchRange = {
basePatchNum: PARENT,
patchNum: 1 as RevisionPatchSetNum,
};
const parentTo2: PatchRange = {
basePatchNum: PARENT,
patchNum: 2 as RevisionPatchSetNum,
};
const _1To2: PatchRange = {
basePatchNum: 1 as BasePatchSetNum,
patchNum: 2 as RevisionPatchSetNum,
};
const fileInfo = createFileInfo();
assert.equal(
changeComments.computeCommentsString(
parentTo1,
'/COMMIT_MSG',
fileInfo
),
'2 comments (1 unresolved)'
);
assert.equal(
changeComments.computeCommentsString(
parentTo1,
'/COMMIT_MSG',
{...fileInfo, status: FileInfoStatus.UNMODIFIED},
true
),
'2 comments (1 unresolved)(no changes)'
);
assert.equal(
changeComments.computeCommentsString(_1To2, '/COMMIT_MSG', fileInfo),
'3 comments (1 unresolved)'
);
assert.equal(
changeComments.computeCommentsString(
parentTo1,
'myfile.txt',
fileInfo
),
'1 comment'
);
assert.equal(
changeComments.computeCommentsString(_1To2, 'myfile.txt', fileInfo),
'3 comments'
);
assert.equal(
changeComments.computeCommentsString(
parentTo1,
'file_added_in_rev2.txt',
fileInfo
),
''
);
assert.equal(
changeComments.computeCommentsString(
_1To2,
'file_added_in_rev2.txt',
fileInfo
),
''
);
assert.equal(
changeComments.computeCommentsString(
parentTo2,
'/COMMIT_MSG',
fileInfo
),
'1 comment'
);
assert.equal(
changeComments.computeCommentsString(_1To2, '/COMMIT_MSG', fileInfo),
'3 comments (1 unresolved)'
);
assert.equal(
changeComments.computeCommentsString(
parentTo2,
'myfile.txt',
fileInfo
),
'2 comments'
);
assert.equal(
changeComments.computeCommentsString(_1To2, 'myfile.txt', fileInfo),
'3 comments'
);
assert.equal(
changeComments.computeCommentsString(
parentTo2,
'file_added_in_rev2.txt',
fileInfo
),
''
);
assert.equal(
changeComments.computeCommentsString(
_1To2,
'file_added_in_rev2.txt',
fileInfo
),
''
);
assert.equal(
changeComments.computeCommentsString(
parentTo2,
'unresolved.file',
fileInfo
),
'2 comments (1 unresolved)'
);
assert.equal(
changeComments.computeCommentsString(
_1To2,
'unresolved.file',
fileInfo
),
'2 comments (1 unresolved)'
);
});
test('computeCommentThreadCount', () => {
assert.equal(
changeComments.computeCommentThreadCount({
patchNum: 2 as PatchSetNum,
path: 'file/one',
}),
3
);
assert.equal(
changeComments.computeCommentThreadCount({
patchNum: 1 as PatchSetNum,
path: 'file/one',
}),
0
);
assert.equal(
changeComments.computeCommentThreadCount({
patchNum: 2 as PatchSetNum,
path: 'file/three',
}),
1
);
});
test('computeDraftCount', () => {
assert.equal(
changeComments.computeDraftCount({
patchNum: 2 as PatchSetNum,
path: 'file/one',
}),
2
);
assert.equal(
changeComments.computeDraftCount({
patchNum: 1 as PatchSetNum,
path: 'file/one',
}),
0
);
assert.equal(
changeComments.computeDraftCount({
patchNum: 2 as PatchSetNum,
path: 'file/three',
}),
0
);
assert.equal(changeComments.computeDraftCount(), 3);
});
test('getAllPublishedComments', () => {
let publishedComments = changeComments.getAllPublishedComments();
assert.equal(Object.keys(publishedComments).length, 4);
assert.equal(Object.keys(publishedComments['file/one']).length, 4);
assert.equal(Object.keys(publishedComments['file/two']).length, 2);
publishedComments = changeComments.getAllPublishedComments(
2 as PatchSetNum
);
assert.equal(Object.keys(publishedComments['file/one']).length, 4);
assert.equal(Object.keys(publishedComments['file/two']).length, 1);
});
test('getAllComments', () => {
let comments = changeComments.getAllComments();
assert.equal(Object.keys(comments).length, 4);
assert.equal(Object.keys(comments['file/one']).length, 4);
assert.equal(Object.keys(comments['file/two']).length, 2);
comments = changeComments.getAllComments(false, 2 as PatchSetNum);
assert.equal(Object.keys(comments).length, 4);
assert.equal(Object.keys(comments['file/one']).length, 4);
assert.equal(Object.keys(comments['file/two']).length, 1);
// Include drafts
comments = changeComments.getAllComments(true);
assert.equal(Object.keys(comments).length, 4);
assert.equal(Object.keys(comments['file/one']).length, 6);
assert.equal(Object.keys(comments['file/two']).length, 3);
comments = changeComments.getAllComments(true, 2 as PatchSetNum);
assert.equal(Object.keys(comments).length, 4);
assert.equal(Object.keys(comments['file/one']).length, 6);
assert.equal(Object.keys(comments['file/two']).length, 1);
});
test('computeAllThreads', () => {
const expectedThreads: CommentThread[] = [
{
...createCommentThread([{...comments[0], path: 'file/one'}]),
},
{
...createCommentThread([{...comments[2], path: 'file/one'}]),
},
{
...createCommentThread([
{...comments[3], path: 'file/one'},
{...comments[1], path: 'file/one'},
{...comments[12], path: 'file/one'},
]),
},
{
...createCommentThread([{...comments[4], path: 'file/two'}]),
},
{
...createCommentThread([{...comments[5], path: 'file/two'}]),
},
{
...createCommentThread([
{...comments[6], path: 'file/three'},
{...comments[7], path: 'file/three'},
]),
},
{
...createCommentThread([{...comments[8], path: 'file/three'}]),
},
{
...createCommentThread([{...comments[9], path: 'file/four'}]),
},
{
...createCommentThread([{...comments[10], path: 'file/four'}]),
},
{
...createCommentThread([{...comments[11], path: 'file/one'}]),
},
{
...createCommentThread([{...comments[13], path: 'file/two'}]),
},
];
const threads = changeComments.getAllThreadsForChange();
assert.deepEqual(threads, expectedThreads);
});
});
});
});