-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: add preParsePostFormat plugin & update Arabic [ar] locale (#1255)
- Loading branch information
Showing
6 changed files
with
320 additions
and
2 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,47 @@ | ||
// Plugin template from https://day.js.org/docs/en/plugin/plugin | ||
export default (option, dayjsClass) => { | ||
const oldParse = dayjsClass.prototype.parse | ||
dayjsClass.prototype.parse = function (cfg) { | ||
if (typeof cfg.date === 'string') { | ||
const locale = this.$locale() | ||
cfg.date = | ||
locale && locale.preparse ? locale.preparse(cfg.date) : cfg.date | ||
} | ||
// original parse result | ||
return oldParse.bind(this)(cfg) | ||
} | ||
|
||
// // overriding existing API | ||
// // e.g. extend dayjs().format() | ||
const oldFormat = dayjsClass.prototype.format | ||
dayjsClass.prototype.format = function (...args) { | ||
// original format result | ||
const result = oldFormat.call(this, ...args) | ||
// return modified result | ||
const locale = this.$locale() | ||
return locale && locale.postformat ? locale.postformat(result) : result | ||
} | ||
|
||
const oldFromTo = dayjsClass.prototype.fromToBase | ||
|
||
if (oldFromTo) { | ||
dayjsClass.prototype.fromToBase = function ( | ||
input, | ||
withoutSuffix, | ||
instance, | ||
isFrom | ||
) { | ||
const locale = this.$locale() || instance.$locale() | ||
|
||
// original format result | ||
return oldFromTo.call( | ||
this, | ||
input, | ||
withoutSuffix, | ||
instance, | ||
isFrom, | ||
locale && locale.postformat | ||
) | ||
} | ||
} | ||
} |
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,52 @@ | ||
import moment from 'moment' | ||
import MockDate from 'mockdate' | ||
import dayjs from '../../src' | ||
import relativeTime from '../../src/plugin/relativeTime' | ||
import preParsePostFormat from '../../src/plugin/preParsePostFormat' | ||
import localeData from '../../src/plugin/localeData' | ||
import '../../src/locale/ar' | ||
|
||
dayjs.extend(localeData) | ||
dayjs.extend(relativeTime) | ||
dayjs.extend(preParsePostFormat) | ||
|
||
beforeEach(() => { | ||
MockDate.set(new Date()) | ||
}) | ||
|
||
afterEach(() => { | ||
MockDate.reset() | ||
}) | ||
|
||
it('Format Month with locale function', () => { | ||
for (let i = 0; i <= 7; i += 1) { | ||
const dayjsAR = dayjs().locale('ar').add(i, 'day') | ||
const momentAR = moment().locale('ar').add(i, 'day') | ||
const testFormat1 = 'DD MMMM YYYY MMM' | ||
const testFormat2 = 'MMMM' | ||
const testFormat3 = 'MMM' | ||
expect(dayjsAR.format(testFormat1)).toEqual(momentAR.format(testFormat1)) | ||
expect(dayjsAR.format(testFormat2)).toEqual(momentAR.format(testFormat2)) | ||
expect(dayjsAR.format(testFormat3)).toEqual(momentAR.format(testFormat3)) | ||
} | ||
}) | ||
|
||
it('Preparse with locale function', () => { | ||
for (let i = 0; i <= 7; i += 1) { | ||
dayjs.locale('ar') | ||
const momentAR = moment().locale('ar').add(i, 'day') | ||
expect(dayjs(momentAR.format()).format()).toEqual(momentAR.format()) | ||
} | ||
}) | ||
|
||
it('RelativeTime: Time from X gets formatted', () => { | ||
const T = [ | ||
[44.4, 'second', 'منذ ثانية واحدة'] | ||
] | ||
|
||
T.forEach((t) => { | ||
dayjs.locale('ar') | ||
expect(dayjs().from(dayjs().add(t[0], t[1]))) | ||
.toBe(t[2]) | ||
}) | ||
}) |
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,169 @@ | ||
import MockDate from 'mockdate' | ||
// import moment from 'moment' | ||
import dayjs from '../../src' | ||
import preParsePostFormat from '../../src/plugin/preParsePostFormat' | ||
import localeData from '../../src/plugin/localeData' | ||
import duration from '../../src/plugin/duration' | ||
import calendar from '../../src/plugin/calendar' | ||
import objectSupport from '../../src/plugin/objectSupport' | ||
import customParseFormat from '../../src/plugin/customParseFormat' | ||
import relativeTime from '../../src/plugin/relativeTime' | ||
import utc from '../../src/plugin/utc' | ||
import arraySupport from '../../src/plugin/arraySupport' | ||
import en from '../../src/locale/en' | ||
|
||
dayjs.extend(utc) | ||
dayjs.extend(localeData) | ||
dayjs.extend(customParseFormat) | ||
dayjs.extend(arraySupport) | ||
dayjs.extend(objectSupport) | ||
dayjs.extend(calendar) | ||
dayjs.extend(duration) | ||
dayjs.extend(relativeTime) | ||
dayjs.extend(preParsePostFormat) | ||
|
||
const symbolMap = { | ||
1: '!', | ||
2: '@', | ||
3: '#', | ||
4: '$', | ||
5: '%', | ||
6: '^', | ||
7: '&', | ||
8: '*', | ||
9: '(', | ||
0: ')' | ||
} | ||
const numberMap = { | ||
'!': '1', | ||
'@': '2', | ||
'#': '3', | ||
$: '4', | ||
'%': '5', | ||
'^': '6', | ||
'&': '7', | ||
'*': '8', | ||
'(': '9', | ||
')': '0' | ||
} | ||
|
||
const localeCustomizations = { | ||
...en, | ||
preparse(string) { | ||
if (typeof string !== 'string') { | ||
// console.error('preparse - Expected string, got', { | ||
// string | ||
// }) | ||
throw new Error(`preparse - Expected string, got ${typeof string}`) | ||
} | ||
try { | ||
const res = string.replace(/[!@#$%^&*()]/g, match => numberMap[match]) | ||
// console.log('Called custom preparse', { string, res }) | ||
return res | ||
} catch (error) { | ||
const errorMsg = `Unexpected error during preparse of '${string}' - ${error}` | ||
// console.error(errorMsg) | ||
throw new Error(errorMsg) | ||
} | ||
}, | ||
postformat(string) { | ||
if (typeof string !== 'string') { | ||
// console.error('postformat - Expected string, got', { | ||
// string | ||
// }) | ||
throw new Error(`postformat - Expected string, got ${typeof string}`) | ||
} | ||
try { | ||
const res = string.replace(/\d/g, match => symbolMap[match]) | ||
// console.log('Called custom postformat', { string, res }) | ||
return res | ||
} catch (error) { | ||
const errorMsg = `Unexpected error during postFormat of '${string}' - ${error}` | ||
// console.error(errorMsg) | ||
throw new Error(errorMsg) | ||
} | ||
} | ||
} | ||
|
||
beforeEach(() => { | ||
MockDate.set(new Date()) | ||
dayjs.locale('symbol', localeCustomizations) | ||
}) | ||
|
||
afterEach(() => { | ||
MockDate.reset() | ||
dayjs.locale('symbol', null) | ||
}) | ||
|
||
describe('preparse and postformat', () => { | ||
describe('transform', () => { | ||
const TEST_DATE = '@)!@-)*-@&' | ||
const TEST_NUM = 1346025600 | ||
it('preparse string + format', () => | ||
expect(dayjs.utc(TEST_DATE, 'YYYY-MM-DD').unix()).toBe(TEST_NUM)) | ||
it('preparse ISO8601 string', () => | ||
expect(dayjs.utc(TEST_DATE).unix()).toBe(TEST_NUM)) | ||
it('postformat', () => | ||
expect(dayjs | ||
.unix(TEST_NUM) | ||
.utc() | ||
.format('YYYY-MM-DD')) | ||
.toBe(TEST_DATE)) | ||
}) | ||
|
||
describe('transform from', () => { | ||
dayjs.locale('symbol', localeCustomizations) | ||
const start = dayjs([2007, 1, 28]) | ||
|
||
const t1 = dayjs([2007, 1, 28]).add({ s: 90 }) | ||
it('postformat should work on dayjs.fn.from', () => | ||
expect(start.from(t1, true)).toBe('@ minutes')) | ||
|
||
const t2 = dayjs().add(6, 'd') | ||
it('postformat should work on dayjs.fn.fromNow', () => | ||
expect(t2.fromNow(true)).toBe('^ days')) | ||
|
||
it('postformat should work on dayjs.duration.fn.humanize', () => | ||
expect(dayjs.duration(10, 'h').humanize()).toBe('!) hours')) | ||
}) | ||
}) | ||
|
||
describe('calendar day', () => { | ||
const a = dayjs() | ||
.hour(12) | ||
.minute(0) | ||
.second(0) | ||
|
||
it('today at the same time', () => | ||
expect(dayjs(a).calendar()).toBe('Today at !@:)) PM')) | ||
|
||
it('Now plus 25 min', () => | ||
expect(dayjs(a) | ||
.add({ m: 25 }) | ||
.calendar()) | ||
.toBe('Today at !@:@% PM')) | ||
|
||
it('Now plus 1 hour', () => | ||
expect(dayjs(a) | ||
.add({ h: 1 }) | ||
.calendar()) | ||
.toBe('Today at !:)) PM')) | ||
|
||
it('tomorrow at the same time', () => | ||
expect(dayjs(a) | ||
.add({ d: 1 }) | ||
.calendar()) | ||
.toBe('Tomorrow at !@:)) PM')) | ||
|
||
it('Now minus 1 hour', () => | ||
expect(dayjs(a) | ||
.subtract({ h: 1 }) | ||
.calendar()) | ||
.toBe('Today at !!:)) AM')) | ||
|
||
it('yesterday at the same time', () => | ||
expect(dayjs(a) | ||
.subtract({ d: 1 }) | ||
.calendar()) | ||
.toBe('Yesterday at !@:)) PM')) | ||
}) |
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,4 @@ | ||
import { PluginFunc } from 'dayjs' | ||
|
||
declare const plugin: PluginFunc | ||
export = plugin |