Skip to content
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

feat(pipes): added formatDuration pipes #353

Merged
merged 1 commit into from
Mar 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 {}