-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Preparse postformat + implementation in ar locale + tests #1255
Merged
Merged
Changes from 5 commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
acd8736
Merge pull request #1 from iamkun/dev
VehpuS e4f4b02
feat: add preparse and postformat features to locales as a plugin
VehpuS 0211f07
test: translate moment tests for preparse postformat for the new plugin
VehpuS e26e802
feat: add preparse postformat to ar locale from moment
VehpuS a5b9200
test: add test for ar locale to ensure preparse and postformat works
VehpuS e565267
refactor: change preparse-postformat to require importing localedata …
VehpuS File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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,53 @@ | ||
import localeData from '../localeData' | ||
|
||
// Plugin template from https://day.js.org/docs/en/plugin/plugin | ||
export default (option, dayjsClass, dayjsFactory) => { | ||
// This plugin depends on other plugins - so I will import them here | ||
// equivalent to dayjsClass.extend(duration) | ||
localeData(option, dayjsClass, dayjsFactory) | ||
|
||
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.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.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,50 @@ | ||
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 '../../src/locale/ar' | ||
|
||
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,167 @@ | ||
import MockDate from 'mockdate' | ||
// import moment from 'moment' | ||
import dayjs from '../../src' | ||
import preParsePostFormat from '../../src/plugin/preParsePostFormat' | ||
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(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 |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we don't have to import other plugins like this.
Just listing the dependent plugin in the doc.