installed plugin Easy Digital Downloads
version 3.1.0.3
This commit is contained in:
@ -0,0 +1,107 @@
|
||||
/* global edd_vars */
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { NumberFormat } from './number.js';
|
||||
|
||||
// Make Number directly accessible from package.
|
||||
export { NumberFormat } from './number.js';
|
||||
|
||||
/**
|
||||
* Currency
|
||||
*
|
||||
* @class Currency
|
||||
*/
|
||||
export const Currency = class Currency {
|
||||
/**
|
||||
* Creates configuration for currency formatting.
|
||||
*
|
||||
* @todo Validate configuration.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param {Object} config Currency configuration arguments.
|
||||
* @param {string} [config.currency=edd_vars.currency] Currency (USD, AUD, etc).
|
||||
* @param {string} [config.currencySymbol=edd_vars.currency_sign] Currency symbol ($, €, etc).
|
||||
* @param {string} [config.currencySymbolPosition=edd_vars.currency_pos] Currency symbol position (left or right).
|
||||
* @param {number} [config.decimalPlaces=edd_vars.currency_decimals] The number of decimals places to format to.
|
||||
* @param {string} [config.decimalSeparator=edd_vars.decimal_separator] The separator between the number and decimal.
|
||||
* @param {string} [config.thousandsSeparator=edd_vars.thousands_separator] Thousands separator.
|
||||
*/
|
||||
constructor( config = {} ) {
|
||||
const {
|
||||
currency,
|
||||
currency_sign: currencySymbol,
|
||||
currency_pos: currencySymbolPosition,
|
||||
currency_decimals: precision,
|
||||
decimal_separator: decimalSeparator,
|
||||
thousands_separator: thousandSeparator,
|
||||
} = edd_vars;
|
||||
|
||||
this.config = {
|
||||
currency,
|
||||
currencySymbol,
|
||||
currencySymbolPosition,
|
||||
precision,
|
||||
decimalSeparator,
|
||||
thousandSeparator,
|
||||
...config,
|
||||
};
|
||||
|
||||
this.number = new NumberFormat( this.config );
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a number for currency display.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param {number} number Number to format.
|
||||
* @return {?string} A formatted string.
|
||||
*/
|
||||
format( number, absint = true ) {
|
||||
const { currencySymbol, currencySymbolPosition } = this.config;
|
||||
|
||||
const isNegative = number < 0;
|
||||
let formattedNumber = this.number.format( number );
|
||||
let currency = '';
|
||||
|
||||
if( isNegative ) {
|
||||
formattedNumber = this.number.format( number * -1 );
|
||||
}
|
||||
|
||||
switch ( currencySymbolPosition ) {
|
||||
case 'before':
|
||||
currency = currencySymbol + formattedNumber;
|
||||
break;
|
||||
case 'after':
|
||||
currency = formattedNumber + currencySymbol;
|
||||
break;
|
||||
}
|
||||
|
||||
// Place negative symbol before currency symbol if needed.
|
||||
if ( true === isNegative && false === absint ) {
|
||||
currency = `-${ currency }`;
|
||||
}
|
||||
|
||||
return currency;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes formatting from a currency string.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param {string} currency String containing currency formatting.
|
||||
* @return {number} Unformatted number.
|
||||
*/
|
||||
unformat( currency ) {
|
||||
const { currencySymbol } = this.config;
|
||||
|
||||
// Remove any existing currency symbol.
|
||||
const number = currency.replace( currencySymbol, '' );
|
||||
|
||||
return this.number.unformat( number );
|
||||
}
|
||||
};
|
@ -0,0 +1,114 @@
|
||||
/* global edd_vars */
|
||||
|
||||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
const numberFormatter = require( 'locutus/php/strings/number_format' );
|
||||
|
||||
/**
|
||||
* NumberFormat
|
||||
*
|
||||
* @class NumberFormat
|
||||
*/
|
||||
export const NumberFormat = class NumberFormat {
|
||||
/**
|
||||
* Creates configuration for number formatting.
|
||||
*
|
||||
* @todo Validate configuration.
|
||||
* @since 3.0
|
||||
* @param {Object} config Configuration for the number formatter.
|
||||
* @param {number} [config.decimalPlaces=edd_vars.currency_decimals] The number of decimals places to format to.
|
||||
* @param {string} [config.decimalSeparator=edd_vars.decimal_separator] The separator between the number and decimal.
|
||||
* @param {string} [config.thousandsSeparator=edd_vars.thousands_separator] Thousands separator.
|
||||
*/
|
||||
constructor( config = {} ) {
|
||||
const {
|
||||
currency_decimals: precision,
|
||||
decimal_separator: decimalSeparator,
|
||||
thousands_separator: thousandSeparator,
|
||||
} = edd_vars;
|
||||
|
||||
this.config = {
|
||||
precision,
|
||||
decimalSeparator,
|
||||
thousandSeparator,
|
||||
...config,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a number for display based on decimal settings.
|
||||
*
|
||||
* @since 3.0
|
||||
* @see http://locutus.io/php/strings/number_format/
|
||||
*
|
||||
* @param {number|string} number Number to format.
|
||||
* @return {?string} A formatted string.
|
||||
*/
|
||||
format( number ) {
|
||||
let toFormat = number;
|
||||
|
||||
if ( 'number' !== typeof number ) {
|
||||
toFormat = parseFloat( number );
|
||||
}
|
||||
|
||||
if ( isNaN( toFormat ) ) {
|
||||
toFormat = 0;
|
||||
}
|
||||
|
||||
const { precision, decimalSeparator, thousandSeparator } = this.config;
|
||||
|
||||
return numberFormatter(
|
||||
toFormat,
|
||||
precision,
|
||||
decimalSeparator,
|
||||
thousandSeparator
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes any non-number formatting applied to a string
|
||||
* and returns a true number.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param {*} number Number to unformat.
|
||||
* @return {number} 0 If number cannot be unformatted properly.
|
||||
*/
|
||||
unformat( number ) {
|
||||
const { decimalSeparator, thousandSeparator } = this.config;
|
||||
|
||||
if ( 'string' !== typeof number ) {
|
||||
number = String( number );
|
||||
}
|
||||
|
||||
const unformatted = number
|
||||
// Remove thousand separator.
|
||||
.replace( thousandSeparator, '' )
|
||||
|
||||
// Replace decimal separator with a decimal.
|
||||
.replace( decimalSeparator, '.' );
|
||||
|
||||
const parsed = parseFloat( unformatted );
|
||||
|
||||
return isNaN( parsed ) ? 0 : parsed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a value to a non-negative number.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param {*} number Number to unformat.
|
||||
* @return {number} A non-negative number.
|
||||
*/
|
||||
absint( number ) {
|
||||
const unformatted = this.unformat( number );
|
||||
|
||||
if ( unformatted >= 0 ) {
|
||||
return unformatted;
|
||||
}
|
||||
|
||||
return unformatted * -1;
|
||||
}
|
||||
};
|
@ -0,0 +1,216 @@
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { Currency, NumberFormat } from './../src';
|
||||
|
||||
global.edd_vars = {
|
||||
currency: 'EUR',
|
||||
currency_sign: '€',
|
||||
currency_pos: 'after',
|
||||
currency_decimals: 2,
|
||||
decimal_separator: ',',
|
||||
thousands_separator: '.',
|
||||
};
|
||||
|
||||
describe( 'Currency', () => {
|
||||
it( 'should be able to set config on instantiation', () => {
|
||||
const currency = new Currency( {
|
||||
currency: 'USD',
|
||||
currencySymbol: '$',
|
||||
currencySymbolPosition: 'before',
|
||||
precision: 2,
|
||||
decimalSeparator: '.',
|
||||
thousandSeparator: ',',
|
||||
} );
|
||||
|
||||
expect( currency.config.currency ).toEqual( 'USD' );
|
||||
|
||||
expect( currency.config.currencySymbol ).toEqual( '$' );
|
||||
|
||||
expect( currency.config.currencySymbolPosition ).toEqual( 'before' );
|
||||
|
||||
expect( currency.config.precision ).toEqual( 2 );
|
||||
|
||||
expect( currency.config.decimalSeparator ).toEqual( '.' );
|
||||
|
||||
expect( currency.config.thousandSeparator ).toEqual( ',' );
|
||||
} );
|
||||
|
||||
it( 'should be inherit config from edd_vars', () => {
|
||||
const currency = new Currency();
|
||||
|
||||
expect( currency.config.currency ).toEqual( 'EUR' );
|
||||
|
||||
expect( currency.config.currencySymbol ).toEqual( '€' );
|
||||
|
||||
expect( currency.config.currencySymbolPosition ).toEqual( 'after' );
|
||||
|
||||
expect( currency.config.precision ).toEqual( 2 );
|
||||
|
||||
expect( currency.config.decimalSeparator ).toEqual( ',' );
|
||||
|
||||
expect( currency.config.thousandSeparator ).toEqual( '.' );
|
||||
} );
|
||||
|
||||
describe( 'format', () => {
|
||||
let currency;
|
||||
|
||||
beforeEach( () => {
|
||||
currency = new Currency( {
|
||||
currency: 'USD',
|
||||
currencySymbol: '$',
|
||||
currencySymbolPosition: 'before',
|
||||
precision: 2,
|
||||
decimalSeparator: ',',
|
||||
thousandSeparator: '.',
|
||||
} );
|
||||
} );
|
||||
|
||||
it( 'should accept a Number', () => {
|
||||
expect( currency.format( Number( 5 ) ) ).toEqual( '$5,00' );
|
||||
} );
|
||||
|
||||
it( 'should accept a numeric String', () => {
|
||||
expect( currency.format( '1285.50' ) ).toEqual( '$1.285,50' );
|
||||
} );
|
||||
|
||||
it( 'should accept an Int', () => {
|
||||
expect( currency.format( parseInt( '5.0' ) ) ).toEqual( '$5,00' );
|
||||
} );
|
||||
|
||||
it( 'should accept an Float', () => {
|
||||
expect( currency.format( parseFloat( '5.0abc' ) ) ).toEqual(
|
||||
'$5,00'
|
||||
);
|
||||
} );
|
||||
|
||||
it( 'should return zero on invalid', () => {
|
||||
expect( currency.format( 'abc' ) ).toEqual( '$0,00' );
|
||||
} );
|
||||
} );
|
||||
|
||||
describe( 'unformat', () => {
|
||||
let currency;
|
||||
|
||||
beforeEach( () => {
|
||||
currency = new Currency( {
|
||||
currency: 'USD',
|
||||
currencySymbol: '$',
|
||||
currencySymbolPosition: 'before',
|
||||
precision: 2,
|
||||
decimalSeparator: '.',
|
||||
thousandSeparator: ',',
|
||||
} );
|
||||
} );
|
||||
|
||||
it( 'should return a number', () => {
|
||||
expect( currency.unformat( '$73.97' ) ).toEqual( 73.97 );
|
||||
} );
|
||||
|
||||
it( 'should return zero on invalid', () => {
|
||||
expect( currency.unformat( 'abc' ) ).toEqual( 0 );
|
||||
} );
|
||||
} );
|
||||
} );
|
||||
|
||||
describe( 'Number', () => {
|
||||
it( 'should be able to set config on instantiation', () => {
|
||||
const number = new NumberFormat( {
|
||||
precision: 2,
|
||||
decimalSeparator: '.',
|
||||
thousandSeparator: ',',
|
||||
} );
|
||||
|
||||
expect( number.config.precision ).toEqual( 2 );
|
||||
|
||||
expect( number.config.decimalSeparator ).toEqual( '.' );
|
||||
|
||||
expect( number.config.thousandSeparator ).toEqual( ',' );
|
||||
} );
|
||||
|
||||
it( 'should be inherit config from edd_vars', () => {
|
||||
const number = new Currency();
|
||||
|
||||
expect( number.config.precision ).toEqual( 2 );
|
||||
|
||||
expect( number.config.decimalSeparator ).toEqual( ',' );
|
||||
|
||||
expect( number.config.thousandSeparator ).toEqual( '.' );
|
||||
} );
|
||||
|
||||
describe( 'format', () => {
|
||||
let number;
|
||||
|
||||
beforeEach( () => {
|
||||
number = new NumberFormat( {
|
||||
precision: 2,
|
||||
decimalSeparator: ',',
|
||||
thousandSeparator: '.',
|
||||
} );
|
||||
} );
|
||||
|
||||
it( 'should accept a Number', () => {
|
||||
expect( number.format( Number( 5 ) ) ).toEqual( '5,00' );
|
||||
} );
|
||||
|
||||
it( 'should accept a numeric String', () => {
|
||||
expect( number.format( '5.838,58' ) ).toEqual( '5,84' );
|
||||
} );
|
||||
|
||||
it( 'should accept an Int', () => {
|
||||
expect( number.format( parseInt( 5 ) ) ).toEqual( '5,00' );
|
||||
} );
|
||||
|
||||
it( 'should accept an Float', () => {
|
||||
expect( number.format( parseFloat( '5.0abc' ) ) ).toEqual( '5,00' );
|
||||
} );
|
||||
|
||||
it( 'should return zero on invalid', () => {
|
||||
expect( number.format( 'abc' ) ).toEqual( '0,00' );
|
||||
} );
|
||||
} );
|
||||
|
||||
describe( 'unformat', () => {
|
||||
let number;
|
||||
|
||||
beforeEach( () => {
|
||||
number = new NumberFormat( {
|
||||
precision: 2,
|
||||
decimalSeparator: ',',
|
||||
thousandSeparator: '.',
|
||||
} );
|
||||
} );
|
||||
|
||||
it( 'should return a number', () => {
|
||||
expect( number.unformat( '1.283,83' ) ).toEqual( 1283.83 );
|
||||
} );
|
||||
|
||||
it( 'should return zero on invalid', () => {
|
||||
expect( number.unformat( 'abc' ) ).toEqual( 0 );
|
||||
} );
|
||||
} );
|
||||
|
||||
describe( 'absint', () => {
|
||||
let number;
|
||||
|
||||
beforeEach( () => {
|
||||
number = new NumberFormat( {
|
||||
precision: 2,
|
||||
decimalSeparator: '.',
|
||||
thousandSeparator: ',',
|
||||
} );
|
||||
} );
|
||||
|
||||
it( 'should return a positive number from a positive number', () => {
|
||||
expect( number.absint( 5 ) ).toEqual( 5 );
|
||||
expect( number.absint( 5.00 ) ).toEqual( 5.00 );
|
||||
expect( number.absint( '5.00' ) ).toEqual( 5 );
|
||||
} );
|
||||
|
||||
it( 'should return a positive number from a negative number', () => {
|
||||
expect( number.absint( -5 ) ).toEqual( 5 );
|
||||
expect( number.absint( -5.00 ) ).toEqual( 5.00 );
|
||||
expect( number.absint( '-5.00' ) ).toEqual( 5 );
|
||||
} );
|
||||
} );
|
||||
} );
|
Reference in New Issue
Block a user