Skip to content

Commit

Permalink
chore(tests): refactor token snaphot serializer
Browse files Browse the repository at this point in the history
Signed-off-by: Lexus Drumgold <unicornware@flexdevelopment.llc>
  • Loading branch information
unicornware committed Jun 30, 2024
1 parent a4837a7 commit 874267c
Show file tree
Hide file tree
Showing 7 changed files with 262 additions and 135 deletions.
58 changes: 6 additions & 52 deletions __tests__/serializers/token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,12 @@
* @see https://vitest.dev/guide/snapshot
*/

import type { Position, Token } from '#src/interfaces'
import { isObjectCurly } from '@flex-development/tutils'
import type { Token } from '#src/interfaces'
import inspect from '#tests/utils/inspect'
import isToken from '#tests/utils/is-token'
import { ok } from 'devlop'
import { stringifyPosition as position } from 'unist-util-stringify-position'
import type { SnapshotSerializer } from 'vitest'

/**
* Check if `value` is a {@linkcode Token}.
*
* @param {unknown} value - Value to check
* @return {value is Token} `true` if `value` is a token
*/
function test(value: unknown): value is Token {
if (!isObjectCurly(value)) return false
return 'end' in value && 'type' in value && 'start' in value
}

/**
* Token snapshot serializer.
*
Expand All @@ -34,49 +23,14 @@ const serializer: SnapshotSerializer = {
* @return {string} Snapshot value
*/
print(value: unknown): string {
ok(test(value), 'expected token')

/**
* Index of current token.
*
* @var {number} index
*/
let index: number = -1

/**
* Snapshot value.
*
* @var {string} snapshot
*/
let snapshot: string = ''

/**
* Current token.
*
* @var {Token | undefined} token
*/
let token: Token | undefined = value

// get snapshot value
while (token) {
/**
* Token range.
*
* @const {Position} range
*/
const range: Position = { end: token.end, start: token.start }

snapshot += `\t├─${++index} ${token.type} (${position(range)})\n`
token = token.next
}

return `tokens[${index + 1}]\n\t${snapshot.trim()}`
ok(isToken(value), 'expected token')
return inspect(value)
},

/**
* Check if the given value is a {@linkcode Token}.
*/
test
test: isToken
}

export default serializer
68 changes: 68 additions & 0 deletions __tests__/utils/inspect.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/**
* @file Test Utilities - inspect
* @module tests/utils/inspect
*/

import type { Token } from '#src/interfaces'
import { omit } from '@flex-development/tutils'
import { u } from '@flex-development/unist-util-builder'
import * as i from '@flex-development/unist-util-inspect'
import type { Literal, Node } from 'unist'

export default inspect

/**
* Inspect a token list.
*
* @see {@linkcode i.Options}
* @see {@linkcode Token}
*
* @param {Token} token - Head token
* @param {(i.Options | null)?} [options] - Configuration options
* @return {string} Pretty printed token list
*/
function inspect(token: Token, options?: i.Options | null): string {
return i.inspectNoColor(u('tokens', nodes(token)), options)
}

/**
* Convert a token to a list of nodes.
*
* @internal
*
* @param {Token} token - Head token
* @return {(Literal | Node)[]} Node list
*/
function nodes(token: Token): (Literal | Node)[] {
/**
* Node list.
*
* @const {(Literal | Node)[]} list
*/
const list: (Literal | Node)[] = []

/**
* Current token.
*
* @var {Token | undefined} tok
*/
let tok: Token | undefined = token

// build list
while (tok) {
/**
* New node.
*
* @const {Literal | Node} node
*/
const node: Literal | Node = u(tok.type, {
...omit(tok, ['end', 'next', 'previous', 'start']),
position: { end: tok.end, start: tok.start }
})

list.push(node)
tok = tok.next
}

return list
}
29 changes: 29 additions & 0 deletions __tests__/utils/is-point.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* @file Test Utilities - isPoint
* @module tests/utils/isPoint
*/

import type { Point } from '@flex-development/vfile-reader'

/**
* Check if the specified `value` is a point.
*
* @see {@linkcode Point}
*
* @param {unknown} value - Value to check
* @return {value is Point} `true` if `value` is point
*/
function isPoint(value: unknown): value is Point {
return (
typeof value === 'object' &&
value !== null &&
'column' in value &&
'line' in value &&
'offset' in value &&
typeof value.column === 'number' &&
typeof value.line === 'number' &&
typeof value.offset === 'number'
)
}

export default isPoint
44 changes: 44 additions & 0 deletions __tests__/utils/is-token.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/**
* @file Test Utilities - isToken
* @module tests/utils/isToken
*/

import type { Token } from '#src/interfaces'
import isPoint from './is-point'

/**
* Check if the specified `value` is a token.
*
* @see {@linkcode Token}
*
* @param {unknown} value - Value to check
* @return {value is Token} `true` if `value` is token
*/
function isToken(value: unknown): value is Token {
return (
check(value) &&
(value.next === undefined || check(value.next)) &&
(value.previous === undefined || check(value.previous))
)

/**
* Check if `value` is token like.
*
* @param {unknown} value - Value to check
* @return {value is Token} `true` if `value` is token like
*/
function check(value: unknown): value is Token {
return (
typeof value === 'object' &&
value !== null &&
'end' in value &&
'type' in value &&
'start' in value &&
isPoint(value.end) &&
isPoint(value.start) &&
typeof value.type === 'string'
)
}
}

export default isToken
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@
"@flex-development/mlly": "1.0.0-alpha.18",
"@flex-development/pathe": "2.0.0",
"@flex-development/tutils": "6.0.0-alpha.25",
"@flex-development/unist-util-builder": "2.0.0",
"@flex-development/unist-util-inspect": "1.0.0",
"@stylistic/eslint-plugin": "2.2.2",
"@types/chai": "4.3.16",
"@types/eslint": "8.56.10",
Expand Down Expand Up @@ -146,7 +148,6 @@
"ts-dedent": "2.2.0",
"typescript": "5.5.2",
"typescript-eslint": "8.0.0-alpha.30",
"unist-util-stringify-position": "4.0.0",
"vite-tsconfig-paths": "4.3.2",
"vitest": "2.0.0-beta.11",
"yaml-eslint-parser": "1.2.3"
Expand Down
Loading

0 comments on commit 874267c

Please sign in to comment.