generated from Tinkoff/angular-open-source-starter
-
Notifications
You must be signed in to change notification settings - Fork 35
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(kit):
DateTime
fails to process value without any separators (p…
…aste from clipboard) (#1779)
- Loading branch information
1 parent
8f4253f
commit 1733422
Showing
8 changed files
with
169 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/** | ||
* Cypress does not have built-in support for pasting from clipboard. | ||
* This utility is VERY approximate alternative for it. | ||
* | ||
* @see https://github.com/cypress-io/cypress/issues/28861 | ||
*/ | ||
export function paste<T extends Cypress.PrevSubjectMap['element']>( | ||
$subject: T, | ||
data: string, | ||
): ReturnType<Cypress.CommandFn<'paste'>> { | ||
const inputType = 'insertFromPaste'; | ||
const element = Cypress.dom.unwrap($subject)[0] as | ||
| HTMLInputElement | ||
| HTMLTextAreaElement; | ||
const {value, selectionStart, selectionEnd} = element; | ||
|
||
Cypress.log({ | ||
displayName: 'paste', | ||
message: data, | ||
consoleProps() { | ||
return { | ||
value, | ||
selectionStart, | ||
selectionEnd, | ||
}; | ||
}, | ||
}); | ||
|
||
return cy | ||
.wrap($subject, {log: false}) | ||
.trigger('beforeinput', { | ||
inputType, | ||
data, | ||
log: false, | ||
}) | ||
.invoke( | ||
'val', | ||
value.slice(0, selectionStart ?? 0) + data + value.slice(selectionEnd ?? 0), | ||
) | ||
.trigger('input', { | ||
inputType, | ||
data, | ||
log: false, | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
29 changes: 13 additions & 16 deletions
29
projects/kit/src/lib/masks/date-time/utils/parse-date-time-string.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,18 @@ | ||
const NON_DIGIT_PLACEHOLDER_RE = /[^dmy]/g; | ||
const LEADING_NON_DIGIT_RE = /^\D*/; | ||
|
||
export function parseDateTimeString( | ||
dateTime: string, | ||
{ | ||
dateModeTemplate, | ||
dateTimeSeparator, | ||
}: { | ||
dateModeTemplate: string; | ||
dateTimeSeparator: string; | ||
}, | ||
dateModeTemplate: string, | ||
): [date: string, time: string] { | ||
const hasSeparator = dateTime.includes(dateTimeSeparator); | ||
const dateDigitsCount = dateModeTemplate.replaceAll( | ||
NON_DIGIT_PLACEHOLDER_RE, | ||
'', | ||
).length; | ||
const [date = ''] = | ||
new RegExp(`(\\d[^\\d]*){0,${dateDigitsCount - 1}}\\d?`).exec(dateTime) || []; | ||
const [dateTimeSeparator = ''] = | ||
LEADING_NON_DIGIT_RE.exec(dateTime.slice(date.length)) || []; | ||
|
||
return [ | ||
dateTime.slice(0, dateModeTemplate.length), | ||
dateTime.slice( | ||
hasSeparator | ||
? dateModeTemplate.length + dateTimeSeparator.length | ||
: dateModeTemplate.length, | ||
), | ||
]; | ||
return [date, dateTime.slice(date.length + dateTimeSeparator.length)]; | ||
} |
63 changes: 63 additions & 0 deletions
63
projects/kit/src/lib/masks/date-time/utils/tests/parse-date-time-string.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import {parseDateTimeString} from '../parse-date-time-string'; | ||
|
||
describe('parseDateTimeString', () => { | ||
describe('dd.mm.yyyy', () => { | ||
const parse = (value: string): [string, string] => | ||
parseDateTimeString(value, 'dd.mm.yyyy'); | ||
|
||
( | ||
[ | ||
{input: '', output: ['', '']}, | ||
{input: '02', output: ['02', '']}, | ||
{input: '02.', output: ['02.', '']}, | ||
{input: '0211', output: ['0211', '']}, | ||
{input: '0211.', output: ['0211.', '']}, | ||
{input: '02.112018', output: ['02.112018', '']}, | ||
{input: '02.112018,', output: ['02.112018', '']}, | ||
{input: '02.112018, ', output: ['02.112018', '']}, | ||
{input: '02.11.2018, ', output: ['02.11.2018', '']}, | ||
{input: '021120181620', output: ['02112018', '1620']}, | ||
{input: '02112018,1620', output: ['02112018', '1620']}, | ||
{input: '02112018, 1620', output: ['02112018', '1620']}, | ||
{input: '02112018, 16:20', output: ['02112018', '16:20']}, | ||
{input: '02112018,16:20', output: ['02112018', '16:20']}, | ||
{input: '02.11.2018,1620', output: ['02.11.2018', '1620']}, | ||
{input: '02.11.2018, 1620', output: ['02.11.2018', '1620']}, | ||
{input: '02.11.2018, 16:20', output: ['02.11.2018', '16:20']}, | ||
{input: '02.11.2018,16:20', output: ['02.11.2018', '16:20']}, | ||
] as const | ||
).forEach(({input, output}) => { | ||
it(`${input} -> ${JSON.stringify(output)}`, () => { | ||
expect(parse(input)).toEqual(output); | ||
}); | ||
}); | ||
}); | ||
|
||
describe('dd. mm. yyyy (date segment separator consists of space and dot)', () => { | ||
const parse = (value: string): [string, string] => | ||
parseDateTimeString(value, 'dd. mm. yyyy'); | ||
|
||
( | ||
[ | ||
{input: '', output: ['', '']}, | ||
{input: '02', output: ['02', '']}, | ||
{input: '02.', output: ['02.', '']}, | ||
{input: '02. ', output: ['02. ', '']}, | ||
{input: '0211', output: ['0211', '']}, | ||
{input: '0211. ', output: ['0211. ', '']}, | ||
{input: '02. 112018', output: ['02. 112018', '']}, | ||
{input: '02. 112018,', output: ['02. 112018', '']}, | ||
{input: '02. 112018, ', output: ['02. 112018', '']}, | ||
{input: '02. 11. 2018, ', output: ['02. 11. 2018', '']}, | ||
{input: '02. 11. 2018,1620', output: ['02. 11. 2018', '1620']}, | ||
{input: '02. 11. 2018, 1620', output: ['02. 11. 2018', '1620']}, | ||
{input: '02. 11. 2018, 16:20', output: ['02. 11. 2018', '16:20']}, | ||
{input: '02. 11. 2018,16:20', output: ['02. 11. 2018', '16:20']}, | ||
] as const | ||
).forEach(({input, output}) => { | ||
it(`${input} -> ${JSON.stringify(output)}`, () => { | ||
expect(parse(input)).toEqual(output); | ||
}); | ||
}); | ||
}); | ||
}); |