Merge "Remove all for...in loops"

This commit is contained in:
Ben Rohlfs
2021-02-12 13:32:31 +00:00
committed by Gerrit Code Review
33 changed files with 124 additions and 286 deletions

View File

@@ -55,6 +55,7 @@ module.exports = {
}], }],
// https://eslint.org/docs/rules/eol-last // https://eslint.org/docs/rules/eol-last
'eol-last': 'off', 'eol-last': 'off',
'guard-for-in': 'error',
// https://eslint.org/docs/rules/indent // https://eslint.org/docs/rules/indent
'indent': ['error', 2, { 'indent': ['error', 2, {
MemberExpression: 2, MemberExpression: 2,

View File

@@ -34,7 +34,6 @@ import {
InheritedBooleanInfo, InheritedBooleanInfo,
} from '../../../types/common'; } from '../../../types/common';
import {InheritedBooleanInfoConfiguredValue} from '../../../constants/constants'; import {InheritedBooleanInfoConfiguredValue} from '../../../constants/constants';
import {hasOwnProperty} from '../../../utils/common-util';
import {GrAutocomplete} from '../../shared/gr-autocomplete/gr-autocomplete'; import {GrAutocomplete} from '../../shared/gr-autocomplete/gr-autocomplete';
import {IronAutogrowTextareaElement} from '@polymer/iron-autogrow-textarea/iron-autogrow-textarea'; import {IronAutogrowTextareaElement} from '@polymer/iron-autogrow-textarea/iron-autogrow-textarea';
import {appContext} from '../../../services/app-context'; import {appContext} from '../../../services/app-context';
@@ -174,19 +173,12 @@ export class GrCreateChangeDialog extends GestureEventListeners(
.then(response => { .then(response => {
if (!response) return []; if (!response) return [];
const branches = []; const branches = [];
let branch; for (const branchInfo of response) {
for (const key in response) { let name: string = branchInfo.ref;
if (!hasOwnProperty(response, key)) { if (name.startsWith('refs/heads/')) {
continue; name = name.substring('refs/heads/'.length);
} }
if (response[key].ref.startsWith('refs/heads/')) { branches.push({name});
branch = response[key].ref.substring('refs/heads/'.length);
} else {
branch = response[key].ref;
}
branches.push({
name: branch,
});
} }
return branches; return branches;
}); });

View File

@@ -28,7 +28,6 @@ import {encodeURL, getBaseUrl} from '../../../utils/url-util';
import {page} from '../../../utils/page-wrapper-utils'; import {page} from '../../../utils/page-wrapper-utils';
import {customElement, observe, property} from '@polymer/decorators'; import {customElement, observe, property} from '@polymer/decorators';
import {ProjectInput, RepoName} from '../../../types/common'; import {ProjectInput, RepoName} from '../../../types/common';
import {hasOwnProperty} from '../../../utils/common-util';
import {AutocompleteQuery} from '../../shared/gr-autocomplete/gr-autocomplete'; import {AutocompleteQuery} from '../../shared/gr-autocomplete/gr-autocomplete';
import {appContext} from '../../../services/app-context'; import {appContext} from '../../../services/app-context';
@@ -115,14 +114,8 @@ export class GrCreateRepoDialog extends GestureEventListeners(
_getRepoSuggestions(input: string) { _getRepoSuggestions(input: string) {
return this.restApiService.getSuggestedProjects(input).then(response => { return this.restApiService.getSuggestedProjects(input).then(response => {
const repos = []; const repos = [];
for (const key in response) { for (const [name, project] of Object.entries(response ?? {})) {
if (!hasOwnProperty(response, key)) { repos.push({name, value: project.id});
continue;
}
repos.push({
name: key,
value: response[key].id,
});
} }
return repos; return repos;
}); });
@@ -131,14 +124,8 @@ export class GrCreateRepoDialog extends GestureEventListeners(
_getGroupSuggestions(input: string) { _getGroupSuggestions(input: string) {
return this.restApiService.getSuggestedGroups(input).then(response => { return this.restApiService.getSuggestedGroups(input).then(response => {
const groups = []; const groups = [];
for (const key in response) { for (const [name, group] of Object.entries(response ?? {})) {
if (!hasOwnProperty(response, key)) { groups.push({name, value: decodeURIComponent(group.id)});
continue;
}
groups.push({
name: key,
value: decodeURIComponent(response[key].id),
});
} }
return groups; return groups;
}); });

View File

@@ -39,9 +39,11 @@ import {
GroupInfo, GroupInfo,
GroupName, GroupName,
} from '../../../types/common'; } from '../../../types/common';
import {AutocompleteQuery} from '../../shared/gr-autocomplete/gr-autocomplete'; import {
AutocompleteQuery,
AutocompleteSuggestion,
} from '../../shared/gr-autocomplete/gr-autocomplete';
import {PolymerDomRepeatEvent} from '../../../types/types'; import {PolymerDomRepeatEvent} from '../../../types/types';
import {hasOwnProperty} from '../../../utils/common-util';
import { import {
fireAlert, fireAlert,
firePageError, firePageError,
@@ -339,23 +341,18 @@ export class GrGroupMembers extends GestureEventListeners(
return this.restApiService return this.restApiService
.getSuggestedAccounts(input, SUGGESTIONS_LIMIT) .getSuggestedAccounts(input, SUGGESTIONS_LIMIT)
.then(accounts => { .then(accounts => {
if (!accounts) return [];
const accountSuggestions = []; const accountSuggestions = [];
let nameAndEmail; for (const account of accounts) {
if (!accounts) { let nameAndEmail;
return []; if (account.email !== undefined) {
} nameAndEmail = `${account.name} <${account.email}>`;
for (const key in accounts) {
if (!hasOwnProperty(accounts, key)) {
continue;
}
if (accounts[key].email !== undefined) {
nameAndEmail = `${accounts[key].name} <${accounts[key].email}>`;
} else { } else {
nameAndEmail = accounts[key].name; nameAndEmail = account.name;
} }
accountSuggestions.push({ accountSuggestions.push({
name: nameAndEmail, name: nameAndEmail,
value: accounts[key]._account_id?.toString(), value: account._account_id?.toString(),
}); });
} }
return accountSuggestions; return accountSuggestions;
@@ -364,15 +361,9 @@ export class GrGroupMembers extends GestureEventListeners(
_getGroupSuggestions(input: string) { _getGroupSuggestions(input: string) {
return this.restApiService.getSuggestedGroups(input).then(response => { return this.restApiService.getSuggestedGroups(input).then(response => {
const groups = []; const groups: AutocompleteSuggestion[] = [];
for (const key in response) { for (const [name, group] of Object.entries(response ?? {})) {
if (!hasOwnProperty(response, key)) { groups.push({name, value: decodeURIComponent(group.id)});
continue;
}
groups.push({
name: key,
value: decodeURIComponent(response[key].id),
});
} }
return groups; return groups;
}); });

View File

@@ -100,7 +100,7 @@ suite('gr-group-members tests', () => {
}, },
]); ]);
} else { } else {
return Promise.resolve({}); return Promise.resolve([]);
} }
}); });
stubRestApi('getSuggestedGroups').callsFake(input => { stubRestApi('getSuggestedGroups').callsFake(input => {

View File

@@ -33,7 +33,6 @@ import {
} from '../../shared/gr-autocomplete/gr-autocomplete'; } from '../../shared/gr-autocomplete/gr-autocomplete';
import {GroupId, GroupInfo, GroupName} from '../../../types/common'; import {GroupId, GroupInfo, GroupName} from '../../../types/common';
import {ErrorCallback} from '../../../services/gr-rest-api/gr-rest-api'; import {ErrorCallback} from '../../../services/gr-rest-api/gr-rest-api';
import {hasOwnProperty} from '../../../utils/common-util';
import { import {
fireEvent, fireEvent,
firePageError, firePageError,
@@ -301,14 +300,8 @@ export class GrGroup extends GestureEventListeners(
_getGroupSuggestions(input: string) { _getGroupSuggestions(input: string) {
return this.restApiService.getSuggestedGroups(input).then(response => { return this.restApiService.getSuggestedGroups(input).then(response => {
const groups: AutocompleteSuggestion[] = []; const groups: AutocompleteSuggestion[] = [];
for (const key in response) { for (const [name, group] of Object.entries(response ?? {})) {
if (!hasOwnProperty(response, key)) { groups.push({name, value: decodeURIComponent(group.id)});
continue;
}
groups.push({
name: key,
value: decodeURIComponent(response[key].id),
});
} }
return groups; return groups;
}); });

View File

@@ -33,7 +33,6 @@ import {
PermissionArray, PermissionArray,
} from '../../../utils/access-util'; } from '../../../utils/access-util';
import {customElement, property, observe} from '@polymer/decorators'; import {customElement, property, observe} from '@polymer/decorators';
import {hasOwnProperty} from '../../../utils/common-util';
import { import {
LabelNameToLabelTypeInfoMap, LabelNameToLabelTypeInfoMap,
LabelTypeInfoValues, LabelTypeInfoValues,
@@ -333,14 +332,8 @@ export class GrPermission extends GestureEventListeners(
.getSuggestedGroups(this._groupFilter || '', MAX_AUTOCOMPLETE_RESULTS) .getSuggestedGroups(this._groupFilter || '', MAX_AUTOCOMPLETE_RESULTS)
.then(response => { .then(response => {
const groups: GroupSuggestion[] = []; const groups: GroupSuggestion[] = [];
for (const key in response) { for (const [name, value] of Object.entries(response ?? {})) {
if (!hasOwnProperty(response, key)) { groups.push({name, value});
continue;
}
groups.push({
name: key,
value: response[key],
});
} }
// Does not return groups in which we already have rules for. // Does not return groups in which we already have rules for.
return groups return groups

View File

@@ -37,7 +37,6 @@ import {
UrlEncodedRepoName, UrlEncodedRepoName,
ProjectAccessGroups, ProjectAccessGroups,
} from '../../../types/common'; } from '../../../types/common';
import {hasOwnProperty} from '../../../utils/common-util';
import {GrButton} from '../../shared/gr-button/gr-button'; import {GrButton} from '../../shared/gr-button/gr-button';
import {GrAccessSection} from '../gr-access-section/gr-access-section'; import {GrAccessSection} from '../gr-access-section/gr-access-section';
import { import {
@@ -370,11 +369,9 @@ export class GrRepoAccess extends GestureEventListeners(
/** /**
* Used to recursively remove any objects with a 'deleted' bit. * Used to recursively remove any objects with a 'deleted' bit.
*/ */
_recursivelyRemoveDeleted(obj: PropertyTreeNode) { _recursivelyRemoveDeleted(obj?: PropertyTreeNode) {
for (const k in obj) { if (!obj) return;
if (!hasOwnProperty(obj, k)) { for (const k of Object.keys(obj)) {
continue;
}
const node = obj[k]; const node = obj[k];
if (typeof node === 'object') { if (typeof node === 'object') {
if (node.deleted) { if (node.deleted) {
@@ -387,17 +384,15 @@ export class GrRepoAccess extends GestureEventListeners(
} }
_recursivelyUpdateAddRemoveObj( _recursivelyUpdateAddRemoveObj(
obj: PropertyTreeNode, obj: PropertyTreeNode | undefined,
addRemoveObj: { addRemoveObj: {
add: PropertyTreeNode; add: PropertyTreeNode;
remove: PropertyTreeNode; remove: PropertyTreeNode;
}, },
path: string[] = [] path: string[] = []
) { ) {
for (const k in obj) { if (!obj) return;
if (!hasOwnProperty(obj, k)) { for (const k of Object.keys(obj)) {
continue;
}
const node = obj[k]; const node = obj[k];
if (typeof node === 'object') { if (typeof node === 'object') {
const updatedId = node.updatedId; const updatedId = node.updatedId;

View File

@@ -392,21 +392,14 @@ export class GrRepo extends GestureEventListeners(
schemesObj?: SchemesInfoMap, schemesObj?: SchemesInfoMap,
_selectedScheme?: string _selectedScheme?: string
) { ) {
if (!schemesObj || !repo || !_selectedScheme) { if (!schemesObj || !repo || !_selectedScheme) return [];
return []; if (!hasOwnProperty(schemesObj, _selectedScheme)) return [];
} const commandObj = schemesObj[_selectedScheme].clone_commands;
const commands = []; const commands = [];
let commandObj: {[title: string]: string} = {}; for (const [title, command] of Object.entries(commandObj)) {
if (hasOwnProperty(schemesObj, _selectedScheme)) {
commandObj = schemesObj[_selectedScheme].clone_commands;
}
for (const title in commandObj) {
if (!hasOwnProperty(commandObj, title)) {
continue;
}
commands.push({ commands.push({
title, title,
command: commandObj[title] command: command
.replace(/\${project}/gi, encodeURI(repo)) .replace(/\${project}/gi, encodeURI(repo))
.replace( .replace(
/\${project-base-name}/gi, /\${project-base-name}/gi,

View File

@@ -37,17 +37,16 @@ import {
} from '../../../types/common'; } from '../../../types/common';
import {ChangeListToggleReviewedDetail} from '../gr-change-list-item/gr-change-list-item'; import {ChangeListToggleReviewedDetail} from '../gr-change-list-item/gr-change-list-item';
import {ChangeStarToggleStarDetail} from '../../shared/gr-change-star/gr-change-star'; import {ChangeStarToggleStarDetail} from '../../shared/gr-change-star/gr-change-star';
import {hasOwnProperty} from '../../../utils/common-util';
import {ChangeListViewState} from '../../../types/types'; import {ChangeListViewState} from '../../../types/types';
import {fireTitleChange} from '../../../utils/event-util'; import {fireTitleChange} from '../../../utils/event-util';
import {appContext} from '../../../services/app-context'; import {appContext} from '../../../services/app-context';
import {GerritView} from '../../../services/router/router-model'; import {GerritView} from '../../../services/router/router-model';
const LookupQueryPatterns = { const LOOKUP_QUERY_PATTERNS: RegExp[] = [
CHANGE_ID: /^\s*i?[0-9a-f]{7,40}\s*$/i, /^\s*i?[0-9a-f]{7,40}\s*$/i, // CHANGE_ID
CHANGE_NUM: /^\s*[1-9][0-9]*\s*$/g, /^\s*[1-9][0-9]*\s*$/g, // CHANGE_NUM
COMMIT: /[0-9a-f]{40}/, /[0-9a-f]{40}/, // COMMIT
}; ];
const USER_QUERY_PATTERN = /^owner:\s?("[^"]+"|[^ ]+)$/; const USER_QUERY_PATTERN = /^owner:\s?("[^"]+"|[^ ]+)$/;
@@ -159,12 +158,8 @@ export class GrChangeListView extends GestureEventListeners(
.then(changes => { .then(changes => {
changes = changes || []; changes = changes || [];
if (this._query && changes.length === 1) { if (this._query && changes.length === 1) {
let query: keyof typeof LookupQueryPatterns; for (const queryPattern of LOOKUP_QUERY_PATTERNS) {
for (query in LookupQueryPatterns) { if (this._query.match(queryPattern)) {
if (
hasOwnProperty(LookupQueryPatterns, query) &&
this._query.match(LookupQueryPatterns[query])
) {
// "Back"/"Forward" buttons work correctly only with // "Back"/"Forward" buttons work correctly only with
// opt_redirect options // opt_redirect options
GerritNav.navigateToChange( GerritNav.navigateToChange(

View File

@@ -940,14 +940,14 @@ export class GrChangeActions
return null; return null;
} }
let result; let result;
for (const label in this.change.labels) { for (const [label, labelInfo] of Object.entries(this.change.labels)) {
if (!(label in this.change.permitted_labels)) { if (!(label in this.change.permitted_labels)) {
continue; continue;
} }
if (this.change.permitted_labels[label].length === 0) { if (this.change.permitted_labels[label].length === 0) {
continue; continue;
} }
const status = this._getLabelStatus(this.change.labels[label]); const status = this._getLabelStatus(labelInfo);
if (status === LabelStatus.NEED) { if (status === LabelStatus.NEED) {
if (result) { if (result) {
// More than one label is missing, so it's unclear which to quick // More than one label is missing, so it's unclear which to quick

View File

@@ -2077,21 +2077,15 @@ export class GrChangeView extends KeyboardShortcutMixin(
} }
_getLatestRevisionSHA(change: ChangeInfo | ParsedChangeInfo) { _getLatestRevisionSHA(change: ChangeInfo | ParsedChangeInfo) {
if (change.current_revision) { if (change.current_revision) return change.current_revision;
return change.current_revision;
}
// current_revision may not be present in the case where the latest rev is // current_revision may not be present in the case where the latest rev is
// a draft and the user doesnt have permission to view that rev. // a draft and the user doesnt have permission to view that rev.
let latestRev = null; let latestRev = null;
let latestPatchNum = -1 as PatchSetNum; let latestPatchNum = -1 as PatchSetNum;
for (const rev in change.revisions) { for (const [rev, revInfo] of Object.entries(change.revisions ?? {})) {
if (!hasOwnProperty(change.revisions, rev)) { if (revInfo._number > latestPatchNum) {
continue;
}
if (change.revisions[rev]._number > latestPatchNum) {
latestRev = rev; latestRev = rev;
latestPatchNum = change.revisions[rev]._number; latestPatchNum = revInfo._number;
} }
} }
return latestRev; return latestRev;

View File

@@ -37,7 +37,6 @@ import {ReportingService} from '../../../services/gr-reporting/gr-reporting';
import {customElement, property, observe} from '@polymer/decorators'; import {customElement, property, observe} from '@polymer/decorators';
import {AutocompleteSuggestion} from '../../shared/gr-autocomplete/gr-autocomplete'; import {AutocompleteSuggestion} from '../../shared/gr-autocomplete/gr-autocomplete';
import {HttpMethod, ChangeStatus} from '../../../constants/constants'; import {HttpMethod, ChangeStatus} from '../../../constants/constants';
import {hasOwnProperty} from '../../../utils/common-util';
import {dom, EventApi} from '@polymer/polymer/lib/legacy/polymer.dom'; import {dom, EventApi} from '@polymer/polymer/lib/legacy/polymer.dom';
const SUGGESTIONS_LIMIT = 15; const SUGGESTIONS_LIMIT = 15;
@@ -399,21 +398,16 @@ export class GrConfirmCherrypickDialog extends GestureEventListeners(
return this.restApiService return this.restApiService
.getRepoBranches(input, this.project, SUGGESTIONS_LIMIT) .getRepoBranches(input, this.project, SUGGESTIONS_LIMIT)
.then((response: BranchInfo[] | undefined) => { .then((response: BranchInfo[] | undefined) => {
const branches = [];
if (!response) return []; if (!response) return [];
let branch; const branches = [];
for (const key in response) { for (const branchInfo of response) {
if (!hasOwnProperty(response, key)) { let branch;
continue; if (branchInfo.ref.startsWith('refs/heads/')) {
} branch = branchInfo.ref.substring('refs/heads/'.length);
if (response[key].ref.startsWith('refs/heads/')) {
branch = response[key].ref.substring('refs/heads/'.length);
} else { } else {
branch = response[key].ref; branch = branchInfo.ref;
} }
branches.push({ branches.push({name: branch});
name: branch,
});
} }
return branches; return branches;
}); });

View File

@@ -39,7 +39,7 @@ suite('gr-confirm-cherrypick-dialog tests', () => {
}, },
]); ]);
} else { } else {
return Promise.resolve({}); return Promise.resolve([]);
} }
}); });
element = basicFixture.instantiate(); element = basicFixture.instantiate();
@@ -77,11 +77,9 @@ suite('gr-confirm-cherrypick-dialog tests', () => {
assert.equal(element.message, myNewMessage); assert.equal(element.message, myNewMessage);
}); });
test('_getProjectBranchesSuggestions empty', done => { test('_getProjectBranchesSuggestions empty', async () => {
element._getProjectBranchesSuggestions('nonexistent').then(branches => { const branches = await element._getProjectBranchesSuggestions('asdf');
assert.equal(branches.length, 0); assert.isEmpty(branches);
done();
});
}); });
suite('cherry pick topic', () => { suite('cherry pick topic', () => {

View File

@@ -22,7 +22,6 @@ import {LegacyElementMixin} from '@polymer/polymer/lib/legacy/legacy-element-mix
import {PolymerElement} from '@polymer/polymer/polymer-element'; import {PolymerElement} from '@polymer/polymer/polymer-element';
import {htmlTemplate} from './gr-confirm-rebase-dialog_html'; import {htmlTemplate} from './gr-confirm-rebase-dialog_html';
import {customElement, property, observe} from '@polymer/decorators'; import {customElement, property, observe} from '@polymer/decorators';
import {hasOwnProperty} from '../../../utils/common-util';
import {NumericChangeId, BranchName} from '../../../types/common'; import {NumericChangeId, BranchName} from '../../../types/common';
import { import {
GrAutocomplete, GrAutocomplete,
@@ -109,13 +108,10 @@ export class GrConfirmRebaseDialog extends GestureEventListeners(
.then(response => { .then(response => {
if (!response) return []; if (!response) return [];
const changes: RebaseChange[] = []; const changes: RebaseChange[] = [];
for (const key in response) { for (const change of response) {
if (!hasOwnProperty(response, key)) {
continue;
}
changes.push({ changes.push({
name: `${response[key]._number}: ${response[key].subject}`, name: `${change._number}: ${change.subject}`,
value: response[key]._number, value: change._number,
}); });
} }
this._recentChanges = changes; this._recentChanges = changes;

View File

@@ -122,14 +122,8 @@ export class GrDownloadDialog extends GestureEventListeners(
} }
} }
const commands = []; const commands = [];
for (const title in commandObj) { for (const [title, command] of Object.entries(commandObj ?? {})) {
if (!commandObj || !hasOwnProperty(commandObj, title)) { commands.push({title, command});
continue;
}
commands.push({
title,
command: commandObj[title],
});
} }
return commands; return commands;
} }

View File

@@ -67,7 +67,6 @@ import {
import {DiffPreferencesInfo} from '../../../types/diff'; import {DiffPreferencesInfo} from '../../../types/diff';
import {GrDiffHost} from '../../diff/gr-diff-host/gr-diff-host'; import {GrDiffHost} from '../../diff/gr-diff-host/gr-diff-host';
import {GrDiffPreferencesDialog} from '../../diff/gr-diff-preferences-dialog/gr-diff-preferences-dialog'; import {GrDiffPreferencesDialog} from '../../diff/gr-diff-preferences-dialog/gr-diff-preferences-dialog';
import {hasOwnProperty} from '../../../utils/common-util';
import {GrDiffCursor} from '../../diff/gr-diff-cursor/gr-diff-cursor'; import {GrDiffCursor} from '../../diff/gr-diff-cursor/gr-diff-cursor';
import {GrCursorManager} from '../../shared/gr-cursor-manager/gr-cursor-manager'; import {GrCursorManager} from '../../shared/gr-cursor-manager/gr-cursor-manager';
import {PolymerSpliceChange} from '@polymer/polymer/interfaces'; import {PolymerSpliceChange} from '@polymer/polymer/interfaces';
@@ -1241,13 +1240,9 @@ export class GrFileList extends KeyboardShortcutMixin(
const files: FileNameToReviewedFileInfoMap = {...filesByPath}; const files: FileNameToReviewedFileInfoMap = {...filesByPath};
addUnmodifiedFiles(files, commentedPaths); addUnmodifiedFiles(files, commentedPaths);
const reviewedSet = new Set(reviewed || []); const reviewedSet = new Set(reviewed || []);
for (const filePath in files) { for (const [filePath, reviewedFileInfo] of Object.entries(files)) {
if (!hasOwnProperty(files, filePath)) { reviewedFileInfo.isReviewed = reviewedSet.has(filePath);
continue;
}
files[filePath].isReviewed = reviewedSet.has(filePath);
} }
this._files = this._normalizeChangeFilesResponse(files); this._files = this._normalizeChangeFilesResponse(files);
} }

View File

@@ -306,11 +306,8 @@ suite('gr-file-list tests', () => {
'-1073741824': '-1 GiB', '-1073741824': '-1 GiB',
'0': '+/-0 B', '0': '+/-0 B',
}; };
for (const [bytes, expected] of Object.entries(table)) {
for (const bytes in table) { assert.equal(element._formatBytes(Number(bytes)), expected);
if (table.hasOwnProperty(bytes)) {
assert.equal(element._formatBytes(Number(bytes)), table[bytes]);
}
} }
}); });
@@ -590,12 +587,8 @@ suite('gr-file-list tests', () => {
flush(); flush();
assert.equal(element.diffs.length, paths.length); assert.equal(element.diffs.length, paths.length);
assert.equal(element._expandedFiles.length, paths.length); assert.equal(element._expandedFiles.length, paths.length);
for (const index in element.diffs) { for (const diff of element.diffs) {
if (!element.diffs.hasOwnProperty(index)) { continue; } assert.isTrue(element._expandedFiles.some(f => f.path === diff.path));
assert.isTrue(
element._expandedFiles
.some(f => f.path === element.diffs[index].path)
);
} }
MockInteractions.keyUpOn(element, 73, 'shift', 'i'); MockInteractions.keyUpOn(element, 73, 'shift', 'i');

View File

@@ -65,11 +65,7 @@ export class GrLabelScores extends GestureEventListeners(
if (this.shadowRoot === null || !this.change) { if (this.shadowRoot === null || !this.change) {
return labels; return labels;
} }
for (const label in this.permittedLabels) { for (const label of Object.keys(this.permittedLabels ?? {})) {
if (!hasOwnProperty(this.permittedLabels, label)) {
continue;
}
const selectorEl = this.shadowRoot.querySelector( const selectorEl = this.shadowRoot.querySelector(
`gr-label-score-row[name="${label}"]` `gr-label-score-row[name="${label}"]`
) as null | GrLabelScoreRow; ) as null | GrLabelScoreRow;
@@ -104,9 +100,10 @@ export class GrLabelScores extends GestureEventListeners(
labelName: string, labelName: string,
numberValue?: number numberValue?: number
) { ) {
for (const k in (labels[labelName] as DetailedLabelInfo).values) { const detailedInfo = labels[labelName] as DetailedLabelInfo;
if (Number(k) === numberValue) { for (const labelValue of Object.keys(detailedInfo.values)) {
return k; if (Number(labelValue) === numberValue) {
return labelValue;
} }
} }
return numberValue; return numberValue;

View File

@@ -85,12 +85,10 @@ suite('gr-label-scores tests', () => {
}); });
test('get and set label scores', () => { test('get and set label scores', () => {
for (const label in element.permittedLabels) { for (const label of Object.keys(element.permittedLabels)) {
if (element.permittedLabels.hasOwnProperty(label)) { const row = element.shadowRoot
const row = element.shadowRoot .querySelector('gr-label-score-row[name="' + label + '"]');
.querySelector('gr-label-score-row[name="' + label + '"]'); row.setSelectedValue(-1);
row.setSelectedValue(-1);
}
} }
assert.deepEqual(element.getLabelValues(), { assert.deepEqual(element.getLabelValues(), {
'Code-Review': -1, 'Code-Review': -1,

View File

@@ -1001,8 +1001,8 @@ suite('gr-reply-dialog tests', () => {
}; };
}; };
const checkObjEmpty = function(obj) { const checkObjEmpty = function(obj) {
for (const prop in obj) { for (const prop of Object.keys(obj)) {
if (obj.hasOwnProperty(prop) && obj[prop].length) { return false; } if (obj[prop].length) { return false; }
} }
return true; return true;
}; };

View File

@@ -231,7 +231,7 @@ export class GrReviewerList extends GestureEventListeners(
} }
let result: AccountInfo[] = []; let result: AccountInfo[] = [];
const reviewers = changeRecord.base; const reviewers = changeRecord.base;
for (const key in reviewers) { for (const key of Object.keys(reviewers)) {
if (this.reviewersOnly && key !== 'REVIEWER') { if (this.reviewersOnly && key !== 'REVIEWER') {
continue; continue;
} }

View File

@@ -32,7 +32,6 @@ import {
FileInfo, FileInfo,
ParentPatchSetNum, ParentPatchSetNum,
} from '../../../types/common'; } from '../../../types/common';
import {hasOwnProperty} from '../../../utils/common-util';
import { import {
Comment, Comment,
CommentMap, CommentMap,
@@ -149,15 +148,11 @@ export class ChangeComments {
]; ];
const commentMap: CommentMap = {}; const commentMap: CommentMap = {};
for (const response of responses) { for (const response of responses) {
for (const path in response) { for (const [path, comments] of Object.entries(response)) {
if ( if (
hasOwnProperty(response, path) && comments.some(c => {
response[path].some(c => {
// If don't care about patch range, we know that the path exists. // If don't care about patch range, we know that the path exists.
if (!patchRange) { return !patchRange || isInPatchRange(c, patchRange);
return true;
}
return isInPatchRange(c, patchRange);
}) })
) { ) {
commentMap[path] = true; commentMap[path] = true;

View File

@@ -85,7 +85,6 @@ import {FilesWebLinks} from '../gr-patch-range-select/gr-patch-range-select';
import {PolymerDeepPropertyChange} from '@polymer/polymer/interfaces'; import {PolymerDeepPropertyChange} from '@polymer/polymer/interfaces';
import {GrDiffCursor} from '../gr-diff-cursor/gr-diff-cursor'; import {GrDiffCursor} from '../gr-diff-cursor/gr-diff-cursor';
import {CommentSide, DiffViewMode, Side} from '../../../constants/constants'; import {CommentSide, DiffViewMode, Side} from '../../../constants/constants';
import {hasOwnProperty} from '../../../utils/common-util';
import {GrApplyFixDialog} from '../gr-apply-fix-dialog/gr-apply-fix-dialog'; import {GrApplyFixDialog} from '../gr-apply-fix-dialog/gr-apply-fix-dialog';
import {LineOfInterest} from '../gr-diff/gr-diff'; import {LineOfInterest} from '../gr-diff/gr-diff';
import {RevisionInfo as RevisionInfoObj} from '../../shared/revision-info/revision-info'; import {RevisionInfo as RevisionInfoObj} from '../../shared/revision-info/revision-info';
@@ -896,9 +895,8 @@ export class GrDiffView extends KeyboardShortcutMixin(
let baseCommit: CommitId | undefined; let baseCommit: CommitId | undefined;
if (!this._change) return; if (!this._change) return;
if (!this._patchRange || !this._patchRange.patchNum) return; if (!this._patchRange || !this._patchRange.patchNum) return;
for (const commitSha in this._change.revisions) { const revisions = this._change.revisions ?? {};
if (!hasOwnProperty(this._change.revisions, commitSha)) continue; for (const [commitSha, revision] of Object.entries(revisions)) {
const revision = this._change.revisions[commitSha];
const patchNum = revision._number; const patchNum = revision._number;
if (patchNum === this._patchRange.patchNum) { if (patchNum === this._patchRange.patchNum) {
commit = commitSha as CommitId; commit = commitSha as CommitId;

View File

@@ -812,10 +812,7 @@ suite('gr-diff-view tests', () => {
} }
test('edit visible only when logged and status NEW', async () => { test('edit visible only when logged and status NEW', async () => {
for (const changeStatus in ChangeStatus) { for (const changeStatus of Object.keys(ChangeStatus)) {
if (!ChangeStatus.hasOwnProperty(changeStatus)) {
continue;
}
assert.isFalse(await isEditVisibile({loggedIn: false, changeStatus}), assert.isFalse(await isEditVisibile({loggedIn: false, changeStatus}),
`loggedIn: false, changeStatus: ${changeStatus}`); `loggedIn: false, changeStatus: ${changeStatus}`);

View File

@@ -172,12 +172,10 @@ suite('gr-styles-api tests', () => {
} }
function assertDisplayPropertyValues(elements, expectedDisplayValues) { function assertDisplayPropertyValues(elements, expectedDisplayValues) {
for (const key in elements) { for (let i = 0; i < elements.length; i++) {
if (elements.hasOwnProperty(key)) { assert.equal(
assert.equal( getComputedStyle(elements[i]).getPropertyValue('display'),
getComputedStyle(elements[key]).getPropertyValue('display'), expectedDisplayValues[i]);
expectedDisplayValues[key]);
}
} }
} }
}); });

View File

@@ -61,10 +61,8 @@ suite('gr-registration-dialog tests', () => {
}); });
teardown(() => { teardown(() => {
for (const eventType in _listeners) { for (const [eventType, listeners] of Object.entries(_listeners)) {
if (_listeners.hasOwnProperty(eventType)) { element.removeEventListener(eventType, listeners);
element.removeEventListener(eventType, _listeners[eventType]);
}
} }
}); });

View File

@@ -121,14 +121,8 @@ export class GrWatchedProjectsEditor extends GestureEventListeners(
_getProjectSuggestions(input: string) { _getProjectSuggestions(input: string) {
return this.restApiService.getSuggestedProjects(input).then(response => { return this.restApiService.getSuggestedProjects(input).then(response => {
const projects: AutocompleteSuggestion[] = []; const projects: AutocompleteSuggestion[] = [];
for (const key in response) { for (const [name, project] of Object.entries(response ?? {})) {
if (!hasOwnProperty(response, key)) { projects.push({name, value: project.id});
continue;
}
projects.push({
name: key,
value: response[key].id,
});
} }
return projects; return projects;
}); });

View File

@@ -350,27 +350,27 @@ export class GrLinkTextParser {
// The outputArray is used to store all of the matches found for all // The outputArray is used to store all of the matches found for all
// patterns. // patterns.
const outputArray: CommentLinkItem[] = []; const outputArray: CommentLinkItem[] = [];
for (const p in config) { for (const [configName, linkInfo] of Object.entries(config)) {
// TODO(TS): it seems, the following line can be rewritten as: // TODO(TS): it seems, the following line can be rewritten as:
// if(enabled === false || enabled === 0 || enabled === '') // if(enabled === false || enabled === 0 || enabled === '')
// Should be double-checked before update // Should be double-checked before update
// eslint-disable-next-line eqeqeq // eslint-disable-next-line eqeqeq
if (config[p].enabled != null && config[p].enabled == false) { if (linkInfo.enabled != null && linkInfo.enabled == false) {
continue; continue;
} }
// PolyGerrit doesn't use hash-based navigation like the GWT UI. // PolyGerrit doesn't use hash-based navigation like the GWT UI.
// Account for this. // Account for this.
const html = config[p].html; const html = linkInfo.html;
const link = config[p].link; const link = linkInfo.link;
if (html) { if (html) {
config[p].html = html.replace(/<a href="#\//g, '<a href="/'); linkInfo.html = html.replace(/<a href="#\//g, '<a href="/');
} else if (link) { } else if (link) {
if (link[0] === '#') { if (link[0] === '#') {
config[p].link = link.substr(1); linkInfo.link = link.substr(1);
} }
} }
const pattern = new RegExp(config[p].match, 'g'); const pattern = new RegExp(linkInfo.match, 'g');
let match; let match;
let textToCheck = text; let textToCheck = text;
@@ -382,10 +382,10 @@ export class GrLinkTextParser {
pattern, pattern,
// Either html or link has a value. Otherwise an exception is thrown // Either html or link has a value. Otherwise an exception is thrown
// in the code below. // in the code below.
(config[p].html || config[p].link)! (linkInfo.html || linkInfo.link)!
); );
if (config[p].html) { if (linkInfo.html) {
let i; let i;
// Skip portion of replacement string that is equal to original to // Skip portion of replacement string that is equal to original to
// allow overlapping patterns. // allow overlapping patterns.
@@ -402,7 +402,7 @@ export class GrLinkTextParser {
match[0].length - i, match[0].length - i,
outputArray outputArray
); );
} else if (config[p].link) { } else if (linkInfo.link) {
this.addLink( this.addLink(
match[0], match[0],
result, result,
@@ -413,7 +413,7 @@ export class GrLinkTextParser {
} else { } else {
throw Error( throw Error(
'linkconfig entry ' + 'linkconfig entry ' +
p + configName +
' doesnt contain a link or html attribute.' ' doesnt contain a link or html attribute.'
); );
} }

View File

@@ -259,27 +259,6 @@ interface GetDiffParams {
type SendChangeRequest = SendRawChangeRequest | SendJSONChangeRequest; type SendChangeRequest = SendRawChangeRequest | SendJSONChangeRequest;
export function _testOnlyResetGrRestApiSharedObjects() { export function _testOnlyResetGrRestApiSharedObjects() {
// TODO(TS): The commented code below didn't do anything.
// It is impossible to reject an existing promise. Should be rewritten in a
// different way
// const fetchPromisesCacheData = fetchPromisesCache.testOnlyGetData();
// for (const key in fetchPromisesCacheData) {
// if (hasOwnProperty(fetchPromisesCacheData, key)) {
// // reject already fulfilled promise does nothing
// fetchPromisesCacheData[key]!.reject();
// }
// }
//
// for (const key in pendingRequest) {
// if (!hasOwnProperty(pendingRequest, key)) {
// continue;
// }
// for (const req of pendingRequest[key]) {
// // reject already fulfilled promise does nothing
// req.reject();
// }
// }
siteBasedCache = new SiteBasedCache(); siteBasedCache = new SiteBasedCache();
fetchPromisesCache = new FetchPromisesCache(); fetchPromisesCache = new FetchPromisesCache();
pendingRequest = {}; pendingRequest = {};

View File

@@ -23,7 +23,6 @@ import {
AuthRequestInit, AuthRequestInit,
AuthService, AuthService,
} from '../../../../services/gr-auth/gr-auth'; } from '../../../../services/gr-auth/gr-auth';
import {hasOwnProperty} from '../../../../utils/common-util';
import { import {
AccountDetailInfo, AccountDetailInfo,
EmailInfo, EmailInfo,
@@ -379,11 +378,7 @@ s */
} }
const params: Array<string | number | boolean> = []; const params: Array<string | number | boolean> = [];
for (const p in fetchParams) { for (const [p, paramValue] of Object.entries(fetchParams)) {
if (!hasOwnProperty(fetchParams, p)) {
continue;
}
const paramValue = fetchParams[p];
// TODO(TS): Replace == null with === and check for null and undefined // TODO(TS): Replace == null with === and check for null and undefined
// eslint-disable-next-line eqeqeq // eslint-disable-next-line eqeqeq
if (paramValue == null) { if (paramValue == null) {
@@ -482,11 +477,8 @@ s */
if (!options.headers) { if (!options.headers) {
options.headers = new Headers(); options.headers = new Headers();
} }
for (const header in req.headers) { for (const [name, value] of Object.entries(req.headers)) {
if (!hasOwnProperty(req.headers, header)) { options.headers.set(name, value);
continue;
}
options.headers.set(header, req.headers[header]);
} }
} }
const url = req.url.startsWith('http') ? req.url : getBaseUrl() + req.url; const url = req.url.startsWith('http') ? req.url : getBaseUrl() + req.url;

View File

@@ -25,7 +25,6 @@ import {
ReviewerUpdateInfo, ReviewerUpdateInfo,
Timestamp, Timestamp,
} from '../../../types/common'; } from '../../../types/common';
import {hasOwnProperty} from '../../../utils/common-util';
import {accountKey} from '../../../utils/account-util'; import {accountKey} from '../../../utils/account-util';
import { import {
FormattedReviewerUpdateInfo, FormattedReviewerUpdateInfo,
@@ -122,12 +121,10 @@ export class GrReviewerUpdatesParser {
*/ */
private _completeBatch(batch: ParserBatch) { private _completeBatch(batch: ParserBatch) {
const items = []; const items = [];
for (const accountId in this._updateItems) { for (const [accountId, item] of Object.entries(this._updateItems ?? {})) {
if (!hasOwnProperty(this._updateItems, accountId)) continue; if (this._lastState[accountId] !== item.state) {
const updateItem = this._updateItems[accountId]; this._lastState[accountId] = item.state;
if (this._lastState[accountId] !== updateItem.state) { items.push(item);
this._lastState[accountId] = updateItem.state;
items.push(updateItem);
} }
} }
if (items.length) { if (items.length) {
@@ -233,15 +230,10 @@ export class GrReviewerUpdatesParser {
const reviewerUpdates = (this.result const reviewerUpdates = (this.result
.reviewer_updates as unknown) as ParserBatchWithNonEmptyUpdates[]; .reviewer_updates as unknown) as ParserBatchWithNonEmptyUpdates[];
for (const update of reviewerUpdates) { for (const update of reviewerUpdates) {
const grouppedReviewers = this._groupUpdatesByMessage(update.updates); const groupedReviewers = this._groupUpdatesByMessage(update.updates);
const newUpdates: {message: string; reviewers: AccountInfo[]}[] = []; const newUpdates: {message: string; reviewers: AccountInfo[]}[] = [];
for (const message in grouppedReviewers) { for (const [message, reviewers] of Object.entries(groupedReviewers)) {
if (hasOwnProperty(grouppedReviewers, message)) { newUpdates.push({message, reviewers});
newUpdates.push({
message,
reviewers: grouppedReviewers[message],
});
}
} }
((update as unknown) as FormattedReviewerUpdateInfo).updates = newUpdates; ((update as unknown) as FormattedReviewerUpdateInfo).updates = newUpdates;
} }

View File

@@ -43,7 +43,6 @@ import {
_testOnly_defaultResinReportHandler, _testOnly_defaultResinReportHandler,
installPolymerResin, installPolymerResin,
} from '../scripts/polymer-resin-install'; } from '../scripts/polymer-resin-install';
import {hasOwnProperty} from '../utils/common-util';
declare global { declare global {
interface Window { interface Window {
@@ -132,12 +131,9 @@ function stubImpl<T extends keyof HTMLElementTagNameMap>(
// This method is inspired by web-component-tester method // This method is inspired by web-component-tester method
const proto = document.createElement(tagName).constructor const proto = document.createElement(tagName).constructor
.prototype as HTMLElementTagNameMap[T]; .prototype as HTMLElementTagNameMap[T];
let key: keyof HTMLElementTagNameMap[T];
const stubs: SinonSpy[] = []; const stubs: SinonSpy[] = [];
for (key in implementation) { for (const [key, value] of Object.entries(implementation)) {
if (hasOwnProperty(implementation, key)) { stubs.push(sinon.stub(proto, key).callsFake(value));
stubs.push(sinon.stub(proto, key).callsFake(implementation[key]));
}
} }
registerTestCleanup(() => { registerTestCleanup(() => {
stubs.forEach(stub => { stubs.forEach(stub => {