Skip to content

Commit d5aade1

Browse files
committed
modified rfc6901
1 parent 91d1820 commit d5aade1

File tree

4 files changed

+49
-37
lines changed

4 files changed

+49
-37
lines changed

general.test.js

+5-6
Original file line numberDiff line numberDiff line change
@@ -123,11 +123,11 @@ describe('Various Test Cases', () => {
123123
})
124124

125125
it('is able to handle simple path escaping', async () => {
126-
for (const engine of [...normalEngines, ...permissiveEngines]) await testEngine(engine, { get: [{ var: 'selected' }, 'b\\.c'] }, { selected: { 'b.c': 2 } }, 2)
126+
for (const engine of [...normalEngines, ...permissiveEngines]) await testEngine(engine, { get: [{ var: 'selected' }, 'b~2c'] }, { selected: { 'b.c': 2 } }, 2)
127127
})
128128

129129
it('is able to handle simple path escaping in a variable', async () => {
130-
for (const engine of [...normalEngines, ...permissiveEngines]) await testEngine(engine, { get: [{ var: 'selected' }, { var: 'key' }] }, { selected: { 'b.c': 2 }, key: 'b\\.c' }, 2)
130+
for (const engine of [...normalEngines, ...permissiveEngines]) await testEngine(engine, { get: [{ var: 'selected' }, { var: 'key' }] }, { selected: { 'b.c': 2 }, key: 'b~2c' }, 2)
131131
})
132132

