Skip to content

Commit

Permalink
feat(pipes): added formatDuration pipes
Browse files Browse the repository at this point in the history
Added two new pipes: `dfnsFormatDuration` and `dfnsFormatDurationPure`

BREAKING CHANGE: This version requires date-fns >= v2.16.0

#351
  • Loading branch information
joanllenas committed Mar 6, 2021
1 parent 2b45dc2 commit 03af4a5
Show file tree
Hide file tree
Showing 8 changed files with 457 additions and 149 deletions.
346 changes: 203 additions & 143 deletions README.md

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"build:app": "ng build --namedChunks=true --sourceMap=true --prod",
"analyze": "source-map-explorer dist/ngx-date-fns-app/main-es5.*.js",
"prettier": "prettier --write src/app/**/*.ts && prettier --write projects/ngx-date-fns/src/lib/**/*.ts",
"precommit": "npm run lint && npm run test -- --watch=false",
"precommit": "npm run lint && npm run test",
"e2e": "ng e2e",
"cm": "git-cz",
"cm-retry": "git-cz --retry",
Expand All @@ -60,7 +60,7 @@
"@angular/platform-browser": "~11.2.1",
"@angular/platform-browser-dynamic": "~11.2.1",
"@angular/router": "~11.2.1",
"date-fns": "^2.0.1",
"date-fns": "^2.19.0",
"rxjs": "~6.6.0",
"tslib": "^2.0.0",
"zone.js": "~0.10.2"
Expand Down
2 changes: 2 additions & 0 deletions projects/ngx-date-fns/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@ export * from './lib/start-of-week-year.pure.pipe';
export * from './lib/last-day-of-week.pure.pipe';
export * from './lib/parse.pure.pipe';
export * from './lib/parse-iso.pipe';
export * from './lib/format-duration.pure.pipe';
export * from './lib/format-duration.pipe';

// Other stuff
export * from './lib/types';
Expand Down
6 changes: 5 additions & 1 deletion projects/ngx-date-fns/src/lib/date-fns.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ import { StartOfWeekYearPurePipeModule } from './start-of-week-year.pure.pipe';
import { LastDayOfWeekPurePipeModule } from './last-day-of-week.pure.pipe';
import { ParsePurePipeModule } from './parse.pure.pipe';
import { ParseIsoPipeModule } from './parse-iso.pipe';
import { FormatDurationPipeModule } from './format-duration.pipe';
import { FormatDurationPurePipeModule } from './format-duration.pure.pipe';

