Skip to content

Commit f97dd84

Browse files
committed
Added better tests and error handling
1 parent 56d0824 commit f97dd84

File tree

6 files changed

+217
-90
lines changed

6 files changed

+217
-90
lines changed

all.js

Lines changed: 0 additions & 56 deletions
This file was deleted.

index.js

Lines changed: 48 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,67 @@
11
'use strict';
22

3-
const find = require('unist-util-find');
3+
const is = require('unist-util-is');
44

5-
function replaceBetween(parent, start, end, func) {
5+
function replaceAllBetween(parent, start, end, func) {
66
if (!parent || !parent.type || !parent.children) {
77
throw new Error('Expected parent node');
88
}
99

1010
const {children} = parent;
1111

12-
const index = check(start);
13-
const length = check(end);
12+
const isStart = node => is(node, start);
13+
const isEnd = node => is(node, end);
1414

15-
const replaced = children.splice(index, length - index + 1);
15+
/**
16+
* @type {Array<{start: number, end: number}>}
17+
*/
18+
const ranges = children.reduce((prev, child, i) => {
19+
const lastPrev = prev[prev.length - 1];
20+
if (isStart(children[i])) {
21+
if (lastPrev && lastPrev.end === undefined) {
22+
console.error('Attempted to start a replacement before the first one was cleaned up')
23+
throw new Error('Attempted to start a replacement before the first one was cleaned up');
24+
}
25+
prev.push({
26+
start: i
27+
});
28+
return prev;
29+
}
30+
if (isEnd(children[i])) {
31+
if (!lastPrev || (lastPrev && lastPrev.start === undefined)) {
32+
console.error('Attempted to end a replacement before finding the start', i, lastPrev)
33+
throw new Error('Attempted to end a replacement before finding the start');
34+
}
35+
lastPrev.end = i;
36+
}
37+
return prev;
38+
}, []);
1639

17-
const changedArray = func(replaced);
40+
if (!ranges[ranges.length - 1].end) {
41+
console.error('No ending value was found')
42+
throw new Error('No ending value was found');
43+
}
1844

19-
children.splice(index, 0, ...changedArray);
45+
// The function will return a different length than the original
46+
// This offset is used to correct
47+
let offset = 0;
2048

21-
return changedArray;
49+
ranges.map(({start, end}) => {
50+
const offsetStart = start + offset;
51+
const offsetEnd = end + offset;
2252

23-
function check(index) {
24-
if (index && index.type) {
25-
const node = find(parent, index);
26-
index = children.indexOf(node);
27-
}
53+
const replaced = children.slice(offsetStart, offsetEnd + 1);
2854

29-
if (isNaN(index) || index < 0 || index === Infinity) {
30-
throw new Error('Expected positive finite index or child node');
31-
}
55+
const changedArray = func(replaced);
3256

33-
if (index >= children.length) {
34-
index = children.length - 1;
35-
}
57+
const diff = children.splice(offsetStart, offsetEnd - offsetStart + 1, ...changedArray);
3658

37-
return index;
38-
}
59+
offset -= diff.length - changedArray.length;
60+
61+
return changedArray;
62+
});
63+
64+
return children;
3965
}
4066

41-
module.exports = replaceBetween;
67+
module.exports = replaceAllBetween;

package.json

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
{
2+
"name": "unist-util-find-all-between",
3+
"version": "2.1.0",
4+
"description": "Utility to find nodes between two nodes",
5+
"main": "index.js",
6+
"engines": {
7+
"node": ">=10"
8+
},
9+
"files": [
10+
"index.js",
11+
"types/index.d.ts"
12+
],
13+
"types": "types/index.d.ts",
14+
"scripts": {
15+
"lint": "xo",
16+
"test:types": "tsd",
17+
"test:logic": "tap -Rspec --100 test.js",
18+
"test": "npm run lint && npm run test:types && npm run test:logic",
19+
"report": "nyc report --reporter=text-lcov | coveralls"
20+
},
21+
"repository": {
22+
"type": "git",
23+
"url": "git+https://github.com/mrzmmr/unist-util-find-all-between.git"
24+
},
25+
"keywords": [
26+
"unist",
27+
"node",
28+
"find",
29+
"between",
30+
"util",
31+
"utility"
32+
],
33+
"author": "mrzmmr",
34+
"license": "MIT",
35+
"bugs": {
36+
"url": "https://github.com/mrzmmr/unist-util-find-all-between/issues"
37+
},
38+
"homepage": "https://github.com/mrzmmr/unist-util-find-all-between#readme",
39+
"dependencies": {
40+
"unist-util-find": "^1.0.1",
41+
"unist-util-is": "^4.0.2"
42+
},
43+
"devDependencies": {
44+
"@types/unist": "^2.0.3",
45+
"coveralls": "^3.1.0",
46+
"prettier": "^2.0.5",
47+
"tap": "^14.10.8",
48+
"tsd": "^0.13.1",
49+
"typescript": "^3.9.7",
50+
"xo": "^0.32.1"
51+
},
52+
"xo": {
53+
"prettier": true,
54+
"rules": {
55+
"unicorn/prefer-number-properties": "off"
56+
}
57+
},
58+
"prettier": {
59+
"tabWidth": 2,
60+
"useTabs": false,
61+
"singleQuote": true,
62+
"bracketSpacing": false,
63+
"semi": true,
64+
"trailingComma": "none"
65+
}
66+
}

test.js

Lines changed: 94 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,43 @@ const {test} = require('tap');
44
const findAllBetween = require('.');
55

66
test('unist-util-find-all-between', (test) => {
7+
test.throws(() => {
8+
findAllBetween();
9+
}, 'Should fail without parent node');
10+
11+
test.throws(() => {
12+
findAllBetween({type: 'foo'});
13+
}, 'Should fail without parent node');
14+
15+
test.throws(() => {
16+
findAllBetween({type: 'foo', children: [
17+
{type: 'start'},
18+
{type: 'start'}
19+
]}, {type: 'start'}, {type: 'end'});
20+
}, 'Tried getting a new start instead of ending');
21+
22+
test.throws(() => {
23+
findAllBetween({type: 'foo', children: [
24+
{type: 'start'},
25+
{type: 'end'},
26+
{type: 'start'}
27+
]}, {type: 'start'}, {type: 'end'});
28+
}, 'No ending value was found');
29+
30+
test.throws(() => {
31+
findAllBetween({type: 'foo', children: [
32+
{type: 'end'},
33+
{type: 'start'}
34+
]}, {type: 'start'}, {type: 'end'});
35+
}, 'Attempted to end a replacement before finding the start');
36+
37+
test.throws(() => {
38+
findAllBetween({type: 'foo', children: [
39+
{type: 'start'},
40+
{type: 'end'},
41+
{type: 'end'},
42+
]}, {type: 'start'}, {type: 'end'});
43+
}, 'Attempted to end a replacement before finding the start');
744

845
test.doesNotThrow(() => {
946
test.deepEqual(
@@ -22,8 +59,8 @@ test('unist-util-find-all-between', (test) => {
2259
}
2360
]
2461
},
25-
0,
26-
2,
62+
{type: 'foo'},
63+
{type: 'baz'},
2764
(v) => [{type: 'test', data: v.length}]
2865
),
2966
[
@@ -33,7 +70,61 @@ test('unist-util-find-all-between', (test) => {
3370
}
3471
]
3572
);
36-
}, 'Replaces range with new output');
73+
}, 'Replaces single match with new output');
74+
75+
test.doesNotThrow(() => {
76+
test.deepEqual(
77+
findAllBetween(
78+
{
79+
type: 'foo',
80+
children: [
81+
{
82+
type: 'foo'
83+
},
84+
{
85+
type: 'bar'
86+
},
87+
{
88+
type: 'baz'
89+
},
90+
{
91+
type: 'hello'
92+
},
93+
94+
{
95+
type: 'foo'
96+
},
97+
{
98+
type: 'what'
99+
},
100+
{
101+
type: 'another'
102+
},
103+
{
104+
type: 'baz'
105+
},
106+
]
107+
},
108+
{type: 'foo'},
109+
{type: 'baz'},
110+
(v) => [{type: 'test', data: v.length}]
111+
),
112+
[
113+
{
114+
type: 'test',
115+
data: 3
116+
},
117+
{
118+
type: 'hello'
119+
},
120+
{
121+
type: 'test',
122+
data: 4
123+
}
124+
]
125+
);
126+
}, 'Replaces two matches with new output');
127+
37128

