Skip to content

Commit 56868aa

Browse files
committed
Refactor code-style
1 parent e3ae114 commit 56868aa

File tree

2 files changed

+84
-93
lines changed

2 files changed

+84
-93
lines changed

lib/index.js

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,7 @@
11
/**
2-
* @typedef {import('unist').Parent} UnistParent
3-
* @typedef {import('nlcst').Root} Root
4-
* @typedef {import('nlcst').Content} Content
5-
*/
6-
7-
/**
8-
* @typedef {Root | Content} Node
9-
* @typedef {Extract<Node, UnistParent>} Parent
2+
* @typedef {import('nlcst').Nodes} Nodes
3+
* @typedef {import('nlcst').Parents} Parents
4+
* @typedef {import('nlcst').RootContent} RootContent
105
*/
116

127
import {toString} from 'nlcst-to-string'
@@ -62,11 +57,11 @@ const open = Object.keys(pairs)
6257
* * `Meant as a literal is - foo.`
6358
* * `The word “foo” is meant as a literal.`
6459
*
65-
* @template {Parent} ParentType
60+
* @template {Parents} ParentType
6661
* Parent node.
6762
* @param {ParentType} parent
6863
* Parent node.
69-
* @param {number | ParentType['children'][number]} index
64+
* @param {ParentType['children'][number] | number} index
7065
* Child node of parent or index of child in parent.
7166
* @returns {boolean}
7267
* Whether the child is a literal.
@@ -76,9 +71,11 @@ export function isLiteral(parent, index) {
7671
throw new Error('Parent must be a node')
7772
}
7873

