Refactoring of <gr-patch-range-select>
Follow-up of the lit conversion, but mainly a preparation for the child
change, which will get rid of the ChangeComments dependency.
Change-Id: Icc81c944dadb2185556c2026d91753930ae13e4c
diff --git a/polygerrit-ui/app/elements/diff/gr-patch-range-select/gr-patch-range-select.ts b/polygerrit-ui/app/elements/diff/gr-patch-range-select/gr-patch-range-select.ts
index 501f688..c819c40 100644
--- a/polygerrit-ui/app/elements/diff/gr-patch-range-select/gr-patch-range-select.ts
+++ b/polygerrit-ui/app/elements/diff/gr-patch-range-select/gr-patch-range-select.ts
@@ -54,6 +54,10 @@
// Maximum length for patch set descriptions.
const PATCH_DESC_MAX_LENGTH = 500;
+function getShaForPatch(patch: PatchSet) {
+ return patch.sha.substring(0, 10);
+}
+
export interface PatchRangeChangeDetail {
patchNum?: PatchSetNum;
basePatchNum?: BasePatchSetNum;
@@ -106,15 +110,16 @@
@property({type: String})
basePatchNum?: BasePatchSetNum;
+ /** Not used directly. Translated into `sortedRevisions` in willUpdate(). */
@property({type: Object})
- revisions?: RevisionInfo[];
+ revisions: (RevisionInfo | EditRevisionInfo)[] = [];
@property({type: Object})
revisionInfo?: RevisionInfoClass;
- @property({type: Array})
+ /** Internal state, derived from `revisions` in willUpdate(). */
@state()
- protected sortedRevisions?: RevisionInfo[];
+ private sortedRevisions: (RevisionInfo | EditRevisionInfo)[] = [];
private readonly reporting: ReportingService = appContext.reportingService;
@@ -152,20 +157,6 @@
];
}
- private renderWeblinks(fileLink?: GeneratedWebLink[]) {
- if (!fileLink) return;
-
- return html`<span class="filesWeblinks">
- ${fileLink.map(
- weblink => html`
- <a target="_blank" rel="noopener" href="${weblink.url}">
- ${weblink.name}
- </a>
- `
- )}</span
- > `;
- }
-
override render() {
return html`
<h3 class="assistive-tech-only">Patchset Range Selection</h3>
@@ -173,14 +164,8 @@
<gr-dropdown-list
id="basePatchDropdown"
.value="${convertToString(this.basePatchNum)}"
- .items="${this._computeBaseDropdownContent(
- this.availablePatches,
- this.patchNum,
- this.sortedRevisions,
- this.changeComments,
- this.revisionInfo
- )}"
- @value-change=${this._handlePatchChange}
+ .items="${this.computeBaseDropdownContent()}"
+ @value-change=${this.handlePatchChange}
>
</gr-dropdown-list>
</span>
@@ -190,13 +175,8 @@
<gr-dropdown-list
id="patchNumDropdown"
.value="${convertToString(this.patchNum)}"
- .items="${this._computePatchDropdownContent(
- this.availablePatches,
- this.basePatchNum,
- this.sortedRevisions,
- this.changeComments
- )}"
- @value-change=${this._handlePatchChange}
+ .items="${this.computePatchDropdownContent()}"
+ @value-change=${this.handlePatchChange}
>
</gr-dropdown-list>
${this.renderWeblinks(this.filesWeblinks?.meta_b)}
@@ -204,63 +184,54 @@
`;
}
- override updated(changedProperties: PropertyValues) {
+ private renderWeblinks(fileLinks?: GeneratedWebLink[]) {
+ if (!fileLinks) return;
+ return html`<span class="filesWeblinks">
+ ${fileLinks.map(
+ weblink => html`
+ <a target="_blank" rel="noopener" href="${weblink.url}">
+ ${weblink.name}
+ </a>
+ `
+ )}</span
+ > `;
+ }
+
+ override willUpdate(changedProperties: PropertyValues) {
if (changedProperties.has('revisions')) {
- this._updateSortedRevisions(this.revisions);
+ this.sortedRevisions = sortRevisions(Object.values(this.revisions || {}));
}
}
- _updateSortedRevisions(revisions?: RevisionInfo[]) {
- if (!revisions) return;
- this.sortedRevisions = sortRevisions(Object.values(revisions));
- }
-
- _getShaForPatch(patch: PatchSet) {
- return patch.sha.substring(0, 10);
- }
-
- _computeBaseDropdownContent(
- availablePatches?: PatchSet[],
- patchNum?: PatchSetNum,
- sortedRevisions?: (RevisionInfo | EditRevisionInfo)[],
- changeComments?: ChangeComments,
- revisionInfo?: RevisionInfoClass
- ): DropdownItem[] {
- // Polymer 2: check for undefined
+ // Private method, but visible for testing.
+ computeBaseDropdownContent(): DropdownItem[] {
if (
- availablePatches === undefined ||
- patchNum === undefined ||
- sortedRevisions === undefined ||
- changeComments === undefined ||
- revisionInfo === undefined
+ this.availablePatches === undefined ||
+ this.patchNum === undefined ||
+ this.changeComments === undefined ||
+ this.revisionInfo === undefined
) {
return [];
}
- const parentCounts = revisionInfo.getParentCountMap();
- const currentParentCount = hasOwnProperty(parentCounts, patchNum)
- ? parentCounts[patchNum as number]
+ const parentCounts = this.revisionInfo.getParentCountMap();
+ const currentParentCount = hasOwnProperty(parentCounts, this.patchNum)
+ ? parentCounts[this.patchNum as number]
: 1;
- const maxParents = revisionInfo.getMaxParents();
+ const maxParents = this.revisionInfo.getMaxParents();
const isMerge = currentParentCount > 1;
const dropdownContent: DropdownItem[] = [];
- for (const basePatch of availablePatches) {
+ for (const basePatch of this.availablePatches) {
const basePatchNum = basePatch.num;
- const entry: DropdownItem = this._createDropdownEntry(
+ const entry: DropdownItem = this.createDropdownEntry(
basePatchNum,
'Patchset ',
- sortedRevisions,
- changeComments,
- this._getShaForPatch(basePatch)
+ getShaForPatch(basePatch)
);
dropdownContent.push({
...entry,
- disabled: this._computeLeftDisabled(
- basePatch.num,
- patchNum,
- sortedRevisions
- ),
+ disabled: this.computeLeftDisabled(basePatch.num, this.patchNum),
});
}
@@ -282,91 +253,61 @@
return dropdownContent;
}
- _computeMobileText(
- patchNum: PatchSetNum,
- changeComments: ChangeComments,
- revisions: (RevisionInfo | EditRevisionInfo)[]
- ) {
+ private computeMobileText(patchNum: PatchSetNum) {
return (
`${patchNum}` +
- `${this._computePatchSetCommentsString(changeComments, patchNum)}` +
- `${this._computePatchSetDescription(revisions, patchNum, true)}`
+ `${this.computePatchSetCommentsString(patchNum)}` +
+ `${this.computePatchSetDescription(patchNum, true)}`
);
}
- _computePatchDropdownContent(
- availablePatches?: PatchSet[],
- basePatchNum?: BasePatchSetNum,
- sortedRevisions?: (RevisionInfo | EditRevisionInfo)[],
- changeComments?: ChangeComments
- ): DropdownItem[] {
- // Polymer 2: check for undefined
+ // Private method, but visible for testing.
+ computePatchDropdownContent(): DropdownItem[] {
if (
- availablePatches === undefined ||
- basePatchNum === undefined ||
- sortedRevisions === undefined ||
- changeComments === undefined
+ this.availablePatches === undefined ||
+ this.basePatchNum === undefined ||
+ this.changeComments === undefined
) {
return [];
}
const dropdownContent: DropdownItem[] = [];
- for (const patch of availablePatches) {
+ for (const patch of this.availablePatches) {
const patchNum = patch.num;
- const entry = this._createDropdownEntry(
+ const entry = this.createDropdownEntry(
patchNum,
patchNum === 'edit' ? '' : 'Patchset ',
- sortedRevisions,
- changeComments,
- this._getShaForPatch(patch)
+ getShaForPatch(patch)
);
dropdownContent.push({
...entry,
- disabled: this._computeRightDisabled(
- basePatchNum,
- patchNum,
- sortedRevisions
- ),
+ disabled: this.computeRightDisabled(this.basePatchNum, patchNum),
});
}
return dropdownContent;
}
- _computeText(
- patchNum: PatchSetNum,
- prefix: string,
- changeComments: ChangeComments,
- sha: string
- ) {
+ private computeText(patchNum: PatchSetNum, prefix: string, sha: string) {
return (
`${prefix}${patchNum}` +
- `${this._computePatchSetCommentsString(changeComments, patchNum)}` +
+ `${this.computePatchSetCommentsString(patchNum)}` +
` | ${sha}`
);
}
- _createDropdownEntry(
+ private createDropdownEntry(
patchNum: PatchSetNum,
prefix: string,
- sortedRevisions: (RevisionInfo | EditRevisionInfo)[],
- changeComments: ChangeComments,
sha: string
) {
const entry: DropdownItem = {
triggerText: `${prefix}${patchNum}`,
- text: this._computeText(patchNum, prefix, changeComments, sha),
- mobileText: this._computeMobileText(
- patchNum,
- changeComments,
- sortedRevisions
- ),
- bottomText: `${this._computePatchSetDescription(
- sortedRevisions,
- patchNum
- )}`,
+ text: this.computeText(patchNum, prefix, sha),
+ mobileText: this.computeMobileText(patchNum),
+ bottomText: `${this.computePatchSetDescription(patchNum)}`,
value: patchNum,
};
- const date = this._computePatchSetDate(sortedRevisions, patchNum);
+ const date = this.computePatchSetDate(patchNum);
if (date) {
entry.date = date;
}
@@ -378,17 +319,18 @@
* is sorted in reverse order (higher patchset nums first), invalid base
* patch nums have an index greater than the index of patchNum.
*
+ * Private method, but visible for testing.
+ *
* @param basePatchNum The possible base patch num.
* @param patchNum The current selected patch num.
*/
- _computeLeftDisabled(
+ computeLeftDisabled(
basePatchNum: PatchSetNum,
- patchNum: PatchSetNum,
- sortedRevisions: (RevisionInfo | EditRevisionInfo)[]
+ patchNum: PatchSetNum
): boolean {
return (
- findSortedIndex(basePatchNum, sortedRevisions) <=
- findSortedIndex(patchNum, sortedRevisions)
+ findSortedIndex(basePatchNum, this.sortedRevisions) <=
+ findSortedIndex(patchNum, this.sortedRevisions)
);
}
@@ -403,13 +345,14 @@
* If the current basePatchNum is a parent index, then only patches that have
* at least that many parents are valid.
*
+ * Private method, but visible for testing.
+ *
* @param basePatchNum The current selected base patch num.
* @param patchNum The possible patch num.
*/
- _computeRightDisabled(
+ computeRightDisabled(
basePatchNum: PatchSetNum,
- patchNum: PatchSetNum,
- sortedRevisions: (RevisionInfo | EditRevisionInfo)[]
+ patchNum: PatchSetNum
): boolean {
if (basePatchNum === ParentPatchSetNum) {
return false;
@@ -427,21 +370,17 @@
}
return (
- findSortedIndex(basePatchNum, sortedRevisions) <=
- findSortedIndex(patchNum, sortedRevisions)
+ findSortedIndex(basePatchNum, this.sortedRevisions) <=
+ findSortedIndex(patchNum, this.sortedRevisions)
);
}
// TODO(dhruvsri): have ported comments contribute to this count
- _computePatchSetCommentsString(
- changeComments: ChangeComments,
- patchNum: PatchSetNum
- ) {
- if (!changeComments) {
- return;
- }
+ // Private method, but visible for testing.
+ computePatchSetCommentsString(patchNum: PatchSetNum): string {
+ if (!this.changeComments) return '';
- const commentThreadCount = changeComments.computeCommentThreadCount(
+ const commentThreadCount = this.changeComments.computeCommentThreadCount(
{
patchNum,
},
@@ -449,7 +388,7 @@
);
const commentThreadString = pluralize(commentThreadCount, 'comment');
- const unresolvedCount = changeComments.computeUnresolvedNum(
+ const unresolvedCount = this.changeComments.computeUnresolvedNum(
{patchNum},
true
);
@@ -468,23 +407,19 @@
);
}
- _computePatchSetDescription(
- revisions: (RevisionInfo | EditRevisionInfo)[],
+ private computePatchSetDescription(
patchNum: PatchSetNum,
addFrontSpace?: boolean
) {
- const rev = getRevisionByPatchNum(revisions, patchNum);
+ const rev = getRevisionByPatchNum(this.sortedRevisions, patchNum);
return rev?.description
? (addFrontSpace ? ' ' : '') +
rev.description.substring(0, PATCH_DESC_MAX_LENGTH)
: '';
}
- _computePatchSetDate(
- revisions: (RevisionInfo | EditRevisionInfo)[],
- patchNum: PatchSetNum
- ): Timestamp | undefined {
- const rev = getRevisionByPatchNum(revisions, patchNum);
+ private computePatchSetDate(patchNum: PatchSetNum): Timestamp | undefined {
+ const rev = getRevisionByPatchNum(this.sortedRevisions, patchNum);
return rev ? rev.created : undefined;
}
@@ -492,7 +427,7 @@
* Catches value-change events from the patchset dropdowns and determines
* whether or not a patch change event should be fired.
*/
- _handlePatchChange(e: DropDownValueChangeEvent) {
+ private handlePatchChange(e: DropDownValueChangeEvent) {
const detail: PatchRangeChangeDetail = {
patchNum: this.patchNum,
basePatchNum: this.basePatchNum,
diff --git a/polygerrit-ui/app/elements/diff/gr-patch-range-select/gr-patch-range-select_test.ts b/polygerrit-ui/app/elements/diff/gr-patch-range-select/gr-patch-range-select_test.ts
index a47b685..342fe3a 100644
--- a/polygerrit-ui/app/elements/diff/gr-patch-range-select/gr-patch-range-select_test.ts
+++ b/polygerrit-ui/app/elements/diff/gr-patch-range-select/gr-patch-range-select_test.ts
@@ -55,7 +55,7 @@
suite('gr-patch-range-select tests', () => {
let element: GrPatchRangeSelect;
- function getInfo(revisions: RevisionInfo[]) {
+ function getInfo(revisions: (RevisionInfo | EditRevisionInfo)[]) {
const revisionObj: Partial<RevIdToRevisionInfo> = {};
for (let i = 0; i < revisions.length; i++) {
revisionObj[i] = revisions[i];
@@ -78,97 +78,54 @@
await element.updateComplete;
});
- test('enabled/disabled options', () => {
- const patchRange = {
- basePatchNum: 'PARENT' as PatchSetNum,
- patchNum: 3 as PatchSetNum,
- };
- const sortedRevisions = [
+ test('enabled/disabled options', async () => {
+ element.revisions = [
createRevision(3) as RevisionInfo,
createEditRevision(2) as EditRevisionInfo,
createRevision(2) as RevisionInfo,
createRevision(1) as RevisionInfo,
];
+ await element.updateComplete;
+
+ const parent = 'PARENT' as PatchSetNum;
+ const edit = EditPatchSetNum;
+
for (const patchNum of [1, 2, 3]) {
assert.isFalse(
- element._computeRightDisabled(
- patchRange.basePatchNum,
- patchNum as PatchSetNum,
- sortedRevisions
- )
+ element.computeRightDisabled(parent, patchNum as PatchSetNum)
);
}
for (const basePatchNum of [1, 2]) {
- assert.isFalse(
- element._computeLeftDisabled(
- basePatchNum as PatchSetNum,
- patchRange.patchNum,
- sortedRevisions
- )
- );
+ const base = basePatchNum as PatchSetNum;
+ assert.isFalse(element.computeLeftDisabled(base, 3 as PatchSetNum));
}
assert.isTrue(
- element._computeLeftDisabled(3 as PatchSetNum, patchRange.patchNum, [])
+ element.computeLeftDisabled(3 as PatchSetNum, 3 as PatchSetNum)
);
- patchRange.basePatchNum = EditPatchSetNum;
assert.isTrue(
- element._computeLeftDisabled(
- 3 as PatchSetNum,
- patchRange.patchNum,
- sortedRevisions
- )
+ element.computeLeftDisabled(3 as PatchSetNum, 3 as PatchSetNum)
);
- assert.isTrue(
- element._computeRightDisabled(
- patchRange.basePatchNum,
- 1 as PatchSetNum,
- sortedRevisions
- )
- );
- assert.isTrue(
- element._computeRightDisabled(
- patchRange.basePatchNum,
- 2 as PatchSetNum,
- sortedRevisions
- )
- );
- assert.isFalse(
- element._computeRightDisabled(
- patchRange.basePatchNum,
- 3 as PatchSetNum,
- sortedRevisions
- )
- );
- assert.isTrue(
- element._computeRightDisabled(
- patchRange.basePatchNum,
- EditPatchSetNum,
- sortedRevisions
- )
- );
+ assert.isTrue(element.computeRightDisabled(edit, 1 as PatchSetNum));
+ assert.isTrue(element.computeRightDisabled(edit, 2 as PatchSetNum));
+ assert.isFalse(element.computeRightDisabled(edit, 3 as PatchSetNum));
+ assert.isTrue(element.computeRightDisabled(edit, edit));
});
- test('_computeBaseDropdownContent', () => {
- const availablePatches = [
+ test('computeBaseDropdownContent', async () => {
+ element.availablePatches = [
{num: 'edit', sha: '1'} as PatchSet,
{num: 3, sha: '2'} as PatchSet,
{num: 2, sha: '3'} as PatchSet,
{num: 1, sha: '4'} as PatchSet,
];
- const revisions: RevisionInfo[] = [
+ element.revisions = [
createRevision(2),
createRevision(3),
createRevision(1),
createRevision(4),
];
- element.revisionInfo = getInfo(revisions);
- const sortedRevisions = [
- createRevision(3) as RevisionInfo,
- createEditRevision(2) as EditRevisionInfo,
- createRevision(2) as RevisionInfo,
- createRevision(1) as RevisionInfo,
- ];
+ element.revisionInfo = getInfo(element.revisions);
const expectedResult: DropdownItem[] = [
{
disabled: true,
@@ -210,19 +167,14 @@
value: 'PARENT',
} as DropdownItem,
];
- assert.deepEqual(
- element._computeBaseDropdownContent(
- availablePatches,
- 1 as PatchSetNum,
- sortedRevisions,
- element.changeComments,
- element.revisionInfo
- ),
- expectedResult
- );
+ element.patchNum = 1 as PatchSetNum;
+ element.basePatchNum = 'PARENT' as BasePatchSetNum;
+ await element.updateComplete;
+
+ assert.deepEqual(element.computeBaseDropdownContent(), expectedResult);
});
- test('_computeBaseDropdownContent called when patchNum updates', async () => {
+ test('computeBaseDropdownContent called when patchNum updates', async () => {
element.revisions = [
createRevision(2),
createRevision(3),
@@ -240,7 +192,7 @@
element.basePatchNum = 'PARENT' as BasePatchSetNum;
await element.updateComplete;
- const baseDropDownStub = sinon.stub(element, '_computeBaseDropdownContent');
+ const baseDropDownStub = sinon.stub(element, 'computeBaseDropdownContent');
// Should be recomputed for each available patch
element.patchNum = 1 as PatchSetNum;
@@ -248,7 +200,7 @@
assert.equal(baseDropDownStub.callCount, 1);
});
- test('_computeBaseDropdownContent called when changeComments update', async () => {
+ test('computeBaseDropdownContent called when changeComments update', async () => {
element.revisions = [
createRevision(2),
createRevision(3),
@@ -266,14 +218,14 @@
await element.updateComplete;
// Should be recomputed for each available patch
- const baseDropDownStub = sinon.stub(element, '_computeBaseDropdownContent');
+ const baseDropDownStub = sinon.stub(element, 'computeBaseDropdownContent');
assert.equal(baseDropDownStub.callCount, 0);
element.changeComments = new ChangeComments();
await element.updateComplete;
assert.equal(baseDropDownStub.callCount, 1);
});
- test('_computePatchDropdownContent called when basePatchNum updates', async () => {
+ test('computePatchDropdownContent called when basePatchNum updates', async () => {
element.revisions = [
createRevision(2),
createRevision(3),
@@ -292,29 +244,27 @@
await element.updateComplete;
// Should be recomputed for each available patch
- const baseDropDownStub = sinon.stub(
- element,
- '_computePatchDropdownContent'
- );
+ const baseDropDownStub = sinon.stub(element, 'computePatchDropdownContent');
element.basePatchNum = 1 as BasePatchSetNum;
await element.updateComplete;
assert.equal(baseDropDownStub.callCount, 1);
});
- test('_computePatchDropdownContent', () => {
- const availablePatches: PatchSet[] = [
+ test('computePatchDropdownContent', async () => {
+ element.availablePatches = [
{num: 'edit', sha: '1'} as PatchSet,
{num: 3, sha: '2'} as PatchSet,
{num: 2, sha: '3'} as PatchSet,
{num: 1, sha: '4'} as PatchSet,
];
- const basePatchNum = 1;
- const sortedRevisions = [
+ element.basePatchNum = 1 as BasePatchSetNum;
+ element.revisions = [
createRevision(3) as RevisionInfo,
createEditRevision(2) as EditRevisionInfo,
createRevision(2, 'description') as RevisionInfo,
createRevision(1) as RevisionInfo,
];
+ await element.updateComplete;
const expectedResult: DropdownItem[] = [
{
@@ -354,15 +304,7 @@
} as DropdownItem,
];
- assert.deepEqual(
- element._computePatchDropdownContent(
- availablePatches,
- basePatchNum as BasePatchSetNum,
- sortedRevisions,
- element.changeComments
- ),
- expectedResult
- );
+ assert.deepEqual(element.computePatchDropdownContent(), expectedResult);
});
test('filesWeblinks', async () => {
@@ -391,7 +333,7 @@
);
});
- test('_computePatchSetCommentsString', () => {
+ test('computePatchSetCommentsString', () => {
// Test string with unresolved comments.
const comments: PathToCommentsInfoMap = {
foo: [
@@ -432,10 +374,7 @@
element.changeComments = new ChangeComments(comments);
assert.equal(
- element._computePatchSetCommentsString(
- element.changeComments,
- 1 as PatchSetNum
- ),
+ element.computePatchSetCommentsString(1 as PatchSetNum),
' (3 comments, 1 unresolved)'
);
@@ -443,23 +382,14 @@
delete comments['foo'];
element.changeComments = new ChangeComments(comments);
assert.equal(
- element._computePatchSetCommentsString(
- element.changeComments,
- 1 as PatchSetNum
- ),
+ element.computePatchSetCommentsString(1 as PatchSetNum),
' (2 comments)'
);
// Test string with no comments.
delete comments['bar'];
element.changeComments = new ChangeComments(comments);
- assert.equal(
- element._computePatchSetCommentsString(
- element.changeComments,
- 1 as PatchSetNum
- ),
- ''
- );
+ assert.equal(element.computePatchSetCommentsString(1 as PatchSetNum), '');
});
test('patch-range-change fires', () => {
diff --git a/polygerrit-ui/app/utils/patch-set-util.ts b/polygerrit-ui/app/utils/patch-set-util.ts
index ee4ed8b..921850a 100644
--- a/polygerrit-ui/app/utils/patch-set-util.ts
+++ b/polygerrit-ui/app/utils/patch-set-util.ts
@@ -103,7 +103,7 @@
return rev;
}
}
- console.warn('no revision found');
+ if (revisions.length > 0) console.warn('no revision found');
return;
}