| /** |
| * @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); |
| }); |
| }); |
| }); |
| }); |