Skip to content

Commit 71d653d

Browse files
committed
Refactor code-style
1 parent bea9857 commit 71d653d

File tree

2 files changed

+152
-120
lines changed

2 files changed

+152
-120
lines changed

lib/index.js

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,54 +7,63 @@
77
* @typedef Options
88
* Configuration.
99
* @property {string | null | undefined} [comment='more']
10-
* Comment value to search for.
10+
* Comment value to search for (default: `'more'`).
11+
* @property {Array<RootContent> | null | undefined} [ignore=[]]
12+
* Nodes to exclude from the resulting tree (default: `[]`).
13+
*
14+
* These are not counted towards `size`.
1115
* @property {number | null | undefined} [maxSearchSize=2048]
12-
* How far to search for the comment before bailing.
16+
* How far to search for the comment before bailing (default: `2048`).
17+
*
1318
* The goal of this project is to find user-defined explicit excerpts, that
1419
* are assumed to be somewhat reasonably placed.
15-
* This option prevents searching giant documents for some comment
16-
* that probably won’t be found at the end.
17-
* @property {Array<RootContent> | null | undefined} [ignore=[]]
18-
* Nodes to exclude from the resulting tree.
19-
* These are not counted towards `size`.
20+
* This option prevents searching giant documents for some comment that
21+
* probably won’t be found at the end.
2022
*/
2123

2224
import {truncate} from 'hast-util-truncate'
2325

