@codingame/monaco-vscode-testing-service-override 2.0.3 → 2.1.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.
@@ -14,7 +14,7 @@ import { Emitter, Event } from 'vscode/vscode/vs/base/common/event';
14
14
  import { stripIcons } from 'vscode/vscode/vs/base/common/iconLabels';
15
15
  import { Iterable } from 'vscode/vscode/vs/base/common/iterator';
16
16
  import { Lazy } from 'vscode/vscode/vs/base/common/lazy';
17
- import { DisposableStore, Disposable, MutableDisposable, toDisposable } from 'vscode/vscode/vs/base/common/lifecycle';
17
+ import { DisposableStore, Disposable, MutableDisposable, toDisposable, combinedDisposable } from 'vscode/vscode/vs/base/common/lifecycle';
18
18
  import { count } from 'vscode/vscode/vs/base/common/strings';
19
19
  import { ThemeIcon } from 'vscode/vscode/vs/base/common/themables';
20
20
  import { isDefined } from 'vscode/vscode/vs/base/common/types';
@@ -28,9 +28,9 @@ import { EmbeddedCodeEditorWidget, EmbeddedDiffEditorWidget } from 'vscode/vscod
28
28
  import { Range } from 'vscode/vscode/vs/editor/common/core/range';
29
29
  import { EditorContextKeys } from 'vscode/vscode/vs/editor/common/editorContextKeys';
30
30
  import { ITextModelService } from 'vscode/vscode/vs/editor/common/services/resolverService';
31
- import { MarkdownRenderer } from 'vscode/vscode/vs/editor/contrib/markdownRenderer/browser/markdownRenderer';
31
+ import { MarkdownRenderer } from 'vscode/vscode/vs/editor/browser/widget/markdownRenderer/browser/markdownRenderer';
32
32
  import { PeekViewWidget, peekViewTitleForeground, peekViewTitleInfoForeground, IPeekViewService, peekViewResultsBackground } from 'vscode/vscode/vs/editor/contrib/peekView/browser/peekView';
33
- import { localizeWithPath } from 'vscode/vscode/vs/nls';
33
+ import { localizeWithPath, localize2WithPath } from 'vscode/vscode/vs/nls';
34
34
  import { Categories } from 'vscode/vscode/vs/platform/action/common/actionCommonCategories';
35
35
  import { FloatingClickMenu } from 'vscode/vscode/vs/platform/actions/browser/floatingMenu';
36
36
  import { MenuEntryActionViewItem, createAndFillInActionBarActions } from 'vscode/vscode/vs/platform/actions/browser/menuEntryActionViewItem';
@@ -50,20 +50,22 @@ import { IStorageService } from 'vscode/vscode/vs/platform/storage/common/storag
50
50
  import { ITelemetryService } from 'vscode/vscode/vs/platform/telemetry/common/telemetry';
51
51
  import { TerminalCapabilityStore } from 'vscode/vscode/vs/platform/terminal/common/capabilities/terminalCapabilityStore';
52
52
  import { formatMessageForTerminal } from 'vscode/vscode/vs/platform/terminal/common/terminalStrings';
53
+ import { editorBackground } from 'vscode/vscode/vs/platform/theme/common/colorRegistry';
53
54
  import { widgetClose } from 'vscode/vscode/vs/platform/theme/common/iconRegistry';
54
55
  import { IThemeService } from 'vscode/vscode/vs/platform/theme/common/themeService';
55
56
  import { IWorkspaceContextService } from 'vscode/vscode/vs/platform/workspace/common/workspace';
56
57
  import { ViewPane } from 'vscode/vscode/vs/workbench/browser/parts/views/viewPane';
57
58
  import { EditorModel } from 'vscode/vscode/vs/workbench/common/editor/editorModel';
58
59
  import { PANEL_BACKGROUND, SIDE_BAR_BACKGROUND } from 'vscode/vscode/vs/workbench/common/theme';
59
- import { IViewsService, IViewDescriptorService } from 'vscode/vscode/vs/workbench/common/views';
60
+ import { IViewDescriptorService } from 'vscode/vscode/vs/workbench/common/views';
61
+ import { IViewsService } from 'vscode/vscode/vs/workbench/services/views/common/viewsService';
60
62
  import { DetachedProcessInfo } from 'vscode/vscode/vs/workbench/contrib/terminal/browser/detachedTerminal';
61
63
  import { ITerminalService } from 'vscode/vscode/vs/workbench/contrib/terminal/browser/terminal';
62
64
  import { getXtermScaledDimensions } from 'vscode/vscode/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal';
63
65
  import { TERMINAL_BACKGROUND_COLOR } from 'vscode/vscode/vs/workbench/contrib/terminal/common/terminalColorRegistry';
64
66
  import { getTestItemContextOverlay } from './explorerProjections/testItemContextOverlay.js';
