@vitest/snapshot 1.0.0-beta.2 → 1.0.0-beta.3

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 (2) hide show
  1. package/dist/index.js +461 -432
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { plugins, format } from 'pretty-format';
2
+ import { resolve as resolve$2 } from 'pathe';
2
3
 
3
4
  function getDefaultExportFromCjs (x) {
4
5
  return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
@@ -140,8 +141,8 @@ function positionToOffset(source, lineNumber, columnNumber) {
140
141
  let start = 0;
141
142
  if (lineNumber > lines.length)
142
143
  return source.length;
143
- for (let i2 = 0; i2 < lineNumber - 1; i2++)
144
- start += lines[i2].length + nl;
144
+ for (let i = 0; i < lineNumber - 1; i++)
145
+ start += lines[i].length + nl;
145
146
  return start + columnNumber;
146
147
  }
147
148
  function offsetToLineNumber(source, offset) {
@@ -326,532 +327,558 @@ function deepMergeSnapshot(target, source) {
326
327
  return target;
327
328
  }
328
329
 
329
- function normalizeWindowsPath(input = "") {
330
- if (!input || !input.includes("\\")) {
331
- return input;
332
- }
333
- return input.replace(/\\/g, "/");
334
- }
335
- const _IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Za-z]:[/\\]/;
336
- function cwd() {
337
- if (typeof process !== "undefined") {
338
- return process.cwd().replace(/\\/g, "/");
339
- }
340
- return "/";
341
- }
342
- const resolve$2 = function(...arguments_) {
343
- arguments_ = arguments_.map((argument) => normalizeWindowsPath(argument));
344
- let resolvedPath = "";
345
- let resolvedAbsolute = false;
346
- for (let index = arguments_.length - 1; index >= -1 && !resolvedAbsolute; index--) {
347
- const path = index >= 0 ? arguments_[index] : cwd();
348
- if (!path || path.length === 0) {
349
- continue;
350
- }
351
- resolvedPath = `${path}/${resolvedPath}`;
352
- resolvedAbsolute = isAbsolute(path);
353
- }
354
- resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute);
355
- if (resolvedAbsolute && !isAbsolute(resolvedPath)) {
356
- return `/${resolvedPath}`;
357
- }
358
- return resolvedPath.length > 0 ? resolvedPath : ".";
359
- };
360
- function normalizeString(path, allowAboveRoot) {
361
- let res = "";
362
- let lastSegmentLength = 0;
363
- let lastSlash = -1;
364
- let dots = 0;
365
- let char = null;
366
- for (let index = 0; index <= path.length; ++index) {
367
- if (index < path.length) {
368
- char = path[index];
369
- } else if (char === "/") {
370
- break;
371
- } else {
372
- char = "/";
373
- }
374
- if (char === "/") {
375
- if (lastSlash === index - 1 || dots === 1)
376
- ;
377
- else if (dots === 2) {
378
- if (res.length < 2 || lastSegmentLength !== 2 || res[res.length - 1] !== "." || res[res.length - 2] !== ".") {
379
- if (res.length > 2) {
380
- const lastSlashIndex = res.lastIndexOf("/");
381
- if (lastSlashIndex === -1) {
382
- res = "";
383
- lastSegmentLength = 0;
384
- } else {
385
- res = res.slice(0, lastSlashIndex);
386
- lastSegmentLength = res.length - 1 - res.lastIndexOf("/");
387
- }
388
- lastSlash = index;
389
- dots = 0;
390
- continue;
391
- } else if (res.length > 0) {
392
- res = "";
393
- lastSegmentLength = 0;
394
- lastSlash = index;
395
- dots = 0;
396
- continue;
397
- }
398
- }
399
- if (allowAboveRoot) {
400
- res += res.length > 0 ? "/.." : "..";
401
- lastSegmentLength = 2;
402
- }
403
- } else {
404
- if (res.length > 0) {
405
- res += `/${path.slice(lastSlash + 1, index)}`;
406
- } else {
407
- res = path.slice(lastSlash + 1, index);
408
- }
409
- lastSegmentLength = index - lastSlash - 1;
410
- }
411
- lastSlash = index;
412
- dots = 0;
413
- } else if (char === "." && dots !== -1) {
414
- ++dots;
415
- } else {
416
- dots = -1;
417
- }
418
- }
419
- return res;
420
- }
421
- const isAbsolute = function(p) {
422
- return _IS_ABSOLUTE_RE.test(p);
423
- };
424
- const comma = ",".charCodeAt(0);
425
- const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
426
- const intToChar = new Uint8Array(64);
427
- const charToInt = new Uint8Array(128);
330
+ const comma = ','.charCodeAt(0);
331
+ const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
332
+ const intToChar = new Uint8Array(64); // 64 possible chars.
333
+ const charToInt = new Uint8Array(128); // z is 122 in ASCII
428
334
  for (let i = 0; i < chars.length; i++) {
429
- const c = chars.charCodeAt(i);
430
- intToChar[i] = c;
431
- charToInt[c] = i;
335
+ const c = chars.charCodeAt(i);
336
+ intToChar[i] = c;
337
+ charToInt[c] = i;
432
338
  }
