@codingame/monaco-vscode-testing-service-override 22.1.9 → 23.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +17 -16
- package/vscode/src/vs/workbench/contrib/debug/browser/callStackWidget.js +6 -6
- package/vscode/src/vs/workbench/contrib/testing/browser/codeCoverageDecorations.d.ts +13 -0
- package/vscode/src/vs/workbench/contrib/testing/browser/codeCoverageDecorations.js +157 -21
- package/vscode/src/vs/workbench/contrib/testing/browser/codeCoverageDisplayUtils.js +5 -5
- package/vscode/src/vs/workbench/contrib/testing/browser/explorerProjections/index.d.ts +1 -1
- package/vscode/src/vs/workbench/contrib/testing/browser/icons.js +29 -29
- package/vscode/src/vs/workbench/contrib/testing/browser/testCoverageBars.d.ts +1 -1
- package/vscode/src/vs/workbench/contrib/testing/browser/testCoverageBars.js +4 -4
- package/vscode/src/vs/workbench/contrib/testing/browser/testCoverageView.js +14 -14
- package/vscode/src/vs/workbench/contrib/testing/browser/testExplorerActions.d.ts +1 -1
- package/vscode/src/vs/workbench/contrib/testing/browser/testExplorerActions.js +99 -95
- package/vscode/src/vs/workbench/contrib/testing/browser/testResultsView/testResultsOutput.d.ts +4 -4
- package/vscode/src/vs/workbench/contrib/testing/browser/testResultsView/testResultsOutput.js +13 -15
- package/vscode/src/vs/workbench/contrib/testing/browser/testResultsView/testResultsTree.d.ts +6 -1
- package/vscode/src/vs/workbench/contrib/testing/browser/testResultsView/testResultsTree.js +67 -39
- package/vscode/src/vs/workbench/contrib/testing/browser/testResultsView/testResultsViewContent.js +3 -3
- package/vscode/src/vs/workbench/contrib/testing/browser/testing.contribution.js +8 -8
- package/vscode/src/vs/workbench/contrib/testing/browser/testingConfigurationUi.js +2 -2
- package/vscode/src/vs/workbench/contrib/testing/browser/testingDecorations.js +20 -20
- package/vscode/src/vs/workbench/contrib/testing/browser/testingExplorerFilter.js +12 -12
- package/vscode/src/vs/workbench/contrib/testing/browser/testingExplorerView.js +37 -31
- package/vscode/src/vs/workbench/contrib/testing/browser/testingOutputPeek.js +11 -11
- package/vscode/src/vs/workbench/contrib/testing/browser/testingViewPaneContainer.js +1 -1
- package/vscode/src/vs/workbench/contrib/testing/browser/theme.js +32 -32
- package/vscode/src/vs/workbench/contrib/testing/common/configuration.js +36 -36
- package/vscode/src/vs/workbench/contrib/testing/common/observableValue.d.ts +1 -1
- package/vscode/src/vs/workbench/contrib/testing/common/testService.d.ts +2 -2
- package/vscode/src/vs/workbench/contrib/testing/common/testService.js +34 -5
- package/vscode/src/vs/workbench/contrib/testing/common/testServiceImpl.js +4 -4
- package/vscode/src/vs/workbench/contrib/testing/common/testingChatAgentTool.js +26 -16
- package/vscode/src/vs/workbench/contrib/testing/common/testingContentProvider.js +1 -1
- package/vscode/src/vs/workbench/contrib/testing/common/testingContextKeys.js +31 -31
- package/vscode/src/vs/workbench/contrib/testing/common/testingProgressMessages.js +5 -5
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codingame/monaco-vscode-testing-service-override",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "23.0.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "VSCode public API plugged on the monaco editor - testing service-override",
|
|
6
6
|
"keywords": [],
|
|
@@ -15,21 +15,22 @@
|
|
|
15
15
|
},
|
|
16
16
|
"type": "module",
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@codingame/monaco-vscode-
|
|
19
|
-
"@codingame/monaco-vscode-
|
|
20
|
-
"@codingame/monaco-vscode-
|
|
21
|
-
"@codingame/monaco-vscode-
|
|
22
|
-
"@codingame/monaco-vscode-
|
|
23
|
-
"@codingame/monaco-vscode-
|
|
24
|
-
"@codingame/monaco-vscode-
|
|
25
|
-
"@codingame/monaco-vscode-
|
|
26
|
-
"@codingame/monaco-vscode-
|
|
27
|
-
"@codingame/monaco-vscode-
|
|
28
|
-
"@codingame/monaco-vscode-
|
|
29
|
-
"@codingame/monaco-vscode-
|
|
30
|
-
"@codingame/monaco-vscode-
|
|
31
|
-
"@codingame/monaco-vscode-
|
|
32
|
-
"@codingame/monaco-vscode-
|
|
18
|
+
"@codingame/monaco-vscode-10af0e5d-64cb-56de-b584-29ab4a355d15-common": "23.0.0",
|
|
19
|
+
"@codingame/monaco-vscode-262ed59d-4f76-57cd-9e9f-1877f26ae049-common": "23.0.0",
|
|
20
|
+
"@codingame/monaco-vscode-3692fc2f-920d-56ed-accd-d988be683cc3-common": "23.0.0",
|
|
21
|
+
"@codingame/monaco-vscode-3b5a5cd1-d4ff-500a-b609-57e0cd4afa0a-common": "23.0.0",
|
|
22
|
+
"@codingame/monaco-vscode-45e04ac3-b807-5ae5-8818-7b9c40b6d31f-common": "23.0.0",
|
|
23
|
+
"@codingame/monaco-vscode-501b06ab-3f58-516b-8a1a-c29d375d3da4-common": "23.0.0",
|
|
24
|
+
"@codingame/monaco-vscode-5ca67a37-98cf-58a6-90cb-0999f3ec6b71-common": "23.0.0",
|
|
25
|
+
"@codingame/monaco-vscode-6845754f-e617-5ed9-8aaa-6ca3653a9532-common": "23.0.0",
|
|
26
|
+
"@codingame/monaco-vscode-88141f48-1af9-57ef-a278-f4b2ff6128fa-common": "23.0.0",
|
|
27
|
+
"@codingame/monaco-vscode-a8d3bd74-e63e-5327-96e8-4f931661e329-common": "23.0.0",
|
|
28
|
+
"@codingame/monaco-vscode-api": "23.0.0",
|
|
29
|
+
"@codingame/monaco-vscode-b6d52a6d-8c8e-51f5-bcd2-1722295e31d9-common": "23.0.0",
|
|
30
|
+
"@codingame/monaco-vscode-b99aef83-0d60-5e8c-a62e-9908b6256f35-common": "23.0.0",
|
|
31
|
+
"@codingame/monaco-vscode-f24e325c-2ce0-5bba-8236-bfc4f53180ab-common": "23.0.0",
|
|
32
|
+
"@codingame/monaco-vscode-f6ab89b2-83b0-5a43-8772-cb0eafa650b5-common": "23.0.0",
|
|
33
|
+
"@codingame/monaco-vscode-terminal-service-override": "23.0.0"
|
|
33
34
|
},
|
|
34
35
|
"main": "index.js",
|
|
35
36
|
"module": "index.js",
|
|
@@ -28,7 +28,7 @@ import { ILabelService } from '@codingame/monaco-vscode-api/vscode/vs/platform/l
|
|
|
28
28
|
import { WorkbenchList } from '@codingame/monaco-vscode-api/vscode/vs/platform/list/browser/listService';
|
|
29
29
|
import { INotificationService } from '@codingame/monaco-vscode-api/vscode/vs/platform/notification/common/notification.service';
|
|
30
30
|
import { defaultButtonStyles } from '@codingame/monaco-vscode-api/vscode/vs/platform/theme/browser/defaultStyles';
|
|
31
|
-
import { ResourceLabel } from '@codingame/monaco-vscode-
|
|
31
|
+
import { ResourceLabel } from '@codingame/monaco-vscode-3b5a5cd1-d4ff-500a-b609-57e0cd4afa0a-common/vscode/vs/workbench/browser/labels';
|
|
32
32
|
import { SIDE_GROUP } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/editor/common/editorService';
|
|
33
33
|
import { IEditorService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/editor/common/editorService.service';
|
|
34
34
|
import { makeStackFrameColumnDecoration, TOP_STACK_FRAME_DECORATION } from '@codingame/monaco-vscode-b99aef83-0d60-5e8c-a62e-9908b6256f35-common/vscode/vs/workbench/contrib/debug/browser/callStackEditorContribution';
|
|
@@ -180,7 +180,7 @@ let StackAccessibilityProvider = class StackAccessibilityProvider {
|
|
|
180
180
|
if (e instanceof CallStackFrame) {
|
|
181
181
|
if (e.source && e.line) {
|
|
182
182
|
return localize(
|
|
183
|
-
|
|
183
|
+
6405,
|
|
184
184
|
'{0}, line {1} in {2}',
|
|
185
185
|
e.name,
|
|
186
186
|
e.line,
|
|
@@ -192,7 +192,7 @@ let StackAccessibilityProvider = class StackAccessibilityProvider {
|
|
|
192
192
|
assertNever();
|
|
193
193
|
}
|
|
194
194
|
getWidgetAriaLabel() {
|
|
195
|
-
return localize(
|
|
195
|
+
return localize(6406, 'Stack Trace');
|
|
196
196
|
}
|
|
197
197
|
};
|
|
198
198
|
StackAccessibilityProvider = ( __decorate([
|
|
@@ -412,7 +412,7 @@ let MissingCodeRenderer = class MissingCodeRenderer {
|
|
|
412
412
|
const cast = element;
|
|
413
413
|
templateData.label.element.setResource({
|
|
414
414
|
name: cast.name,
|
|
415
|
-
description: ( localize(
|
|
415
|
+
description: ( localize(6407, 'Line {0} column {1}', cast.line, cast.column)),
|
|
416
416
|
range: { startLineNumber: cast.line, startColumn: cast.column, endColumn: cast.column, endLineNumber: cast.line },
|
|
417
417
|
}, {
|
|
418
418
|
icon: Codicon.fileBinary,
|
|
@@ -473,7 +473,7 @@ let SkippedRenderer = class SkippedRenderer {
|
|
|
473
473
|
}
|
|
474
474
|
button.enabled = false;
|
|
475
475
|
this.loadFrames(data.current).catch(e => {
|
|
476
|
-
this.notificationService.error(( localize(
|
|
476
|
+
this.notificationService.error(( localize(6408, 'Failed to load stack frames: {0}', e.message)));
|
|
477
477
|
});
|
|
478
478
|
}));
|
|
479
479
|
return data;
|
|
@@ -550,7 +550,7 @@ registerAction2(class extends Action2 {
|
|
|
550
550
|
constructor() {
|
|
551
551
|
super({
|
|
552
552
|
id: 'callStackWidget.goToFile',
|
|
553
|
-
title: ( localize2(
|
|
553
|
+
title: ( localize2(6409, 'Open File')),
|
|
554
554
|
icon: Codicon.goToFile,
|
|
555
555
|
menu: {
|
|
556
556
|
id: MenuId.DebugCallStackToolbar,
|
|
@@ -8,12 +8,14 @@ import { IConfigurationService } from "@codingame/monaco-vscode-api/vscode/vs/pl
|
|
|
8
8
|
import { IContextKeyService } from "@codingame/monaco-vscode-api/vscode/vs/platform/contextkey/common/contextkey.service";
|
|
9
9
|
import { IInstantiationService } from "@codingame/monaco-vscode-api/vscode/vs/platform/instantiation/common/instantiation";
|
|
10
10
|
import { ILogService } from "@codingame/monaco-vscode-api/vscode/vs/platform/log/common/log.service";
|
|
11
|
+
import { Testing } from "@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/testing/common/constants";
|
|
11
12
|
import { ITestCoverageService } from "@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/testing/common/testCoverageService.service";
|
|
12
13
|
import { CoverageDetails, DetailType, IStatementCoverage } from "@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/testing/common/testTypes";
|
|
13
14
|
export declare class CodeCoverageDecorations extends Disposable implements IEditorContribution {
|
|
14
15
|
private readonly editor;
|
|
15
16
|
private readonly coverage;
|
|
16
17
|
private readonly log;
|
|
18
|
+
static readonly ID = Testing.CoverageDecorationsContributionId;
|
|
17
19
|
private loadingCancellation?;
|
|
18
20
|
private readonly displayedStore;
|
|
19
21
|
private readonly hoveredStore;
|
|
@@ -26,6 +28,17 @@ export declare class CodeCoverageDecorations extends Disposable implements IEdit
|
|
|
26
28
|
private updateEditorStyles;
|
|
27
29
|
private hoverInlineDecoration;
|
|
28
30
|
private hoverLineNumber;
|
|
31
|
+
/**
|
|
32
|
+
* Navigate to the next missed (uncovered) line from the current cursor position.
|
|
33
|
+
* @returns true if navigation occurred, false if no missed line was found
|
|
34
|
+
*/
|
|
35
|
+
goToNextMissedLine(): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Navigate to the previous missed (uncovered) line from the current cursor position.
|
|
38
|
+
* @returns true if navigation occurred, false if no missed line was found
|
|
39
|
+
*/
|
|
40
|
+
goToPreviousMissedLine(): boolean;
|
|
41
|
+
private navigateToMissedLine;
|
|
29
42
|
private apply;
|
|
30
43
|
private clear;
|
|
31
44
|
private loadDetails;
|
|
@@ -39,7 +39,7 @@ import { IQuickInputService } from '@codingame/monaco-vscode-api/vscode/vs/platf
|
|
|
39
39
|
import { ActiveEditorContext } from '@codingame/monaco-vscode-api/vscode/vs/workbench/common/contextkeys';
|
|
40
40
|
import { TEXT_FILE_EDITOR_ID } from '@codingame/monaco-vscode-f24e325c-2ce0-5bba-8236-bfc4f53180ab-common/vscode/vs/workbench/contrib/files/common/files';
|
|
41
41
|
import { TestingConfigKeys, getTestingConfiguration } from '../common/configuration.js';
|
|
42
|
-
import { TestCommandId } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/testing/common/constants';
|
|
42
|
+
import { Testing, TestCommandId } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/testing/common/constants';
|
|
43
43
|
import { FileCoverage } from '@codingame/monaco-vscode-6845754f-e617-5ed9-8aaa-6ca3653a9532-common/vscode/vs/workbench/contrib/testing/common/testCoverage';
|
|
44
44
|
import { ITestCoverageService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/testing/common/testCoverageService.service';
|
|
45
45
|
import { TestId } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/testing/common/testId';
|
|
@@ -56,10 +56,13 @@ import { autorun } from '@codingame/monaco-vscode-api/vscode/vs/base/common/obse
|
|
|
56
56
|
|
|
57
57
|
const CLASS_HIT = 'coverage-deco-hit';
|
|
58
58
|
const CLASS_MISS = 'coverage-deco-miss';
|
|
59
|
-
const TOGGLE_INLINE_COMMAND_TEXT = ( localize(
|
|
59
|
+
const TOGGLE_INLINE_COMMAND_TEXT = ( localize(12187, 'Toggle Inline'));
|
|
60
60
|
const TOGGLE_INLINE_COMMAND_ID = 'testing.toggleInlineCoverage';
|
|
61
61
|
const BRANCH_MISS_INDICATOR_CHARS = 4;
|
|
62
|
+
const GO_TO_NEXT_MISSED_LINE_TITLE = ( localize2(12188, "Go to Next Uncovered Line"));
|
|
63
|
+
const GO_TO_PREVIOUS_MISSED_LINE_TITLE = ( localize2(12189, "Go to Previous Uncovered Line"));
|
|
62
64
|
let CodeCoverageDecorations = class CodeCoverageDecorations extends Disposable {
|
|
65
|
+
static { this.ID = Testing.CoverageDecorationsContributionId; }
|
|
63
66
|
constructor(editor, instantiationService, coverage, configurationService, log, contextKeyService) {
|
|
64
67
|
super();
|
|
65
68
|
this.editor = editor;
|
|
@@ -201,6 +204,59 @@ let CodeCoverageDecorations = class CodeCoverageDecorations extends Disposable {
|
|
|
201
204
|
});
|
|
202
205
|
}));
|
|
203
206
|
}
|
|
207
|
+
goToNextMissedLine() {
|
|
208
|
+
return this.navigateToMissedLine(true);
|
|
209
|
+
}
|
|
210
|
+
goToPreviousMissedLine() {
|
|
211
|
+
return this.navigateToMissedLine(false);
|
|
212
|
+
}
|
|
213
|
+
navigateToMissedLine(next) {
|
|
214
|
+
const model = this.editor.getModel();
|
|
215
|
+
const position = this.editor.getPosition();
|
|
216
|
+
if (!model || !position || !this.details) {
|
|
217
|
+
return false;
|
|
218
|
+
}
|
|
219
|
+
const currentLine = position.lineNumber;
|
|
220
|
+
let closestBefore;
|
|
221
|
+
let closestAfter;
|
|
222
|
+
let firstMissed;
|
|
223
|
+
let lastMissed;
|
|
224
|
+
for (const [, { detail, options }] of this.decorationIds) {
|
|
225
|
+
if (options.lineNumberClassName?.includes(CLASS_MISS)) {
|
|
226
|
+
const range = detail.range;
|
|
227
|
+
if (range.isEmpty()) {
|
|
228
|
+
continue;
|
|
229
|
+
}
|
|
230
|
+
const lineNumber = range.startLineNumber;
|
|
231
|
+
const missedLine = { lineNumber, range };
|
|
232
|
+
if (!firstMissed || lineNumber < firstMissed.lineNumber) {
|
|
233
|
+
firstMissed = missedLine;
|
|
234
|
+
}
|
|
235
|
+
if (!lastMissed || lineNumber > lastMissed.lineNumber) {
|
|
236
|
+
lastMissed = missedLine;
|
|
237
|
+
}
|
|
238
|
+
if (lineNumber < currentLine) {
|
|
239
|
+
if (!closestBefore || lineNumber > closestBefore.lineNumber) {
|
|
240
|
+
closestBefore = missedLine;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
else if (lineNumber > currentLine) {
|
|
244
|
+
if (!closestAfter || lineNumber < closestAfter.lineNumber) {
|
|
245
|
+
closestAfter = missedLine;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
const targetLine = next
|
|
251
|
+
? (closestAfter || firstMissed)
|
|
252
|
+
: (closestBefore || lastMissed);
|
|
253
|
+
if (targetLine) {
|
|
254
|
+
this.editor.setPosition(( new Position(targetLine.lineNumber, 1)));
|
|
255
|
+
this.editor.revealLineInCenter(targetLine.lineNumber);
|
|
256
|
+
return true;
|
|
257
|
+
}
|
|
258
|
+
return false;
|
|
259
|
+
}
|
|
204
260
|
async apply(model, coverage, testId, showInlineByDefault) {
|
|
205
261
|
const details = this.details = await this.loadDetails(coverage, testId, model);
|
|
206
262
|
if (!details) {
|
|
@@ -386,7 +442,7 @@ class CoverageDetailsModel {
|
|
|
386
442
|
if (detail.branches?.length) {
|
|
387
443
|
const covered = detail.branches.filter(b => !!b.count).length;
|
|
388
444
|
return ( new MarkdownString()).appendMarkdown(( localize(
|
|
389
|
-
|
|
445
|
+
12190,
|
|
390
446
|
'{0} of {1} of branches in {2} were covered.',
|
|
391
447
|
covered,
|
|
392
448
|
detail.branches.length,
|
|
@@ -402,13 +458,13 @@ class CoverageDetailsModel {
|
|
|
402
458
|
const { count, label } = detail.detail.branches[detail.branch];
|
|
403
459
|
const label2 = label ? wrapInBackticks(label) : `#${detail.branch + 1}`;
|
|
404
460
|
if (!count) {
|
|
405
|
-
return ( new MarkdownString()).appendMarkdown(( localize(
|
|
461
|
+
return ( new MarkdownString()).appendMarkdown(( localize(12191, 'Branch {0} in {1} was not covered.', label2, text)));
|
|
406
462
|
}
|
|
407
463
|
else if (count === true) {
|
|
408
|
-
return ( new MarkdownString()).appendMarkdown(( localize(
|
|
464
|
+
return ( new MarkdownString()).appendMarkdown(( localize(12192, 'Branch {0} in {1} was executed.', label2, text)));
|
|
409
465
|
}
|
|
410
466
|
else {
|
|
411
|
-
return ( new MarkdownString()).appendMarkdown(( localize(
|
|
467
|
+
return ( new MarkdownString()).appendMarkdown(( localize(12193, 'Branch {0} in {1} was executed {2} time(s).', label2, text, count)));
|
|
412
468
|
}
|
|
413
469
|
}
|
|
414
470
|
assertNever();
|
|
@@ -416,10 +472,10 @@ class CoverageDetailsModel {
|
|
|
416
472
|
}
|
|
417
473
|
function namedDetailLabel(name, detail) {
|
|
418
474
|
return ( new MarkdownString()).appendMarkdown(!detail.count
|
|
419
|
-
? ( localize(
|
|
475
|
+
? ( localize(12194, '`{0}` was not executed.', name))
|
|
420
476
|
: typeof detail.count === 'number'
|
|
421
|
-
? ( localize(
|
|
422
|
-
: ( localize(
|
|
477
|
+
? ( localize(12195, '`{0}` was executed {1} time(s).', name, detail.count))
|
|
478
|
+
: ( localize(12196, '`{0}` was executed.', name)));
|
|
423
479
|
}
|
|
424
480
|
function tidyLocation(location) {
|
|
425
481
|
if (location instanceof Position) {
|
|
@@ -516,13 +572,27 @@ let CoverageToolbarWidget = class CoverageToolbarWidget extends Disposable {
|
|
|
516
572
|
return;
|
|
517
573
|
}
|
|
518
574
|
const toggleAction = ( new ActionWithIcon('toggleInline', this.coverage.showInline.get()
|
|
519
|
-
? ( localize(
|
|
520
|
-
: ( localize(
|
|
575
|
+
? ( localize(12197, 'Hide Inline Coverage'))
|
|
576
|
+
: ( localize(12198, 'Show Inline Coverage')), testingCoverageReport, undefined, () => this.coverage.showInline.set(!this.coverage.showInline.get(), undefined)));
|
|
521
577
|
const kb = this.keybindingService.lookupKeybinding(TOGGLE_INLINE_COMMAND_ID);
|
|
522
578
|
if (kb) {
|
|
523
579
|
toggleAction.tooltip = `${TOGGLE_INLINE_COMMAND_TEXT} (${kb.getLabel()})`;
|
|
524
580
|
}
|
|
525
581
|
this.actionBar.push(toggleAction);
|
|
582
|
+
this.actionBar.push(( new ActionWithIcon(
|
|
583
|
+
'goToPreviousMissed',
|
|
584
|
+
GO_TO_PREVIOUS_MISSED_LINE_TITLE.value,
|
|
585
|
+
Codicon.arrowUp,
|
|
586
|
+
undefined,
|
|
587
|
+
() => this.commandService.executeCommand(TestCommandId.CoverageGoToPreviousMissedLine)
|
|
588
|
+
)));
|
|
589
|
+
this.actionBar.push(( new ActionWithIcon(
|
|
590
|
+
'goToNextMissed',
|
|
591
|
+
GO_TO_NEXT_MISSED_LINE_TITLE.value,
|
|
592
|
+
Codicon.arrowDown,
|
|
593
|
+
undefined,
|
|
594
|
+
() => this.commandService.executeCommand(TestCommandId.CoverageGoToNextMissedLine)
|
|
595
|
+
)));
|
|
526
596
|
if (current.testId) {
|
|
527
597
|
const testItem = current.coverage.fromResult.getTestById(( current.testId.toString()));
|
|
528
598
|
assert(!!testItem, 'got coverage for an unreported test');
|
|
@@ -536,12 +606,12 @@ let CoverageToolbarWidget = class CoverageToolbarWidget extends Disposable {
|
|
|
536
606
|
}
|
|
537
607
|
else if (current.coverage.perTestData?.size) {
|
|
538
608
|
this.actionBar.push(( new ActionWithIcon('perTestFilter', ( localize(
|
|
539
|
-
|
|
609
|
+
12199,
|
|
540
610
|
"{0} test(s) ran code in this file",
|
|
541
611
|
current.coverage.perTestData.size
|
|
542
612
|
)), testingFilterIcon, undefined, () => this.commandService.executeCommand(TestCommandId.CoverageFilterToTestInEditor, this.current, this.editor))));
|
|
543
613
|
}
|
|
544
|
-
this.actionBar.push(( new ActionWithIcon('rerun', ( localize(
|
|
614
|
+
this.actionBar.push(( new ActionWithIcon('rerun', ( localize(12200, 'Rerun')), testingRerunIcon, !this.isRunning, () => this.rerunTest())));
|
|
545
615
|
}
|
|
546
616
|
show() {
|
|
547
617
|
if (this.registered) {
|
|
@@ -601,7 +671,7 @@ registerAction2(class ToggleInlineCoverage extends Action2 {
|
|
|
601
671
|
constructor() {
|
|
602
672
|
super({
|
|
603
673
|
id: TOGGLE_INLINE_COMMAND_ID,
|
|
604
|
-
title: ( localize2(
|
|
674
|
+
title: ( localize2(12201, "Toggle Inline Coverage")),
|
|
605
675
|
category: Categories.Test,
|
|
606
676
|
keybinding: {
|
|
607
677
|
weight: KeybindingWeight.WorkbenchContrib,
|
|
@@ -609,7 +679,7 @@ registerAction2(class ToggleInlineCoverage extends Action2 {
|
|
|
609
679
|
},
|
|
610
680
|
toggled: {
|
|
611
681
|
condition: TestingContextKeys.inlineCoverageEnabled,
|
|
612
|
-
title: ( localize(
|
|
682
|
+
title: ( localize(12202, "Hide Inline Coverage")),
|
|
613
683
|
},
|
|
614
684
|
icon: testingCoverageReport,
|
|
615
685
|
menu: [
|
|
@@ -627,9 +697,9 @@ registerAction2(class ToggleCoverageToolbar extends Action2 {
|
|
|
627
697
|
constructor() {
|
|
628
698
|
super({
|
|
629
699
|
id: TestCommandId.CoverageToggleToolbar,
|
|
630
|
-
title: ( localize2(
|
|
700
|
+
title: ( localize2(12203, "Test Coverage Toolbar")),
|
|
631
701
|
metadata: {
|
|
632
|
-
description: ( localize2(
|
|
702
|
+
description: ( localize2(12204, 'Toggle the sticky coverage bar in the editor.'))
|
|
633
703
|
},
|
|
634
704
|
category: Categories.Test,
|
|
635
705
|
toggled: {
|
|
@@ -652,7 +722,7 @@ registerAction2(class FilterCoverageToTestInEditor extends Action2 {
|
|
|
652
722
|
constructor() {
|
|
653
723
|
super({
|
|
654
724
|
id: TestCommandId.CoverageFilterToTestInEditor,
|
|
655
|
-
title: ( localize2(
|
|
725
|
+
title: ( localize2(12205, "Filter Coverage to Test")),
|
|
656
726
|
category: Categories.Test,
|
|
657
727
|
icon: Codicon.filter,
|
|
658
728
|
toggled: {
|
|
@@ -740,14 +810,14 @@ registerAction2(class ToggleCoverageInExplorer extends Action2 {
|
|
|
740
810
|
constructor() {
|
|
741
811
|
super({
|
|
742
812
|
id: TestCommandId.CoverageToggleInExplorer,
|
|
743
|
-
title: ( localize2(
|
|
813
|
+
title: ( localize2(12206, "Toggle Coverage in Explorer")),
|
|
744
814
|
metadata: {
|
|
745
|
-
description: ( localize2(
|
|
815
|
+
description: ( localize2(12207, 'Toggle the display of test coverage in the File Explorer view.'))
|
|
746
816
|
},
|
|
747
817
|
category: Categories.Test,
|
|
748
818
|
toggled: {
|
|
749
819
|
condition: ( ContextKeyExpr.equals('config.testing.showCoverageInExplorer', true)),
|
|
750
|
-
title: ( localize(
|
|
820
|
+
title: ( localize(12208, "Hide Coverage in Explorer")),
|
|
751
821
|
},
|
|
752
822
|
menu: [
|
|
753
823
|
{ id: MenuId.CommandPalette, when: TestingContextKeys.isTestCoverageOpen },
|
|
@@ -760,6 +830,72 @@ registerAction2(class ToggleCoverageInExplorer extends Action2 {
|
|
|
760
830
|
config.updateValue(TestingConfigKeys.ShowCoverageInExplorer, !value);
|
|
761
831
|
}
|
|
762
832
|
});
|
|
833
|
+
registerAction2(class GoToNextMissedCoverageLine extends Action2 {
|
|
834
|
+
constructor() {
|
|
835
|
+
super({
|
|
836
|
+
id: TestCommandId.CoverageGoToNextMissedLine,
|
|
837
|
+
title: GO_TO_NEXT_MISSED_LINE_TITLE,
|
|
838
|
+
metadata: {
|
|
839
|
+
description: ( localize2(12209, 'Navigate to the next line that is not covered by tests.'))
|
|
840
|
+
},
|
|
841
|
+
category: Categories.Test,
|
|
842
|
+
icon: Codicon.arrowDown,
|
|
843
|
+
f1: true,
|
|
844
|
+
precondition: TestingContextKeys.hasCoverageInFile,
|
|
845
|
+
keybinding: {
|
|
846
|
+
when: ActiveEditorContext,
|
|
847
|
+
weight: KeybindingWeight.EditorContrib,
|
|
848
|
+
primary: KeyMod.Alt | KeyCode.F9,
|
|
849
|
+
},
|
|
850
|
+
menu: [
|
|
851
|
+
{ id: MenuId.CommandPalette, when: TestingContextKeys.isTestCoverageOpen },
|
|
852
|
+
{ id: MenuId.EditorTitle, when: TestingContextKeys.hasCoverageInFile, group: 'coverage@2' },
|
|
853
|
+
]
|
|
854
|
+
});
|
|
855
|
+
}
|
|
856
|
+
run(accessor) {
|
|
857
|
+
const codeEditorService = accessor.get(ICodeEditorService);
|
|
858
|
+
const activeEditor = codeEditorService.getActiveCodeEditor();
|
|
859
|
+
if (!activeEditor) {
|
|
860
|
+
return;
|
|
861
|
+
}
|
|
862
|
+
const contribution = activeEditor.getContribution(CodeCoverageDecorations.ID);
|
|
863
|
+
contribution?.goToNextMissedLine();
|
|
864
|
+
}
|
|
865
|
+
});
|
|
866
|
+
registerAction2(class GoToPreviousMissedCoverageLine extends Action2 {
|
|
867
|
+
constructor() {
|
|
868
|
+
super({
|
|
869
|
+
id: TestCommandId.CoverageGoToPreviousMissedLine,
|
|
870
|
+
title: GO_TO_PREVIOUS_MISSED_LINE_TITLE,
|
|
871
|
+
metadata: {
|
|
872
|
+
description: ( localize2(12210, 'Navigate to the previous line that is not covered by tests.'))
|
|
873
|
+
},
|
|
874
|
+
category: Categories.Test,
|
|
875
|
+
icon: Codicon.arrowUp,
|
|
876
|
+
f1: true,
|
|
877
|
+
precondition: TestingContextKeys.hasCoverageInFile,
|
|
878
|
+
keybinding: {
|
|
879
|
+
when: ActiveEditorContext,
|
|
880
|
+
weight: KeybindingWeight.EditorContrib,
|
|
881
|
+
primary: KeyMod.Alt | KeyMod.Shift | KeyCode.F9,
|
|
882
|
+
},
|
|
883
|
+
menu: [
|
|
884
|
+
{ id: MenuId.CommandPalette, when: TestingContextKeys.isTestCoverageOpen },
|
|
885
|
+
{ id: MenuId.EditorTitle, when: TestingContextKeys.hasCoverageInFile, group: 'coverage@3' },
|
|
886
|
+
]
|
|
887
|
+
});
|
|
888
|
+
}
|
|
889
|
+
run(accessor) {
|
|
890
|
+
const codeEditorService = accessor.get(ICodeEditorService);
|
|
891
|
+
const activeEditor = codeEditorService.getActiveCodeEditor();
|
|
892
|
+
if (!activeEditor) {
|
|
893
|
+
return;
|
|
894
|
+
}
|
|
895
|
+
const contribution = activeEditor.getContribution(CodeCoverageDecorations.ID);
|
|
896
|
+
contribution?.goToPreviousMissedLine();
|
|
897
|
+
}
|
|
898
|
+
});
|
|
763
899
|
class ActionWithIcon extends Action {
|
|
764
900
|
constructor(id, title, icon, enabled, run) {
|
|
765
901
|
super(id, title, undefined, enabled, run);
|
|
@@ -75,11 +75,11 @@ function getLabelForItem(result, testId, commonPrefixLen) {
|
|
|
75
75
|
}
|
|
76
76
|
var labels;
|
|
77
77
|
(function (labels) {
|
|
78
|
-
labels.showingFilterFor = (label) => ( localize(
|
|
79
|
-
labels.clickToChangeFiltering = ( localize(
|
|
80
|
-
labels.percentCoverage = (percent, precision) => ( localize(
|
|
81
|
-
labels.allTests = ( localize(
|
|
82
|
-
labels.pickShowCoverage = ( localize(
|
|
78
|
+
labels.showingFilterFor = (label) => ( localize(12211, "Showing \"{0}\"", label));
|
|
79
|
+
labels.clickToChangeFiltering = ( localize(12212, 'Click to view coverage for a single test'));
|
|
80
|
+
labels.percentCoverage = (percent, precision) => ( localize(12213, '{0} Coverage', displayPercent(percent, precision)));
|
|
81
|
+
labels.allTests = ( localize(12214, 'All tests'));
|
|
82
|
+
labels.pickShowCoverage = ( localize(12215, 'Pick a test to show coverage for'));
|
|
83
83
|
})(labels || (labels = {}));
|
|
84
84
|
|
|
85
85
|
export { calculateDisplayedStat, displayPercent, getCoverageColor, getLabelForItem, labels, percent };
|
|
@@ -18,7 +18,7 @@ export interface ITestTreeProjection extends IDisposable {
|
|
|
18
18
|
/**
|
|
19
19
|
* Event that fires when the projection changes.
|
|
20
20
|
*/
|
|
21
|
-
onUpdate: Event<void>;
|
|
21
|
+
readonly onUpdate: Event<void>;
|
|
22
22
|
/**
|
|
23
23
|
* State to use for applying default collapse state of items.
|
|
24
24
|
*/
|
|
@@ -7,37 +7,37 @@ import { ThemeIcon } from '@codingame/monaco-vscode-api/vscode/vs/base/common/th
|
|
|
7
7
|
import { testStatesToIconColors, testStatesToRetiredIconColors, testingColorRunAction } from './theme.js';
|
|
8
8
|
import { TestResultState } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/testing/common/testTypes';
|
|
9
9
|
|
|
10
|
-
const testingViewIcon = registerIcon('test-view-icon', Codicon.beaker, ( localize(
|
|
11
|
-
const testingResultsIcon = registerIcon('test-results-icon', Codicon.checklist, ( localize(
|
|
12
|
-
const testingRunIcon = registerIcon('testing-run-icon', Codicon.run, ( localize(
|
|
13
|
-
const testingRerunIcon = registerIcon('testing-rerun-icon', Codicon.debugRerun, ( localize(
|
|
14
|
-
const testingRunAllIcon = registerIcon('testing-run-all-icon', Codicon.runAll, ( localize(
|
|
15
|
-
const testingDebugAllIcon = registerIcon('testing-debug-all-icon', Codicon.debugAltSmall, ( localize(
|
|
16
|
-
const testingDebugIcon = registerIcon('testing-debug-icon', Codicon.debugAltSmall, ( localize(
|
|
17
|
-
const testingCoverageIcon = registerIcon('testing-coverage-icon', Codicon.runCoverage, ( localize(
|
|
18
|
-
const testingCoverageAllIcon = registerIcon('testing-coverage-all-icon', Codicon.runAllCoverage, ( localize(
|
|
19
|
-
const testingCancelIcon = registerIcon('testing-cancel-icon', Codicon.debugStop, ( localize(
|
|
20
|
-
const testingFilterIcon = registerIcon('testing-filter', Codicon.filter, ( localize(
|
|
21
|
-
const testingHiddenIcon = registerIcon('testing-hidden', Codicon.eyeClosed, ( localize(
|
|
22
|
-
registerIcon('testing-show-as-list-icon', Codicon.listTree, ( localize(
|
|
23
|
-
registerIcon('testing-show-as-list-icon', Codicon.listFlat, ( localize(
|
|
24
|
-
const testingUpdateProfiles = registerIcon('testing-update-profiles', Codicon.gear, ( localize(
|
|
25
|
-
const testingRefreshTests = registerIcon('testing-refresh-tests', Codicon.refresh, ( localize(
|
|
26
|
-
const testingTurnContinuousRunOn = registerIcon('testing-turn-continuous-run-on', Codicon.eye, ( localize(
|
|
27
|
-
const testingTurnContinuousRunOff = registerIcon('testing-turn-continuous-run-off', Codicon.eyeClosed, ( localize(
|
|
28
|
-
const testingContinuousIsOn = registerIcon('testing-continuous-is-on', Codicon.eye, ( localize(
|
|
29
|
-
const testingCancelRefreshTests = registerIcon('testing-cancel-refresh-tests', Codicon.stop, ( localize(
|
|
30
|
-
const testingCoverageReport = registerIcon('testing-coverage', Codicon.coverage, ( localize(
|
|
31
|
-
const testingWasCovered = registerIcon('testing-was-covered', Codicon.check, ( localize(
|
|
32
|
-
const testingCoverageMissingBranch = registerIcon('testing-missing-branch', Codicon.question, ( localize(
|
|
10
|
+
const testingViewIcon = registerIcon('test-view-icon', Codicon.beaker, ( localize(12216, 'View icon of the test view.')));
|
|
11
|
+
const testingResultsIcon = registerIcon('test-results-icon', Codicon.checklist, ( localize(12217, 'Icons for test results.')));
|
|
12
|
+
const testingRunIcon = registerIcon('testing-run-icon', Codicon.run, ( localize(12218, 'Icon of the "run test" action.')));
|
|
13
|
+
const testingRerunIcon = registerIcon('testing-rerun-icon', Codicon.debugRerun, ( localize(12219, 'Icon of the "rerun tests" action.')));
|
|
14
|
+
const testingRunAllIcon = registerIcon('testing-run-all-icon', Codicon.runAll, ( localize(12220, 'Icon of the "run all tests" action.')));
|
|
15
|
+
const testingDebugAllIcon = registerIcon('testing-debug-all-icon', Codicon.debugAltSmall, ( localize(12221, 'Icon of the "debug all tests" action.')));
|
|
16
|
+
const testingDebugIcon = registerIcon('testing-debug-icon', Codicon.debugAltSmall, ( localize(12222, 'Icon of the "debug test" action.')));
|
|
17
|
+
const testingCoverageIcon = registerIcon('testing-coverage-icon', Codicon.runCoverage, ( localize(12223, 'Icon of the "run test with coverage" action.')));
|
|
18
|
+
const testingCoverageAllIcon = registerIcon('testing-coverage-all-icon', Codicon.runAllCoverage, ( localize(12224, 'Icon of the "run all tests with coverage" action.')));
|
|
19
|
+
const testingCancelIcon = registerIcon('testing-cancel-icon', Codicon.debugStop, ( localize(12225, 'Icon to cancel ongoing test runs.')));
|
|
20
|
+
const testingFilterIcon = registerIcon('testing-filter', Codicon.filter, ( localize(12226, 'Icon for the \'Filter\' action in the testing view.')));
|
|
21
|
+
const testingHiddenIcon = registerIcon('testing-hidden', Codicon.eyeClosed, ( localize(12227, 'Icon shown beside hidden tests, when they\'ve been shown.')));
|
|
22
|
+
registerIcon('testing-show-as-list-icon', Codicon.listTree, ( localize(12228, 'Icon shown when the test explorer is disabled as a tree.')));
|
|
23
|
+
registerIcon('testing-show-as-list-icon', Codicon.listFlat, ( localize(12229, 'Icon shown when the test explorer is disabled as a list.')));
|
|
24
|
+
const testingUpdateProfiles = registerIcon('testing-update-profiles', Codicon.gear, ( localize(12230, 'Icon shown to update test profiles.')));
|
|
25
|
+
const testingRefreshTests = registerIcon('testing-refresh-tests', Codicon.refresh, ( localize(12231, 'Icon on the button to refresh tests.')));
|
|
26
|
+
const testingTurnContinuousRunOn = registerIcon('testing-turn-continuous-run-on', Codicon.eye, ( localize(12232, 'Icon to turn continuous test runs on.')));
|
|
27
|
+
const testingTurnContinuousRunOff = registerIcon('testing-turn-continuous-run-off', Codicon.eyeClosed, ( localize(12233, 'Icon to turn continuous test runs off.')));
|
|
28
|
+
const testingContinuousIsOn = registerIcon('testing-continuous-is-on', Codicon.eye, ( localize(12234, 'Icon when continuous run is on for a test ite,.')));
|
|
29
|
+
const testingCancelRefreshTests = registerIcon('testing-cancel-refresh-tests', Codicon.stop, ( localize(12235, 'Icon on the button to cancel refreshing tests.')));
|
|
30
|
+
const testingCoverageReport = registerIcon('testing-coverage', Codicon.coverage, ( localize(12236, 'Icon representing test coverage')));
|
|
31
|
+
const testingWasCovered = registerIcon('testing-was-covered', Codicon.check, ( localize(12237, 'Icon representing that an element was covered')));
|
|
32
|
+
const testingCoverageMissingBranch = registerIcon('testing-missing-branch', Codicon.question, ( localize(12238, 'Icon representing a uncovered block without a range')));
|
|
33
33
|
const testingStatesToIcons = ( new Map([
|
|
34
|
-
[TestResultState.Errored, registerIcon('testing-error-icon', Codicon.issues, ( localize(
|
|
35
|
-
[TestResultState.Failed, registerIcon('testing-failed-icon', Codicon.error, ( localize(
|
|
36
|
-
[TestResultState.Passed, registerIcon('testing-passed-icon', Codicon.pass, ( localize(
|
|
37
|
-
[TestResultState.Queued, registerIcon('testing-queued-icon', Codicon.history, ( localize(
|
|
34
|
+
[TestResultState.Errored, registerIcon('testing-error-icon', Codicon.issues, ( localize(12239, 'Icon shown for tests that have an error.')))],
|
|
35
|
+
[TestResultState.Failed, registerIcon('testing-failed-icon', Codicon.error, ( localize(12240, 'Icon shown for tests that failed.')))],
|
|
36
|
+
[TestResultState.Passed, registerIcon('testing-passed-icon', Codicon.pass, ( localize(12241, 'Icon shown for tests that passed.')))],
|
|
37
|
+
[TestResultState.Queued, registerIcon('testing-queued-icon', Codicon.history, ( localize(12242, 'Icon shown for tests that are queued.')))],
|
|
38
38
|
[TestResultState.Running, spinningLoading],
|
|
39
|
-
[TestResultState.Skipped, registerIcon('testing-skipped-icon', Codicon.debugStepOver, ( localize(
|
|
40
|
-
[TestResultState.Unset, registerIcon('testing-unset-icon', Codicon.circleOutline, ( localize(
|
|
39
|
+
[TestResultState.Skipped, registerIcon('testing-skipped-icon', Codicon.debugStepOver, ( localize(12243, 'Icon shown for tests that are skipped.')))],
|
|
40
|
+
[TestResultState.Unset, registerIcon('testing-unset-icon', Codicon.circleOutline, ( localize(12244, 'Icon shown for tests that are in an unset state.')))],
|
|
41
41
|
]));
|
|
42
42
|
registerThemingParticipant((theme, collector) => {
|
|
43
43
|
for (const [state, icon] of testingStatesToIcons.entries()) {
|
|
@@ -3,7 +3,7 @@ import { ITransaction } from "@codingame/monaco-vscode-api/vscode/vs/base/common
|
|
|
3
3
|
import { URI } from "@codingame/monaco-vscode-api/vscode/vs/base/common/uri";
|
|
4
4
|
import { IConfigurationService } from "@codingame/monaco-vscode-api/vscode/vs/platform/configuration/common/configuration.service";
|
|
5
5
|
import { IHoverService } from "@codingame/monaco-vscode-api/vscode/vs/platform/hover/browser/hover.service";
|
|
6
|
-
import { IExplorerFileContribution } from "@codingame/monaco-vscode-
|
|
6
|
+
import { IExplorerFileContribution } from "@codingame/monaco-vscode-5ca67a37-98cf-58a6-90cb-0999f3ec6b71-common/vscode/vs/workbench/contrib/files/browser/explorerFileContrib";
|
|
7
7
|
import { AbstractFileCoverage } from "@codingame/monaco-vscode-6845754f-e617-5ed9-8aaa-6ca3653a9532-common/vscode/vs/workbench/contrib/testing/common/testCoverage";
|
|
8
8
|
import { ITestCoverageService } from "@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/testing/common/testCoverageService.service";
|
|
9
9
|
export interface TestCoverageBarsOptions {
|
|
@@ -11,7 +11,7 @@ import { localize } from '@codingame/monaco-vscode-api/vscode/vs/nls';
|
|
|
11
11
|
import { IConfigurationService } from '@codingame/monaco-vscode-api/vscode/vs/platform/configuration/common/configuration.service';
|
|
12
12
|
import { IHoverService } from '@codingame/monaco-vscode-api/vscode/vs/platform/hover/browser/hover.service';
|
|
13
13
|
import { Registry } from '@codingame/monaco-vscode-api/vscode/vs/platform/registry/common/platform';
|
|
14
|
-
import { ExplorerExtensions } from '@codingame/monaco-vscode-
|
|
14
|
+
import { ExplorerExtensions } from '@codingame/monaco-vscode-5ca67a37-98cf-58a6-90cb-0999f3ec6b71-common/vscode/vs/workbench/contrib/files/browser/explorerFileContrib';
|
|
15
15
|
import { calculateDisplayedStat, displayPercent, percent, getCoverageColor } from './codeCoverageDisplayUtils.js';
|
|
16
16
|
import { TestingConfigKeys, getTestingConfiguration, observeTestingConfiguration } from '../common/configuration.js';
|
|
17
17
|
import { ITestCoverageService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/testing/common/testCoverageService.service';
|
|
@@ -127,21 +127,21 @@ const renderBar = (bar, pct, isZero, thresholds) => {
|
|
|
127
127
|
};
|
|
128
128
|
const nf = safeIntl.NumberFormat();
|
|
129
129
|
const stmtCoverageText = (coverage) => ( localize(
|
|
130
|
-
|
|
130
|
+
12245,
|
|
131
131
|
'{0}/{1} statements covered ({2})',
|
|
132
132
|
nf.value.format(coverage.statement.covered),
|
|
133
133
|
nf.value.format(coverage.statement.total),
|
|
134
134
|
displayPercent(percent(coverage.statement))
|
|
135
135
|
));
|
|
136
136
|
const fnCoverageText = (coverage) => coverage.declaration && ( localize(
|
|
137
|
-
|
|
137
|
+
12246,
|
|
138
138
|
'{0}/{1} functions covered ({2})',
|
|
139
139
|
nf.value.format(coverage.declaration.covered),
|
|
140
140
|
nf.value.format(coverage.declaration.total),
|
|
141
141
|
displayPercent(percent(coverage.declaration))
|
|
142
142
|
));
|
|
143
143
|
const branchCoverageText = (coverage) => coverage.branch && ( localize(
|
|
144
|
-
|
|
144
|
+
12247,
|
|
145
145
|
'{0}/{1} branches covered ({2})',
|
|
146
146
|
nf.value.format(coverage.branch.covered),
|
|
147
147
|
nf.value.format(coverage.branch.total),
|