26+
/** @type {Readonly<Options>} */
27+
const emptyOptions = {}
28+
2429
/**
2530
* Truncate `tree` to a certain comment.
2631
*
2732
* @template {Nodes} Tree
28-
* Type of tree.
33+
* Tree kind.
2934
* @param {Tree} tree
3035
* Tree to truncate.
31-
* @param {Options | null | undefined} [options]
32-
* Configuration (optional)
36+
* @param {Readonly<Options> | null | undefined} [options]
37+
* Configuration (optional).
3338
* @returns {Tree | undefined}
34-
* Truncated copy of `tree` when a comment is found, `undefined` otherwise.
39+
* Truncated clone of `tree` when a comment is found, `undefined` otherwise.
3540
*/
3641
export function excerpt(tree, options) {
37-
const config = options || {}
42+
const config = options || emptyOptions
3843
const comment = config.comment || 'more'
3944
const maxSearchSize =
4045
typeof config.maxSearchSize === 'number' ? config.maxSearchSize : 2048
4146
let found = false
47+
// Note: `truncate` returns a deep clone.
4248
const result = preorder(
4349
truncate(tree, {ignore: config.ignore, size: maxSearchSize})
4450
)
4551

46-
// @ts-expect-error: `result` is most likely a clone of `tree`
4752
return found ? result : undefined
4853

4954
/**
5055
* Truncate `node`.
5156
*
52-
* @param {Nodes} node
57+
* @template {Nodes} Kind
58+
* Node kind.
59+
* @param {Kind} node
5360
* Node to truncate.
54-
* @returns {Nodes | undefined}
61+
* @returns {Kind | undefined}
5562
* Copy of `node` or `undefined` when done.
5663
*/
5764
function preorder(node) {
65+
/** @typedef {Kind extends import('unist').Parent ? Kind['children'][number] : never} Child */
66+
5867
if (node.type === 'comment' && node.value.trim() === comment) {
5968
found = true
6069
return
@@ -67,27 +76,28 @@ export function excerpt(tree, options) {
6776
node.data &&
6877
node.data.estree &&
6978
node.data.estree.comments &&
70-
node.data.estree.comments.some((node) => node.value.trim() === comment)
79+
node.data.estree.comments.some(function (node) {
80+
return node.value.trim() === comment
81+
})
7182
) {
7283
found = true
7384
return
7485
}
7586

76-
/** @type {Nodes} */
87+
/** @type {Kind} */
7788
const replacement = {...node}
7889

79-
if ('children' in node) {
80-
/** @type {Array<RootContent>} */
90+
if ('children' in replacement) {
91+
/** @type {Array<Child>} */
8192
const children = []
8293
let index = -1
8394

84-
while (++index < node.children.length && !found) {
85-
const child = node.children[index]
86-
const result = /** @type {RootContent | undefined} */ (preorder(child))
95+
while (++index < replacement.children.length && !found) {
96+
const child = /** @type {Child} */ (replacement.children[index])
97+
const result = preorder(child)
8798
if (result) children.push(result)
8899
}
89100

90-
// @ts-expect-error: assume content model matches.
91101
replacement.children = children
92102
}
93103

test.js

Lines changed: 119 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -1,123 +1,145 @@
11
import assert from 'node:assert/strict'
22
import test from 'node:test'
3-
import {u} from 'unist-builder'
43
import {h} from 'hastscript'
5-
import {removePosition} from 'unist-util-remove-position'
64
import {selectAll} from 'hast-util-select'
75
import {fromMarkdown} from 'mdast-util-from-markdown'
8-
import {mdxjs} from 'micromark-extension-mdxjs'
96
import {mdxFromMarkdown} from 'mdast-util-mdx'
107
import {toHast} from 'mdast-util-to-hast'
8+
import {mdxjs} from 'micromark-extension-mdxjs'
9+
import {u} from 'unist-builder'
10+
import {removePosition} from 'unist-util-remove-position'
1111
import {excerpt} from './index.js'
12-
import * as mod from './index.js'
13-
14-
test('excerpt', () => {
15-
assert.deepEqual(
16-
Object.keys(mod).sort(),
17-
['excerpt'],
18-
'should expose the public api'
19-
)
20-
21-
assert.deepEqual(
22-
excerpt(
23-
h('div', [
24-
h('p', 'Lorem ipsum dolor sit amet.'),
25-
u('comment', 'more'),
26-
h('p', 'Consectetur adipisicing elit.')
27-
])
28-
),
29-
h('div', [h('p', 'Lorem ipsum dolor sit amet.')]),
30-
'should copy to an excerpt comment'
31-
)
3212

33-
assert.deepEqual(
34-
excerpt(
35-
h('div', [
36-
h('p', 'Lorem ipsum dolor sit amet.'),
37-
u('comment', 'more'),
38-
h('p', 'Consectetur adipisicing elit.')
39-
]),
40-
{maxSearchSize: 24}
41-
),
42-
undefined,
43-
'should support `maxSearchSize`'
44-
)
13+
test('excerpt', async function (t) {
14+
await t.test('should expose the public api', async function () {
15+
assert.deepEqual(Object.keys(await import('./index.js')).sort(), [
16+
'excerpt'
17+
])
18+
})
4519

46-
assert.deepEqual(
47-
excerpt(
48-
h('div', [
49-
h('p', [
50-
'Lorem ipsum dolor sit amet.',
20+
await t.test('should copy to an excerpt comment', async function () {
21+
assert.deepEqual(
22+
excerpt(
23+
h('div', [
24+
h('p', 'Lorem ipsum dolor sit amet.'),
5125
u('comment', 'more'),
52-
'Consectetur adipisicing elit.'
26+
h('p', 'Consectetur adipisicing elit.')
5327
])
54-
])
55-
),
56-
h('div', [h('p', 'Lorem ipsum dolor sit amet.')]),
57-
'should copy to an excerpt comment inside a paragraph'
58-
)
28+
),
29+
h('div', [h('p', 'Lorem ipsum dolor sit amet.')])
30+
)
31+
})
5932

60-
assert.deepEqual(
61-
excerpt(
62-
h('div', [
63-
h('p', 'Lorem ipsum dolor sit amet.'),
64-
h('p', 'Consectetur adipisicing elit.')
65-
])
66-
),
67-
undefined,
68-
'should return `undefined` if there’s no comment'
69-
)
33+
await t.test('should support `maxSearchSize`', async function () {
34+
assert.deepEqual(
35+
excerpt(
36+
h('div', [
37+
h('p', 'Lorem ipsum dolor sit amet.'),
38+
u('comment', 'more'),
39+
h('p', 'Consectetur adipisicing elit.')
40+
]),
41+
{maxSearchSize: 24}
42+
),
43+
undefined
44+
)
45+
})
7046

71-
assert.deepEqual(
72-
excerpt(
73-
h('div', [
74-
h('p', 'Lorem ipsum dolor sit amet.'),
75-
u('comment', 'just a comment'),
76-
h('p', 'Consectetur adipisicing elit.')
77-
])
78-
),
79-
undefined,
80-
'should not match on comments with other values'
47+
await t.test(
48+
'should copy to an excerpt comment inside a paragraph',
49+
async function () {
50+
assert.deepEqual(
51+
excerpt(
52+
h('div', [
53+
h('p', [
54+
'Lorem ipsum dolor sit amet.',
55+
u('comment', 'more'),
56+
'Consectetur adipisicing elit.'
57+
])
58+
])
59+
),
60+
h('div', [h('p', 'Lorem ipsum dolor sit amet.')])
61+
)
62+
}
8163
)
8264

83-
assert.deepEqual(
84-
excerpt(
85-
h('div', [
86-
h('p', 'Lorem ipsum dolor sit amet.'),
87-
u('comment', '\r\n stop here\t\n'),
88-
h('p', 'Consectetur adipisicing elit.')
89-
]),
90-
{comment: 'stop here'}
91-
),
92-
h('div', [h('p', 'Lorem ipsum dolor sit amet.')]),
93-
'should ignore trailing whitespace around comments'
65+
await t.test(
66+
'should return `undefined` if there’s no comment',
67+
async function () {
68+
assert.deepEqual(
69+
excerpt(
70+
h('div', [
71+
h('p', 'Lorem ipsum dolor sit amet.'),
72+
h('p', 'Consectetur adipisicing elit.')
73+
])
74+
),
75+
undefined
76+
)
77+
}
9478
)
9579

96-
const tree = h('div', [
97-
h('p', ['Lorem ipsum ', h('del', 'dolor'), ' sit amet.']),
98-
u('comment', 'more'),
99-
h('p', 'Consectetur adipisicing elit.')
100-
])
80+
await t.test(
81+
'should not match on comments with other values',
82+
async function () {
83+
assert.deepEqual(
84+
excerpt(
85+
h('div', [
86+
h('p', 'Lorem ipsum dolor sit amet.'),
87+
u('comment', 'just a comment'),
88+
h('p', 'Consectetur adipisicing elit.')
89+
])
90+
),
91+
undefined
92+
)
93+
}
94+
)
10195

102-
assert.deepEqual(
103-
excerpt(tree, {ignore: selectAll('del', tree)}),
104-
h('div', [h('p', ['Lorem ipsum ', ' sit amet.'])]),
105-
'should support `ignore`'
96+
await t.test(
97+
'should ignore trailing whitespace around comments',
98+
async function () {
99+
assert.deepEqual(
100+
excerpt(
101+
h('div', [
102+
h('p', 'Lorem ipsum dolor sit amet.'),
103+
u('comment', '\r\n stop here\t\n'),
104+
h('p', 'Consectetur adipisicing elit.')
105+
]),
106+
{comment: 'stop here'}
107+
),
108+
h('div', [h('p', 'Lorem ipsum dolor sit amet.')])
109+
)
110+
}
106111
)
107112

108-
const tree2 = fromMarkdown('Some text\n\n{/* more */}\n\nSome more text', {
109-
extensions: [mdxjs()],
110-
mdastExtensions: [mdxFromMarkdown()]
113+
await t.test('should support `ignore`', async function () {
114+
const tree = h('div', [
115+
h('p', ['Lorem ipsum ', h('del', 'dolor'), ' sit amet.']),
116+
u('comment', 'more'),
117+
h('p', 'Consectetur adipisicing elit.')
118+
])
119+
120+
assert.deepEqual(
121+
excerpt(tree, {ignore: selectAll('del', tree)}),
122+
h('div', [h('p', ['Lorem ipsum ', ' sit amet.'])])
123+
)
111124
})
112-
removePosition(tree2)
113125

114-
assert.deepEqual(
115-
excerpt(
116-
toHast(tree2, {
117-
passThrough: ['mdxFlowExpression', 'mdxTextExpression', 'mdxjsEsm']
126+
await t.test(
127+
'should integrate w/ `mdast-util-mdx` (support `/* comments */`)',
128+
async function () {
129+
const tree = fromMarkdown('Some text\n\n{/* more */}\n\nSome more text', {
130+
extensions: [mdxjs()],
131+
mdastExtensions: [mdxFromMarkdown()]
118132
})
119-
),
120-
u('root', [h('p', 'Some text'), u('text', '\n')]),
121-
'should integrate w/ `mdast-util-mdx` (support `/* comments */`)'
133+
removePosition(tree)
134+
135+
assert.deepEqual(
136+
excerpt(
137+
toHast(tree, {
138+
passThrough: ['mdxFlowExpression', 'mdxTextExpression', 'mdxjsEsm']
139+
})
140+
),
141+
u('root', [h('p', 'Some text'), u('text', '\n')])
142+
)
143+
}
122144
)
123145
})

0 commit comments

Comments
 (0)