@codingame/monaco-vscode-testing-service-override 6.0.2 → 7.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.
Files changed (20) hide show
  1. package/package.json +3 -3
  2. package/vscode/src/vs/workbench/contrib/testing/browser/codeCoverageDecorations.js +75 -77
  3. package/vscode/src/vs/workbench/contrib/testing/browser/explorerProjections/treeProjection.js +1 -1
  4. package/vscode/src/vs/workbench/contrib/testing/browser/testCoverageBars.js +2 -2
  5. package/vscode/src/vs/workbench/contrib/testing/browser/testCoverageView.js +1 -1
  6. package/vscode/src/vs/workbench/contrib/testing/browser/testExplorerActions.js +32 -24
  7. package/vscode/src/vs/workbench/contrib/testing/browser/testingDecorations.js +1 -1
  8. package/vscode/src/vs/workbench/contrib/testing/browser/testingExplorerFilter.js +9 -8
  9. package/vscode/src/vs/workbench/contrib/testing/browser/testingExplorerView.js +51 -30
  10. package/vscode/src/vs/workbench/contrib/testing/browser/testingOutputPeek.js +17 -10
  11. package/vscode/src/vs/workbench/contrib/testing/browser/theme.js +14 -74
  12. package/vscode/src/vs/workbench/contrib/testing/common/configuration.js +2 -1
  13. package/vscode/src/vs/workbench/contrib/testing/common/testCoverageService.js +4 -1
  14. package/vscode/src/vs/workbench/contrib/testing/common/testExplorerFilterState.js +2 -0
  15. package/vscode/src/vs/workbench/contrib/testing/common/testProfileService.js +9 -11
  16. package/vscode/src/vs/workbench/contrib/testing/common/testResultService.js +2 -2
  17. package/vscode/src/vs/workbench/contrib/testing/common/testService.js +2 -6
  18. package/vscode/src/vs/workbench/contrib/testing/common/testServiceImpl.js +21 -13
  19. package/vscode/src/vs/workbench/contrib/testing/common/testingContextKeys.js +13 -8
  20. package/vscode/src/vs/workbench/contrib/testing/common/testingContinuousRunService.js +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codingame/monaco-vscode-testing-service-override",
3
- "version": "6.0.2",
3
+ "version": "7.0.0",
4
4
  "keywords": [],
5
5
  "author": {
6
6
  "name": "CodinGame",
@@ -26,7 +26,7 @@
26
26
  }
27
27
  },
28
28
  "dependencies": {
29
- "vscode": "npm:@codingame/monaco-vscode-api@6.0.2",
30
- "@codingame/monaco-vscode-terminal-service-override": "6.0.2"
29
+ "vscode": "npm:@codingame/monaco-vscode-api@7.0.0",
30
+ "@codingame/monaco-vscode-terminal-service-override": "7.0.0"
31
31
  }
32
32
  }
@@ -12,11 +12,10 @@ import { MarkdownString } from 'vscode/vscode/vs/base/common/htmlContent';
12
12
  import { KeyChord, KeyMod, KeyCode } from 'vscode/vscode/vs/base/common/keyCodes';
13
13
  import { Lazy } from 'vscode/vscode/vs/base/common/lazy';
14
14
  import { Disposable, DisposableStore, toDisposable, MutableDisposable } from 'vscode/vscode/vs/base/common/lifecycle';
15
- import { observableValue } from 'vscode/vscode/vs/base/common/observableInternal/base';
15
+ import 'vscode/vscode/vs/base/common/arrays';
16
16
  import { derived } from 'vscode/vscode/vs/base/common/observableInternal/derived';
17
17
  import { autorun } from 'vscode/vscode/vs/base/common/observableInternal/autorun';
18
18
  import { observableFromEvent } from 'vscode/vscode/vs/base/common/observableInternal/utils';
19
- import 'vscode/vscode/vs/base/common/arrays';
20
19
  import { ThemeIcon } from 'vscode/vscode/vs/base/common/themables';
21
20
  import { isUriComponents, URI } from 'vscode/vscode/vs/base/common/uri';
22
21
  import { MouseTargetType, OverlayWidgetPositionPreference } from 'vscode/vscode/vs/editor/browser/editorBrowser';
@@ -50,21 +49,17 @@ import { ITestService } from 'vscode/vscode/vs/workbench/contrib/testing/common/
50
49
  import { DetailType } from 'vscode/vscode/vs/workbench/contrib/testing/common/testTypes';
51
50
  import { TestingContextKeys } from '../common/testingContextKeys.js';
52
51
 
53
- var CodeCoverageDecorations_1;
54
52
  const _moduleId = "vs/workbench/contrib/testing/browser/codeCoverageDecorations";
55
- const MAX_HOVERED_LINES = 30;
56
53
  const CLASS_HIT = 'coverage-deco-hit';
57
54
  const CLASS_MISS = 'coverage-deco-miss';
58
55
  const TOGGLE_INLINE_COMMAND_TEXT = ( localizeWithPath(_moduleId, 0, 'Toggle Inline'));
59
56
  const TOGGLE_INLINE_COMMAND_ID = 'testing.toggleInlineCoverage';
60
57
  const BRANCH_MISS_INDICATOR_CHARS = 4;
