Skip to content

Commit

Permalink
fix(keyboard): parse escaped bracket followed by descriptor (#814)
Browse files Browse the repository at this point in the history
  • Loading branch information
ph-fritsche committed Dec 30, 2021
1 parent 2c5d9f1 commit 684451f
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 35 deletions.
18 changes: 8 additions & 10 deletions src/utils/keyDef/readNextDescriptor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,7 @@ export function readNextDescriptor(text: string) {

pos += startBracket.length

// `foo{{bar` is an escaped char at position 3,
// but `foo{{{>5}bar` should be treated as `{` pressed down for 5 keydowns.
const startBracketRepeated = startBracket
? (text.match(new RegExp(`^\\${startBracket}+`)) as RegExpMatchArray)[0]
.length
: 0
const isEscapedChar =
startBracketRepeated === 2 ||
(startBracket === '{' && startBracketRepeated > 3)
const isEscapedChar = new RegExp(`^\\${startBracket}{2}`).test(text)

const type = isEscapedChar ? '' : startBracket

Expand Down Expand Up @@ -64,7 +56,13 @@ function readTag(

pos += releasePreviousModifier.length

const descriptor = text.slice(pos).match(/^\w+/)?.[0]
const escapedDescriptor = startBracket === '{' && text[pos] === '\\'

pos += Number(escapedDescriptor)

const descriptor = escapedDescriptor
? text[pos]
: text.slice(pos).match(startBracket === '{' ? /^\w+|^[^}>/]/ : /^\w+/)?.[0]

assertDescriptor(descriptor, text, pos)

Expand Down
4 changes: 2 additions & 2 deletions tests/keyboard/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ it('type asynchronous', async () => {
})

it('error in async', async () => {
await expect(userEvent.keyboard('{!', {delay: 1})).rejects.toThrowError(
'Expected key descriptor but found "!" in "{!"',
await expect(userEvent.keyboard('[!', {delay: 1})).rejects.toThrowError(
'Expected key descriptor but found "!" in "[!"',
)
})

Expand Down
84 changes: 61 additions & 23 deletions tests/keyboard/parseKeyDef.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,66 @@ import {keyboardKey} from '#src/keyboard/types'

cases(
'reference key per',
({text, key, code}) => {
({text, keyDef}) => {
const parsed = parseKeyDef(defaultKeyMap, `/${text}/`)
expect(parsed).toHaveLength(3)
expect(parsed[1]).toEqual({
keyDef: expect.objectContaining({
key,
code,
}) as keyboardKey,
releasePrevious: false,
releaseSelf: true,
repeat: 1,
})
keyDef = Array.isArray(keyDef) ? keyDef : [keyDef]
expect(parsed).toHaveLength(2 + keyDef.length)
expect(parsed.slice(1, -1)).toEqual(
keyDef.map(d =>
expect.objectContaining({
keyDef: expect.objectContaining(d) as keyboardKey,
}),
),
)
},
{
code: {text: '[ControlLeft]', key: 'Control', code: 'ControlLeft'},
'unimplemented code': {text: '[Foo]', key: 'Unknown', code: 'Foo'},
key: {text: '{Control}', key: 'Control', code: 'ControlLeft'},
'unimplemented key': {text: '{Foo}', key: 'Foo', code: 'Unknown'},
'printable character': {text: 'a', key: 'a', code: 'KeyA'},
'modifiers as printable characters': {text: '/', key: '/', code: 'Unknown'},
'{ as printable': {text: '{{', key: '{', code: 'Unknown'},
'[ as printable': {text: '[[', key: '[', code: 'Unknown'},
code: {
text: '[ControlLeft]',
keyDef: {key: 'Control', code: 'ControlLeft'},
},
'unimplemented code': {
text: '[Foo]',
keyDef: {key: 'Unknown', code: 'Foo'},
},
key: {
text: '{Control}',
keyDef: {key: 'Control', code: 'ControlLeft'},
},
'unimplemented key': {
text: '{Foo}',
keyDef: {key: 'Foo', code: 'Unknown'},
},
'printable character': {
text: 'a',
keyDef: {key: 'a', code: 'KeyA'},
},
'modifiers as printable characters': {
text: '/',
keyDef: {key: '/', code: 'Unknown'},
},
'{ as printable': {
text: '{{',
keyDef: {key: '{', code: 'Unknown'},
},
'{ as printable followed by descriptor': {
text: '{{{foo}',
keyDef: [
{key: '{', code: 'Unknown'},
{key: 'foo', code: 'Unknown'},
],
},
'{ as key with modifiers': {
text: '{\\{>5/}',
keyDef: {key: '{', code: 'Unknown'},
},
'modifier as key with modifiers': {
text: '{/\\/>5/}',
keyDef: {key: '/', code: 'Unknown'},
},
'[ as printable': {
text: '[[',
keyDef: {key: '[', code: 'Unknown'},
},
},
)

Expand Down Expand Up @@ -79,10 +117,6 @@ cases(
expect(() => parseKeyDef(defaultKeyMap, `${text}`)).toThrow(expectedError)
},
{
'invalid descriptor': {
text: '{!}',
expectedError: 'but found "!" in "{!}"',
},
'missing descriptor': {
text: '',
expectedError: 'but found "" in ""',
Expand All @@ -99,5 +133,9 @@ cases(
text: '{a>3)',
expectedError: 'but found ")" in "{a>3)"',
},
'unescaped modifier': {
text: '{/>5}',
expectedError: 'but found ">" in "{/>5}"',
},
},
)

0 comments on commit 684451f

Please sign in to comment.