aboutsummaryrefslogtreecommitdiffstats
path: root/vanilla/node_modules/vitest/dist/chunks/console.Cf-YriPC.js
blob: 0c72553385916d4484162d71221c24717687eeba (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
import { Console } from 'node:console';
import { relative } from 'node:path';
import { Writable } from 'node:stream';
import { getSafeTimers } from '@vitest/utils/timers';
import c from 'tinyrainbow';
import { R as RealDate } from './date.Bq6ZW5rf.js';
import { g as getWorkerState } from './utils.DvEY5TfP.js';

const UNKNOWN_TEST_ID = "__vitest__unknown_test__";
function getTaskIdByStack(root) {
	const stack = (/* @__PURE__ */ new Error("STACK_TRACE_ERROR")).stack?.split("\n");
	if (!stack) return UNKNOWN_TEST_ID;
	const index = stack.findIndex((line) => line.includes("at Console.value"));
	const line = index === -1 ? null : stack[index + 2];
	if (!line) return UNKNOWN_TEST_ID;
	const filepath = line.match(/at\s(.*)\s?/)?.[1];
	if (filepath) return relative(root, filepath);
	return UNKNOWN_TEST_ID;
}
function createCustomConsole(defaultState) {
	const stdoutBuffer = /* @__PURE__ */ new Map();
	const stderrBuffer = /* @__PURE__ */ new Map();
	const timers = /* @__PURE__ */ new Map();
	const { queueMicrotask } = getSafeTimers();
	function queueCancelableMicrotask(callback) {
		let canceled = false;
		queueMicrotask(() => {
			if (!canceled) callback();
		});
		return () => {
			canceled = true;
		};
	}
	const state = () => defaultState || getWorkerState();
	// group sync console.log calls with micro task
	function schedule(taskId) {
		const timer = timers.get(taskId);
		const { stdoutTime, stderrTime } = timer;
		timer.cancel?.();
		timer.cancel = queueCancelableMicrotask(() => {
			if (stderrTime < stdoutTime) {
				sendStderr(taskId);
				sendStdout(taskId);
			} else {
				sendStdout(taskId);
				sendStderr(taskId);
			}
		});
	}
	function sendStdout(taskId) {
		sendBuffer("stdout", taskId);
	}
	function sendStderr(taskId) {
		sendBuffer("stderr", taskId);
	}
	function sendBuffer(type, taskId) {
		const buffers = type === "stdout" ? stdoutBuffer : stderrBuffer;
		const buffer = buffers.get(taskId);
		if (!buffer) return;
		if (state().config.printConsoleTrace) buffer.forEach(([buffer, origin]) => {
			sendLog(type, taskId, String(buffer), buffer.length, origin);
		});
		else sendLog(type, taskId, buffer.map((i) => String(i[0])).join(""), buffer.length);
		const timer = timers.get(taskId);
		buffers.delete(taskId);
		if (type === "stderr") timer.stderrTime = 0;
		else timer.stdoutTime = 0;
	}
	function sendLog(type, taskId, content, size, origin) {
		const timer = timers.get(taskId);
		const time = type === "stderr" ? timer.stderrTime : timer.stdoutTime;
		state().rpc.onUserConsoleLog({
			type,
			content: content || "<empty line>",
			taskId,
			time: time || RealDate.now(),
			size,
			origin
		});
	}
	return new Console({
		stdout: new Writable({ write(data, encoding, callback) {
			const s = state();
			const id = s?.current?.id || s?.current?.suite?.id || s.current?.file.id || getTaskIdByStack(s.config.root);
			let timer = timers.get(id);
			if (timer) timer.stdoutTime = timer.stdoutTime || RealDate.now();
			else {
				timer = {
					stdoutTime: RealDate.now(),
					stderrTime: RealDate.now()
				};
				timers.set(id, timer);
			}
			let buffer = stdoutBuffer.get(id);
			if (!buffer) {
				buffer = [];
				stdoutBuffer.set(id, buffer);
			}
			if (state().config.printConsoleTrace) {
				const limit = Error.stackTraceLimit;
				Error.stackTraceLimit = limit + 6;
				const trace = (/* @__PURE__ */ new Error("STACK_TRACE")).stack?.split("\n").slice(7).join("\n");
				Error.stackTraceLimit = limit;
				buffer.push([data, trace]);
			} else buffer.push([data, void 0]);
			schedule(id);
			callback();
		} }),
		stderr: new Writable({ write(data, encoding, callback) {
			const s = state();
			const id = s?.current?.id || s?.current?.suite?.id || s.current?.file.id || getTaskIdByStack(s.config.root);
			let timer = timers.get(id);
			if (timer) timer.stderrTime = timer.stderrTime || RealDate.now();
			else {
				timer = {
					stderrTime: RealDate.now(),
					stdoutTime: RealDate.now()
				};
				timers.set(id, timer);
			}
			let buffer = stderrBuffer.get(id);
			if (!buffer) {
				buffer = [];
				stderrBuffer.set(id, buffer);
			}
			if (state().config.printConsoleTrace) {
				const limit = Error.stackTraceLimit;
				Error.stackTraceLimit = limit + 6;
				const stack = (/* @__PURE__ */ new Error("STACK_TRACE")).stack?.split("\n");
				Error.stackTraceLimit = limit;
				if (stack?.some((line) => line.includes("at Console.trace"))) buffer.push([data, void 0]);
				else {
					const trace = stack?.slice(7).join("\n");
					Error.stackTraceLimit = limit;
					buffer.push([data, trace]);
				}
			} else buffer.push([data, void 0]);
			schedule(id);
			callback();
		} }),
		colorMode: c.isColorSupported,
		groupIndentation: 2
	});
}

export { UNKNOWN_TEST_ID, createCustomConsole };