11<script setup lang="ts">
2- import type { Task , TestAttachment } from ' @vitest/runner'
2+ import type { Task } from ' @vitest/runner'
33import type CodeMirror from ' codemirror'
44import type { ErrorWithDiff , File , TestAnnotation , TestError } from ' vitest'
55import { createTooltip , destroyTooltip } from ' floating-vue'
6+ import { getAttachmentUrl , sanitizeFilePath } from ' ~/composables/attachments'
67import { client , isReport } from ' ~/composables/client'
78import { finished } from ' ~/composables/client/state'
89import { codemirrorRef } from ' ~/composables/codemirror'
910import { openInEditor } from ' ~/composables/error'
10- import { lineNumber } from ' ~/composables/params'
11+ import { columnNumber , lineNumber } from ' ~/composables/params'
1112
1213const props = defineProps <{
1314 file? : File
@@ -56,12 +57,12 @@ watch(
5657 { immediate: true },
5758)
5859
59- watch (() => [loading .value , saving .value , props .file , lineNumber .value ] as const , ([loadingFile , s , _ , l ]) => {
60+ watch (() => [loading .value , saving .value , props .file , lineNumber .value , columnNumber . value ] as const , ([loadingFile , s , _ , l , c ]) => {
6061 if (! loadingFile && ! s ) {
6162 if (l != null ) {
6263 nextTick (() => {
6364 const cp = currentPosition .value
64- const line = cp ?? { line: l ?? 0 , ch: 0 }
65+ const line = cp ?? { line: ( l ?? 1 ) - 1 , ch: c ?? 0 }
6566 // restore caret position: the watchDebounced below will use old value
6667 if (cp ) {
6768 currentPosition .value = undefined
@@ -155,7 +156,7 @@ function createErrorElement(e: ErrorWithDiff) {
155156 div .className = ' op80 flex gap-x-2 items-center'
156157 const pre = document .createElement (' pre' )
157158 pre .className = ' c-red-600 dark:c-red-400'
158- pre .textContent = ` ${' ' .repeat (stack .column )}^ ${e ?. nameStr || e .name }: ${
159+ pre .textContent = ` ${' ' .repeat (stack .column )}^ ${e .name }: ${
159160 e ?.message || ' '
160161 } `
161162 div .appendChild (pre )
@@ -184,7 +185,6 @@ function createErrorElement(e: ErrorWithDiff) {
184185
185186function createAnnotationElement(annotation : TestAnnotation ) {
186187 if (! annotation .location ) {
187- // TODO(v4): print unknown annotations somewhere
188188 return
189189 }
190190
@@ -222,9 +222,8 @@ function createAnnotationElement(annotation: TestAnnotation) {
222222 if (attachment .contentType ?.startsWith (' image/' )) {
223223 const link = document .createElement (' a' )
224224 const img = document .createElement (' img' )
225- img .classList .add (' mt-3' , ' inline-block' )
226- img .width = 600
227- img .width = 400
225+ link .classList .add (' inline-block' , ' mt-3' )
226+ link .style .maxWidth = ' 50vw'
228227 const potentialUrl = attachment .path || attachment .body
229228 if (typeof potentialUrl === ' string' && (potentialUrl .startsWith (' http://' ) || potentialUrl .startsWith (' https://' ))) {
230229 img .setAttribute (' src' , potentialUrl )
@@ -241,7 +240,7 @@ function createAnnotationElement(annotation: TestAnnotation) {
241240 else {
242241 const download = document .createElement (' a' )
243242 download .href = getAttachmentUrl (attachment )
244- download .download = sanitizeFilePath (annotation .message )
243+ download .download = sanitizeFilePath (annotation .message , attachment . contentType )
245244 download .classList .add (' flex' , ' w-min' , ' gap-2' , ' items-center' , ' font-sans' , ' underline' , ' cursor-pointer' )
246245 const icon = document .createElement (' div' )
247246 icon .classList .add (' i-carbon:download' , ' block' )
@@ -254,19 +253,6 @@ function createAnnotationElement(annotation: TestAnnotation) {
254253 widgets .push (codemirrorRef .value ! .addLineWidget (line - 1 , notice ))
255254}
256255
257- function getAttachmentUrl(attachment : TestAttachment ) {
258- // html reporter always saves files into /data/ folder
259- if (isReport ) {
260- return ` /data/${attachment .path } `
261- }
262- const contentType = attachment .contentType ?? ' application/octet-stream'
263- if (attachment .path ) {
264- return ` /__vitest_attachment__?path=${encodeURIComponent (attachment .path )}&contentType=${contentType }&token=${(window as any ).VITEST_API_TOKEN } `
265- }
266- // attachment.body is always a string outside of the test frame
267- return ` data:${contentType };base64,${attachment .body } `
268- }
269-
270256const { pause, resume } = watch (
271257 [codemirrorRef , errors , annotations , finished ] as const ,
272258 ([cmValue , errors , annotations , end ]) => {
@@ -389,11 +375,6 @@ async function onSave(content: string) {
389375
390376// we need to remove listeners before unmounting the component: the watcher will not be called
391377onBeforeUnmount (clearListeners )
392-
393- function sanitizeFilePath(s : string ): string {
394- // eslint-disable-next-line no-control-regex
395- return s .replace (/ [\x00 -\x2C \x2E\x2F \x3A -\x40\x5B -\x60\x7B -\x7F ] + / g , ' -' )
396- }
397378 </script >
398379
399380<template >
0 commit comments