38129
test.end();
39130
});

types/index.d.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,16 @@ import {Node, Parent} from 'unist';
55
export = findAllBetween;
66

77
/**
8-
* A unist utility to get all children of a parent between two nodes or indices.
8+
* A unist utility to get all children of multiple different parents between two nodes or indices.
99
*
1010
* @param parent Parent node to search in
11-
* @param start A node or index to start search with
12-
* @param end A node or index to end search with
11+
* @param start A node to start search with
12+
* @param end A node to end search with
1313
* @param func The function ran to change the nodes
1414
*/
1515
declare function findAllBetween<T extends Node>(
1616
parent: Parent,
17-
start: Node | number,
18-
end: Node | number,
17+
start: Node,
18+
end: Node,
1919
func: (val: Node[]) => Node[]
20-
): Node[];
20+
): Node[][];

types/index.test-d.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ expectError(between(parent, n1, n2));
1717
/**
1818
* Incorrect types of arguments
1919
*/
20-
expectError(between((v: Node[]) => v));
21-
expectError(between(parent, (v: Node[]) => v));
22-
expectError(between(parent, n1, (v: Node[]) => v));
20+
expectError(between((v: Node[][]) => v));
21+
expectError(between(parent, (v: Node[][]) => v));
22+
expectError(between(parent, n1, (v: Node[][]) => v));
2323

2424
/**
2525
* Incorrect test type

0 commit comments

Comments
 (0)