65
- import { testingStatesToIcons, testingRunIcon, testingDebugIcon, testingCoverage } from './icons.js';
66
- import { testingPeekBorder, testingPeekHeaderBackground } from './theme.js';
67
+ import { testingStatesToIcons, testingRunIcon, testingDebugIcon, testingCoverageReport } from './icons.js';
68
+ import { testingPeekBorder, testingMessagePeekBorder, testingPeekHeaderBackground, testingPeekMessageHeaderBackground } from './theme.js';
67
69
  import { getTestingConfiguration } from '../common/configuration.js';
68
70
  import { MutableObservableValue, staticObservableValue } from 'vscode/vscode/vs/workbench/contrib/testing/common/observableValue';
69
71
  import { StoredValue } from 'vscode/vscode/vs/workbench/contrib/testing/common/storedValue';
@@ -119,12 +121,12 @@ class TaskSubject {
119
121
  }
120
122
  }
121
123
  class TestOutputSubject {
122
- constructor(result, taskIndex, task, test) {
124
+ constructor(result, taskIndex, test) {
123
125
  this.result = result;
124
126
  this.taskIndex = taskIndex;
125
- this.task = task;
126
127
  this.test = test;
127
128
  this.outputUri = buildTestUri({ resultId: this.result.id, taskIndex: this.taskIndex, testExtId: this.test.item.extId, type: 1 });
129
+ this.task = result.tasks[this.taskIndex];
128
130
  }
129
131
  }
130
132
  const equalsSubject = (a, b) => ((a instanceof MessageSubject && b instanceof MessageSubject && a.message === b.message) ||
@@ -185,15 +187,14 @@ let TestingPeekOpener = class TestingPeekOpener extends Disposable {
185
187
  if (!candidate) {
186
188
  return false;
187
189
  }
188
- const message = candidate.message;
189
190
  this.showPeekFromUri({
190
191
  type: 2 ,
191
- documentUri: message.location.uri,
192
+ documentUri: candidate.location.uri,
192
193
  taskIndex: candidate.taskId,
193
194
  messageIndex: candidate.index,
194
195
  resultId: result.id,
195
196
  testExtId: test.item.extId,
196
- }, undefined, { selection: message.location.range, ...options });
197
+ }, undefined, { selection: candidate.location.range, selectionRevealType: 3 , ...options });
197
198
  return true;
198
199
  }
