diff --git a/src/index.js b/src/index.js index 112ae33b0..a80fcd3ac 100644 --- a/src/index.js +++ b/src/index.js @@ -232,7 +232,8 @@ class Dayjs { number = Number(number) // eslint-disable-line no-param-reassign const unit = Utils.p(units) const instanceFactory = (u, n) => { - const date = this.set(C.DATE, 1).set(u, n + number) + // clone is for badMutable plugin + const date = this.clone().set(C.DATE, 1).set(u, n + number) return date.set(C.DATE, Math.min(this.$D, date.daysInMonth())) } const instanceFactorySet = (n) => { @@ -343,7 +344,8 @@ class Dayjs { } daysInMonth() { - return this.endOf(C.M).$D + // clone is for badMutable plugin + return this.clone().endOf(C.M).$D } $locale() { // get locale object diff --git a/src/plugin/badMutable/index.js b/src/plugin/badMutable/index.js new file mode 100644 index 000000000..d8c362400 --- /dev/null +++ b/src/plugin/badMutable/index.js @@ -0,0 +1,26 @@ +export default (o, c) => { // locale needed later + const proto = c.prototype + proto.$g = function (input, get, set) { + if (this.$utils().u(input)) return this[get] + return this.$set(set, input) + } + + proto.set = function (string, int) { + return this.$set(string, int) + } + + const oldStartOf = proto.startOf + proto.startOf = function (units, startOf) { + this.$d = oldStartOf.bind(this)(units, startOf).toDate() + this.init() + return this + } + + const oldAdd = proto.add + proto.add = function (number, units) { + this.$d = oldAdd.bind(this)(number, units).toDate() + this.init() + return this + } +} + diff --git a/test/plugin/badMutable.test.js b/test/plugin/badMutable.test.js new file mode 100644 index 000000000..e2413df84 --- /dev/null +++ b/test/plugin/badMutable.test.js @@ -0,0 +1,150 @@ +import MockDate from 'mockdate' +import moment from 'moment' +import dayjs from '../../src' +import badMutable from '../../src/plugin/badMutable' + +dayjs.extend(badMutable) + +beforeEach(() => { + MockDate.set(new Date()) +}) + +afterEach(() => { + MockDate.reset() +}) + +describe('Set', () => { + it('Setters', () => { + const d = dayjs() + const m = moment() + expect(d.year()).toBe(m.year()) + d.year(2000) + m.year(2000) + expect(d.format()).toBe(m.format()) + d.month(1) + m.month(1) + expect(d.format()).toBe(m.format()) + d.day(1) + m.day(1) + expect(d.format()).toBe(m.format()) + d.date(1) + m.date(1) + expect(d.format()).toBe(m.format()) + d.hour(1) + m.hour(1) + expect(d.format()).toBe(m.format()) + d.minute(1) + m.minute(1) + expect(d.format()).toBe(m.format()) + d.second(1) + m.second(1) + expect(d.format()).toBe(m.format()) + d.millisecond(1) + m.millisecond(1) + expect(d.format()).toBe(m.format()) + }) + + it('Set', () => { + const d = dayjs() + const m = moment() + d.set('year', 2000) + m.set('year', 2000) + expect(d.format()).toBe(m.format()) + d.set('month', 12) + m.set('month', 12) + expect(d.format()).toBe(m.format()) + d.set('day', 1) + m.set('day', 1) + expect(d.format()).toBe(m.format()) + d.set('date', 1) + m.set('date', 1) + expect(d.format()).toBe(m.format()) + d.set('hour', 1) + m.set('hour', 1) + expect(d.format()).toBe(m.format()) + d.set('minute', 1) + m.set('minute', 1) + expect(d.format()).toBe(m.format()) + d.set('second', 1) + m.set('second', 1) + expect(d.format()).toBe(m.format()) + d.set('millisecond', 1) + m.set('millisecond', 1) + expect(d.format()).toBe(m.format()) + }) +}) + +describe('StartOf', () => { + it('StartOf', () => { + const d = dayjs() + const m = moment() + d.startOf('year') + m.startOf('year') + expect(d.format()).toBe(m.format()) + d.startOf('month') + m.startOf('month') + expect(d.format()).toBe(m.format()) + d.startOf('day') + m.startOf('day') + expect(d.format()).toBe(m.format()) + d.startOf('date') + m.startOf('date') + expect(d.format()).toBe(m.format()) + d.startOf('hour') + m.startOf('hour') + expect(d.format()).toBe(m.format()) + d.startOf('minute') + m.startOf('minute') + expect(d.format()).toBe(m.format()) + d.startOf('second') + m.startOf('second') + expect(d.format()).toBe(m.format()) + d.startOf('millisecond') + m.startOf('millisecond') + expect(d.format()).toBe(m.format()) + d.startOf('week') + m.startOf('week') + expect(d.format()).toBe(m.format()) + }) +}) + +describe('Add', () => { + it('Add', () => { + const d = dayjs() + const m = moment() + d.add(1, 'year') + m.add(1, 'year') + expect(d.format()).toBe(m.format()) + d.add(12, 'month') + m.add(12, 'month') + expect(d.format()).toBe(m.format()) + d.add(1, 'day') + m.add(1, 'day') + expect(d.format()).toBe(m.format()) + d.add(1, 'date') + m.add(1, 'date') + expect(d.format()).toBe(m.format()) + d.add(1, 'hour') + m.add(1, 'hour') + expect(d.format()).toBe(m.format()) + d.add(1, 'minute') + m.add(1, 'minute') + expect(d.format()).toBe(m.format()) + d.add(1, 'second') + m.add(1, 'second') + expect(d.format()).toBe(m.format()) + d.add(1, 'millisecond') + m.add(1, 'millisecond') + expect(d.format()).toBe(m.format()) + d.add(1, 'week') + m.add(1, 'week') + expect(d.format()).toBe(m.format()) + }) +}) + +it('daysInMonth', () => { + const d = dayjs() + const m = moment() + expect(d.daysInMonth()).toBe(m.daysInMonth()) + expect(d.format()).toBe(m.format()) +}) diff --git a/types/plugin/badMutable.d.ts b/types/plugin/badMutable.d.ts new file mode 100644 index 000000000..30ec75e5d --- /dev/null +++ b/types/plugin/badMutable.d.ts @@ -0,0 +1,4 @@ +import { PluginFunc } from 'dayjs' + +declare const plugin: PluginFunc +export = plugin