133133
it('is able to avoid returning functions', async () => {
@@ -154,24 +154,23 @@ describe('Various Test Cases', () => {
154154
})
155155

156156
it('is able to handle path escaping in a var call', async () => {
157-
for (const engine of [...normalEngines, ...permissiveEngines]) await testEngine(engine, { var: 'hello\\.world' }, { 'hello.world': 2 }, 2)
157+
for (const engine of [...normalEngines, ...permissiveEngines]) await testEngine(engine, { var: 'hello~2world' }, { 'hello.world': 2 }, 2)
158158
})
159159

160160
it('is able to access empty keys', async () => {
161161
for (const engine of [...normalEngines, ...permissiveEngines]) await testEngine(engine, { var: '.' }, { '': 2 }, 2)
162162
})
163163

164164
it('is able to access dot keys', async () => {
165-
for (const engine of [...normalEngines, ...permissiveEngines]) await testEngine(engine, { var: '\\.' }, { '.': 2 }, 2)
165+
for (const engine of [...normalEngines, ...permissiveEngines]) await testEngine(engine, { var: '~2' }, { '.': 2 }, 2)
166166
})
167167

168168
it('is able to access "/" keys from above', async () => {
169-
for (const engine of [...normalEngines, ...permissiveEngines]) await testEngine(engine, { map: [[1], { '+': [{ var: '' }, { var: '../../..\\/' }] }] }, { '': { '': { '/': 3 } } }, [4])
169+
for (const engine of [...normalEngines, ...permissiveEngines]) await testEngine(engine, { map: [[1], { '+': [{ var: '' }, { var: '../../..~1' }] }] }, { '': { '': { '/': 3 } } }, [4])
170170
})
171171

172172
it('is able to handle path escaping with multiple escapes', async () => {
173173
for (const engine of [...normalEngines, ...permissiveEngines]) await testEngine(engine, { var: '\\foo' }, { '\\foo': 2 }, 2)
174-
for (const engine of [...normalEngines, ...permissiveEngines]) await testEngine(engine, { var: '\\\\foo' }, { '\\foo': 2 }, 2)
175174
})
176175

177176
it('is able to access the index in the iterators', async () => {

suites/scopes.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
"rule": {
5959
"map": [
6060
{ "var": "arr" },
61-
{ "+": [{ "var": "../../\\.\\./" }, { "var": "../../..\\/" }]}
61+
{ "+": [{ "var": "../../~2~2~1" }, { "var": "../../..~1" }]}
6262
]
6363
},
6464
"data": { "arr": [1,2,3], "../": 10, "": { "": { "/": 7 }} },

suites/vars.json

+33-15
Original file line numberDiff line numberDiff line change
@@ -20,62 +20,80 @@
2020
},
2121
{
2222
"description": "Fetches a value from a key that is purely a dot",
23-
"rule": { "var": "\\." },
23+
"rule": { "var": "~2" },
2424
"data": { "." : 20 },
2525
"result": 20
2626
},
2727
{
2828
"description": "Fetches a value from a key with a dot in it",
29-
"rule": { "var": "\\.key" },
29+
"rule": { "var": "~2key" },
3030
"data": { ".key" : 4 },
3131
"result": 4
3232
},
3333
{
3434
"description":"Fetches a value from a key with a dot in it (2)",
35-
"rule": { "var": "hello\\.world" },
35+
"rule": { "var": "hello~2world" },
3636
"data": { "hello.world" : 5 },
3737
"result": 5
3838
},
3939
{
4040
"description": "Fetches a value from a key inside an empty key with a dot in it",
41-
"rule": { "var": ".\\.key" },
41+
"rule": { "var": "/~2key" },
4242
"data": { "": { ".key" : 6 } },
4343
"result": 6
4444
},
4545
{
4646
"description": "Going a few levels deep",
47-
"rule": { "var": "..\\.key." },
47+
"rule": { "var": "//~2key." },
4848
"data": { "": { "": { ".key": { "": 7 }} }},
4949
"result": 7
5050
},
5151
{
5252
"description": "Escape / as well, which is useful for the scope proposal",
53-
"rule": { "var": "\\/" },
53+
"rule": { "var": "~1" },
5454
"data": { "/" : 8 },
5555
"result": 8
5656
},
57-
{
58-
"description": "Though / doesn't inherently need to be escaped",
59-
"rule": { "var": "/" },
60-
"data": { "/" : 9 },
61-
"result": 9
62-
},
6357
{
6458
"description": "Dot then empty key",
65-
"rule": { "var": "\\.." },
59+
"rule": { "var": "~2." },
6660
"data": { "." : { "" : 10 } },
6761
"result": 10
6862
},
6963
{
7064
"description": "Empty key then dot",
71-
"rule": { "var": ".\\." },
65+
"rule": { "var": ".~2" },
7266
"data": { "" : { "." : 11 } },
7367
"result": 11
7468
},
7569
{
7670
"description": "Can use backslack in name, too",
77-
"rule": { "var": "\\\\.Hello" },
71+
"rule": { "var": "\\.Hello" },
7872
"data": { "\\" : { "Hello" : 12 } },
7973
"result": 12
74+
},
75+
{
76+
"description": "Can escape tilde",
77+
"rule": { "var": "~0" },
78+
"data": { "~" : 13 },
79+
"result": 13
80+
},
81+
{
82+
"description": "Fetches a value from an empty key, traditional",
83+
"rule": { "var": "/" },
84+
"data": { "" : 1 },
85+
"result": 1
86+
},
87+
{
88+
"description": "Fetches a value from a nested empty key, traditional",
89+
"rule": { "var": "//" },
90+
"data": { "" : { "": 2 } },
91+
"result": 2
92+
},
93+
{
94+
"description": "Fetches a value from a doubly nested empty key, traditional",
95+
"rule": { "var": "///" },
96+
"data": { "" : { "": { "": 3 } } },
97+
"result": 3
8098
}
8199
]

utilities/splitPath.js

+10-15
Original file line numberDiff line numberDiff line change
@@ -20,37 +20,32 @@ export function splitPathMemoized (str) {
2020
return parts
2121
}
2222

23+
const chars = ['~', '/', '.']
24+
2325
/**
2426
* Splits a path string into an array of parts.
2527
*
26-
* @example splitPath('a.b.c') // ['a', 'b', 'c']
27-
* @example splitPath('a\\.b.c') // ['a.b', 'c']
28-
* @example splitPath('a\\\\.b.c') // ['a\\', 'b', 'c']
29-
* @example splitPath('a\\\\\\.b.c') // ['a\\.b', 'c']
30-
* @example splitPath('hello') // ['hello']
31-
* @example splitPath('hello\\') // ['hello\\']
32-
* @example splitPath('hello\\\\') // ['hello\\']
3328
*
3429
* @param {string} str
3530
* @param {string} separator
3631
* @returns {string[]}
3732
*/
38-
export function splitPath (str, separator = '.', escape = '\\', up = '/') {
33+
export function splitPath (str) {
3934
const parts = []
4035
let current = ''
4136

4237
for (let i = 0; i < str.length; i++) {
4338
const char = str[i]
44-
if (char === escape) {
45-
if (str[i + 1] === separator || str[i + 1] === up) {
46-
current += str[i + 1]
39+
if (char === '~') {
40+
if (str[i + 1] === '0' || str[i + 1] === '1' || str[i + 1] === '2') {
41+
current += chars[+str[i + 1]]
4742
i++
48-
} else if (str[i + 1] === escape) {
49-
current += escape
43+
} else if (str[i + 1] === '~') {
44+
current += '~'
5045
i++
5146
// The following else might be something tweaked in a spec.
52-
} else current += escape
53-
} else if (char === separator) {
47+
} else throw new Error('Invalid escape sequence')
48+
} else if (char === '.' || char === '/') {
5449
parts.push(current)
5550
current = ''
5651
} else current += char

0 commit comments

Comments
 (0)