Skip to content
This repository has been archived by the owner on Dec 8, 2022. It is now read-only.

Replace CurrencyPipe and DecimalPipe with custom utility #74

Merged
merged 2 commits into from
May 2, 2019
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
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@
"peerDependencies": {
"@angular/common": ">=4.3.6",
"@angular/core": ">=4.3.6",
"@skyux/i18n": "^3.3.0"
"@skyux/i18n": "^3.6.0"
},
"dependencies": {},
"devDependencies": {
"@blackbaud/skyux": "2.43.0",
"@blackbaud/skyux-builder": "1.33.0",
"@skyux-sdk/builder-plugin-skyux": "1.0.0-rc.6"
"@blackbaud/skyux": "2.48.3",
"@blackbaud/skyux-builder": "1.34.0",
"@skyux-sdk/builder-plugin-skyux": "1.0.0"
}
}
4 changes: 4 additions & 0 deletions src/app/public/modules/format/format.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ export {
} from './app-format';

export class SkyFormat {

/* istanbul ignore next */
constructor() { }

public static formatText(
format: string,
...args: any[]
Expand Down
65 changes: 65 additions & 0 deletions src/app/public/modules/numeric/number-format-utility.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/* tslint:disable:no-null-keyword */
import {
SkyIntlNumberFormatStyle
} from '@skyux/i18n/modules/i18n/intl-number-format-style';

import {
SkyNumberFormatUtility
} from './number-format-utility';

function formatCurrency(value: any, digits: string): string {
return SkyNumberFormatUtility.formatNumber(
'en-US',
value,
SkyIntlNumberFormatStyle.Currency,
digits,
'USD',
true
);
}

describe('Number format utility', function () {

it('should format currency from number strings', function () {
const result = formatCurrency('50.00', '');

expect(result).toEqual('$50.00');
});

it('should throw error for invalid types', function () {
try {
formatCurrency({}, '');
fail('It should fail!');
} catch (err) {
expect(err.message).toEqual('SkyInvalidPipeArgument: \'[object Object]\'');
}
});

it('should return null for null values', function () {
const result = formatCurrency(null, '');

expect(result).toBeNull();
});

it('should throw error if digits invalid', function () {
const digits = 'abcd-foobar';

try {
formatCurrency(50, digits);
fail('It should fail!');
} catch (err) {
expect(err.message).toEqual(`${digits} is not a valid digit info for number pipes`);
}
});

it('should throw error if digits out of range', function () {
const digits = '0.9-0';

try {
formatCurrency(50, digits);
fail('It should fail!');
} catch (err) {
expect(err.message).toEqual('minimumIntegerDigits value is out of range.');
}
});
});
97 changes: 97 additions & 0 deletions src/app/public/modules/numeric/number-format-utility.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/* tslint:disable:no-null-keyword */

// This file is mostly ported from the Angular 4.x NumberPipe in order to maintain the old
// behavior of using the `Intl` API for formatting numbers rather than having to register every
// supported locale.
// https://github.com/angular/angular/blob/4.4.x/packages/common/src/pipes/number_pipe.ts

import {
SkyIntlNumberFormatStyle
} from '@skyux/i18n/modules/i18n/intl-number-format-style';

import {
SkyIntlNumberFormatter
} from '@skyux/i18n/modules/i18n/intl-number-formatter';

function isNumeric(value: any): boolean {
return !isNaN(value - parseFloat(value));
}

function parseIntAutoRadix(text: string): number {
const result: number = parseInt(text, 10);

/* istanbul ignore next */
if (isNaN(result)) {
throw new Error('Invalid integer literal when parsing ' + text);
}

return result;
}

export class SkyNumberFormatUtility {
private static _NUMBER_FORMAT_REGEXP = /^(\d+)?\.((\d+)(-(\d+))?)?$/;

/* istanbul ignore next */
constructor() { }

public static formatNumber(
locale: string,
value: number | string,
style: SkyIntlNumberFormatStyle,
digits?: string | null,
currency: string | null = null,
currencyAsSymbol: boolean = false
): string | null {

if (value == null) {
return null;
}

// Convert strings to numbers
value = typeof value === 'string' && isNumeric(value) ? +value : value;
if (typeof value !== 'number') {
throw Error(`SkyInvalidPipeArgument: '${value}'`);
}

let minInt: number|undefined = undefined;
let minFraction: number|undefined = undefined;
let maxFraction: number|undefined = undefined;
if (style !== SkyIntlNumberFormatStyle.Currency) {
// rely on Intl default for currency
minInt = 1;
minFraction = 0;
maxFraction = 3;
}

if (digits) {
const parts = digits.match(this._NUMBER_FORMAT_REGEXP);

if (parts === null) {
throw new Error(`${digits} is not a valid digit info for number pipes`);
}

/* istanbul ignore else */
if (parts[1] != null) { // min integer digits
minInt = parseIntAutoRadix(parts[1]);
}

/* istanbul ignore else */
if (parts[3] != null) { // min fraction digits
minFraction = parseIntAutoRadix(parts[3]);
}

/* istanbul ignore else */
if (parts[5] != null) { // max fraction digits
maxFraction = parseIntAutoRadix(parts[5]);
}
}

return SkyIntlNumberFormatter.format(value as number, locale, style, {
minimumIntegerDigits: minInt,
minimumFractionDigits: minFraction,
maximumFractionDigits: maxFraction,
currency: currency,
currencyAsSymbol: currencyAsSymbol
});
}
}
7 changes: 0 additions & 7 deletions src/app/public/modules/numeric/numeric.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,6 @@ import {
NgModule
} from '@angular/core';

import {
CurrencyPipe,
DecimalPipe
} from '@angular/common';

import {
SkyI18nModule
} from '@skyux/i18n';
Expand All @@ -28,8 +23,6 @@ import {
SkyNumericPipe
],
providers: [
CurrencyPipe,
DecimalPipe,
SkyNumericPipe,
SkyNumericService
],
Expand Down
7 changes: 0 additions & 7 deletions src/app/public/modules/numeric/numeric.service.spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
import {
CurrencyPipe,
DecimalPipe
} from '@angular/common';

import {
SkyLibResourcesTestService
} from '@skyux/i18n/testing/lib-resources-test.service';
Expand All @@ -16,8 +11,6 @@ import {
} from './numeric.service';

const skyNumeric = new SkyNumericService(
new CurrencyPipe('en-US'),
new DecimalPipe('en-US'),
new SkyLibResourcesTestService() as any
);

Expand Down
31 changes: 20 additions & 11 deletions src/app/public/modules/numeric/numeric.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@ import {
} from '@angular/core';

import {
CurrencyPipe,
DecimalPipe
} from '@angular/common';
SkyIntlNumberFormatStyle
} from '@skyux/i18n/modules/i18n/intl-number-format-style';

import {
SkyLibResourcesService
} from '@skyux/i18n/modules/i18n/lib-resources.service';
} from '@skyux/i18n';