const PIPES = [
AddBusinessDaysPipeModule,
Expand Down Expand Up @@ -265,7 +267,9 @@ const PIPES = [
StartOfWeekYearPurePipeModule,
LastDayOfWeekPurePipeModule,
ParsePurePipeModule,
ParseIsoPipeModule
ParseIsoPipeModule,
FormatDurationPipeModule,
FormatDurationPurePipeModule
];

@NgModule({
Expand Down
162 changes: 162 additions & 0 deletions projects/ngx-date-fns/src/lib/format-duration.pipe.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
import { ChangeDetectorRef } from '@angular/core';
import { DateFnsConfigurationService } from './date-fns-configuration.service';
import { FormatDurationPipe } from './format-duration.pipe';
import { es } from 'date-fns/locale';
import { FormatDurationPurePipe } from './format-duration.pure.pipe';

describe('FormatDurationPipe', () => {
let pipe: FormatDurationPipe;

const createPipe = () => {
const MyChangeDetector = class extends ChangeDetectorRef {
markForCheck(): void {
throw new Error('Method not implemented.');
}
detach(): void {
throw new Error('Method not implemented.');
}
detectChanges(): void {
throw new Error('Method not implemented.');
}
checkNoChanges(): void {
throw new Error('Method not implemented.');
}
reattach(): void {
throw new Error('Method not implemented.');
}
};
return new FormatDurationPipe(
new DateFnsConfigurationService(),
new MyChangeDetector()
);
};

beforeEach(() => {
pipe = createPipe();
});

it('should format full durations', () => {
expect(
pipe.transform({
years: 2,
months: 9,
weeks: 1,
days: 7,
hours: 5,
minutes: 9,
seconds: 30
})
).toBe('2 years 9 months 1 week 7 days 5 hours 9 minutes 30 seconds');
});

it('should format partial durations', () => {
expect(pipe.transform({ months: 9, days: 2 })).toBe('9 months 2 days');
});

it('should customize the format', () => {
expect(
pipe.transform(
{
years: 2,
months: 9,
weeks: 1,
days: 7,
hours: 5,
minutes: 9,
seconds: 30
},
{ format: ['months', 'weeks'] }
)
).toBe('9 months 1 week');
});

it('should customize the zeroes presence', () => {
expect(pipe.transform({ years: 0, months: 9 }, { zero: true })).toBe(
'0 years 9 months'
);
});

it('should customize the delimiter', () => {
expect(
pipe.transform({ years: 2, months: 9, weeks: 3 }, { delimiter: ', ' })
).toBe('2 years, 9 months, 3 weeks');
});

it('should customize the locale', () => {
expect(
pipe.transform({ years: 2, months: 9, weeks: 3 }, { locale: es })
).toBe('2 años 9 meses 3 semanas');
});
});

describe('FormatDurationPipe Pure', () => {
const createPipe = () =>
new FormatDurationPurePipe(new DateFnsConfigurationService());

it('should format full durations', () => {
expect(
createPipe().transform({
years: 2,
months: 9,
weeks: 1,
days: 7,
hours: 5,
minutes: 9,
seconds: 30
})
).toBe('2 years 9 months 1 week 7 days 5 hours 9 minutes 30 seconds');
});

it('should format partial durations', () => {
expect(createPipe().transform({ months: 9, days: 2 })).toBe(
'9 months 2 days'
);
});

it('should customize the format', () => {
expect(
createPipe().transform(
{
years: 2,
months: 9,
weeks: 1,
days: 7,
hours: 5,
minutes: 9,
seconds: 30
},
{ format: ['months', 'weeks'] }
)
).toBe('9 months 1 week');
});

it('should customize the zeroes presence', () => {
expect(
createPipe().transform({ years: 0, months: 9 }, { zero: true })
).toBe('0 years 9 months');
});

it('should customize the delimiter', () => {
expect(
createPipe().transform(
{ years: 2, months: 9, weeks: 3 },
{ delimiter: ', ' }
)
).toBe('2 years, 9 months, 3 weeks');
});

it('should customize the locale', () => {
expect(
createPipe().transform({ years: 2, months: 9, weeks: 3 }, { locale: es })
).toBe('2 años 9 meses 3 semanas');
});

it('should customize the locale provided via config', () => {
const conf = new DateFnsConfigurationService();
conf.setLocale(es);
const pipe = new FormatDurationPurePipe(conf);
expect(pipe.transform({ years: 2, months: 9, weeks: 3 })).toBe(
'2 años 9 meses 3 semanas'
);
});
});
50 changes: 50 additions & 0 deletions projects/ngx-date-fns/src/lib/format-duration.pipe.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import {
Pipe,
PipeTransform,
ChangeDetectorRef,
OnDestroy,
NgModule
} from '@angular/core';
import {
DateFnsConfigurationService,
calculateLocale
} from './date-fns-configuration.service';
import { Subscription } from 'rxjs';
import { Locale } from 'date-fns';
import formatDuration from 'date-fns/formatDuration';

@Pipe({ name: 'dfnsFormatDuration', pure: false })
export class FormatDurationPipe implements PipeTransform, OnDestroy {
private localeChanged$: Subscription;

constructor(
public config: DateFnsConfigurationService,
public cd: ChangeDetectorRef
) {
this.localeChanged$ = this.config.localeChanged.subscribe(_ =>
this.cd.markForCheck()
);
}

ngOnDestroy(): void {
this.localeChanged$.unsubscribe();
}

transform(
duration: Duration,
options?: {
format?: string[];
zero?: boolean;
delimiter?: string;
locale?: Locale;
}
): string {
return formatDuration(duration, calculateLocale(options, this.config));
}
}

@NgModule({
declarations: [FormatDurationPipe],
exports: [FormatDurationPipe]
})
export class FormatDurationPipeModule {}
30 changes: 30 additions & 0 deletions projects/ngx-date-fns/src/lib/format-duration.pure.pipe.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { NgModule, Pipe, PipeTransform } from '@angular/core';
import { Locale } from 'date-fns';
import formatDuration from 'date-fns/formatDuration';
import {
calculateLocale,
DateFnsConfigurationService
} from './date-fns-configuration.service';

@Pipe({ name: 'dfnsFormatDurationPure' })
export class FormatDurationPurePipe implements PipeTransform {
constructor(public config: DateFnsConfigurationService) {}

transform(
duration: Duration,
options?: {
format?: string[];
zero?: boolean;
delimiter?: string;
locale?: Locale;
}
): string {
return formatDuration(duration, calculateLocale(options, this.config));
}
}

@NgModule({
declarations: [FormatDurationPurePipe],
exports: [FormatDurationPurePipe]
})
export class FormatDurationPurePipeModule {}

0 comments on commit 03af4a5

Please sign in to comment.