74+
/** @type {Array<RootContent>} */
75+
const siblings = parent.children
76+
7977
if (index !== null && typeof index === 'object' && 'type' in index) {
80-
// @ts-expect-error: assume child of `parent`.
81-
index = parent.children.indexOf(index)
78+
index = siblings.indexOf(index)
8279

8380
if (index === -1) {
8481
throw new Error('Node must be a child of `parent`')
@@ -92,7 +89,7 @@ export function isLiteral(parent, index) {
9289
return Boolean(
9390
(!containsWord(parent, -1, index) &&
9491
siblingDelimiter(parent, index, 1, single)) ||
95-
(!containsWord(parent, index, parent.children.length) &&
92+
(!containsWord(parent, index, siblings.length) &&
9693
siblingDelimiter(parent, index, -1, single)) ||
9794
isWrapped(parent, index)
9895
)
@@ -102,7 +99,7 @@ export function isLiteral(parent, index) {
10299
* Check if the node in `parent` at `position` is enclosed by matching
103100
* delimiters.
104101
*
105-
* @param {Parent} parent
102+
* @param {Parents} parent
106103
* Parent node.
107104
* @param {number} position
108105
* Position to look around.
@@ -126,15 +123,15 @@ function isWrapped(parent, position) {
126123
* Find the previous or next delimiter before or after `position` in `parent`.
127124
* Returns the delimiter node when found.
128125
*
129-
* @param {Parent} parent
126+
* @param {Parents} parent
130127
* Parent node.
131128
* @param {number} position
132129
* Start position in `parent`.
133130
* @param {number} step
134131
* Step (`-1` to move back, `1` to move forward).
135132
* @param {Array<string>} delimiters
136133
* Delimiters to look for.
137-
* @returns {Node | void}
134+
* @returns {Nodes | undefined}
138135
* Delimiter, if found.
139136
*/
140137
function siblingDelimiter(parent, position, step, delimiters) {
@@ -159,7 +156,7 @@ function siblingDelimiter(parent, position, step, delimiters) {
159156
* Check if parent contains word nodes between `start` and `end` (both
160157
* excluding).
161158
*
162-
* @param {Parent} parent
159+
* @param {Parents} parent
163160
* Parent node.
164161
* @param {number} start
165162
* Start index in `parent` (excluding).

test.js

Lines changed: 70 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -8,67 +8,61 @@ import test from 'node:test'
88
import {ParseEnglish} from 'parse-english'
99
import {visit} from 'unist-util-visit'
1010
import {isLiteral} from './index.js'
11-
import * as mod from './index.js'
12-
13-
test('isLiteral()', () => {
14-
assert.deepEqual(
15-
Object.keys(mod).sort(),
16-
['isLiteral'],
17-
'should expose the public api'
18-
)
19-
20-
assert.throws(
21-
() => {
22-
// @ts-expect-error runtime.
11+
12+
test('isLiteral', async function (t) {
13+
await t.test('should expose the public api', async function () {
14+
assert.deepEqual(Object.keys(await import('./index.js')).sort(), [
15+
'isLiteral'
16+
])
17+
})
18+
19+
await t.test('should throw without arguments', async function () {
20+
assert.throws(function () {
21+
// @ts-expect-error: check how the runtime handles a missing node.
2322
isLiteral()
24-
},
25-
/Parent must be a node/,
26-
'should throw without arguments'
27-
)
28-
29-
assert.throws(
30-
() => {
31-
// @ts-expect-error runtime.
23+
}, /Parent must be a node/)
24+
})
25+
26+
await t.test('should throw without parent', async function () {
27+
assert.throws(function () {
28+
// @ts-expect-error: check how the runtime handles a non-none.
3229
isLiteral({})
33-
},
34-
/Parent must be a node/,
35-
'should throw without parent'
36-
)
37-
38-
assert.throws(
39-
() => {
40-
// @ts-expect-error runtime.
30+
}, /Parent must be a node/)
31+
})
32+
33+
await t.test('should throw without node', async function () {
34+
assert.throws(function () {
35+
// @ts-expect-error: check how the runtime handles a non-none.
4136
isLiteral({children: []})
42-
},
43-
/Index must be a number/,
44-
'should throw without node'
45-
)
46-
47-
assert.throws(
48-
() => {
49-
// @ts-expect-error runtime.
37+
}, /Index must be a number/)
38+
})
39+
40+
await t.test('should throw if `node` is not in `parent`', async function () {
41+
assert.throws(function () {
42+
// @ts-expect-error: check how the runtime handles a non-none.
5043
isLiteral({children: []}, {type: 'a'})
51-
},
52-
/Node must be a child of `parent`/,
53-
'should throw if `node` is not in `parent`'
54-
)
55-
56-
assert.doesNotThrow(() => {
57-
const n = {type: 'a'}
58-
// @ts-expect-error runtime.
59-
isLiteral({children: [n]}, n)
60-
}, 'should not throw if `node` is in `parent`')
61-
62-
assert.doesNotThrow(() => {
63-
process('Well? Ha! Funky', (_, index, parent) => {
64-
assert.strictEqual(
65-
parent && index !== undefined && isLiteral(parent, index),
66-
false
67-
)
44+
}, /Node must be a child of `parent`/)
45+
})
46+
47+
await t.test('should not throw if `node` is in `parent`', async function () {
48+
assert.doesNotThrow(function () {
49+
const n = {type: 'a'}
50+
// @ts-expect-error: check how the runtime handles a non-none.
51+
isLiteral({children: [n]}, n)
6852
})
69-
}, 'should work on single word sentences')
53+
})
54+
55+
await t.test('should work on single word sentences', async function () {
56+
assert.doesNotThrow(function () {
57+
process('Well? Ha! Funky', function (_, index, parent) {
58+
assert(parent)
59+
assert(index !== undefined)
60+
assert.strictEqual(isLiteral(parent, index), false)
61+
})
62+
})
63+
})
7064

71-
assert.doesNotThrow(() => {
65+
await t.test('should work on initial nodes', async function () {
7266
const fixtures = [
7367
'Foo - is meant as a literal.',
7468
'Foo – is meant as a literal.',
@@ -83,17 +77,15 @@ test('isLiteral()', () => {
8377
let index = -1
8478

8579
while (++index < fixtures.length) {
86-
process(fixtures[index], (_, index, parent) => {
87-
assert.strictEqual(
88-
parent && index !== undefined && isLiteral(parent, index),
89-
index === 0,
90-
String(index)
91-
)
80+
process(fixtures[index], function (_, index, parent) {
81+
assert(parent)
82+
assert(index !== undefined)
83+
assert.strictEqual(isLiteral(parent, index), index === 0)
9284
})
9385
}
94-
}, 'Initial')
86+
})
9587

96-
assert.doesNotThrow(() => {
88+
await t.test('should work on final nodes', async function () {
9789
const fixtures = [
9890
'Meant as a literal is - foo.',
9991
'Meant as a literal is – foo.',
@@ -108,17 +100,18 @@ test('isLiteral()', () => {
108100
let index = -1
109101

110102
while (++index < fixtures.length) {
111-
process(fixtures[index], (_, index, parent) => {
103+
process(fixtures[index], function (_, index, parent) {
104+
assert(parent)
105+
assert(index !== undefined)
112106
assert.strictEqual(
113-
parent && index !== undefined && isLiteral(parent, index),
114-
parent && index === parent.children.length - 2,
115-
String(index)
107+
isLiteral(parent, index),
108+
index === parent.children.length - 2
116109
)
117110
})
118111
}
119-
}, 'Final')
112+
})
120113

121-
assert.doesNotThrow(() => {
114+
await t.test('should work on internal nodes', async function () {
122115
const fixtures = [
123116
'The word, foo, is meant as a literal.',
124117
'The word -foo- is meant as a literal.',
@@ -150,7 +143,7 @@ test('isLiteral()', () => {
150143
let index = -1
151144

152145
while (++index < fixtures.length) {
153-
process(fixtures[index], (_, place, parent) => {
146+
process(fixtures[index], function (_, place, parent) {
154147
let pos = 5
155148

156149
// Adjacent hyphens are part of the word.
@@ -163,21 +156,22 @@ test('isLiteral()', () => {
163156
pos = 6
164157
}
165158

166-
assert.strictEqual(
167-
parent && place !== undefined && isLiteral(parent, place),
168-
place === pos,
169-
String(index)
170-
)
159+
assert(parent)
160+
assert(place !== undefined)
161+
assert.strictEqual(isLiteral(parent, place), place === pos)
171162
})
172163
}
173-
}, 'Internal')
164+
})
174165
})
175166

176167
/**
177168
* Shortcut to process a fixture and invoke `visitor` for each of its word
178169
* nodes.
170+
*
179171
* @param {string} fixture
172+
* Natural language.
180173
* @param {Visitor} visitor
174+
* Visitor.
181175
*/
182176
function process(fixture, visitor) {
183177
const tree = new ParseEnglish().parse(fixture)

0 commit comments

Comments
 (0)