61
58
  let CodeCoverageDecorations = class CodeCoverageDecorations extends Disposable {
62
- static { CodeCoverageDecorations_1 = this; }
63
- static { this.showInline = observableValue('inlineCoverage', false); }
64
- static { this.fileCoverageDecorations = ( (new WeakMap())); }
65
59
  constructor(editor, instantiationService, coverage, configurationService, log) {
66
60
  super();
67
61
  this.editor = editor;
62
+ this.coverage = coverage;
68
63
  this.log = log;
69
64
  this.displayedStore = this._register(( (new DisposableStore())));
70
65
  this.hoveredStore = this._register(( (new DisposableStore())));
@@ -72,8 +67,8 @@ let CodeCoverageDecorations = class CodeCoverageDecorations extends Disposable {
72
67
  this.summaryWidget = ( (new Lazy(
73
68
  () => this._register(instantiationService.createInstance(CoverageToolbarWidget, this.editor))
74
69
  )));
75
- const modelObs = observableFromEvent(editor.onDidChangeModel, () => editor.getModel());
76
- const configObs = observableFromEvent(editor.onDidChangeConfiguration, i => i);
70
+ const modelObs = observableFromEvent(this, editor.onDidChangeModel, () => editor.getModel());
71
+ const configObs = observableFromEvent(this, editor.onDidChangeConfiguration, i => i);
77
72
  const fileCoverage = derived(reader => {
78
73
  const report = coverage.selected.read(reader);
79
74
  if (!report) {
@@ -83,21 +78,17 @@ let CodeCoverageDecorations = class CodeCoverageDecorations extends Disposable {
83
78
  if (!model) {
84
79
  return;
85
80
  }
86
- let file = report.getUri(model.uri);
87
- if (file) {
88
- const testFilter = coverage.filterToTest.read(reader);
89
- if (testFilter) {
90
- file = file.perTestData?.get(( (testFilter.toString()))) || file;
91
- }
92
- return file;
81
+ const file = report.getUri(model.uri);
82
+ if (!file) {
83
+ return;
93
84
  }
94
85
  report.didAddCoverage.read(reader);
95
- return undefined;
86
+ return { file, testId: coverage.filterToTest.read(reader) };
96
87
  });
97
88
  this._register(autorun(reader => {
98
89
  const c = fileCoverage.read(reader);
99
90
  if (c) {
100
- this.apply(editor.getModel(), c, CodeCoverageDecorations_1.showInline.read(reader));
91
+ this.apply(editor.getModel(), c.file, c.testId, coverage.showInline.read(reader));
101
92
  }
102
93
  else {
103
94
  this.clear();
@@ -107,10 +98,10 @@ let CodeCoverageDecorations = class CodeCoverageDecorations extends Disposable {
107
98
  this._register(autorun(reader => {
108
99
  const c = fileCoverage.read(reader);
109
100
  if (c && toolbarEnabled.read(reader)) {
110
- this.summaryWidget.value.setCoverage(c);
101
+ this.summaryWidget.value.setCoverage(c.file, c.testId);
111
102
  }
112
103
  else {
113
- this.summaryWidget.rawValue?.setCoverage(undefined);
104
+ this.summaryWidget.rawValue?.clearCoverage();
114
105
  }
115
106
  }));
116
107
  this._register(autorun(reader => {
@@ -127,7 +118,7 @@ let CodeCoverageDecorations = class CodeCoverageDecorations extends Disposable {
127
118
  if (e.target.type === MouseTargetType.GUTTER_LINE_NUMBERS && model) {
128
119
  this.hoverLineNumber(editor.getModel(), e.target.position.lineNumber);
129
120
  }
130
- else if (CodeCoverageDecorations_1.showInline.get() && e.target.type === MouseTargetType.CONTENT_TEXT && model) {
121
+ else if (coverage.showInline.get() && e.target.type === MouseTargetType.CONTENT_TEXT && model) {
131
122
  this.hoverInlineDecoration(model, e.target.position);
132
123
  }
133
124
  else {
@@ -184,9 +175,13 @@ let CodeCoverageDecorations = class CodeCoverageDecorations extends Disposable {
184
175
  this.hoveredSubject = lineNumber;
185
176
  const todo = [{ line: lineNumber, dir: 0 }];
186
177
  const toEnable = ( (new Set()));
187
- if (!CodeCoverageDecorations_1.showInline.get()) {
188
- for (let i = 0; i < todo.length && i < MAX_HOVERED_LINES; i++) {
178
+ const ranges = this.editor.getVisibleRanges();
179
+ if (!this.coverage.showInline.get()) {
180
+ for (let i = 0; i < todo.length; i++) {
189
181
  const { line, dir } = todo[i];
182
+ if (!( (ranges.some(r => r.startLineNumber <= line && r.endLineNumber >= line)))) {
183
+ continue;
184
+ }
190
185
  let found = false;
191
186
  for (const decoration of model.getLineDecorations(line)) {
192
187
  if (( (this.decorationIds.has(decoration.id)))) {
@@ -227,8 +222,8 @@ let CodeCoverageDecorations = class CodeCoverageDecorations extends Disposable {
227
222
  });
228
223
  }));
229
224
  }
230
- async apply(model, coverage, showInlineByDefault) {
231
- const details = this.details = await this.loadDetails(coverage, model);
225
+ async apply(model, coverage, testId, showInlineByDefault) {
226
+ const details = this.details = await this.loadDetails(coverage, testId, model);
232
227
  if (!details) {
233
228
  return this.clear();
234
229
  }
@@ -303,22 +298,19 @@ let CodeCoverageDecorations = class CodeCoverageDecorations extends Disposable {
303
298
  this.displayedStore.clear();
304
299
  this.hoveredStore.clear();
305
300
  }
306
- async loadDetails(coverage, textModel) {
307
- const existing = CodeCoverageDecorations_1.fileCoverageDecorations.get(coverage);
308
- if (existing) {
309
- return existing;
310
- }
301
+ async loadDetails(coverage, testId, textModel) {
311
302
  const cts = this.loadingCancellation = ( (new CancellationTokenSource()));
312
303
  this.displayedStore.add(this.loadingCancellation);
313
304
  try {
314
- const details = await coverage.details(this.loadingCancellation.token);
305
+ const details = testId
306
+ ? await coverage.detailsForTest(testId, this.loadingCancellation.token)
307
+ : await coverage.details(this.loadingCancellation.token);
315
308
  if (cts.token.isCancellationRequested) {
316
309
  return;
317
310
  }
318
- const model = CodeCoverageDecorations_1.fileCoverageDecorations.get(coverage)
319
- || ( (new CoverageDetailsModel(details, textModel)));
320
- CodeCoverageDecorations_1.fileCoverageDecorations.set(coverage, model);
321
- return model;
311
+ return (
312
+ (new CoverageDetailsModel(details, textModel))
313
+ );
322
314
  }
323
315
  catch (e) {
324
316
  this.log.error('Error loading coverage details', e);
@@ -326,7 +318,7 @@ let CodeCoverageDecorations = class CodeCoverageDecorations extends Disposable {
326
318
  return undefined;
327
319
  }
328
320
  };
329
- CodeCoverageDecorations = CodeCoverageDecorations_1 = ( (__decorate([
321
+ CodeCoverageDecorations = ( (__decorate([
330
322
  ( (__param(1, IInstantiationService))),
331
323
  ( (__param(2, ITestCoverageService))),
332
324
  ( (__param(3, IConfigurationService))),
@@ -472,7 +464,7 @@ function wrapName(functionNameOrCode) {
472
464
  return wrapInBackticks(functionNameOrCode);
473
465
  }
474
466
  let CoverageToolbarWidget = class CoverageToolbarWidget extends Disposable {
475
- constructor(editor, configurationService, contextMenuService, testService, keybindingService, commandService, instaService) {
467
+ constructor(editor, configurationService, contextMenuService, testService, keybindingService, commandService, coverage, instaService) {
476
468
  super();
477
469
  this.editor = editor;
478
470
  this.configurationService = configurationService;
@@ -480,6 +472,7 @@ let CoverageToolbarWidget = class CoverageToolbarWidget extends Disposable {
480
472
  this.testService = testService;
481
473
  this.keybindingService = keybindingService;
482
474
  this.commandService = commandService;
475
+ this.coverage = coverage;
483
476
  this.registered = false;
484
477
  this.isRunning = false;
485
478
  this.showStore = this._register(( (new DisposableStore())));
@@ -505,7 +498,7 @@ let CoverageToolbarWidget = class CoverageToolbarWidget extends Disposable {
505
498
  }
506
499
  }));
507
500
  this._register(autorun(reader => {
508
- CodeCoverageDecorations.showInline.read(reader);
501
+ coverage.showInline.read(reader);
509
502
  this.setActions();
510
503
  }));
511
504
  this._register(addStandardDisposableListener(this._domNode.root, EventType.CONTEXT_MENU, e => {
@@ -527,8 +520,13 @@ let CoverageToolbarWidget = class CoverageToolbarWidget extends Disposable {
527
520
  stackOridinal: 9,
528
521
  };
529
522
  }
530
- setCoverage(coverage) {
531
- this.current = coverage;
523
+ clearCoverage() {
524
+ this.current = undefined;
525
+ this.bars.setCoverageInfo(undefined);
526
+ this.hide();
527
+ }
528
+ setCoverage(coverage, testId) {
529
+ this.current = { coverage, testId };
532
530
  this.bars.setCoverageInfo(coverage);
533
531
  if (!coverage) {
534
532
  this.hide();
@@ -540,36 +538,36 @@ let CoverageToolbarWidget = class CoverageToolbarWidget extends Disposable {
540
538
  }
541
539
  setActions() {
542
540
  this.actionBar.clear();
543
- const coverage = this.current;
544
- if (!coverage) {
541
+ const current = this.current;
542
+ if (!current) {
545
543
  return;
546
544
  }
547
- const toggleAction = ( (new ActionWithIcon('toggleInline', CodeCoverageDecorations.showInline.get()
545
+ const toggleAction = ( (new ActionWithIcon('toggleInline', this.coverage.showInline.get()
548
546
  ? ( localizeWithPath(_moduleId, 8, 'Hide Inline Coverage'))
549
- : ( localizeWithPath(_moduleId, 9, 'Show Inline Coverage')), testingCoverageReport, undefined, () => CodeCoverageDecorations.showInline.set(!CodeCoverageDecorations.showInline.get(), undefined))));
547
+ : ( localizeWithPath(_moduleId, 9, 'Show Inline Coverage')), testingCoverageReport, undefined, () => this.coverage.showInline.set(!this.coverage.showInline.get(), undefined))));
550
548
  const kb = this.keybindingService.lookupKeybinding(TOGGLE_INLINE_COMMAND_ID);
551
549
  if (kb) {
552
550
  toggleAction.tooltip = `${TOGGLE_INLINE_COMMAND_TEXT} (${kb.getLabel()})`;
553
551
  }
554
552
  this.actionBar.push(toggleAction);
555
- if (coverage.isForTest) {
556
- const testItem = coverage.fromResult.getTestById(( (coverage.isForTest.id.toString())));
553
+ if (current.testId) {
554
+ const testItem = current.coverage.fromResult.getTestById(( (current.testId.toString())));
557
555
  assert(!!testItem, 'got coverage for an unreported test');
558
556
  this.actionBar.push(( (new ActionWithIcon(
559
557
  'perTestFilter',
560
558
  labels.showingFilterFor(testItem.label),
561
559
  testingFilterIcon,
562
560
  undefined,
563
- () => this.commandService.executeCommand(TestCommandId.CoverageFilterToTestInEditor, this.current)
561
+ () => this.commandService.executeCommand(TestCommandId.CoverageFilterToTestInEditor, this.current, this.editor)
564
562
  ))));
565
563
  }
566
- else if (coverage.perTestData?.size) {
564
+ else if (current.coverage.perTestData?.size) {
567
565
  this.actionBar.push(( (new ActionWithIcon('perTestFilter', ( localizeWithPath(
568
566
  _moduleId,
569
567
  10,
570
568
  "{0} test(s) ran code in this file",
571
- coverage.perTestData.size
572
- )), testingFilterIcon, undefined, () => this.commandService.executeCommand(TestCommandId.CoverageFilterToTestInEditor, this.current)))));
569
+ current.coverage.perTestData.size
570
+ )), testingFilterIcon, undefined, () => this.commandService.executeCommand(TestCommandId.CoverageFilterToTestInEditor, this.current, this.editor)))));
573
571
  }
574
572
  this.actionBar.push(( (new ActionWithIcon('rerun', ( localizeWithPath(_moduleId, 11, 'Rerun')), testingRerunIcon, !this.isRunning, () => this.rerunTest()))));
575
573
  }
@@ -598,8 +596,8 @@ let CoverageToolbarWidget = class CoverageToolbarWidget extends Disposable {
598
596
  });
599
597
  }));
600
598
  ds.add(this.configurationService.onDidChangeConfiguration(e => {
601
- if (e.affectsConfiguration(TestingConfigKeys.CoverageBarThresholds) || e.affectsConfiguration(TestingConfigKeys.CoveragePercent)) {
602
- this.setCoverage(this.current);
599
+ if (this.current && (e.affectsConfiguration(TestingConfigKeys.CoverageBarThresholds) || e.affectsConfiguration(TestingConfigKeys.CoveragePercent))) {
600
+ this.setCoverage(this.current.coverage, this.current.testId);
603
601
  }
604
602
  }));
605
603
  }
@@ -608,7 +606,7 @@ let CoverageToolbarWidget = class CoverageToolbarWidget extends Disposable {
608
606
  if (current) {
609
607
  this.isRunning = true;
610
608
  this.setActions();
611
- this.testService.runResolvedTests(current.fromResult.request).finally(() => {
609
+ this.testService.runResolvedTests(current.coverage.fromResult.request).finally(() => {
612
610
  this.isRunning = false;
613
611
  this.setActions();
614
612
  });
@@ -624,18 +622,23 @@ CoverageToolbarWidget = ( (__decorate([
624
622
  ( (__param(3, ITestService))),
625
623
  ( (__param(4, IKeybindingService))),
626
624
  ( (__param(5, ICommandService))),
627
- ( (__param(6, IInstantiationService)))
625
+ ( (__param(6, ITestCoverageService))),
626
+ ( (__param(7, IInstantiationService)))
628
627
  ], CoverageToolbarWidget)));
629
628
  registerAction2(class ToggleInlineCoverage extends Action2 {
630
629
  constructor() {
631
630
  super({
632
631
  id: TOGGLE_INLINE_COMMAND_ID,
633
- title: ( localize2WithPath(_moduleId, 12, "Show Inline Coverage")),
632
+ title: ( localize2WithPath(_moduleId, 12, "Toggle Inline Coverage")),
634
633
  category: Categories.Test,
635
634
  keybinding: {
636
635
  weight: KeybindingWeight.WorkbenchContrib,
637
636
  primary: KeyChord(KeyMod.CtrlCmd | KeyCode.Semicolon, KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KeyI),
638
637
  },
638
+ toggled: {
639
+ condition: TestingContextKeys.inlineCoverageEnabled,
640
+ title: ( localizeWithPath(_moduleId, 13, "Hide Inline Coverage")),
641
+ },
639
642
  icon: testingCoverageReport,
640
643
  menu: [
641
644
  { id: MenuId.CommandPalette, when: TestingContextKeys.isTestCoverageOpen },
@@ -646,17 +649,18 @@ registerAction2(class ToggleInlineCoverage extends Action2 {
646
649
  ]
647
650
  });
648
651
  }
649
- run() {
650
- CodeCoverageDecorations.showInline.set(!CodeCoverageDecorations.showInline.get(), undefined);
652
+ run(accessor) {
653
+ const coverage = accessor.get(ITestCoverageService);
654
+ coverage.showInline.set(!coverage.showInline.get(), undefined);
651
655
  }
652
656
  });
653
657
  registerAction2(class ToggleCoverageToolbar extends Action2 {
654
658
  constructor() {
655
659
  super({
656
660
  id: TestCommandId.CoverageToggleToolbar,
657
- title: ( localize2WithPath(_moduleId, 13, "Test Coverage Toolbar")),
661
+ title: ( localize2WithPath(_moduleId, 14, "Test Coverage Toolbar")),
658
662
  metadata: {
659
- description: ( localize2WithPath(_moduleId, 14, 'Toggle the sticky coverage bar in the editor.'))
663
+ description: ( localize2WithPath(_moduleId, 15, 'Toggle the sticky coverage bar in the editor.'))
660
664
  },
661
665
  category: Categories.Test,
662
666
  toggled: {
@@ -679,7 +683,7 @@ registerAction2(class FilterCoverageToTestInEditor extends Action2 {
679
683
  constructor() {
680
684
  super({
681
685
  id: TestCommandId.CoverageFilterToTestInEditor,
682
- title: ( localize2WithPath(_moduleId, 15, "Filter Coverage to Test")),
686
+ title: ( localize2WithPath(_moduleId, 16, "Filter Coverage to Test")),
683
687
  category: Categories.Test,
684
688
  icon: Codicon.filter,
685
689
  toggled: {
@@ -694,10 +698,10 @@ registerAction2(class FilterCoverageToTestInEditor extends Action2 {
694
698
  ]
695
699
  });
696
700
  }
697
- run(accessor, coverageOrUri) {
701
+ run(accessor, coverageOrUri, editor) {
698
702
  const testCoverageService = accessor.get(ITestCoverageService);
699
703
  const quickInputService = accessor.get(IQuickInputService);
700
- const activeEditor = accessor.get(ICodeEditorService).getActiveCodeEditor();
704
+ const activeEditor = editor ?? accessor.get(ICodeEditorService).getActiveCodeEditor();
701
705
  let coverage;
702
706
  if (coverageOrUri instanceof FileCoverage) {
703
707
  coverage = coverageOrUri;
@@ -709,23 +713,17 @@ registerAction2(class FilterCoverageToTestInEditor extends Action2 {
709
713
  const uri = activeEditor?.getModel()?.uri;
710
714
  coverage = uri && testCoverageService.selected.get()?.getUri(uri);
711
715
  }
712
- if (!coverage || !(coverage.isForTest || coverage.perTestData?.size)) {
713
- return;
714
- }
715
- const options = coverage?.perTestData ?? coverage?.isForTest?.parent.perTestData;
716
- if (!options) {
716
+ if (!coverage || !coverage.perTestData?.size) {
717
717
  return;
718
718
  }
719
- const tests = [...( (options.values()))];
720
- const commonPrefix = TestId.getLengthOfCommonPrefix(tests.length, i => tests[i].isForTest.id);
719
+ const tests = ( ([...coverage.perTestData].map(TestId.fromString)));
720
+ const commonPrefix = TestId.getLengthOfCommonPrefix(tests.length, i => tests[i]);
721
721
  const result = coverage.fromResult;
722
722
  const previousSelection = testCoverageService.filterToTest.get();
723
723
  const items = [
724
- { label: labels.allTests, item: undefined },
724
+ { label: labels.allTests, testId: undefined },
725
725
  { type: 'separator' },
726
- ...( (tests.map(
727
- item => ({ label: getLabelForItem(result, item.isForTest.id, commonPrefix), description: labels.percentCoverage(item.tpc), item })
728
- ))),
726
+ ...( (tests.map(id => ({ label: getLabelForItem(result, id, commonPrefix), testId: id })))),
729
727
  ];
730
728
  const scrollTop = activeEditor?.getScrollTop() || 0;
731
729
  const revealScrollCts = ( (new MutableDisposable()));
@@ -733,20 +731,20 @@ registerAction2(class FilterCoverageToTestInEditor extends Action2 {
733
731
  activeItem: items.find((item) => 'item' in item && item.item === coverage),
734
732
  placeHolder: labels.pickShowCoverage,
735
733
  onDidFocus: (entry) => {
736
- if (!entry.item) {
734
+ if (!entry.testId) {
737
735
  revealScrollCts.clear();
738
736
  activeEditor?.setScrollTop(scrollTop);
739
737
  testCoverageService.filterToTest.set(undefined, undefined);
740
738
  }
741
739
  else {
742
740
  const cts = revealScrollCts.value = ( (new CancellationTokenSource()));
743
- entry.item.details(cts.token).then(details => {
741
+ coverage.detailsForTest(entry.testId, cts.token).then(details => {
744
742
  const first = details.find(d => d.type === DetailType.Statement);
745
743
  if (!cts.token.isCancellationRequested && first) {
746
744
  activeEditor?.revealLineNearTop(first.location instanceof Position ? first.location.lineNumber : first.location.startLineNumber);
747
745
  }
748
746
  }, () => { });
749
- testCoverageService.filterToTest.set(entry.item.isForTest.id, undefined);
747
+ testCoverageService.filterToTest.set(entry.testId, undefined);
750
748
  }
751
749
  },
752
750
  }).then(selected => {
@@ -754,7 +752,7 @@ registerAction2(class FilterCoverageToTestInEditor extends Action2 {
754
752
  activeEditor?.setScrollTop(scrollTop);
755
753
  }
756
754
  revealScrollCts.dispose();
757
- testCoverageService.filterToTest.set(selected ? selected.item?.isForTest.id : previousSelection, undefined);
755
+ testCoverageService.filterToTest.set(selected ? selected.testId : previousSelection, undefined);
758
756
  });
759
757
  }
760
758
  });
@@ -142,7 +142,7 @@ let TreeProjection = class TreeProjection extends Disposable {
142
142
  break;
143
143
  }
144
144
  const parent = toRemove.parent;
145
- const affectsRootElement = toRemove.depth === 1 && parent?.children.size === 1;
145
+ const affectsRootElement = toRemove.depth === 1 && (parent?.children.size === 1 || !( Iterable.some(this.rootsWithChildren, (_, i) => i === 1)));
146
146
  this.changedParents.add(affectsRootElement ? null : parent);
147
147
  const queue = [[toRemove]];
148
148
  while (queue.length) {
@@ -57,7 +57,7 @@ let ManagedTestCoverageBars = class ManagedTestCoverageBars extends Disposable {
57
57
  this.customHovers = [];
58
58
  }
59
59
  attachHover(target, factory) {
60
- this._register(this.hoverService.setupUpdatableHover(getDefaultHoverDelegate('element'), target, () => this._coverage && factory(this._coverage)));
60
+ this._register(this.hoverService.setupManagedHover(getDefaultHoverDelegate('element'), target, () => this._coverage && factory(this._coverage)));
61
61
  }
62
62
  setCoverageInfo(coverage) {
63
63
  const ds = this.visibleStore;
@@ -71,7 +71,7 @@ let ManagedTestCoverageBars = class ManagedTestCoverageBars extends Disposable {
71
71
  }
72
72
  if (!this._coverage) {
73
73
  const root = this.el.value.root;
74
- ds.add(toDisposable(() => this.options.container.removeChild(root)));
74
+ ds.add(toDisposable(() => root.remove()));
75
75
  this.options.container.appendChild(root);
76
76
  ds.add(this.configurationService.onDidChangeConfiguration(c => {
77
77
  if (!this._coverage) {
@@ -541,7 +541,7 @@ registerAction2(class TestCoverageChangePerTestFilterAction extends Action2 {
541
541
  if (!coverage) {
542
542
  return;
543
543
  }
544
- const tests = ( ([...coverage.perTestCoverageIDs].map(TestId.fromString)));
544
+ const tests = ( ([...coverage.allPerTestIDs()].map(TestId.fromString)));
545
545
  const commonPrefix = TestId.getLengthOfCommonPrefix(tests.length, i => tests[i]);
546
546
  const result = coverage.result;
547
547
  const previousSelection = coverageService.filterToTest.get();
@@ -38,7 +38,7 @@ import { ITestProfileService } from 'vscode/vscode/vs/workbench/contrib/testing/
38
38
  import { ITestResultService } from 'vscode/vscode/vs/workbench/contrib/testing/common/testResultService.service';
39
39
  import { testsInFile, testsUnderUri, expandAndGetTestById } from '../common/testService.js';
40
40
  import { ITestService } from 'vscode/vscode/vs/workbench/contrib/testing/common/testService.service';
41
- import { TestRunProfileBitset, ExtTestRunProfileKind } from 'vscode/vscode/vs/workbench/contrib/testing/common/testTypes';
41
+ import { TestRunProfileBitset, ExtTestRunProfileKind, TestItemExpandState } from 'vscode/vscode/vs/workbench/contrib/testing/common/testTypes';
42
42
  import { TestingContextKeys } from '../common/testingContextKeys.js';
43
43
  import { ITestingContinuousRunService } from 'vscode/vscode/vs/workbench/contrib/testing/common/testingContinuousRunService.service';
44
44
  import { ITestingPeekOpener } from 'vscode/vscode/vs/workbench/contrib/testing/common/testingPeekOpener.service';
@@ -199,8 +199,8 @@ class RunUsingProfileAction extends Action2 {
199
199
  return;
200
200
  }
201
201
  testService.runResolvedTests({
202
+ group: profile.group,
202
203
  targets: [{
203
- profileGroup: profile.group,
204
204
  profileId: profile.profileId,
205
205
  controllerId: profile.controllerId,
206
206
  testIds: ( (elements.filter(t => canUseProfileWithTest(profile, t.test)).map(t => t.test.item.extId)))
@@ -543,7 +543,8 @@ class RunOrDebugAllTestsAction extends Action2 {
543
543
  async run(accessor) {
544
544
  const testService = accessor.get(ITestService);
545
545
  const notifications = accessor.get(INotificationService);
546
- const roots = [...testService.collection.rootItems];
546
+ const roots = [...testService.collection.rootItems].filter(r => r.children.size
547
+ || r.expand === TestItemExpandState.Expandable || r.expand === TestItemExpandState.BusyExpanding);
547
548
  if (!roots.length) {
548
549
  notifications.info(this.noTestsFoundError);
549
550
  return;
@@ -1150,7 +1151,7 @@ class RunOrDebugFailedTests extends RunOrDebugExtsByPath {
1150
1151
  return ids;
1151
1152
  }
1152
1153
  }
1153
- class RunOrDebugLastRun extends RunOrDebugExtsByPath {
1154
+ class RunOrDebugLastRun extends Action2 {
1154
1155
  constructor(options) {
1155
1156
  super({
1156
1157
  ...options,
@@ -1163,17 +1164,33 @@ class RunOrDebugLastRun extends RunOrDebugExtsByPath {
1163
1164
  },
1164
1165
  });
1165
1166
  }
1166
- *getTestExtIdsToRun(accessor, runId) {
1167
+ getLastTestRunRequest(accessor, runId) {
1168
+ const resultService = accessor.get(ITestResultService);
1169
+ const lastResult = runId ? resultService.results.find(r => r.id === runId) : resultService.results[0];
1170
+ return lastResult?.request;
1171
+ }
1172
+ async run(accessor, runId) {
1167
1173
  const resultService = accessor.get(ITestResultService);
1168
1174
  const lastResult = runId ? resultService.results.find(r => r.id === runId) : resultService.results[0];
1169
1175
  if (!lastResult) {
1170
1176
  return;
1171
1177
  }
1172
- for (const test of lastResult.request.targets) {
1173
- for (const testId of test.testIds) {
1174
- yield testId;
1178
+ const req = lastResult.request;
1179
+ const testService = accessor.get(ITestService);
1180
+ const profileService = accessor.get(ITestProfileService);
1181
+ const profileExists = (t) => ( (profileService.getControllerProfiles(t.controllerId).some(p => p.profileId === t.profileId)));
1182
+ await discoverAndRunTests(testService.collection, accessor.get(IProgressService), req.targets.flatMap(t => t.testIds), tests => {
1183
+ if (this.getGroup() & req.group && req.targets.every(profileExists)) {
1184
+ return testService.runResolvedTests({
1185
+ targets: req.targets,
1186
+ group: req.group,
1187
+ exclude: req.exclude,
1188
+ });
1175
1189
  }
1176
- }
1190
+ else {
1191
+ return testService.runTests({ tests, group: this.getGroup() });
1192
+ }
1193
+ });
1177
1194
  }
1178
1195
  }
1179
1196
  class ReRunFailedTests extends RunOrDebugFailedTests {
@@ -1226,11 +1243,8 @@ class ReRunLastRun extends RunOrDebugLastRun {
1226
1243
  },
1227
1244
  });
1228
1245
  }
1229
- runTest(service, internalTests) {
1230
- return service.runTests({
1231
- group: TestRunProfileBitset.Run,
1232
- tests: internalTests,
1233
- });
1246
+ getGroup() {
1247
+ return TestRunProfileBitset.Run;
1234
1248
  }
1235
1249
  }
1236
1250
  class DebugLastRun extends RunOrDebugLastRun {
@@ -1245,11 +1259,8 @@ class DebugLastRun extends RunOrDebugLastRun {
1245
1259
  },
1246
1260
  });
1247
1261
  }
1248
- runTest(service, internalTests) {
1249
- return service.runTests({
1250
- group: TestRunProfileBitset.Debug,
1251
- tests: internalTests,
1252
- });
1262
+ getGroup() {
1263
+ return TestRunProfileBitset.Debug;
1253
1264
  }
1254
1265
  }
1255
1266
  class CoverageLastRun extends RunOrDebugLastRun {
@@ -1264,11 +1275,8 @@ class CoverageLastRun extends RunOrDebugLastRun {
1264
1275
  },
1265
1276
  });
1266
1277
  }
1267
- runTest(service, internalTests) {
1268
- return service.runTests({
1269
- group: TestRunProfileBitset.Coverage,
1270
- tests: internalTests,
1271
- });
1278
+ getGroup() {
1279
+ return TestRunProfileBitset.Coverage;
1272
1280
  }
1273
1281
  }
1274
1282
  class SearchForTestExtension extends Action2 {
@@ -682,8 +682,8 @@ let RunTestDecoration = class RunTestDecoration {
682
682
  return;
683
683
  }
684
684
  this.testService.runResolvedTests({
685
+ group: profile.group,
685
686
  targets: [{
686
- profileGroup: profile.group,
687
687
  profileId: profile.profileId,
688
688
  controllerId: profile.controllerId,
689
689
  testIds: [test.item.extId]
@@ -26,7 +26,8 @@ const testFilterDescriptions = {
26
26
  [TestFilterTerm.Failed]: ( localizeWithPath(_moduleId, 0, "Show Only Failed Tests")),
27
27
  [TestFilterTerm.Executed]: ( localizeWithPath(_moduleId, 1, "Show Only Executed Tests")),
28
28
  [TestFilterTerm.CurrentDoc]: ( localizeWithPath(_moduleId, 2, "Show in Active File Only")),
29
- [TestFilterTerm.Hidden]: ( localizeWithPath(_moduleId, 3, "Show Hidden Tests")),
29
+ [TestFilterTerm.OpenedFiles]: ( localizeWithPath(_moduleId, 3, "Show in Opened Files Only")),
30
+ [TestFilterTerm.Hidden]: ( localizeWithPath(_moduleId, 4, "Show Hidden Tests")),
30
31
  };
31
32
  let TestingExplorerFilter = class TestingExplorerFilter extends BaseActionViewItem {
32
33
  constructor(action, options, state, instantiationService, testService) {
@@ -41,7 +42,7 @@ let TestingExplorerFilter = class TestingExplorerFilter extends BaseActionViewIt
41
42
  scope: StorageScope.WORKSPACE,
42
43
  target: StorageTarget.MACHINE
43
44
  }));
44
- this.filtersAction = ( (new Action('markersFiltersAction', ( localizeWithPath(_moduleId, 4, "More Filters...")), 'testing-filter-button ' + ThemeIcon.asClassName(testingFilterIcon))));
45
+ this.filtersAction = ( (new Action('markersFiltersAction', ( localizeWithPath(_moduleId, 5, "More Filters...")), 'testing-filter-button ' + ThemeIcon.asClassName(testingFilterIcon))));
45
46
  this.updateFilterActiveState();
46
47
  this._register(testService.excluded.onTestExclusionsChanged(this.updateFilterActiveState, this));
47
48
  }
@@ -59,7 +60,7 @@ let TestingExplorerFilter = class TestingExplorerFilter extends BaseActionViewIt
59
60
  }
60
61
  const input = this.input = this._register(this.instantiationService.createInstance(ContextScopedSuggestEnabledInputWithHistory, {
61
62
  id: 'testing.explorer.filter',
62
- ariaLabel: ( localizeWithPath(_moduleId, 5, "Filter text for tests in the explorer")),
63
+ ariaLabel: ( localizeWithPath(_moduleId, 6, "Filter text for tests in the explorer")),
63
64
  parent: wrapper,
64
65
  suggestionProvider: {
65
66
  triggerCharacters: ['@'],
@@ -79,7 +80,7 @@ let TestingExplorerFilter = class TestingExplorerFilter extends BaseActionViewIt
79
80
  resourceHandle: 'testing:filter',
80
81
  suggestOptions: {
81
82
  value: this.state.text.value,
82
- placeholderText: ( localizeWithPath(_moduleId, 6, "Filter (e.g. text, !exclude, @tag)")),
83
+ placeholderText: ( localizeWithPath(_moduleId, 7, "Filter (e.g. text, !exclude, @tag)")),
83
84
  },
84
85
  history: history.values
85
86
  }));
@@ -148,7 +149,7 @@ let FiltersDropdownMenuActionViewItem = class FiltersDropdownMenuActionViewItem
148
149
  }
149
150
  getActions() {
150
151
  return [
151
- ...( ([TestFilterTerm.Failed, TestFilterTerm.Executed, TestFilterTerm.CurrentDoc].map(term => ({
152
+ ...( ([TestFilterTerm.Failed, TestFilterTerm.Executed, TestFilterTerm.CurrentDoc, TestFilterTerm.OpenedFiles].map(term => ({
152
153
  checked: this.filters.isFilteringFor(term),
153
154
  class: undefined,
154
155
  enabled: true,
@@ -164,7 +165,7 @@ let FiltersDropdownMenuActionViewItem = class FiltersDropdownMenuActionViewItem
164
165
  class: undefined,
165
166
  enabled: true,
166
167
  id: 'fuzzy',
167
- label: ( localizeWithPath(_moduleId, 7, "Fuzzy Match")),
168
+ label: ( localizeWithPath(_moduleId, 8, "Fuzzy Match")),
168
169
  run: () => this.filters.fuzzy.value = !this.filters.fuzzy.value,
169
170
  tooltip: ''
170
171
  },
@@ -174,7 +175,7 @@ let FiltersDropdownMenuActionViewItem = class FiltersDropdownMenuActionViewItem
174
175
  class: undefined,
175
176
  enabled: this.testService.excluded.hasAny,
176
177
  id: 'showExcluded',
177
- label: ( localizeWithPath(_moduleId, 3, "Show Hidden Tests")),
178
+ label: ( localizeWithPath(_moduleId, 4, "Show Hidden Tests")),
178
179
  run: () => this.filters.toggleFilteringFor(TestFilterTerm.Hidden),
179
180
  tooltip: ''
180
181
  },
@@ -182,7 +183,7 @@ let FiltersDropdownMenuActionViewItem = class FiltersDropdownMenuActionViewItem
182
183
  class: undefined,
183
184
  enabled: this.testService.excluded.hasAny,
184
185
  id: 'removeExcluded',
185
- label: ( localizeWithPath(_moduleId, 8, "Unhide All Tests")),
186
+ label: ( localizeWithPath(_moduleId, 9, "Unhide All Tests")),
186
187
  run: async () => this.testService.excluded.clear(),
187
188
  tooltip: ''
188
189
  }