import {
NumericOptions
Expand All @@ -19,6 +18,10 @@ import {
SkyNumericSymbol
} from './numeric-symbol';

import {
SkyNumberFormatUtility
} from './number-format-utility';

@Injectable()
export class SkyNumericService {
public shortSymbol: string;
Expand All @@ -30,9 +33,9 @@ export class SkyNumericService {
{ value: 1E3, label: this.getSymbol('skyux_numeric_thousands_symbol') }
];

private defaultLocale = 'en-US';

constructor(
private currencyPipe: CurrencyPipe,
private decimalPipe: DecimalPipe,
private resourcesService: SkyLibResourcesService
) { }

Expand All @@ -45,7 +48,9 @@ export class SkyNumericService {
value: number,
options: NumericOptions
): string {
if (isNaN(value)) {

/* tslint:disable-next-line:no-null-keyword */
if (isNaN(value) || value === null) {
return '';
}

Expand Down Expand Up @@ -107,11 +112,13 @@ export class SkyNumericService {
// See: https://angular.io/api/common/CurrencyPipe#parameters
const symbolDisplay: any = 'symbol';

output = this.currencyPipe.transform(
output = SkyNumberFormatUtility.formatNumber(
this.defaultLocale,
parseFloat(output),
SkyIntlNumberFormatStyle.Currency,
digits,
options.iso,
symbolDisplay,
digits
symbolDisplay
);
break;

Expand All @@ -129,8 +136,10 @@ export class SkyNumericService {
digits = `1.${options.digits}-${options.digits}`;
}

output = this.decimalPipe.transform(
output = SkyNumberFormatUtility.formatNumber(
this.defaultLocale,
parseFloat(output),
SkyIntlNumberFormatStyle.Decimal,
digits
);
break;
Expand Down