433
339
  function decode(mappings) {
434
- const state = new Int32Array(5);
435
- const decoded = [];
436
- let index = 0;
437
- do {
438
- const semi = indexOf(mappings, index);
439
- const line = [];
440
- let sorted = true;
441
- let lastCol = 0;
442
- state[0] = 0;
443
- for (let i = index; i < semi; i++) {
444
- let seg;
445
- i = decodeInteger(mappings, i, state, 0);
446
- const col = state[0];
447
- if (col < lastCol)
448
- sorted = false;
449
- lastCol = col;
450
- if (hasMoreVlq(mappings, i, semi)) {
451
- i = decodeInteger(mappings, i, state, 1);
452
- i = decodeInteger(mappings, i, state, 2);
453
- i = decodeInteger(mappings, i, state, 3);
454
- if (hasMoreVlq(mappings, i, semi)) {
455
- i = decodeInteger(mappings, i, state, 4);
456
- seg = [col, state[1], state[2], state[3], state[4]];
457
- } else {
458
- seg = [col, state[1], state[2], state[3]];
340
+ const state = new Int32Array(5);
341
+ const decoded = [];
342
+ let index = 0;
343
+ do {
344
+ const semi = indexOf(mappings, index);
345
+ const line = [];
346
+ let sorted = true;
347
+ let lastCol = 0;
348
+ state[0] = 0;
349
+ for (let i = index; i < semi; i++) {
350
+ let seg;
351
+ i = decodeInteger(mappings, i, state, 0); // genColumn
352
+ const col = state[0];
353
+ if (col < lastCol)
354
+ sorted = false;
355
+ lastCol = col;
356
+ if (hasMoreVlq(mappings, i, semi)) {
357
+ i = decodeInteger(mappings, i, state, 1); // sourcesIndex
358
+ i = decodeInteger(mappings, i, state, 2); // sourceLine
359
+ i = decodeInteger(mappings, i, state, 3); // sourceColumn
360
+ if (hasMoreVlq(mappings, i, semi)) {
361
+ i = decodeInteger(mappings, i, state, 4); // namesIndex
362
+ seg = [col, state[1], state[2], state[3], state[4]];
363
+ }
364
+ else {
365
+ seg = [col, state[1], state[2], state[3]];
366
+ }
367
+ }
368
+ else {
369
+ seg = [col];
370
+ }
371
+ line.push(seg);
459
372
  }
460
- } else {
461
- seg = [col];
462
- }
463
- line.push(seg);
464
- }
465
- if (!sorted)
466
- sort(line);
467
- decoded.push(line);
468
- index = semi + 1;
469
- } while (index <= mappings.length);
470
- return decoded;
373
+ if (!sorted)
374
+ sort(line);
375
+ decoded.push(line);
376
+ index = semi + 1;
377
+ } while (index <= mappings.length);
378
+ return decoded;
471
379
  }
472
380
  function indexOf(mappings, index) {
473
- const idx = mappings.indexOf(";", index);
474
- return idx === -1 ? mappings.length : idx;
381
+ const idx = mappings.indexOf(';', index);
382
+ return idx === -1 ? mappings.length : idx;
475
383
  }
476
384
  function decodeInteger(mappings, pos, state, j) {
477
- let value = 0;
478
- let shift = 0;
479
- let integer = 0;
480
- do {
481
- const c = mappings.charCodeAt(pos++);
482
- integer = charToInt[c];
483
- value |= (integer & 31) << shift;
484
- shift += 5;
485
- } while (integer & 32);
486
- const shouldNegate = value & 1;
487
- value >>>= 1;
488
- if (shouldNegate) {
489
- value = -2147483648 | -value;
490
- }
491
- state[j] += value;
492
- return pos;
385
+ let value = 0;
386
+ let shift = 0;
387
+ let integer = 0;
388
+ do {
389
+ const c = mappings.charCodeAt(pos++);
390
+ integer = charToInt[c];
391
+ value |= (integer & 31) << shift;
392
+ shift += 5;
393
+ } while (integer & 32);
394
+ const shouldNegate = value & 1;
395
+ value >>>= 1;
396
+ if (shouldNegate) {
397
+ value = -0x80000000 | -value;
398
+ }
399
+ state[j] += value;
400
+ return pos;
493
401
  }
494
402
  function hasMoreVlq(mappings, i, length) {
495
- if (i >= length)
496
- return false;
497
- return mappings.charCodeAt(i) !== comma;
403
+ if (i >= length)
404
+ return false;
405
+ return mappings.charCodeAt(i) !== comma;
498
406
  }
499
407
  function sort(line) {
500
- line.sort(sortComparator$1);
408
+ line.sort(sortComparator$1);
501
409
  }
502
410
  function sortComparator$1(a, b) {
503
- return a[0] - b[0];
411
+ return a[0] - b[0];
504
412
  }
413
+
414
+ // Matches the scheme of a URL, eg "http://"
505
415
  const schemeRegex = /^[\w+.-]+:\/\//;
416
+ /**
417
+ * Matches the parts of a URL:
418
+ * 1. Scheme, including ":", guaranteed.
419
+ * 2. User/password, including "@", optional.
420
+ * 3. Host, guaranteed.
421
+ * 4. Port, including ":", optional.
422
+ * 5. Path, including "/", optional.
423
+ * 6. Query, including "?", optional.
424
+ * 7. Hash, including "#", optional.
425
+ */
506
426
  const urlRegex = /^([\w+.-]+:)\/\/([^@/#?]*@)?([^:/#?]*)(:\d+)?(\/[^#?]*)?(\?[^#]*)?(#.*)?/;
427
+ /**
428
+ * File URLs are weird. They dont' need the regular `//` in the scheme, they may or may not start
429
+ * with a leading `/`, they can have a domain (but only if they don't start with a Windows drive).
430
+ *
431
+ * 1. Host, optional.
432
+ * 2. Path, which may include "/", guaranteed.
433
+ * 3. Query, including "?", optional.
434
+ * 4. Hash, including "#", optional.
435
+ */
507
436
  const fileRegex = /^file:(?:\/\/((?![a-z]:)[^/#?]*)?)?(\/?[^#?]*)(\?[^#]*)?(#.*)?/i;
508
437
  var UrlType;
509
- (function(UrlType2) {
510
- UrlType2[UrlType2["Empty"] = 1] = "Empty";
511
- UrlType2[UrlType2["Hash"] = 2] = "Hash";
512
- UrlType2[UrlType2["Query"] = 3] = "Query";
513
- UrlType2[UrlType2["RelativePath"] = 4] = "RelativePath";
514
- UrlType2[UrlType2["AbsolutePath"] = 5] = "AbsolutePath";
515
- UrlType2[UrlType2["SchemeRelative"] = 6] = "SchemeRelative";
516
- UrlType2[UrlType2["Absolute"] = 7] = "Absolute";
438
+ (function (UrlType) {
439
+ UrlType[UrlType["Empty"] = 1] = "Empty";
440
+ UrlType[UrlType["Hash"] = 2] = "Hash";
441
+ UrlType[UrlType["Query"] = 3] = "Query";
442
+ UrlType[UrlType["RelativePath"] = 4] = "RelativePath";
443
+ UrlType[UrlType["AbsolutePath"] = 5] = "AbsolutePath";
444
+ UrlType[UrlType["SchemeRelative"] = 6] = "SchemeRelative";
445
+ UrlType[UrlType["Absolute"] = 7] = "Absolute";
517
446
  })(UrlType || (UrlType = {}));
518
447
  function isAbsoluteUrl(input) {
519
- return schemeRegex.test(input);
448
+ return schemeRegex.test(input);
520
449
  }
521
450
  function isSchemeRelativeUrl(input) {
522
- return input.startsWith("//");
451
+ return input.startsWith('//');
523
452
  }
524
453
  function isAbsolutePath(input) {
525
- return input.startsWith("/");
454
+ return input.startsWith('/');
526
455
  }
527
456
  function isFileUrl(input) {
528
- return input.startsWith("file:");
457
+ return input.startsWith('file:');
529
458
  }
530
459
  function isRelative(input) {
531
- return /^[.?#]/.test(input);
460
+ return /^[.?#]/.test(input);
532
461
  }
533
462
  function parseAbsoluteUrl(input) {
534
- const match = urlRegex.exec(input);
535
- return makeUrl(match[1], match[2] || "", match[3], match[4] || "", match[5] || "/", match[6] || "", match[7] || "");
463
+ const match = urlRegex.exec(input);
464
+ return makeUrl(match[1], match[2] || '', match[3], match[4] || '', match[5] || '/', match[6] || '', match[7] || '');
536
465
  }
537
466
  function parseFileUrl(input) {
538
- const match = fileRegex.exec(input);
539
- const path = match[2];
540
- return makeUrl("file:", "", match[1] || "", "", isAbsolutePath(path) ? path : "/" + path, match[3] || "", match[4] || "");
467
+ const match = fileRegex.exec(input);
468
+ const path = match[2];
469
+ return makeUrl('file:', '', match[1] || '', '', isAbsolutePath(path) ? path : '/' + path, match[3] || '', match[4] || '');
541
470
  }
542
471
  function makeUrl(scheme, user, host, port, path, query, hash) {
543
- return {
544
- scheme,
545
- user,
546
- host,
547
- port,
548
- path,
549
- query,
550
- hash,
551
- type: UrlType.Absolute
552
- };
472
+ return {
473
+ scheme,
474
+ user,
475
+ host,
476
+ port,
477
+ path,
478
+ query,
479
+ hash,
480
+ type: UrlType.Absolute,
481
+ };
553
482
  }
554
483
  function parseUrl(input) {
555
- if (isSchemeRelativeUrl(input)) {
556
- const url2 = parseAbsoluteUrl("http:" + input);
557
- url2.scheme = "";
558
- url2.type = UrlType.SchemeRelative;
559
- return url2;
560
- }
561
- if (isAbsolutePath(input)) {
562
- const url2 = parseAbsoluteUrl("http://foo.com" + input);
563
- url2.scheme = "";
564
- url2.host = "";
565
- url2.type = UrlType.AbsolutePath;
566
- return url2;
567
- }
568
- if (isFileUrl(input))
569
- return parseFileUrl(input);
570
- if (isAbsoluteUrl(input))
571
- return parseAbsoluteUrl(input);
572
- const url = parseAbsoluteUrl("http://foo.com/" + input);
573
- url.scheme = "";
574
- url.host = "";
575
- url.type = input ? input.startsWith("?") ? UrlType.Query : input.startsWith("#") ? UrlType.Hash : UrlType.RelativePath : UrlType.Empty;
576
- return url;
484
+ if (isSchemeRelativeUrl(input)) {
485
+ const url = parseAbsoluteUrl('http:' + input);
486
+ url.scheme = '';
487
+ url.type = UrlType.SchemeRelative;
488
+ return url;
489
+ }
490
+ if (isAbsolutePath(input)) {
491
+ const url = parseAbsoluteUrl('http://foo.com' + input);
492
+ url.scheme = '';
493
+ url.host = '';
494
+ url.type = UrlType.AbsolutePath;
495
+ return url;
496
+ }
497
+ if (isFileUrl(input))
498
+ return parseFileUrl(input);
499
+ if (isAbsoluteUrl(input))
500
+ return parseAbsoluteUrl(input);
501
+ const url = parseAbsoluteUrl('http://foo.com/' + input);
502
+ url.scheme = '';
503
+ url.host = '';
504
+ url.type = input
505
+ ? input.startsWith('?')
506
+ ? UrlType.Query
507
+ : input.startsWith('#')
508
+ ? UrlType.Hash
509
+ : UrlType.RelativePath
510
+ : UrlType.Empty;
511
+ return url;
577
512
  }
578
513
  function stripPathFilename(path) {
579
- if (path.endsWith("/.."))
580
- return path;
581
- const index = path.lastIndexOf("/");
582
- return path.slice(0, index + 1);
514
+ // If a path ends with a parent directory "..", then it's a relative path with excess parent
515
+ // paths. It's not a file, so we can't strip it.
516
+ if (path.endsWith('/..'))
517
+ return path;
518
+ const index = path.lastIndexOf('/');
519
+ return path.slice(0, index + 1);
583
520
  }
584
521
  function mergePaths(url, base) {
585
- normalizePath(base, base.type);
586
- if (url.path === "/") {
587
- url.path = base.path;
588
- } else {
589
- url.path = stripPathFilename(base.path) + url.path;
590
- }
522
+ normalizePath(base, base.type);
523
+ // If the path is just a "/", then it was an empty path to begin with (remember, we're a relative
524
+ // path).
525
+ if (url.path === '/') {
526
+ url.path = base.path;
527
+ }
528
+ else {
529
+ // Resolution happens relative to the base path's directory, not the file.
530
+ url.path = stripPathFilename(base.path) + url.path;
531
+ }
591
532
  }
533
+ /**
534
+ * The path can have empty directories "//", unneeded parents "foo/..", or current directory
535
+ * "foo/.". We need to normalize to a standard representation.
536
+ */
592
537
  function normalizePath(url, type) {
593
- const rel = type <= UrlType.RelativePath;
594
- const pieces = url.path.split("/");
595
- let pointer = 1;
596
- let positive = 0;
597
- let addTrailingSlash = false;
598
- for (let i = 1; i < pieces.length; i++) {
599
- const piece = pieces[i];
600
- if (!piece) {
601
- addTrailingSlash = true;
602
- continue;
603
- }
604
- addTrailingSlash = false;
605
- if (piece === ".")
606
- continue;
607
- if (piece === "..") {
608
- if (positive) {
609
- addTrailingSlash = true;
610
- positive--;
611
- pointer--;
612
- } else if (rel) {
538
+ const rel = type <= UrlType.RelativePath;
539
+ const pieces = url.path.split('/');
540
+ // We need to preserve the first piece always, so that we output a leading slash. The item at
541
+ // pieces[0] is an empty string.
542
+ let pointer = 1;
543
+ // Positive is the number of real directories we've output, used for popping a parent directory.
544
+ // Eg, "foo/bar/.." will have a positive 2, and we can decrement to be left with just "foo".
545
+ let positive = 0;
546
+ // We need to keep a trailing slash if we encounter an empty directory (eg, splitting "foo/" will
547
+ // generate `["foo", ""]` pieces). And, if we pop a parent directory. But once we encounter a
548
+ // real directory, we won't need to append, unless the other conditions happen again.
549
+ let addTrailingSlash = false;
550
+ for (let i = 1; i < pieces.length; i++) {
551
+ const piece = pieces[i];
552
+ // An empty directory, could be a trailing slash, or just a double "//" in the path.
553
+ if (!piece) {
554
+ addTrailingSlash = true;
555
+ continue;
556
+ }
557
+ // If we encounter a real directory, then we don't need to append anymore.
558
+ addTrailingSlash = false;
559
+ // A current directory, which we can always drop.
560
+ if (piece === '.')
561
+ continue;
562
+ // A parent directory, we need to see if there are any real directories we can pop. Else, we
563
+ // have an excess of parents, and we'll need to keep the "..".
564
+ if (piece === '..') {
565
+ if (positive) {
566
+ addTrailingSlash = true;
567
+ positive--;
568
+ pointer--;
569
+ }
570
+ else if (rel) {
571
+ // If we're in a relativePath, then we need to keep the excess parents. Else, in an absolute
572
+ // URL, protocol relative URL, or an absolute path, we don't need to keep excess.
573
+ pieces[pointer++] = piece;
574
+ }
575
+ continue;
576
+ }
577
+ // We've encountered a real directory. Move it to the next insertion pointer, which accounts for
578
+ // any popped or dropped directories.
613
579
  pieces[pointer++] = piece;
614
- }
615
- continue;
580
+ positive++;
616
581
  }
617
- pieces[pointer++] = piece;
618
- positive++;
619
- }
620
- let path = "";
621
- for (let i = 1; i < pointer; i++) {
622
- path += "/" + pieces[i];
623
- }
624
- if (!path || addTrailingSlash && !path.endsWith("/..")) {
625
- path += "/";
626
- }
627
- url.path = path;
582
+ let path = '';
583
+ for (let i = 1; i < pointer; i++) {
584
+ path += '/' + pieces[i];
585
+ }
586
+ if (!path || (addTrailingSlash && !path.endsWith('/..'))) {
587
+ path += '/';
588
+ }
589
+ url.path = path;
628
590
  }
591
+ /**
592
+ * Attempts to resolve `input` URL/path relative to `base`.
593
+ */
629
594
  function resolve$1(input, base) {
630
- if (!input && !base)
631
- return "";
632
- const url = parseUrl(input);
633
- let inputType = url.type;
634
- if (base && inputType !== UrlType.Absolute) {
635
- const baseUrl = parseUrl(base);
636
- const baseType = baseUrl.type;
637
- switch (inputType) {
638
- case UrlType.Empty:
639
- url.hash = baseUrl.hash;
640
- case UrlType.Hash:
641
- url.query = baseUrl.query;
642
- case UrlType.Query:
643
- case UrlType.RelativePath:
644
- mergePaths(url, baseUrl);
645
- case UrlType.AbsolutePath:
646
- url.user = baseUrl.user;
647
- url.host = baseUrl.host;
648
- url.port = baseUrl.port;
649
- case UrlType.SchemeRelative:
650
- url.scheme = baseUrl.scheme;
595
+ if (!input && !base)
596
+ return '';
597
+ const url = parseUrl(input);
598
+ let inputType = url.type;
599
+ if (base && inputType !== UrlType.Absolute) {
600
+ const baseUrl = parseUrl(base);
601
+ const baseType = baseUrl.type;
602
+ switch (inputType) {
603
+ case UrlType.Empty:
604
+ url.hash = baseUrl.hash;
605
+ // fall through
606
+ case UrlType.Hash:
607
+ url.query = baseUrl.query;
608
+ // fall through
609
+ case UrlType.Query:
610
+ case UrlType.RelativePath:
611
+ mergePaths(url, baseUrl);
612
+ // fall through
613
+ case UrlType.AbsolutePath:
614
+ // The host, user, and port are joined, you can't copy one without the others.
615
+ url.user = baseUrl.user;
616
+ url.host = baseUrl.host;
617
+ url.port = baseUrl.port;
618
+ // fall through
619
+ case UrlType.SchemeRelative:
620
+ // The input doesn't have a schema at least, so we need to copy at least that over.
621
+ url.scheme = baseUrl.scheme;
622
+ }
623
+ if (baseType > inputType)
624
+ inputType = baseType;
651
625
  }
652
- if (baseType > inputType)
653
- inputType = baseType;
654
- }
655
- normalizePath(url, inputType);
656
- const queryHash = url.query + url.hash;
657
- switch (inputType) {
658
- case UrlType.Hash:
659
- case UrlType.Query:
660
- return queryHash;
661
- case UrlType.RelativePath: {
662
- const path = url.path.slice(1);
663
- if (!path)
664
- return queryHash || ".";
665
- if (isRelative(base || input) && !isRelative(path)) {
666
- return "./" + path + queryHash;
667
- }
668
- return path + queryHash;
626
+ normalizePath(url, inputType);
627
+ const queryHash = url.query + url.hash;
628
+ switch (inputType) {
629
+ // This is impossible, because of the empty checks at the start of the function.
630
+ // case UrlType.Empty:
631
+ case UrlType.Hash:
632
+ case UrlType.Query:
633
+ return queryHash;
634
+ case UrlType.RelativePath: {
635
+ // The first char is always a "/", and we need it to be relative.
636
+ const path = url.path.slice(1);
637
+ if (!path)
638
+ return queryHash || '.';
639
+ if (isRelative(base || input) && !isRelative(path)) {
640
+ // If base started with a leading ".", or there is no base and input started with a ".",
641
+ // then we need to ensure that the relative path starts with a ".". We don't know if
642
+ // relative starts with a "..", though, so check before prepending.
643
+ return './' + path + queryHash;
644
+ }
645
+ return path + queryHash;
646
+ }
647
+ case UrlType.AbsolutePath:
648
+ return url.path + queryHash;
649
+ default:
650
+ return url.scheme + '//' + url.user + url.host + url.port + url.path + queryHash;
669
651
  }
670
- case UrlType.AbsolutePath:
671
- return url.path + queryHash;
672
- default:
673
- return url.scheme + "//" + url.user + url.host + url.port + url.path + queryHash;
674
- }
675
652
  }
653
+
676
654
  function resolve(input, base) {
677
- if (base && !base.endsWith("/"))
678
- base += "/";
679
- return resolve$1(input, base);
655
+ // The base is always treated as a directory, if it's not empty.
656
+ // https://github.com/mozilla/source-map/blob/8cb3ee57/lib/util.js#L327
657
+ // https://github.com/chromium/chromium/blob/da4adbb3/third_party/blink/renderer/devtools/front_end/sdk/SourceMap.js#L400-L401
658
+ if (base && !base.endsWith('/'))
659
+ base += '/';
660
+ return resolve$1(input, base);
680
661
  }
662
+
663
+ /**
664
+ * Removes everything after the last "/", but leaves the slash.
665
+ */
681
666
  function stripFilename(path) {
682
- if (!path)
683
- return "";
684
- const index = path.lastIndexOf("/");
685
- return path.slice(0, index + 1);
667
+ if (!path)
668
+ return '';
669
+ const index = path.lastIndexOf('/');
670
+ return path.slice(0, index + 1);
686
671
  }
672
+
687
673
  const COLUMN = 0;
688
674
  const SOURCES_INDEX = 1;
689
675
  const SOURCE_LINE = 2;
690
676
  const SOURCE_COLUMN = 3;
691
677
  const NAMES_INDEX = 4;
678
+
692
679
  function maybeSort(mappings, owned) {
693
- const unsortedIndex = nextUnsortedSegmentLine(mappings, 0);
694
- if (unsortedIndex === mappings.length)
680
+ const unsortedIndex = nextUnsortedSegmentLine(mappings, 0);
681
+ if (unsortedIndex === mappings.length)
682
+ return mappings;
683
+ // If we own the array (meaning we parsed it from JSON), then we're free to directly mutate it. If
684
+ // not, we do not want to modify the consumer's input array.
685
+ if (!owned)
686
+ mappings = mappings.slice();
687
+ for (let i = unsortedIndex; i < mappings.length; i = nextUnsortedSegmentLine(mappings, i + 1)) {
688
+ mappings[i] = sortSegments(mappings[i], owned);
689
+ }
695
690
  return mappings;
696
- if (!owned)
697
- mappings = mappings.slice();
698
- for (let i = unsortedIndex; i < mappings.length; i = nextUnsortedSegmentLine(mappings, i + 1)) {
699
- mappings[i] = sortSegments(mappings[i], owned);
700
- }
701
- return mappings;
702
691
  }
703
692
  function nextUnsortedSegmentLine(mappings, start) {
704
- for (let i = start; i < mappings.length; i++) {
705
- if (!isSorted(mappings[i]))
706
- return i;
707
- }
708
- return mappings.length;
693
+ for (let i = start; i < mappings.length; i++) {
694
+ if (!isSorted(mappings[i]))
695
+ return i;
696
+ }
697
+ return mappings.length;
709
698
  }
710
699
  function isSorted(line) {
711
- for (let j = 1; j < line.length; j++) {
712
- if (line[j][COLUMN] < line[j - 1][COLUMN]) {
713
- return false;
700
+ for (let j = 1; j < line.length; j++) {
701
+ if (line[j][COLUMN] < line[j - 1][COLUMN]) {
702
+ return false;
703
+ }
714
704
  }
715
- }
716
- return true;
705
+ return true;
717
706
  }
718
707
  function sortSegments(line, owned) {
719
- if (!owned)
720
- line = line.slice();
721
- return line.sort(sortComparator);
708
+ if (!owned)
709
+ line = line.slice();
710
+ return line.sort(sortComparator);
722
711
  }
723
712
  function sortComparator(a, b) {
724
- return a[COLUMN] - b[COLUMN];
713
+ return a[COLUMN] - b[COLUMN];
725
714
  }
715
+
726
716
  let found = false;
717
+ /**
718
+ * A binary search implementation that returns the index if a match is found.
719
+ * If no match is found, then the left-index (the index associated with the item that comes just
720
+ * before the desired index) is returned. To maintain proper sort order, a splice would happen at
721
+ * the next index:
722
+ *
723
+ * ```js
724
+ * const array = [1, 3];
725
+ * const needle = 2;
726
+ * const index = binarySearch(array, needle, (item, needle) => item - needle);
727
+ *
728
+ * assert.equal(index, 0);
729
+ * array.splice(index + 1, 0, needle);
730
+ * assert.deepEqual(array, [1, 2, 3]);
731
+ * ```
732
+ */
727
733
  function binarySearch(haystack, needle, low, high) {
728
- while (low <= high) {
729
- const mid = low + (high - low >> 1);
730
- const cmp = haystack[mid][COLUMN] - needle;
731
- if (cmp === 0) {
732
- found = true;
733
- return mid;
734
- }
735
- if (cmp < 0) {
736
- low = mid + 1;
737
- } else {
738
- high = mid - 1;
734
+ while (low <= high) {
735
+ const mid = low + ((high - low) >> 1);
736
+ const cmp = haystack[mid][COLUMN] - needle;
737
+ if (cmp === 0) {
738
+ found = true;
739
+ return mid;
740
+ }
741
+ if (cmp < 0) {
742
+ low = mid + 1;
743
+ }
744
+ else {
745
+ high = mid - 1;
746
+ }
739
747
  }
740
- }
741
- found = false;
742
- return low - 1;
748
+ found = false;
749
+ return low - 1;
743
750
  }
744
751
  function upperBound(haystack, needle, index) {
745
- for (let i = index + 1; i < haystack.length; index = i++) {
746
- if (haystack[i][COLUMN] !== needle)
747
- break;
748
- }
749
- return index;
752
+ for (let i = index + 1; i < haystack.length; index = i++) {
753
+ if (haystack[i][COLUMN] !== needle)
754
+ break;
755
+ }
756
+ return index;
750
757
  }
751
758
  function lowerBound(haystack, needle, index) {
752
- for (let i = index - 1; i >= 0; index = i--) {
753
- if (haystack[i][COLUMN] !== needle)
754
- break;
755
- }
756
- return index;
759
+ for (let i = index - 1; i >= 0; index = i--) {
760
+ if (haystack[i][COLUMN] !== needle)
761
+ break;
762
+ }
763
+ return index;
757
764
  }
758
765
  function memoizedState() {
759
- return {
760
- lastKey: -1,
761
- lastNeedle: -1,
762
- lastIndex: -1
763
- };
766
+ return {
767
+ lastKey: -1,
768
+ lastNeedle: -1,
769
+ lastIndex: -1,
770
+ };
764
771
  }
772
+ /**
773
+ * This overly complicated beast is just to record the last tested line/column and the resulting
774
+ * index, allowing us to skip a few tests if mappings are monotonically increasing.
775
+ */
765
776
  function memoizedBinarySearch(haystack, needle, state, key) {
766
- const { lastKey, lastNeedle, lastIndex } = state;
767
- let low = 0;
768
- let high = haystack.length - 1;
769
- if (key === lastKey) {
770
- if (needle === lastNeedle) {
771
- found = lastIndex !== -1 && haystack[lastIndex][COLUMN] === needle;
772
- return lastIndex;
773
- }
774
- if (needle >= lastNeedle) {
775
- low = lastIndex === -1 ? 0 : lastIndex;
776
- } else {
777
- high = lastIndex;
777
+ const { lastKey, lastNeedle, lastIndex } = state;
778
+ let low = 0;
779
+ let high = haystack.length - 1;
780
+ if (key === lastKey) {
781
+ if (needle === lastNeedle) {
782
+ found = lastIndex !== -1 && haystack[lastIndex][COLUMN] === needle;
783
+ return lastIndex;
784
+ }
785
+ if (needle >= lastNeedle) {
786
+ // lastIndex may be -1 if the previous needle was not found.
787
+ low = lastIndex === -1 ? 0 : lastIndex;
788
+ }
789
+ else {
790
+ high = lastIndex;
791
+ }
778
792
  }
779
- }
780
- state.lastKey = key;
781
- state.lastNeedle = needle;
782
- return state.lastIndex = binarySearch(haystack, needle, low, high);
793
+ state.lastKey = key;
794
+ state.lastNeedle = needle;
795
+ return (state.lastIndex = binarySearch(haystack, needle, low, high));
783
796
  }
784
- const LINE_GTR_ZERO = "`line` must be greater than 0 (lines start at line 1)";
785
- const COL_GTR_EQ_ZERO = "`column` must be greater than or equal to 0 (columns start at column 0)";
797
+
798
+ const LINE_GTR_ZERO = '`line` must be greater than 0 (lines start at line 1)';
799
+ const COL_GTR_EQ_ZERO = '`column` must be greater than or equal to 0 (columns start at column 0)';
786
800
  const LEAST_UPPER_BOUND = -1;
787
801
  const GREATEST_LOWER_BOUND = 1;
802
+ /**
803
+ * Returns the decoded (array of lines of segments) form of the SourceMap's mappings field.
804
+ */
788
805
  let decodedMappings;
806
+ /**
807
+ * A higher-level API to find the source/line/column associated with a generated line/column
808
+ * (think, from a stack trace). Line is 1-based, but column is 0-based, due to legacy behavior in
809
+ * `source-map` library.
810
+ */
789
811
  let originalPositionFor;
790
812
  class TraceMap {
791
- constructor(map, mapUrl) {
792
- const isString = typeof map === "string";
793
- if (!isString && map._decodedMemo)
794
- return map;
795
- const parsed = isString ? JSON.parse(map) : map;
796
- const { version, file, names, sourceRoot, sources, sourcesContent } = parsed;
797
- this.version = version;
798
- this.file = file;
799
- this.names = names;
800
- this.sourceRoot = sourceRoot;
801
- this.sources = sources;
802
- this.sourcesContent = sourcesContent;
803
- const from = resolve(sourceRoot || "", stripFilename(mapUrl));
804
- this.resolvedSources = sources.map((s) => resolve(s || "", from));
805
- const { mappings } = parsed;
806
- if (typeof mappings === "string") {
807
- this._encoded = mappings;
808
- this._decoded = void 0;
809
- } else {
810
- this._encoded = void 0;
811
- this._decoded = maybeSort(mappings, isString);
813
+ constructor(map, mapUrl) {
814
+ const isString = typeof map === 'string';
815
+ if (!isString && map._decodedMemo)
816
+ return map;
817
+ const parsed = (isString ? JSON.parse(map) : map);
818
+ const { version, file, names, sourceRoot, sources, sourcesContent } = parsed;
819
+ this.version = version;
820
+ this.file = file;
821
+ this.names = names;
822
+ this.sourceRoot = sourceRoot;
823
+ this.sources = sources;
824
+ this.sourcesContent = sourcesContent;
825
+ const from = resolve(sourceRoot || '', stripFilename(mapUrl));
826
+ this.resolvedSources = sources.map((s) => resolve(s || '', from));
827
+ const { mappings } = parsed;
828
+ if (typeof mappings === 'string') {
829
+ this._encoded = mappings;
830
+ this._decoded = undefined;
831
+ }
832
+ else {
833
+ this._encoded = undefined;
834
+ this._decoded = maybeSort(mappings, isString);
835
+ }
836
+ this._decodedMemo = memoizedState();
837
+ this._bySources = undefined;
838
+ this._bySourceMemos = undefined;
812
839
  }
813
- this._decodedMemo = memoizedState();
814
- this._bySources = void 0;
815
- this._bySourceMemos = void 0;
816
- }
817
840
  }
818
841
  (() => {
819
- decodedMappings = (map) => {
820
- return map._decoded || (map._decoded = decode(map._encoded));
821
- };
822
- originalPositionFor = (map, { line, column, bias }) => {
823
- line--;
824
- if (line < 0)
825
- throw new Error(LINE_GTR_ZERO);
826
- if (column < 0)
827
- throw new Error(COL_GTR_EQ_ZERO);
828
- const decoded = decodedMappings(map);
829
- if (line >= decoded.length)
830
- return OMapping(null, null, null, null);
831
- const segments = decoded[line];
832
- const index = traceSegmentInternal(segments, map._decodedMemo, line, column, bias || GREATEST_LOWER_BOUND);
833
- if (index === -1)
834
- return OMapping(null, null, null, null);
835
- const segment = segments[index];
836
- if (segment.length === 1)
837
- return OMapping(null, null, null, null);
838
- const { names, resolvedSources } = map;
839
- return OMapping(resolvedSources[segment[SOURCES_INDEX]], segment[SOURCE_LINE] + 1, segment[SOURCE_COLUMN], segment.length === 5 ? names[segment[NAMES_INDEX]] : null);
840
- };
842
+ decodedMappings = (map) => {
843
+ return (map._decoded || (map._decoded = decode(map._encoded)));
844
+ };
845
+ originalPositionFor = (map, { line, column, bias }) => {
846
+ line--;
847
+ if (line < 0)
848
+ throw new Error(LINE_GTR_ZERO);
849
+ if (column < 0)
850
+ throw new Error(COL_GTR_EQ_ZERO);
851
+ const decoded = decodedMappings(map);
852
+ // It's common for parent source maps to have pointers to lines that have no
853
+ // mapping (like a "//# sourceMappingURL=") at the end of the child file.
854
+ if (line >= decoded.length)
855
+ return OMapping(null, null, null, null);
856
+ const segments = decoded[line];
857
+ const index = traceSegmentInternal(segments, map._decodedMemo, line, column, bias || GREATEST_LOWER_BOUND);
858
+ if (index === -1)
859
+ return OMapping(null, null, null, null);
860
+ const segment = segments[index];
861
+ if (segment.length === 1)
862
+ return OMapping(null, null, null, null);
863
+ const { names, resolvedSources } = map;
864
+ return OMapping(resolvedSources[segment[SOURCES_INDEX]], segment[SOURCE_LINE] + 1, segment[SOURCE_COLUMN], segment.length === 5 ? names[segment[NAMES_INDEX]] : null);
865
+ };
841
866
  })();
842
867
  function OMapping(source, line, column, name) {
843
- return { source, line, column, name };
868
+ return { source, line, column, name };
844
869
  }
845
870
  function traceSegmentInternal(segments, memo, line, column, bias) {
846
- let index = memoizedBinarySearch(segments, column, memo, line);
847
- if (found) {
848
- index = (bias === LEAST_UPPER_BOUND ? upperBound : lowerBound)(segments, column, index);
849
- } else if (bias === LEAST_UPPER_BOUND)
850
- index++;
851
- if (index === -1 || index === segments.length)
852
- return -1;
853
- return index;
871
+ let index = memoizedBinarySearch(segments, column, memo, line);
872
+ if (found) {
873
+ index = (bias === LEAST_UPPER_BOUND ? upperBound : lowerBound)(segments, column, index);
874
+ }
875
+ else if (bias === LEAST_UPPER_BOUND)
876
+ index++;
877
+ if (index === -1 || index === segments.length)
878
+ return -1;
879
+ return index;
854
880
  }
881
+
855
882
  const CHROME_IE_STACK_REGEXP = /^\s*at .*(\S+:\d+|\(native\))/m;
856
883
  const SAFARI_NATIVE_CODE_REGEXP = /^(eval@)?(\[native code])?$/;
857
884
  const stackIgnorePatterns = [
@@ -963,7 +990,9 @@ function parseErrorStacktrace(e, options = {}) {
963
990
  if (e.stacks)
964
991
  return e.stacks;
965
992
  const stackStr = e.stack || e.stackStr || "";
966
- const stackFrames = parseStacktrace(stackStr, options);
993
+ let stackFrames = parseStacktrace(stackStr, options);
994
+ if (options.frameFilter)
995
+ stackFrames = stackFrames.filter((f) => options.frameFilter(e, f) !== false);
967
996
  e.stacks = stackFrames;
968
997
  return stackFrames;
969
998
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@vitest/snapshot",
3
3
  "type": "module",
4
- "version": "1.0.0-beta.2",
4
+ "version": "1.0.0-beta.3",
5
5
  "description": "Vitest snapshot manager",
6
6
  "license": "MIT",
7
7
  "funding": "https://opencollective.com/vitest",
@@ -38,14 +38,14 @@
38
38
  "*.d.ts"
39
39
  ],
40
40
  "dependencies": {
41
- "magic-string": "^0.30.1",
41
+ "magic-string": "^0.30.5",
42
42
  "pathe": "^1.1.1",
43
43
  "pretty-format": "^29.5.0"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@types/natural-compare": "^1.4.1",
47
47
  "natural-compare": "^1.4.0",
48
- "@vitest/utils": "1.0.0-beta.2"
48
+ "@vitest/utils": "1.0.0-beta.3"
49
49
  },
50
50
  "scripts": {
51
51
  "build": "rimraf dist && rollup -c",