-
Notifications
You must be signed in to change notification settings - Fork 30k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
PR-URL: #44095 Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
- Loading branch information
Showing
20 changed files
with
380 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
'use strict'; | ||
|
||
const { | ||
ArrayPrototypeJoin, | ||
ArrayPrototypeMap, | ||
ArrayPrototypeSlice, | ||
RegExp, | ||
SafeMap, | ||
SafeSet, | ||
StringPrototypeSplit, | ||
StringPrototypeReplace, | ||
Symbol, | ||
} = primordials; | ||
|
||
const { codes: { ERR_ASSERT_SNAPSHOT_NOT_SUPPORTED } } = require('internal/errors'); | ||
const AssertionError = require('internal/assert/assertion_error'); | ||
const { inspect } = require('internal/util/inspect'); | ||
const { getOptionValue } = require('internal/options'); | ||
const { validateString } = require('internal/validators'); | ||
const { once } = require('events'); | ||
const { createReadStream, createWriteStream } = require('fs'); | ||
const path = require('path'); | ||
const assert = require('assert'); | ||
|
||
const kUpdateSnapshot = getOptionValue('--update-assert-snapshot'); | ||
const kInitialSnapshot = Symbol('kInitialSnapshot'); | ||
const kDefaultDelimiter = '\n#*#*#*#*#*#*#*#*#*#*#*#\n'; | ||
const kDefaultDelimiterRegex = new RegExp(kDefaultDelimiter.replaceAll('*', '\\*').replaceAll('\n', '\r?\n'), 'g'); | ||
const kKeyDelimiter = /:\r?\n/g; | ||
|
||
function getSnapshotPath() { | ||
if (process.mainModule) { | ||
const { dir, name } = path.parse(process.mainModule.filename); | ||
return path.join(dir, `${name}.snapshot`); | ||
} | ||
if (!process.argv[1]) { | ||
throw new ERR_ASSERT_SNAPSHOT_NOT_SUPPORTED(); | ||
} | ||
const { dir, name } = path.parse(process.argv[1]); | ||
return path.join(dir, `${name}.snapshot`); | ||
} | ||
|
||
function getSource() { | ||
return createReadStream(getSnapshotPath(), { encoding: 'utf8' }); | ||
} | ||
|
||
let _target; | ||
function getTarget() { | ||
_target ??= createWriteStream(getSnapshotPath(), { encoding: 'utf8' }); | ||
return _target; | ||
} | ||
|
||
function serializeName(name) { | ||
validateString(name, 'name'); | ||
return StringPrototypeReplace(`${name}`, kKeyDelimiter, '_'); | ||
} | ||
|
||
let writtenNames; | ||
let snapshotValue; | ||
let counter = 0; | ||
|
||
async function writeSnapshot({ name, value }) { | ||
const target = getTarget(); | ||
if (counter > 1) { | ||
target.write(kDefaultDelimiter); | ||
} | ||
writtenNames = writtenNames || new SafeSet(); | ||
if (writtenNames.has(name)) { | ||
throw new AssertionError({ message: `Snapshot "${name}" already used` }); | ||
} | ||
writtenNames.add(name); | ||
const drained = target.write(`${name}:\n${value}`); | ||
await drained || once(target, 'drain'); | ||
} | ||
|
||
async function getSnapshot() { | ||
if (snapshotValue !== undefined) { | ||
return snapshotValue; | ||
} | ||
if (kUpdateSnapshot) { | ||
snapshotValue = kInitialSnapshot; | ||
return kInitialSnapshot; | ||
} | ||
try { | ||
const source = getSource(); | ||
let data = ''; | ||
for await (const line of source) { | ||
data += line; | ||
} | ||
snapshotValue = new SafeMap( | ||
ArrayPrototypeMap( | ||
StringPrototypeSplit(data, kDefaultDelimiterRegex), | ||
(item) => { | ||
const arr = StringPrototypeSplit(item, kKeyDelimiter); | ||
return [ | ||
arr[0], | ||
ArrayPrototypeJoin(ArrayPrototypeSlice(arr, 1), ':\n'), | ||
]; | ||
} | ||
)); | ||
} catch (e) { | ||
if (e.code === 'ENOENT') { | ||
snapshotValue = kInitialSnapshot; | ||
} else { | ||
throw e; | ||
} | ||
} | ||
return snapshotValue; | ||
} | ||
|
||
|
||
async function snapshot(input, name) { | ||
const snapshot = await getSnapshot(); | ||
counter = counter + 1; | ||
name = serializeName(name); | ||
|
||
const value = inspect(input); | ||
if (snapshot === kInitialSnapshot) { | ||
await writeSnapshot({ name, value }); | ||
} else if (snapshot.has(name)) { | ||
const expected = snapshot.get(name); | ||
// eslint-disable-next-line no-restricted-syntax | ||
assert.strictEqual(value, expected); | ||
} else { | ||
throw new AssertionError({ message: `Snapshot "${name}" does not exist`, actual: inspect(snapshot) }); | ||
} | ||
} | ||
|
||
module.exports = snapshot; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import assert from 'node:assert'; | ||
|
||
await assert.snapshot("test", "name"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
import assert from 'node:assert'; | ||
|
||
await assert.snapshot("test", "name"); | ||
await assert.snapshot("test", "another name"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
import assert from 'node:assert'; | ||
|
||
await assert.snapshot("test", "another name"); | ||
await assert.snapshot("test", "non existing"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
another name: | ||
'test' | ||
#*#*#*#*#*#*#*#*#*#*#*# | ||
name: | ||
'test' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import assert from 'node:assert'; | ||
|
||
function random() { | ||
return `Random Value: ${Math.random()}`; | ||
} | ||
function transform(value) { | ||
return value.replaceAll(/Random Value: \d+\.+\d+/g, 'Random Value: *'); | ||
} | ||
|
||
await assert.snapshot(transform(random()), 'random1'); | ||
await assert.snapshot(transform(random()), 'random2'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
random1: | ||
'Random Value: *' | ||
#*#*#*#*#*#*#*#*#*#*#*# | ||
random2: | ||
'Random Value: *' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import assert from 'node:assert'; | ||
|
||
function fn() { | ||
this.should.be.a.fn(); | ||
return false; | ||
} | ||
|
||
await assert.snapshot(fn, 'function'); | ||
await assert.snapshot({ foo: "bar" }, 'object'); | ||
await assert.snapshot(new Set([1, 2, 3]), 'set'); | ||
await assert.snapshot(new Map([['one', 1], ['two', 2]]), 'map'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
function: | ||
[Function: fn] | ||
#*#*#*#*#*#*#*#*#*#*#*# | ||
object: | ||
{ foo: 'bar' } | ||
#*#*#*#*#*#*#*#*#*#*#*# | ||
set: | ||
Set(3) { 1, 2, 3 } | ||
#*#*#*#*#*#*#*#*#*#*#*# | ||
map: | ||
Map(2) { 'one' => 1, 'two' => 2 } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import assert from 'node:assert'; | ||
|
||
await assert.snapshot("test", "snapshot"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import assert from 'node:assert'; | ||
|
||
await assert.snapshot("changed", "snapshot"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
snapshot: | ||
'original' |
Oops, something went wrong.