199
200
  peekUri(uri, options = {}) {
@@ -368,15 +369,19 @@ let TestingPeekOpener = class TestingPeekOpener extends Disposable {
368
369
  return undefined;
369
370
  }
370
371
  getFailedCandidateMessage(test) {
372
+ const fallbackLocation = test.item.uri && test.item.range
373
+ ? { uri: test.item.uri, range: test.item.range }
374
+ : undefined;
371
375
  let best;
372
376
  mapFindTestMessage(test, (task, message, messageIndex, taskId) => {
373
- if (!isFailedState(task.state) || !message.location) {
377
+ const location = message.location || fallbackLocation;
378
+ if (!isFailedState(task.state) || !location) {
374
379
  return;
375
380
  }
376
381
  if (best && message.type !== 0 ) {
377
382
  return;
378
383
  }
379
- best = { taskId, index: messageIndex, message };
384
+ best = { taskId, index: messageIndex, message, location };
380
385
  });
381
386
  return best;
382
387
  }
@@ -568,11 +573,10 @@ let TestingOutputPeekController = TestingOutputPeekController_1 = class TestingO
568
573
  }
569
574
  if (parts.type === 1 ) {
570
575
  const test = result.getStateById(parts.testExtId);
571
- const task = result.tasks[parts.taskIndex];
572
- if (!test || !task) {
576
+ if (!test) {
573
577
  return;
574
578
  }
575
- return ( new TestOutputSubject(result, parts.taskIndex, task, test));
579
+ return ( new TestOutputSubject(result, parts.taskIndex, test));
576
580
  }
577
581
  const { testExtId, taskIndex, messageIndex } = parts;
578
582
  const test = result?.getStateById(testExtId);
@@ -710,6 +714,7 @@ let TestResultsPeek = class TestResultsPeek extends PeekViewWidget {
710
714
  static { TestResultsPeek_1 = this; }
711
715
  constructor(editor, themeService, peekViewService, testingPeek, contextKeyService, menuService, instantiationService, modelService) {
712
716
  super(editor, { showFrame: true, frameWidth: 1, showArrow: true, isResizeable: true, isAccessible: true, className: 'test-output-peek' }, instantiationService);
717
+ this.themeService = themeService;
713
718
  this.testingPeek = testingPeek;
714
719
  this.contextKeyService = contextKeyService;
715
720
  this.menuService = menuService;
@@ -717,16 +722,18 @@ let TestResultsPeek = class TestResultsPeek extends PeekViewWidget {
717
722
  this.visibilityChange = this._disposables.add(( new Emitter()));
718
723
  this._disposables.add(themeService.onDidColorThemeChange(this.applyTheme, this));
719
724
  this._disposables.add(this.onDidClose(() => this.visibilityChange.fire(false)));
720
- this.applyTheme(themeService.getColorTheme());
721
725
  peekViewService.addExclusiveWidget(editor, this);
722
726
  }
723
- applyTheme(theme) {
724
- const borderColor = theme.getColor(testingPeekBorder) || Color.transparent;
725
- const headerBg = theme.getColor(testingPeekHeaderBackground) || Color.transparent;
727
+ applyTheme() {
728
+ const theme = this.themeService.getColorTheme();
729
+ const isError = this.current instanceof MessageSubject && this.current.message.type === 0 ;
730
+ const borderColor = (isError ? theme.getColor(testingPeekBorder) : theme.getColor(testingMessagePeekBorder)) || Color.transparent;
731
+ const headerBg = (isError ? theme.getColor(testingPeekHeaderBackground) : theme.getColor(testingPeekMessageHeaderBackground)) || Color.transparent;
732
+ const editorBg = theme.getColor(editorBackground);
726
733
  this.style({
727
734
  arrowColor: borderColor,
728
735
  frameColor: borderColor,
729
- headerBackgroundColor: headerBg,
736
+ headerBackgroundColor: editorBg && headerBg ? headerBg.makeOpaque(editorBg) : headerBg,
730
737
  primaryHeadingColor: theme.getColor(peekViewTitleForeground),
731
738
  secondaryHeadingColor: theme.getColor(peekViewTitleInfoForeground)
732
739
  });
@@ -771,7 +778,8 @@ let TestResultsPeek = class TestResultsPeek extends PeekViewWidget {
771
778
  return this.showInPlace(subject);
772
779
  }
773
780
  this.show(subject.revealLocation.range, TestResultsPeek_1.lastHeightInLines || hintMessagePeekHeight(message));
774
- this.editor.revealPositionNearTop(subject.revealLocation.range.getStartPosition(), 0 );
781
+ const startPosition = subject.revealLocation.range.getStartPosition();
782
+ this.editor.revealRangeNearTopIfOutsideViewport(Range.fromPositions(startPosition), 0 );
775
783
  return this.showInPlace(subject);
776
784
  }
777
785
  async showInPlace(subject) {
@@ -786,6 +794,7 @@ let TestResultsPeek = class TestResultsPeek extends PeekViewWidget {
786
794
  'Test Output'
787
795
  )));
788
796
  }
797
+ this.applyTheme();
789
798
  await this.content.reveal({ subject: subject, preserveFocus: false });
790
799
  }
791
800
  _relayout(newHeightInLines) {
@@ -833,6 +842,9 @@ let TestResultsView = class TestResultsView extends ViewPane {
833
842
  }
834
843
  this.content.reveal({ preserveFocus, subject: ( new TaskSubject(result, 0)) });
835
844
  }
845
+ showMessage(result, test, taskIndex, messageIndex) {
846
+ this.content.reveal({ preserveFocus: false, subject: ( new MessageSubject(result, test, taskIndex, messageIndex)) });
847
+ }
836
848
  renderBody(container) {
837
849
  super.renderBody(container);
838
850
  this.content.fillBody(container);
@@ -1113,6 +1125,11 @@ let TerminalMessagePeek = class TerminalMessagePeek extends Disposable {
1113
1125
  const testItem = subject instanceof TestOutputSubject ? subject.test.item : subject.test;
1114
1126
  const terminal = await this.updateGenerically({
1115
1127
  subject,
1128
+ noOutputMessage: ( localizeWithPath(
1129
+ 'vs/workbench/contrib/testing/browser/testingOutputPeek',
1130
+ 'caseNoOutput',
1131
+ 'The test case did not report any output.'
1132
+ )),
1116
1133
  getTarget: result => result?.tasks[subject.taskIndex].output,
1117
1134
  *doInitialWrite(output, results) {
1118
1135
  that.updateCwd(testItem.uri);
@@ -1126,10 +1143,10 @@ let TerminalMessagePeek = class TerminalMessagePeek extends Disposable {
1126
1143
  }
1127
1144
  }
1128
1145
  },
1129
- doListenForMoreData: (output, result, { xterm }) => result.onChange(e => {
1146
+ doListenForMoreData: (output, result, write) => result.onChange(e => {
1130
1147
  if (e.reason === 2 && e.item.item.extId === testItem.extId && e.message.type === 1 ) {
1131
1148
  for (const chunk of output.getRangeIter(e.message.offset, e.message.length)) {
1132
- xterm.write(chunk.buffer);
1149
+ write(chunk.buffer);
1133
1150
  }
1134
1151
  }
1135
1152
  }),
@@ -1141,12 +1158,17 @@ let TerminalMessagePeek = class TerminalMessagePeek extends Disposable {
1141
1158
  updateForTaskSubject(subject) {
1142
1159
  return this.updateGenerically({
1143
1160
  subject,
1161
+ noOutputMessage: ( localizeWithPath(
1162
+ 'vs/workbench/contrib/testing/browser/testingOutputPeek',
1163
+ 'runNoOutput',
1164
+ 'The test run did not record any output.'
1165
+ )),
1144
1166
  getTarget: result => result?.tasks[subject.taskIndex],
1145
1167
  doInitialWrite: (task, result) => {
1146
1168
  this.updateCwd(Iterable.find(result.tests, t => !!t.item.uri)?.item.uri);
1147
1169
  return task.output.buffers;
1148
1170
  },
1149
- doListenForMoreData: (task, _result, { xterm }) => task.output.onDidWriteData(e => xterm.write(e.buffer)),
1171
+ doListenForMoreData: (task, _result, write) => task.output.onDidWriteData(e => write(e.buffer)),
1150
1172
  });
1151
1173
  }
1152
1174
  async updateGenerically(opts) {
@@ -1174,13 +1196,21 @@ let TerminalMessagePeek = class TerminalMessagePeek extends Disposable {
1174
1196
  )));
1175
1197
  }
1176
1198
  this.attachTerminalToDom(terminal);
1177
- this.outputDataListener.value = result instanceof LiveTestResult ? opts.doListenForMoreData(target, result, terminal) : undefined;
1199
+ this.outputDataListener.clear();
1200
+ if (result instanceof LiveTestResult && !result.completedAt) {
1201
+ const l1 = result.onComplete(() => {
1202
+ if (!didWriteData) {
1203
+ this.writeNotice(terminal, opts.noOutputMessage);
1204
+ }
1205
+ });
1206
+ const l2 = opts.doListenForMoreData(target, result, data => {
1207
+ terminal.xterm.write(data);
1208
+ didWriteData ||= data.byteLength > 0;
1209
+ });
1210
+ this.outputDataListener.value = combinedDisposable(l1, l2);
1211
+ }
1178
1212
  if (!this.outputDataListener.value && !didWriteData) {
1179
- this.writeNotice(terminal, ( localizeWithPath(
1180
- 'vs/workbench/contrib/testing/browser/testingOutputPeek',
1181
- 'runNoOutput',
1182
- 'The test run did not record any output.'
1183
- )));
1213
+ this.writeNotice(terminal, opts.noOutputMessage);
1184
1214
  }
1185
1215
  if (pendingWrites.value > 0) {
1186
1216
  await ( new Promise(resolve => {
@@ -1320,7 +1350,7 @@ class CoverageElement {
1320
1350
  return this.isOpen ? closeCoverageLabel : openCoverageLabel;
1321
1351
  }
1322
1352
  get icon() {
1323
- return this.isOpen ? widgetClose : testingCoverage;
1353
+ return this.isOpen ? widgetClose : testingCoverageReport;
1324
1354
  }
1325
1355
  get isOpen() {
1326
1356
  return this.coverageService.selected.get()?.fromTaskId === this.task.id;
@@ -1354,11 +1384,10 @@ class TestCaseElement {
1354
1384
  return testingStatesToIcons.get(this.state);
1355
1385
  }
1356
1386
  get outputSubject() {
1357
- return ( new TestOutputSubject(this.results, this.taskIndex, this.task, this.test));
1387
+ return ( new TestOutputSubject(this.results, this.taskIndex, this.test));
1358
1388
  }
1359
- constructor(results, task, test, taskIndex) {
1389
+ constructor(results, test, taskIndex) {
1360
1390
  this.results = results;
1361
- this.task = task;
1362
1391
  this.test = test;
1363
1392
  this.taskIndex = taskIndex;
1364
1393
  this.type = 'test';
@@ -1484,7 +1513,7 @@ let OutputPeekTree = class OutputPeekTree extends Disposable {
1484
1513
  const { results, index, itemsCache, task } = taskElem;
1485
1514
  const tests = Iterable.filter(results.tests, test => test.tasks[index].state >= 2 || test.tasks[index].messages.length > 0);
1486
1515
  let result = ( Iterable.map(tests, test => ({
1487
- element: itemsCache.getOrCreate(test, () => ( new TestCaseElement(results, task, test, index))),
1516
+ element: itemsCache.getOrCreate(test, () => ( new TestCaseElement(results, test, index))),
1488
1517
  incompressible: true,
1489
1518
  children: getTestChildren(results, test, index),
1490
1519
  })));
@@ -1643,6 +1672,11 @@ let OutputPeekTree = class OutputPeekTree extends Disposable {
1643
1672
  e.element.messageIndex
1644
1673
  )));
1645
1674
  }
1675
+ else if (e.element instanceof TestCaseElement) {
1676
+ const t = e.element;
1677
+ const message = mapFindTestMessage(e.element.test, (_t, _m, mesasgeIndex, taskIndex) => ( new MessageSubject(t.results, t.test, taskIndex, mesasgeIndex)));
1678
+ this.requestReveal.fire(message || ( new TestOutputSubject(t.results, 0, t.test)));
1679
+ }
1646
1680
  else if (e.element instanceof CoverageElement) {
1647
1681
  const task = e.element.task;
1648
1682
  if (e.element.isOpen) {
@@ -1914,11 +1948,11 @@ class GoToNextMessageAction extends Action2 {
1914
1948
  super({
1915
1949
  id: GoToNextMessageAction.ID,
1916
1950
  f1: true,
1917
- title: { value: ( localizeWithPath(
1951
+ title: ( localize2WithPath(
1918
1952
  'vs/workbench/contrib/testing/browser/testingOutputPeek',
1919
1953
  'testing.goToNextMessage',
1920
- "Go to Next Test Failure"
1921
- )), original: 'Go to Next Test Failure' },
1954
+ 'Go to Next Test Failure'
1955
+ )),
1922
1956
  icon: Codicon.arrowDown,
1923
1957
  category: Categories.Test,
1924
1958
  keybinding: {
@@ -1949,11 +1983,11 @@ class GoToPreviousMessageAction extends Action2 {
1949
1983
  super({
1950
1984
  id: GoToPreviousMessageAction.ID,
1951
1985
  f1: true,
1952
- title: { value: ( localizeWithPath(
1986
+ title: ( localize2WithPath(
1953
1987
  'vs/workbench/contrib/testing/browser/testingOutputPeek',
1954
1988
  'testing.goToPreviousMessage',
1955
- "Go to Previous Test Failure"
1956
- )), original: 'Go to Previous Test Failure' },
1989
+ 'Go to Previous Test Failure'
1990
+ )),
1957
1991
  icon: Codicon.arrowUp,
1958
1992
  category: Categories.Test,
1959
1993
  keybinding: {
@@ -1984,11 +2018,11 @@ class OpenMessageInEditorAction extends Action2 {
1984
2018
  super({
1985
2019
  id: OpenMessageInEditorAction.ID,
1986
2020
  f1: false,
1987
- title: { value: ( localizeWithPath(
2021
+ title: ( localize2WithPath(
1988
2022
  'vs/workbench/contrib/testing/browser/testingOutputPeek',
1989
2023
  'testing.openMessageInEditor',
1990
- "Open in Editor"
1991
- )), original: 'Open in Editor' },
2024
+ 'Open in Editor'
2025
+ )),
1992
2026
  icon: Codicon.goToFile,
1993
2027
  category: Categories.Test,
1994
2028
  menu: [{ id: MenuId.TestPeekTitle }],
@@ -2004,11 +2038,11 @@ class ToggleTestingPeekHistory extends Action2 {
2004
2038
  super({
2005
2039
  id: ToggleTestingPeekHistory.ID,
2006
2040
  f1: true,
2007
- title: { value: ( localizeWithPath(
2041
+ title: ( localize2WithPath(
2008
2042
  'vs/workbench/contrib/testing/browser/testingOutputPeek',
2009
2043
  'testing.toggleTestingPeekHistory',
2010
- "Toggle Test History in Peek"
2011
- )), original: 'Toggle Test History in Peek' },
2044
+ 'Toggle Test History in Peek'
2045
+ )),
2012
2046
  icon: Codicon.history,
2013
2047
  category: Categories.Test,
2014
2048
  menu: [{
@@ -2,7 +2,7 @@ import { __decorate, __param } from '../../../../../../../external/tslib/tslib.e
2
2
  import { Disposable, DisposableStore } from 'vscode/vscode/vs/base/common/lifecycle';
3
3
  import { localizeWithPath } from 'vscode/vscode/vs/nls';
4
4
  import { IConfigurationService } from 'vscode/vscode/vs/platform/configuration/common/configuration';
5
- import { IViewsService } from 'vscode/vscode/vs/workbench/common/views';
5
+ import { IViewsService } from 'vscode/vscode/vs/workbench/services/views/common/viewsService';
6
6
  import { getTestingConfiguration } from '../common/configuration.js';
7
7
  import { isFailedState } from 'vscode/vscode/vs/workbench/contrib/testing/common/testingStates';
8
8
  import { ITestResultService } from 'vscode/vscode/vs/workbench/contrib/testing/common/testResultService';
@@ -1,6 +1,7 @@
1
1
  import { Color, RGBA } from 'vscode/vscode/vs/base/common/color';
2
2
  import { localizeWithPath } from 'vscode/vscode/vs/nls';
3
- import { registerColor, editorErrorForeground, contrastBorder, transparent, editorForeground } from 'vscode/vscode/vs/platform/theme/common/colorRegistry';
3
+ import { registerColor, editorErrorForeground, contrastBorder, editorInfoForeground, transparent, diffInserted, chartsGreen, opaque, diffRemoved, editorBackground, chartsRed, badgeBackground, badgeForeground, editorForeground } from 'vscode/vscode/vs/platform/theme/common/colorRegistry';
4
+ import { registerThemingParticipant } from 'vscode/vscode/vs/platform/theme/common/themeService';
4
5
 
5
6
  const testingColorIconFailed = registerColor('testing.iconFailed', {
6
7
  dark: '#f14c4c',
@@ -82,6 +83,16 @@ const testingPeekBorder = registerColor('testing.peekBorder', {
82
83
  'testing.peekBorder',
83
84
  'Color of the peek view borders and arrow.'
84
85
  )));
86
+ const testingMessagePeekBorder = registerColor('testing.messagePeekBorder', {
87
+ dark: editorInfoForeground,
88
+ light: editorInfoForeground,
89
+ hcDark: contrastBorder,
90
+ hcLight: contrastBorder
91
+ }, ( localizeWithPath(
92
+ 'vs/workbench/contrib/testing/browser/theme',
93
+ 'testing.messagePeekBorder',
94
+ 'Color of the peek view borders and arrow when peeking a logged message.'
95
+ )));
85
96
  const testingPeekHeaderBackground = registerColor('testing.peekHeaderBackground', {
86
97
  dark: ( transparent(editorErrorForeground, 0.1)),
87
98
  light: ( transparent(editorErrorForeground, 0.1)),
@@ -92,6 +103,106 @@ const testingPeekHeaderBackground = registerColor('testing.peekHeaderBackground'
92
103
  'testing.peekBorder',
93
104
  'Color of the peek view borders and arrow.'
94
105
  )));
106
+ const testingPeekMessageHeaderBackground = registerColor('testing.messagePeekHeaderBackground', {
107
+ dark: ( transparent(editorInfoForeground, 0.1)),
108
+ light: ( transparent(editorInfoForeground, 0.1)),
109
+ hcDark: null,
110
+ hcLight: null
111
+ }, ( localizeWithPath(
112
+ 'vs/workbench/contrib/testing/browser/theme',
113
+ 'testing.messagePeekHeaderBackground',
114
+ 'Color of the peek view borders and arrow when peeking a logged message.'
115
+ )));
116
+ const testingCoveredBackground = registerColor('testing.coveredBackground', {
117
+ dark: diffInserted,
118
+ light: diffInserted,
119
+ hcDark: null,
120
+ hcLight: null
121
+ }, ( localizeWithPath(
122
+ 'vs/workbench/contrib/testing/browser/theme',
123
+ 'testing.coveredBackground',
124
+ 'Background color of text that was covered.'
125
+ )));
126
+ const testingCoveredBorder = registerColor('testing.coveredBorder', {
127
+ dark: ( transparent(testingCoveredBackground, 0.75)),
128
+ light: ( transparent(testingCoveredBackground, 0.75)),
129
+ hcDark: contrastBorder,
130
+ hcLight: contrastBorder
131
+ }, ( localizeWithPath(
132
+ 'vs/workbench/contrib/testing/browser/theme',
133
+ 'testing.coveredBorder',
134
+ 'Border color of text that was covered.'
135
+ )));
136
+ registerColor('testing.coveredGutterBackground', {
137
+ dark: ( transparent(diffInserted, 0.6)),
138
+ light: ( transparent(diffInserted, 0.6)),
139
+ hcDark: chartsGreen,
140
+ hcLight: chartsGreen
141
+ }, ( localizeWithPath(
142
+ 'vs/workbench/contrib/testing/browser/theme',
143
+ 'testing.coveredGutterBackground',
144
+ 'Gutter color of regions where code was covered.'
145
+ )));
146
+ registerColor('testing.uncoveredBranchBackground', {
147
+ dark: opaque(( transparent(diffRemoved, 2)), editorBackground),
148
+ light: opaque(( transparent(diffRemoved, 2)), editorBackground),
149
+ hcDark: null,
150
+ hcLight: null
151
+ }, ( localizeWithPath(
152
+ 'vs/workbench/contrib/testing/browser/theme',
153
+ 'testing.uncoveredBranchBackground',
154
+ 'Background of the widget shown for an uncovered branch.'
155
+ )));
156
+ const testingUncoveredBackground = registerColor('testing.uncoveredBackground', {
157
+ dark: diffRemoved,
158
+ light: diffRemoved,
159
+ hcDark: null,
160
+ hcLight: null
161
+ }, ( localizeWithPath(
162
+ 'vs/workbench/contrib/testing/browser/theme',
163
+ 'testing.uncoveredBackground',
164
+ 'Background color of text that was not covered.'
165
+ )));
166
+ const testingUncoveredBorder = registerColor('testing.uncoveredBorder', {
167
+ dark: ( transparent(testingUncoveredBackground, 0.75)),
168
+ light: ( transparent(testingUncoveredBackground, 0.75)),
169
+ hcDark: contrastBorder,
170
+ hcLight: contrastBorder
171
+ }, ( localizeWithPath(
172
+ 'vs/workbench/contrib/testing/browser/theme',
173
+ 'testing.uncoveredBorder',
174
+ 'Border color of text that was not covered.'
175
+ )));
176
+ registerColor('testing.uncoveredGutterBackground', {
177
+ dark: ( transparent(diffRemoved, 1.5)),
178
+ light: ( transparent(diffRemoved, 1.5)),
179
+ hcDark: chartsRed,
180
+ hcLight: chartsRed
181
+ }, ( localizeWithPath(
182
+ 'vs/workbench/contrib/testing/browser/theme',
183
+ 'testing.uncoveredGutterBackground',
184
+ 'Gutter color of regions where code not covered.'
185
+ )));
186
+ registerColor('testing.coverCountBadgeBackground', {
187
+ dark: badgeBackground,
188
+ light: badgeBackground,
189
+ hcDark: badgeBackground,
190
+ hcLight: badgeBackground
191
+ }, ( localizeWithPath(
192
+ 'vs/workbench/contrib/testing/browser/theme',
193
+ 'testing.coverCountBadgeBackground',
194
+ 'Background for the badge indicating execution count'
195
+ )));
196
+ registerColor('testing.coverCountBadgeForeground', {
197
+ dark: badgeForeground,
198
+ light: badgeForeground,
199
+ hcDark: badgeForeground,
200
+ hcLight: badgeForeground
201
+ }, ( localizeWithPath(
202
+ 'vs/workbench/contrib/testing/browser/theme',
203
+ 'testing.coverCountBadgeForeground',
204
+ 'Foreground for the badge indicating execution count'
205
+ )));
95
206
  ({
96
207
  [0 ]: {
97
208
  decorationForeground: registerColor('testing.message.error.decorationForeground', { dark: editorErrorForeground, light: editorErrorForeground, hcDark: editorForeground, hcLight: editorForeground }, ( localizeWithPath(
@@ -126,5 +237,23 @@ const testStatesToIconColors = {
126
237
  [0 ]: testingColorIconUnset,
127
238
  [5 ]: testingColorIconSkipped,
128
239
  };
240
+ registerThemingParticipant((theme, collector) => {
241
+ const editorBg = theme.getColor(editorBackground);
242
+ const missBadgeBackground = editorBg && theme.getColor(testingUncoveredBackground)?.transparent(2).makeOpaque(editorBg);
243
+ collector.addRule(`
244
+ .coverage-deco-inline.coverage-deco-hit.coverage-deco-hovered {
245
+ background: ${theme.getColor(testingCoveredBackground)?.transparent(1.3)};
246
+ outline-color: ${theme.getColor(testingCoveredBorder)?.transparent(2)};
247
+ }
248
+ .coverage-deco-inline.coverage-deco-miss.coverage-deco-hovered {
249
+ background: ${theme.getColor(testingUncoveredBackground)?.transparent(1.3)};
250
+ outline-color: ${theme.getColor(testingUncoveredBorder)?.transparent(2)};
251
+ }
252
+ .coverage-deco-branch-miss-indicator::before {
253
+ border-color: ${missBadgeBackground?.transparent(1.3)};
254
+ background-color: ${missBadgeBackground};
255
+ }
256
+ `);
257
+ });
129
258
 
130
- export { testStatesToIconColors, testingColorIconErrored, testingColorIconFailed, testingColorIconPassed, testingColorIconQueued, testingColorIconSkipped, testingColorIconUnset, testingColorRunAction, testingPeekBorder, testingPeekHeaderBackground };
259
+ export { testStatesToIconColors, testingColorIconErrored, testingColorIconFailed, testingColorIconPassed, testingColorIconQueued, testingColorIconSkipped, testingColorIconUnset, testingColorRunAction, testingCoveredBackground, testingCoveredBorder, testingMessagePeekBorder, testingPeekBorder, testingPeekHeaderBackground, testingPeekMessageHeaderBackground, testingUncoveredBackground, testingUncoveredBorder };
@@ -1,4 +1,5 @@
1
1
  import { localizeWithPath } from 'vscode/vscode/vs/nls';
2
+ import { observableFromEvent } from 'vscode/vscode/vs/base/common/observableInternal/utils';
2
3
 
3
4
  const testingConfiguration = {
4
5
  id: 'testing',
@@ -122,6 +123,7 @@ const testingConfiguration = {
122
123
  enum: [
123
124
  "run" ,
124
125
  "debug" ,
126
+ "runWithCoverage" ,
125
127
  "contextMenu" ,
126
128
  ],
127
129
  enumDescriptions: [
@@ -135,6 +137,11 @@ const testingConfiguration = {
135
137
  'testing.defaultGutterClickAction.debug',
136
138
  'Debug the test.'
137
139
  )),
140
+ ( localizeWithPath(
141
+ 'vs/workbench/contrib/testing/common/configuration',
142
+ 'testing.defaultGutterClickAction.coverage',
143
+ 'Run the test with coverage.'
144
+ )),
138
145
  ( localizeWithPath(
139
146
  'vs/workbench/contrib/testing/common/configuration',
140
147
  'testing.defaultGutterClickAction.contextMenu',
@@ -245,8 +252,22 @@ const testingConfiguration = {
245
252
  )),
246
253
  ],
247
254
  },
255
+ ["testing.coverageBarThresholds" ]: {
256
+ markdownDescription: ( localizeWithPath(
257
+ 'vs/workbench/contrib/testing/common/configuration',
258
+ 'testing.coverageBarThresholds',
259
+ "Configures the colors used for percentages in test coverage bars."
260
+ )),
261
+ default: { red: 0, yellow: 60, green: 90 },
262
+ properties: {
263
+ red: { type: 'number', minimum: 0, maximum: 100, default: 0 },
264
+ yellow: { type: 'number', minimum: 0, maximum: 100, default: 60 },
265
+ green: { type: 'number', minimum: 0, maximum: 100, default: 90 },
266
+ },
267
+ },
248
268
  }
249
269
  };
250
270
  const getTestingConfiguration = (config, key) => config.getValue(key);
271
+ const observeTestingConfiguration = (config, key) => observableFromEvent(config.onDidChangeConfiguration, () => getTestingConfiguration(config, key));
251
272
 
252
- export { getTestingConfiguration, testingConfiguration };
273
+ export { getTestingConfiguration, observeTestingConfiguration, testingConfiguration };
@@ -1,7 +1,7 @@
1
1
  import { Emitter } from 'vscode/vscode/vs/base/common/event';
2
2
  import { Iterable } from 'vscode/vscode/vs/base/common/iterator';
3
- import { AbstractIncrementalTestCollection } from 'vscode/vscode/vs/workbench/contrib/testing/common/testTypes';
4
3
  import { ResourceMap } from 'vscode/vscode/vs/base/common/map';
4
+ import { AbstractIncrementalTestCollection } from 'vscode/vscode/vs/workbench/contrib/testing/common/testTypes';
5
5
 
6
6
  class MainThreadTestCollection extends AbstractIncrementalTestCollection {
7
7
  get busyProviders() {
@@ -16,8 +16,8 @@ class MainThreadTestCollection extends AbstractIncrementalTestCollection {
16
16
  get rootIds() {
17
17
  return ( Iterable.map(( this.roots.values()), r => r.item.extId));
18
18
  }
19
- constructor(expandActual) {
20
- super();
19
+ constructor(uriIdentityService, expandActual) {
20
+ super(uriIdentityService);
21
21
  this.expandActual = expandActual;
22
22
  this.testsByUrl = ( new ResourceMap());
23
23
  this.busyProvidersChangeEmitter = ( new Emitter());
@@ -22,10 +22,12 @@ import { IEditorService } from 'vscode/vscode/vs/workbench/services/editor/commo
22
22
  import { IConfigurationService } from 'vscode/vscode/vs/platform/configuration/common/configuration';
23
23
  import { getTestingConfiguration } from './configuration.js';
24
24
  import { isDefined } from 'vscode/vscode/vs/base/common/types';
25
+ import { IUriIdentityService } from 'vscode/vscode/vs/platform/uriIdentity/common/uriIdentity';
25
26
 
26
27
  let TestService = class TestService extends Disposable {
27
- constructor(contextKeyService, instantiationService, storage, editorService, testProfiles, notificationService, configurationService, testResults, workspaceTrustRequestService) {
28
+ constructor(contextKeyService, instantiationService, uriIdentityService, storage, editorService, testProfiles, notificationService, configurationService, testResults, workspaceTrustRequestService) {
28
29
  super();
30
+ this.uriIdentityService = uriIdentityService;
29
31
  this.storage = storage;
30
32
  this.editorService = editorService;
31
33
  this.testProfiles = testProfiles;
@@ -42,7 +44,7 @@ let TestService = class TestService extends Disposable {
42
44
  this.onWillProcessDiff = this.willProcessDiffEmitter.event;
43
45
  this.onDidProcessDiff = this.didProcessDiffEmitter.event;
44
46
  this.onDidCancelTestRun = this.cancelExtensionTestRunEmitter.event;
45
- this.collection = ( new MainThreadTestCollection(this.expandTest.bind(this)));
47
+ this.collection = ( new MainThreadTestCollection(this.uriIdentityService, this.expandTest.bind(this)));
46
48
  this.showInlineOutput = MutableObservableValue.stored(this._register(( new StoredValue({
47
49
  key: 'inlineTestOutputVisible',
48
50
  scope: 1 ,
@@ -281,13 +283,14 @@ let TestService = class TestService extends Disposable {
281
283
  TestService = ( __decorate([
282
284
  ( __param(0, IContextKeyService)),
283
285
  ( __param(1, IInstantiationService)),
284
- ( __param(2, IStorageService)),
285
- ( __param(3, IEditorService)),
286
- ( __param(4, ITestProfileService)),
287
- ( __param(5, INotificationService)),
288
- ( __param(6, IConfigurationService)),
289
- ( __param(7, ITestResultService)),
290
- ( __param(8, IWorkspaceTrustRequestService))
286
+ ( __param(2, IUriIdentityService)),
287
+ ( __param(3, IStorageService)),
288
+ ( __param(4, IEditorService)),
289
+ ( __param(5, ITestProfileService)),
290
+ ( __param(6, INotificationService)),
291
+ ( __param(7, IConfigurationService)),
292
+ ( __param(8, ITestResultService)),
293
+ ( __param(9, IWorkspaceTrustRequestService))
291
294
  ], TestService));
292
295
 
293
296
  export { TestService };