From 0419f39e859a707e16ecd13ecedbbb76825c5142 Mon Sep 17 00:00:00 2001 From: Juan Carlos Picado Date: Sun, 4 Dec 2016 17:19:52 +0100 Subject: [PATCH 01/17] Add memoizee definitions --- memoizee/index.d.ts | 31 ++++++++++++++++++++ memoizee/memoizee-tests.ts | 60 ++++++++++++++++++++++++++++++++++++++ memoizee/tsconfig.json | 19 ++++++++++++ memoizee/tslint.json | 1 + 4 files changed, 111 insertions(+) create mode 100644 memoizee/index.d.ts create mode 100644 memoizee/memoizee-tests.ts create mode 100644 memoizee/tsconfig.json create mode 100644 memoizee/tslint.json diff --git a/memoizee/index.d.ts b/memoizee/index.d.ts new file mode 100644 index 0000000000..007bbc7d27 --- /dev/null +++ b/memoizee/index.d.ts @@ -0,0 +1,31 @@ + +// Type definitions for memoizee 0.4.1 +// Project: https://github.com/medikoo/memoizee +// Definitions by: Juan Picado +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped + +interface RevolversArray { + [index:number]:Object +} + +interface MemoizeeOptions { + length?: number, + maxAge?: number, + max?: number, + preFetch?: number, + promise?: boolean, + dispose?: Function, + async?: boolean, + primitive?: boolean, + normalizer?:Function, + resolvers?: RevolversArray +} + +interface IMemoizee extends Function { + delete: Function, + clear: Function +} + +declare function memoizee(f: any, options?:MemoizeeOptions): IMemoizee; + +export = memoizee; diff --git a/memoizee/memoizee-tests.ts b/memoizee/memoizee-tests.ts new file mode 100644 index 0000000000..138a605712 --- /dev/null +++ b/memoizee/memoizee-tests.ts @@ -0,0 +1,60 @@ +import memoize = require('memoizee'); + +var fn = function (one:any, two:any, three:any) { /* ... */ }; + +let memoized = memoize(fn); +memoized('foo', 3, 'bar'); +memoized('foo', 3, 'bar'); +memoized = memoize(fn, { length: 2 }); +memoized('foo'); +memoized('foo', undefined); +memoized('foo', 3, {}); +memoized('foo', 3, 13); +memoized('foo', undefined); +memoized('foo', undefined); +memoized('foo', 3, {}); +memoized('foo', 3, 13); +memoized('foo', 3, 13); +memoized = memoize(fn, { primitive: true }); +memoized('/path/one'); +memoized('/path/one'); +memoized = memoize(fn, { dispose: function (value:number) { /*…*/ } }); +var foo3 = memoized('foo', 3); +var bar7 = memoized('bar', 7); +memoized.clear('foo', 3); // Dispose called with foo3 value +memoized.clear('bar', 7); // Dispose called with bar7 value +memoized.delete('foo', true); +var mFn = memoize(function (hash:any) { + // body of memoized function +}, { normalizer: function (args:any) { + // args is arguments object as accessible in memoized function + return JSON.stringify(args[0]); +} }); + +mFn({ foo: 'bar' }); + +memoized = memoize(fn, { length: 2, resolvers: [String, Boolean] }); +memoized(12, [1,2,3].length); +memoized("12", true); +memoized({ toString: function () { return "12"; } }, {}); + +var afn = function (a:number, b:number) { + return new Promise(function (res) { res(a + b); }); +}; +memoized = memoize(afn, { promise: true }); + +memoized(3, 7); +memoized(3, 7); + +memoized = memoize(fn, { maxAge: 1000, preFetch: 0.6 }); + +memoized('foo', 3); +memoized('foo', 3); + +setTimeout(function () { + memoized('foo', 3); +}, 500); + +setTimeout(function () { + memoized('foo', 3); +}, 1300); diff --git a/memoizee/tsconfig.json b/memoizee/tsconfig.json new file mode 100644 index 0000000000..e2f4dc61cb --- /dev/null +++ b/memoizee/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es6", + "noImplicitAny": true, + "strictNullChecks": false, + "baseUrl": "../", + "typeRoots": [ + "../" + ], + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "memoizee-tests.ts" + ] +} \ No newline at end of file diff --git a/memoizee/tslint.json b/memoizee/tslint.json new file mode 100644 index 0000000000..2221e40e4a --- /dev/null +++ b/memoizee/tslint.json @@ -0,0 +1 @@ +{ "extends": "../tslint.json" } \ No newline at end of file From 125fee99068e49e0e7ba72222ace7f7abafa612e Mon Sep 17 00:00:00 2001 From: Juan Carlos Picado Date: Sun, 4 Dec 2016 18:45:49 +0100 Subject: [PATCH 02/17] Fix common issues, added doc --- memoizee/index.d.ts | 31 +++++++++++++++++++++++++------ memoizee/tsconfig.json | 4 ++-- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/memoizee/index.d.ts b/memoizee/index.d.ts index 007bbc7d27..db0eb4e84f 100644 --- a/memoizee/index.d.ts +++ b/memoizee/index.d.ts @@ -4,28 +4,47 @@ // Definitions by: Juan Picado // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +/** + * Resolver options + * @interface RevolversArray + */ interface RevolversArray { [index:number]:Object } -interface MemoizeeOptions { +/** + * List of options + * @interface IMemoizeeOptions + */ +interface IMemoizeeOptions { length?: number, maxAge?: number, max?: number, preFetch?: number, promise?: boolean, - dispose?: Function, + dispose?: () => void, async?: boolean, primitive?: boolean, - normalizer?:Function, + normalizer?:() => void, resolvers?: RevolversArray } +/** + * Main interface functions + * @interface IMemoizee + * @extends {Function} + */ interface IMemoizee extends Function { - delete: Function, - clear: Function + delete: () => void, + clear: () => void } -declare function memoizee(f: any, options?:MemoizeeOptions): IMemoizee; +/** + * Memoize function + * @param {*} f + * @param {IMemoizeeOptions} [options] + * @returns {IMemoizee} + */ +declare function memoizee(f: any, options?: IMemoizeeOptions): IMemoizee; export = memoizee; diff --git a/memoizee/tsconfig.json b/memoizee/tsconfig.json index e2f4dc61cb..68b204fbd9 100644 --- a/memoizee/tsconfig.json +++ b/memoizee/tsconfig.json @@ -3,7 +3,7 @@ "module": "commonjs", "target": "es6", "noImplicitAny": true, - "strictNullChecks": false, + "strictNullChecks": true, "baseUrl": "../", "typeRoots": [ "../" @@ -16,4 +16,4 @@ "index.d.ts", "memoizee-tests.ts" ] -} \ No newline at end of file +} From fa5e2817687917261672de48eaf23b4c62830568 Mon Sep 17 00:00:00 2001 From: Juan Carlos Picado Date: Sun, 4 Dec 2016 19:08:59 +0100 Subject: [PATCH 03/17] Removed blank line --- memoizee/index.d.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/memoizee/index.d.ts b/memoizee/index.d.ts index db0eb4e84f..6cefaf39d5 100644 --- a/memoizee/index.d.ts +++ b/memoizee/index.d.ts @@ -1,4 +1,3 @@ - // Type definitions for memoizee 0.4.1 // Project: https://github.com/medikoo/memoizee // Definitions by: Juan Picado From 05272150f091ce3a75b73259eadbd7fafb63b53e Mon Sep 17 00:00:00 2001 From: Juan Carlos Picado Date: Sun, 4 Dec 2016 19:51:04 +0100 Subject: [PATCH 04/17] fix test --- memoizee/index.d.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/memoizee/index.d.ts b/memoizee/index.d.ts index 6cefaf39d5..5d6fc049ad 100644 --- a/memoizee/index.d.ts +++ b/memoizee/index.d.ts @@ -21,10 +21,10 @@ interface IMemoizeeOptions { max?: number, preFetch?: number, promise?: boolean, - dispose?: () => void, + dispose?: ()=> void, async?: boolean, primitive?: boolean, - normalizer?:() => void, + normalizer?:()=> void, resolvers?: RevolversArray } @@ -44,6 +44,6 @@ interface IMemoizee extends Function { * @param {IMemoizeeOptions} [options] * @returns {IMemoizee} */ -declare function memoizee(f: any, options?: IMemoizeeOptions): IMemoizee; +declare function memoizee(f: () => void, options?: IMemoizeeOptions): IMemoizee; export = memoizee; From 42ffcea96b84be8a230ea14bc03a272d9c63686c Mon Sep 17 00:00:00 2001 From: Juan Carlos Picado Date: Sun, 4 Dec 2016 21:03:41 +0100 Subject: [PATCH 05/17] Fix test methods --- memoizee/index.d.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/memoizee/index.d.ts b/memoizee/index.d.ts index 5d6fc049ad..be984e3575 100644 --- a/memoizee/index.d.ts +++ b/memoizee/index.d.ts @@ -21,10 +21,10 @@ interface IMemoizeeOptions { max?: number, preFetch?: number, promise?: boolean, - dispose?: ()=> void, + dispose?: (value: any) => void, async?: boolean, primitive?: boolean, - normalizer?:()=> void, + normalizer?:(value:any ) => void, resolvers?: RevolversArray } @@ -34,8 +34,8 @@ interface IMemoizeeOptions { * @extends {Function} */ interface IMemoizee extends Function { - delete: () => void, - clear: () => void + delete: (...params: any[]) => void, + clear: (...params: any[]) => void } /** @@ -44,6 +44,6 @@ interface IMemoizee extends Function { * @param {IMemoizeeOptions} [options] * @returns {IMemoizee} */ -declare function memoizee(f: () => void, options?: IMemoizeeOptions): IMemoizee; +declare function memoizee(f: Function, options?: IMemoizeeOptions): IMemoizee; export = memoizee; From 7808c389685e0a06870095c233d786bbfcc7fceb Mon Sep 17 00:00:00 2001 From: Juan Carlos Picado Date: Sun, 4 Dec 2016 21:10:22 +0100 Subject: [PATCH 06/17] Fix check style --- memoizee/index.d.ts | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/memoizee/index.d.ts b/memoizee/index.d.ts index be984e3575..5de5fb9a2d 100644 --- a/memoizee/index.d.ts +++ b/memoizee/index.d.ts @@ -8,7 +8,7 @@ * @interface RevolversArray */ interface RevolversArray { - [index:number]:Object + [index:number]: {}; } /** @@ -16,16 +16,16 @@ interface RevolversArray { * @interface IMemoizeeOptions */ interface IMemoizeeOptions { - length?: number, - maxAge?: number, - max?: number, - preFetch?: number, - promise?: boolean, - dispose?: (value: any) => void, - async?: boolean, - primitive?: boolean, - normalizer?:(value:any ) => void, - resolvers?: RevolversArray + length?: number; + maxAge?: number; + max?: number; + preFetch?: number; + promise?: boolean; + dispose?: (value: any) => void; + async?: boolean; + primitive?: boolean; + normalizer?: (value:any ) => void; + resolvers?: RevolversArray; } /** @@ -34,8 +34,8 @@ interface IMemoizeeOptions { * @extends {Function} */ interface IMemoizee extends Function { - delete: (...params: any[]) => void, - clear: (...params: any[]) => void + delete: (...params: any[]) => void; + clear: (...params: any[]) => void; } /** @@ -44,6 +44,6 @@ interface IMemoizee extends Function { * @param {IMemoizeeOptions} [options] * @returns {IMemoizee} */ -declare function memoizee(f: Function, options?: IMemoizeeOptions): IMemoizee; +declare function memoizee(f: (...params: any[])=>void, options?: IMemoizeeOptions): IMemoizee; export = memoizee; From fbb5f29d19c564346f01b8c7b3139c354f136184 Mon Sep 17 00:00:00 2001 From: Juan Carlos Picado Date: Sun, 4 Dec 2016 21:15:20 +0100 Subject: [PATCH 07/17] Fix check style --- memoizee/index.d.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/memoizee/index.d.ts b/memoizee/index.d.ts index 5de5fb9a2d..8f943c4167 100644 --- a/memoizee/index.d.ts +++ b/memoizee/index.d.ts @@ -8,7 +8,7 @@ * @interface RevolversArray */ interface RevolversArray { - [index:number]: {}; + [index: number]: {}; } /** @@ -24,7 +24,7 @@ interface IMemoizeeOptions { dispose?: (value: any) => void; async?: boolean; primitive?: boolean; - normalizer?: (value:any ) => void; + normalizer?: (value: any ) => void; resolvers?: RevolversArray; } @@ -44,6 +44,6 @@ interface IMemoizee extends Function { * @param {IMemoizeeOptions} [options] * @returns {IMemoizee} */ -declare function memoizee(f: (...params: any[])=>void, options?: IMemoizeeOptions): IMemoizee; +declare function memoizee(f: (...params: any[]) => void, options?: IMemoizeeOptions): IMemoizee; export = memoizee; From 8070c5a1fcb555b7372911b152ada272590cde44 Mon Sep 17 00:00:00 2001 From: Juan Carlos Picado Date: Sun, 4 Dec 2016 21:26:41 +0100 Subject: [PATCH 08/17] Fixing semver header --- memoizee/index.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/memoizee/index.d.ts b/memoizee/index.d.ts index 8f943c4167..aba59ed744 100644 --- a/memoizee/index.d.ts +++ b/memoizee/index.d.ts @@ -1,4 +1,4 @@ -// Type definitions for memoizee 0.4.1 +// Type definitions for memoizee v0.4.1 // Project: https://github.com/medikoo/memoizee // Definitions by: Juan Picado // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped From 8825deefbc83b48fb75649dc8b988e21d18d7f62 Mon Sep 17 00:00:00 2001 From: Juan Carlos Picado Date: Sun, 4 Dec 2016 21:37:20 +0100 Subject: [PATCH 09/17] Fixing semver header --- memoizee/index.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/memoizee/index.d.ts b/memoizee/index.d.ts index aba59ed744..125b34f264 100644 --- a/memoizee/index.d.ts +++ b/memoizee/index.d.ts @@ -1,4 +1,4 @@ -// Type definitions for memoizee v0.4.1 +// Type definitions for memoizee 0.4 // Project: https://github.com/medikoo/memoizee // Definitions by: Juan Picado // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped From 87fb5359400a3fd267813bdf461534e09cd5745f Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Thu, 29 Dec 2016 14:25:38 -0500 Subject: [PATCH 10/17] `memoizee`: Clean up types --- memoizee/index.d.ts | 60 +++++++++++++------------------------- memoizee/memoizee-tests.ts | 25 ++++++++-------- memoizee/tsconfig.json | 1 + 3 files changed, 34 insertions(+), 52 deletions(-) diff --git a/memoizee/index.d.ts b/memoizee/index.d.ts index 125b34f264..456641dc59 100644 --- a/memoizee/index.d.ts +++ b/memoizee/index.d.ts @@ -3,47 +3,27 @@ // Definitions by: Juan Picado // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped -/** - * Resolver options - * @interface RevolversArray - */ -interface RevolversArray { - [index: number]: {}; +declare namespace memoizee { + interface Options { + length?: number; + maxAge?: number; + max?: number; + preFetch?: number | true; + promise?: boolean; + dispose?: (value: any) => void; + async?: boolean; + primitive?: boolean; + normalizer?: (value: any) => void; + resolvers?: Array<(arg: any) => any>; + } + + interface Memoized { + delete: F; + clear: F & (() => void); + } } -/** - * List of options - * @interface IMemoizeeOptions - */ -interface IMemoizeeOptions { - length?: number; - maxAge?: number; - max?: number; - preFetch?: number; - promise?: boolean; - dispose?: (value: any) => void; - async?: boolean; - primitive?: boolean; - normalizer?: (value: any ) => void; - resolvers?: RevolversArray; -} - -/** - * Main interface functions - * @interface IMemoizee - * @extends {Function} - */ -interface IMemoizee extends Function { - delete: (...params: any[]) => void; - clear: (...params: any[]) => void; -} - -/** - * Memoize function - * @param {*} f - * @param {IMemoizeeOptions} [options] - * @returns {IMemoizee} - */ -declare function memoizee(f: (...params: any[]) => void, options?: IMemoizeeOptions): IMemoizee; +// tslint:disable:forbidden-types +declare function memoizee(f: F, options?: memoizee.Options): F & memoizee.Memoized; export = memoizee; diff --git a/memoizee/memoizee-tests.ts b/memoizee/memoizee-tests.ts index 138a605712..e8e73a2d6a 100644 --- a/memoizee/memoizee-tests.ts +++ b/memoizee/memoizee-tests.ts @@ -1,6 +1,6 @@ import memoize = require('memoizee'); -var fn = function (one:any, two:any, three:any) { /* ... */ }; +var fn = function (one: string, two?: number, three?: any) { /* ... */ }; let memoized = memoize(fn); memoized('foo', 3, 'bar'); @@ -23,7 +23,7 @@ var foo3 = memoized('foo', 3); var bar7 = memoized('bar', 7); memoized.clear('foo', 3); // Dispose called with foo3 value memoized.clear('bar', 7); // Dispose called with bar7 value -memoized.delete('foo', true); +memoized.delete('foo', 0); var mFn = memoize(function (hash:any) { // body of memoized function }, { normalizer: function (args:any) { @@ -34,17 +34,18 @@ var mFn = memoize(function (hash:any) { mFn({ foo: 'bar' }); memoized = memoize(fn, { length: 2, resolvers: [String, Boolean] }); -memoized(12, [1,2,3].length); -memoized("12", true); -memoized({ toString: function () { return "12"; } }, {}); +memoized(String(12), [1,2,3].length); +memoized("12", Number(true)); +memoized(String({ toString: function () { return "12"; } }), Number({})); -var afn = function (a:number, b:number) { - return new Promise(function (res) { res(a + b); }); -}; -memoized = memoize(afn, { promise: true }); - -memoized(3, 7); -memoized(3, 7); +{ + var afn = function (a:number, b:number) { + return new Promise(function (res) { res(a + b); }); + }; + let memoized = memoize(afn, { promise: true }); + memoized(3, 7); + memoized(3, 7); +} memoized = memoize(fn, { maxAge: 1000, preFetch: 0.6 }); diff --git a/memoizee/tsconfig.json b/memoizee/tsconfig.json index 68b204fbd9..c2ccff1cab 100644 --- a/memoizee/tsconfig.json +++ b/memoizee/tsconfig.json @@ -3,6 +3,7 @@ "module": "commonjs", "target": "es6", "noImplicitAny": true, + "noImplicitThis": true, "strictNullChecks": true, "baseUrl": "../", "typeRoots": [ From 0232616783affa57eb6615c7acead2649ca41fa4 Mon Sep 17 00:00:00 2001 From: William Rummler Date: Fri, 30 Dec 2016 16:47:00 -0600 Subject: [PATCH 11/17] Types 2.0 - Fix JS-quantities (#12739) * Enable strict null checking per readme FAQ. * Add tslint.json. * Improve test file with project spec. * Fix js-quantities d.ts, with adjustment of test. * Add trailing newline to tslint. * Simplify functional interface per linter. * js-quantities: add readme examples to tests * js-quantities: fix & clean declaration --- js-quantities/index.d.ts | 132 ++- js-quantities/js-quantities-tests.ts | 1503 +++++++++++++++++++++++++- js-quantities/tsconfig.json | 4 +- js-quantities/tslint.json | 3 + 4 files changed, 1567 insertions(+), 75 deletions(-) create mode 100644 js-quantities/tslint.json diff --git a/js-quantities/index.d.ts b/js-quantities/index.d.ts index a2e3c2d96c..5d4a8df304 100644 --- a/js-quantities/index.d.ts +++ b/js-quantities/index.d.ts @@ -1,79 +1,73 @@ -// Type definitions for JS-quantities +// Type definitions for JS-quantities 1.6 // Project: http://gentooboontoo.github.io/js-quantities/ -// Definitions by: William Comartin +// Definitions by: William Rummler // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped -declare var Qty: QtyModule.QtyStatic; - -declare namespace QtyModule { - interface QtyStatic { - (value: string): Qty; - (value: number): Qty; - (value: number, unit: string): Qty; - (value: Qty): Qty; - } - - interface Qty { - version: string; - - scalar: number; - baseScalar: number; - - parse(value: string): Qty; - - swiftConverter(srcUnits:string, dstUnits:string): (value:number) => number; - - getkinds(): string[]; - - getUnits(kind:string): string[]; - - getAliases(unitName:string): string[]; - - formatter(scalar:number, units:string):string; - - toFloat(): number; - - isUnitless(): boolean; - - isCompatible(other:string|Qty): boolean; - - isInverse(other:string|Qty): boolean - - kind(): string; - - isBase(): boolean; - - toBase(): Qty; +declare const Qty: Qty.Type; +declare interface Qty { + readonly numerator: string[]; + readonly denominator: string[]; + readonly scalar: number; + readonly baseScalar: number; + readonly initValue: string; units(): string; - - eq(other:Qty): boolean; - lt(other:Qty): boolean; - lte(other:Qty): boolean; - gt(other:Qty): boolean; - gte(other:Qty): boolean; - - toPrec(precQuantity: Qty|string|number): Qty; - - toString(targetUnitsOrMaxDecimalsOrPrec?:number|string|Qty, maxDecimals?: number): string; - - format(targetUnits?:string, formatter?:(scalar:number, units:string) => string): string; - - compareTo(other:Qty|string): number; - - same(other: Qty): boolean; - + isCompatible(value: Qty.UnitSource): boolean; + kind(): string; + isUnitless(): boolean; + isBase(): boolean; + toBase(): Qty; + toFloat(): number; + to(value: Qty.UnitSource): Qty; inverse(): Qty; + eq(value: Qty.UnitSource): boolean; + same(value: Qty.UnitSource): boolean; + lt(value: Qty.UnitSource): boolean; + lte(value: Qty.UnitSource): boolean; + gt(value: Qty.UnitSource): boolean; + gte(value: Qty.UnitSource): boolean; + compareTo(value: Qty): Qty.ComparisonResult; + add(value: Qty.Source): Qty; + sub(value: Qty.Source): Qty; + mul(value: Qty.Source): Qty; + div(value: Qty.Source): Qty; + toPrec(value: Qty.Source): Qty; + toString(valueOrPrecision?: Qty.Source): string; + toString(value: string, precision: number): string; + format(formatter?: Qty.Formatter): string; + format(value: string, formatter?: Qty.Formatter): string; +} - isDegrees(): boolean; +declare namespace Qty { - isTemperature(): boolean; + interface Type { + (value: Source): Qty; + (value: number, unit: string): Qty; + new (value: Source): Qty; + new (value: number, unit: string): Qty; + parse(value: string): Qty; + getKinds(): string[]; + getUnits(kind?: string): string[]; + getAliases(unit: string): string[]; + swiftConverter(sourceUnit: string, targetUnit: string): Converter; + formatter: Formatter; + readonly Error: any; + mulSafe(n1: number, n2: number): number; + divSafe(n1: number, n2: number): number; + } - to(other:string|Qty): Qty; + interface Converter { + (sourceValue: number): number; + (sourceValues: number[]): number[]; + } - add(other:string|Qty): Qty; - sub(other:string|Qty): Qty; - mul(other:number|string|Qty): Qty; - div(other:number|string|Qty): Qty; - } -} \ No newline at end of file + type Formatter = (scalar: number, unit: string) => string; + + type ComparisonResult = -1 | 0 | 1; + + type Source = UnitSource | number; + + type UnitSource = Qty | string; +} + +export default Qty; diff --git a/js-quantities/js-quantities-tests.ts b/js-quantities/js-quantities-tests.ts index c09867634a..b1916bb626 100644 --- a/js-quantities/js-quantities-tests.ts +++ b/js-quantities/js-quantities-tests.ts @@ -1,7 +1,1502 @@ -var Val1 = Qty('1 m') +import "../jasmine"; +import Qty from "."; -var Val2 = Qty(1); +// From project readme -var Val3 = Qty(1, 'm'); +let qty: Qty; -var Val4 = Qty(Val1); \ No newline at end of file +qty = new Qty('23 ft'); // constructor +qty = Qty('23 ft'); // factory + +qty = new Qty(124, 'cm'); // => 1.24 meter +qty = Qty(124, 'cm'); // => 1.24 meter + +qty = Qty('1m'); // => 1 meter +qty = Qty('m'); // => 1 meter (scalar defaults to 1) + +qty = Qty('1 N*m'); +qty = Qty('1 N m'); // * is optional + +qty = Qty('1 m/s'); + +qty = Qty('1 m^2/s^2'); +qty = Qty('1 m^2 s^-2'); // negative powers +qty = Qty('1 m2 s-2'); // ^ is optional + +qty = Qty('1 m^2 kg^2 J^2/s^2 A'); + +qty = Qty('1.5'); // unitless quantity +qty = Qty(1.5); // number as initializing value + +qty = Qty('1 attoparsec/microfortnight'); + +let qtyCopy: Qty; + +qtyCopy = Qty(qty); // quantity could be copied when used as initializing value + +Qty.parse('1 m'); // => 1 meter +Qty.parse('foo'); // => null + +Qty.getKinds(); // => Array of names of every well-known kind of units + +Qty.getUnits('currency'); // => [ 'dollar', 'cents' ] +// Or all alphabetically sorted +Qty.getUnits(); // => [ 'acre','Ah','ampere','AMU','angstrom'] + +Qty.getAliases('m'); // => [ 'm', 'meter', 'meters', 'metre', 'metres' ] + +const qty1 = Qty('1m'); +const qty2 = Qty('2m'); + +qty1.isCompatible(qty2); // => true or false + +qty.kind(); // => 'length', 'area', etc... + +qty.isUnitless(); // => true or false +qty.isBase(); // => true if quantity is represented with base units + +qty.toBase(); // converts to SI units (10 cm => 0.1 m) (new instance) + +qty.toFloat(); // returns scalar of unitless quantity (otherwise throws error) + +qty.to('m'); // converts quantity to meter if compatible or throws an error (new instance) +qty1.to(qty2); // converts quantity to same unit of qty2 if compatible or throws an error (new instance) + +qty.inverse(); // converts quantity to its inverse ('100 m/s' => '.01 s/m') +// Inverses can be used, but there is no special checking to +// rename the units +Qty('10ohm').inverse(); // '.1/ohm' (not '.1S', although they are equivalent) +// however, the 'to' command will convert between inverses also +Qty('10ohm').to('S'); // '.1S' + +var convert = Qty.swiftConverter('m/h', 'ft/s'); // Configures converter + +// Converting single value +var converted = convert(2500); // => 2.278.. + +// Converting large array of values +var convertedSerie = convert([2500, 5000]); // => [2.278.., 4.556.., ...] + +qty1.eq(qty2); // => true if both quantities are equal (1m == 100cm => true) +qty1.same(qty2); // => true if both quantities are same (1m == 100cm => false) +qty1.lt(qty2); // => true if qty1 is stricty less than qty2 +qty1.lte(qty2); // => true if qty1 is less than or equal to qty2 +qty1.gt(qty2); // => true if qty1 is stricty greater than qty2 +qty1.gte(qty2); // => true if qty1 is greater than or equal to qty2 + +qty1.compareTo(qty2); // => -1 if qty1 < qty2, => 0 if qty1 == qty2, => 1 if qty1 > qty2 + +qty = Qty('5.17 ft'); +qty.toPrec('ft'); // => 5 ft +qty.toPrec('0.5 ft'); // => 5 ft +qty.toPrec('0.25 ft'); // => 5.25 ft +qty.toPrec('0.1 ft'); // => 5.2 ft +qty.toPrec('0.05 ft'); // => 5.15 ft +qty.toPrec('0.01 ft'); // => 5.17 ft +qty.toPrec('0.00001 ft'); // => 5.17 ft +qty.toPrec('2 ft'); // => 6 ft +qty.toPrec('2'); // => 6 ft + +qty = Qty('6.3782 m'); +qty.toPrec('dm'); // => 6.4 m +qty.toPrec('cm'); // => 6.38 m +qty.toPrec('mm'); // => 6.378 m +qty.toPrec('5 cm'); // => 6.4 m +qty.toPrec('10 m'); // => 10 m +qty.toPrec(0.1); // => 6.3 m + +qty = Qty('1.146 MPa'); +qty.toPrec('0.1 bar'); // => 1.15 MPa + +qty = Qty('1.146 MPa'); +qty.toString(); // => '1.146 MPa' + +qty = Qty('1.146 MPa'); +qty.toString('bar'); // => '11.46 bar' +qty.to('bar').toString(); // => '11.46 bar' + +qty = Qty('1.146 MPa'); +qty.toPrec(0.1).toString(); // => '1.1 MPa' +qty.to('bar').toPrec(0.1).toString(); // => '11.5 bar' + +qty = Qty('1.1234 m'); +qty.format(); // same units, default formatter => '1.234 m' +qty.format('cm'); // converted to 'cm', default formatter => '123.45 cm' + +var configurableRoundingFormatter = function (maxDecimals: number) { + return function (scalar: number, units: string) { + var pow = Math.pow(10, maxDecimals); + var rounded = Math.round(scalar * pow) / pow; + + return rounded + ' ' + units; + }; +}; + +qty = Qty('1.1234 m'); + +// same units, custom formatter => '1.12 m' +qty.format(configurableRoundingFormatter(2)); + +// convert to 'cm', custom formatter => '123.4 cm' +qty.format('cm', configurableRoundingFormatter(1)); + +Qty.formatter = configurableRoundingFormatter(2); +qty = Qty('1.1234 m'); +qty.format(); // same units, current default formatter => '1.12 m' + +Qty('37 tempC').to('tempF'); // => 98.6 tempF + +let scalar: number = 42; + +Qty('100 tempC').add('10 degC'); // 110 tempC +Qty('100 tempC').sub('10 degC'); // 90 tempC +Qty('100 tempC').add('50 tempC'); // throws error +Qty('100 tempC').sub('50 tempC'); // 50 degC +Qty('50 tempC').sub('100 tempC'); // -50 degC +Qty('100 tempC').mul(scalar); // 100*scalar tempC +Qty('100 tempC').div(scalar); // 100/scalar tempC +Qty('100 tempC').mul(qty); // throws error +Qty('100 tempC').div(qty); // throws error +Qty('100 tempC*unit'); // throws error +Qty('100 tempC/unit'); // throws error +Qty('100 unit/tempC'); // throws error +Qty('100 tempC').inverse(); // throws error + +Qty('100 tempC').to('degC'); // => 100 degC + +Qty('100 degC').to('tempC'); // => -173.15 tempC + +Qty('0 tempC').add('100 degC'); // => 100 tempC + +try { + // code triggering an error inside JS-quantities +} catch (e) { + if (e instanceof Qty.Error) { + // ... + } else { + // ... + } +} + +// From project spec + +describe("js-quantities", function () { + "use strict"; + + describe("initialization", function () { + it("should create unit only", function () { + var qty = Qty("m"); + expect(qty.numerator).toEqual([""]); + expect(qty.scalar).toBe(1); + }); + + it("should create unitless", function () { + var qty = Qty("1"); + expect(qty.toFloat()).toBe(1); + expect(qty.numerator).toEqual(["<1>"]); + expect(qty.denominator).toEqual(["<1>"]); + qty = Qty("1.5"); + expect(qty.toFloat()).toBe(1.5); + expect(qty.numerator).toEqual(["<1>"]); + expect(qty.denominator).toEqual(["<1>"]); + }); + + it("should create unitless from numbers", function () { + var qty = Qty(1.5); + expect(qty.toFloat()).toBe(1.5); + expect(qty.numerator).toEqual(["<1>"]); + expect(qty.denominator).toEqual(["<1>"]); + }); + + it("should create from numbers with explicit units", function () { + var qty = Qty(1.5, "m"); + expect(qty.scalar).toBe(1.5); + expect(qty.numerator).toEqual([""]); + expect(qty.denominator).toEqual(["<1>"]); + }); + + it("temperatures should have base unit in kelvin", function () { + var qty = Qty("1 tempK").toBase(); + expect(qty.scalar).toBe(1); + expect(qty.units()).toBe("tempK"); + + qty = Qty("1 tempR").toBase(); + expect(qty.scalar).toBe(5 / 9); + expect(qty.units()).toBe("tempK"); + + qty = Qty("0 tempC").toBase(); + expect(qty.scalar).toBe(273.15); + expect(qty.units()).toBe("tempK"); + + qty = Qty("0 tempF").toBase(); + expect(qty.scalar).toBeCloseTo(255.372, 3); + expect(qty.units()).toBe("tempK"); + }); + + it("temperature degrees should have base unit in kelvin", function () { + var qty = Qty("1 degK").toBase(); + expect(qty.scalar).toBe(1); + expect(qty.units()).toBe("degK"); + + qty = Qty("1 degR").toBase(); + expect(qty.scalar).toBe(5 / 9); + expect(qty.units()).toBe("degK"); + + qty = Qty("1 degC").toBase(); + expect(qty.scalar).toBe(1); + expect(qty.units()).toBe("degK"); + + qty = Qty("1 degF").toBase(); + expect(qty.scalar).toBe(5 / 9); + expect(qty.units()).toBe("degK"); + }); + + it("should not create temperatures below absolute zero", function () { + expect(function () { Qty("-1 tempK"); }).toThrow("Temperatures must not be less than absolute zero"); + expect(function () { Qty("-273.16 tempC"); }).toThrow("Temperatures must not be less than absolute zero"); + expect(function () { Qty("-459.68 tempF"); }).toThrow("Temperatures must not be less than absolute zero"); + expect(function () { Qty("-1 tempR"); }).toThrow("Temperatures must not be less than absolute zero"); + + var qty = Qty("1 tempK"); + expect(function () { qty.mul("-1"); }).toThrow("Temperatures must not be less than absolute zero"); + + qty = Qty("0 tempK"); + expect(function () { qty.sub("1 degK"); }).toThrow("Temperatures must not be less than absolute zero"); + + qty = Qty("-273.15 tempC"); + expect(function () { qty.sub("1 degC"); }).toThrow("Temperatures must not be less than absolute zero"); + + qty = Qty("-459.67 tempF"); + expect(function () { qty.sub("1 degF"); }).toThrow("Temperatures must not be less than absolute zero"); + + qty = Qty("0 tempR"); + expect(function () { qty.sub("1 degR"); }).toThrow("Temperatures must not be less than absolute zero"); + }); + + it("should create simple", function () { + var qty = Qty("1m"); + expect(qty.scalar).toBe(1); + expect(qty.numerator).toEqual([""]); + expect(qty.denominator).toEqual(["<1>"]); + }); + + it("should create negative", function () { + var qty = Qty("-1m"); + expect(qty.scalar).toBe(-1); + expect(qty.numerator).toEqual([""]); + expect(qty.denominator).toEqual(["<1>"]); + }); + + it("should create compound", function () { + var qty = Qty("1 N*m"); + expect(qty.scalar).toBe(1); + expect(qty.numerator).toEqual(["", ""]); + expect(qty.denominator).toEqual(["<1>"]); + }); + + it("should create pressure units in term of height of water", function () { + var qty = Qty("1 inH2O"); + expect(qty.scalar).toBe(1); + expect(qty.numerator).toEqual([""]); + + qty = Qty("1 cmH2O"); + expect(qty.scalar).toBe(1); + expect(qty.numerator).toEqual([""]); + }); + + it("should create with denominator", function () { + var qty = Qty("1 m/s"); + expect(qty.scalar).toBe(1); + expect(qty.numerator).toEqual([""]); + expect(qty.denominator).toEqual([""]); + }); + + it("should create with denominator only", function () { + var qty = Qty("1 /s"); + expect(qty.scalar).toBe(1); + expect(qty.numerator).toEqual(["<1>"]); + expect(qty.denominator).toEqual([""]); + + qty = Qty("1 1/s"); + expect(qty.scalar).toBe(1); + expect(qty.numerator).toEqual(["<1>"]); + expect(qty.denominator).toEqual([""]); + + qty = Qty("1 s^-1"); + expect(qty.scalar).toBe(1); + expect(qty.numerator).toEqual(["<1>"]); + expect(qty.denominator).toEqual([""]); + }); + + it("should create with powers", function () { + var qty = Qty("1 m^2/s^2"); + expect(qty.scalar).toBe(1); + expect(qty.numerator).toEqual(["", ""]); + expect(qty.denominator).toEqual(["", ""]); + qty = Qty("1 m^2 kg^2 J^2/s^2"); + expect(qty.scalar).toBe(1); + expect(qty.numerator).toEqual(["", "", "", "", "", ""]); + expect(qty.denominator).toEqual(["", ""]); + qty = Qty("1 m^2/s^2*J^3"); + expect(qty.scalar).toBe(1); + expect(qty.numerator).toEqual(["", ""]); + expect(qty.denominator).toEqual(["", "", "", "", ""]); + }); + + it("should create with zero power", function () { + var qty = Qty("1 m^0"); + expect(qty.scalar).toBe(1); + expect(qty.numerator).toEqual(["<1>"]); + expect(qty.denominator).toEqual(["<1>"]); + }); + + it("should create with negative powers", function () { + var qty = Qty("1 m^2 s^-2"); + expect(qty.scalar).toBe(1); + expect(qty.numerator).toEqual(["", ""]); + expect(qty.denominator).toEqual(["", ""]); + expect(qty.same(Qty("1 m^2/s^2"))).toBe(true); + }); + + it("should accept powers without ^ syntax (simple)", function () { + var qty1 = Qty("1 m2"); + var qty2 = Qty("1 m^2"); + expect(qty1.eq(qty2)).toBe(true); + }); + + it("should accept powers without ^ syntax (negative power)", function () { + var qty1 = Qty("1 m-2"); + var qty2 = Qty("1 m^-2"); + expect(qty1.eq(qty2)).toBe(true); + }); + + it("should accept powers without ^ syntax (compound)", function () { + var qty1 = Qty("1 m^2 kg^2 J^2/s^2"); + var qty2 = Qty("1 m2 kg2 J2/s2"); + expect(qty1.eq(qty2)).toBe(true); + }); + + it("should accept powers without ^ syntax (compound and negative power)", function () { + var qty1 = Qty("1 m^2 kg^2 J^2 s^-2"); + var qty2 = Qty("1 m2 kg2 J2 s-2"); + expect(qty1.eq(qty2)).toBe(true); + }); + + it("should throw 'Unit not recognized' error when initializing with an invalid unit", function () { + expect(function () { Qty("aa"); }).toThrow("Unit not recognized"); + expect(function () { Qty("m/aa"); }).toThrow("Unit not recognized"); + expect(function () { Qty("m-"); }).toThrow("Unit not recognized"); + expect(function () { Qty("N*m"); }).not.toThrow("Unit not recognized"); + // mm is millimeter, but mmm is not a valid unit + expect(function () { Qty("mmm"); }).toThrow("Unit not recognized"); + }); + + it("should accept empty string as unitless 1", function () { + expect(Qty("").same(Qty("1"))).toBe(true); + expect(Qty(" ").same(Qty("1"))).toBe(true); + }); + + it("should throw error when passing NaN", function () { + expect( + function () { Qty(NaN); } + ).toThrow("Only string, number or quantity accepted as single " + + "initialization value"); + }); + + it("should throw 'Unit not recognized' error when initializing with an invalid unit and a 0 exponent", function () { + expect(function () { Qty("3p0"); }).toThrow("Unit not recognized"); + expect(function () { Qty("3p-0"); }).toThrow("Unit not recognized"); + }); + + it("should set baseScalar", function () { + var qty = Qty("0.018 MPa"); + expect(qty.baseScalar).toBe(18000); + + qty = Qty("66 cm3"); + expect(qty.baseScalar).toBe(0.000066); + }); + + it("should keep init value as is", function () { + var initValue = " 66 cm3 "; + var qty = Qty(initValue); + + expect(qty.initValue).toEqual(initValue); + }); + + it("should allow whitespace-wrapped value", function () { + expect(function () { Qty(" 2 MPa "); }).not.toThrow(); + }); + + it("should allow whitespaces between sign and scalar", function () { + var qty = Qty("- 1m"); + + expect(qty.scalar).toEqual(-1); + expect(qty.units()).toEqual("m"); + }); + + it("should throw an error when parsing negative quantity " + + "with no scalar", function () { + expect(function () { Qty("-m"); }).toThrow("Unit not recognized"); + }); + }); + + describe("isCompatible", function () { + it("should return true with compatible quantities", function () { + var qty1 = Qty("1 m*kg/s"); + var qty2 = Qty("1 in*pound/min"); + expect(qty1.isCompatible(qty2)).toBe(true); + qty2 = Qty("1 in/min"); + expect(qty1.isCompatible(qty2)).toBe(false); + }); + + it("should return true with dimensionless quantities", function () { + var qty1 = Qty("1"); + var qty2 = Qty("2"); + expect(qty1.isCompatible(qty2)).toBe(true); + }); + }); + + describe("conversion", function () { + it("should convert to base units", function () { + var qty = Qty("100 cm"); + expect(qty.toBase().scalar).toBe(1); + expect(qty.toBase().units()).toBe("m"); + qty = Qty("10 cm"); + expect(qty.toBase().scalar).toBe(0.1); + expect(qty.toBase().units()).toBe("m"); + qty = Qty("0.3 mm^2 ms^-2"); + expect(qty.toBase().scalar).toBe(0.3); + expect(qty.toBase().units()).toBe("m2/s2"); + }); + + it("should convert to compatible units", function () { + var qty = Qty("10 cm"); + expect(qty.to("ft").scalar).toBe(Qty.divSafe(0.1, 0.3048)); + qty = Qty("2m^3"); + expect(qty.to("l").scalar).toBe(2000); + + qty = Qty("10 cm"); + expect(qty.to(Qty("m")).scalar).toBe(0.1); + expect(qty.to(Qty("20m")).scalar).toBe(0.1); + + qty = Qty("1 m3"); + expect(qty.to("cm3").scalar).toBe(1000000); + + qty = Qty("1 cm3"); + expect(qty.to("mm3").scalar).toBe(1000); + + qty = Qty("550 cm3"); + expect(qty.to("cm^3").scalar).toBe(550); + + qty = Qty("0.000773 m3"); + expect(qty.to("cm^3").scalar).toBe(773); + }); + + describe('percents', function () { + it("should convert from % to unitless", function () { + expect(Qty("10 %").to("").same(Qty("0.1"))).toBe(true); + }); + + it("should convert from unitless to %", function () { + expect(Qty("0.1").to("%").same(Qty("10 %"))).toBe(true); + }); + }); + + it("should convert temperatures to compatible units", function () { + var qty = Qty("0 tempK"); + expect(qty.to("tempC").scalar).toBe(-273.15); + + qty = Qty("0 tempF"); + expect(qty.to("tempK").scalar).toBeCloseTo(255.372, 3); + + qty = Qty("32 tempF"); + expect(qty.to("tempC").scalar).toBe(0); + + qty = Qty("0 tempC"); + expect(qty.to("tempF").scalar).toBeCloseTo(32, 10); + }); + + it("should convert temperature degrees to compatible units", function () { + var qty = Qty("0 degK"); + expect(qty.to("degC").scalar).toBe(0); + + qty = Qty("1 degK/s"); + expect(qty.to("degC/min").scalar).toBe(60); + + qty = Qty("100 cm/degF"); + expect(qty.to("m/degF").scalar).toBe(1); + + qty = Qty("10 degC"); + expect(qty.to("degF").scalar).toBe(18); + }); + + it("should convert temperature degrees to temperatures", function () { + // according to ruby-units, deg -> temp conversion adds the degress to 0 kelvin before converting + var qty = Qty("100 degC"); + expect(qty.to("tempC").scalar).toBeCloseTo(-173.15, 10); + + qty = Qty("273.15 degC"); + expect(qty.to("tempC").scalar).toBe(0); + + qty = Qty("460.67 degF"); + expect(qty.to("tempF").scalar).toBeCloseTo(1, 10); + }); + + it("should convert temperatures to temperature degrees", function () { + // according to ruby-units, temp -> deg conversion always uses the 0 relative degrees + var qty = Qty("100 tempC"); + expect(qty.to("degC").scalar).toBe(100); + + qty = Qty("0 tempK"); + expect(qty.to("degC").scalar).toBe(0); + + qty = Qty("0 tempF"); + expect(qty.to("degK").scalar).toBe(0); + + qty = Qty("18 tempF"); + expect(qty.to("degC").scalar).toBe(10); + + qty = Qty("10 tempC"); + expect(qty.to("degF").scalar).toBe(18); + }); + + it("should calculate inverses", function () { + var qty = Qty("1 ohm"); + var result = qty.to("siemens"); + expect(result.scalar).toBe(1); + expect(result.kind()).toBe("conductance"); + + qty = Qty("10 ohm"); + result = qty.to("siemens"); + expect(result.scalar).toBe(0.1); + expect(result.kind()).toBe("conductance"); + + qty = Qty("10 siemens"); + result = qty.to("ohm"); + expect(result.scalar).toBe(0.1); + expect(result.kind()).toBe("resistance"); + + qty = Qty("10 siemens"); + result = qty.inverse(); + expect(result.eq(".1 ohm")).toBe(true); + expect(result.kind()).toBe("resistance"); + + // cannot inverse a quantity with a 0 scalar + qty = Qty("0 ohm"); + expect(function () { qty.inverse(); }).toThrow("Divide by zero"); + + qty = Qty("10 ohm").inverse(); + result = qty.to("S"); + expect(result.scalar).toBe(0.1); + expect(result.kind()).toBe("conductance"); + + qty = Qty("12 in").inverse(); + // TODO: Swap toBeCloseTo with toBe once divSafe is fixed + expect(qty.to("ft").scalar).toBeCloseTo(1, 10); + }); + + it("should return itself if target units are the same", function () { + var qty = Qty("123 cm3"); + + expect(qty.to("cm3")).toBe(qty); + expect(qty.to("cm^3")).toBe(qty); + + qty = Qty("123 mcg"); + expect(qty.to("ug")).toBe(qty); + }); + + it("should be cached", function () { + var qty = Qty("100 m"), + converted = qty.to("ft"); + + expect(qty.to("ft") === converted).toBe(true); + }); + }); + + describe("comparison", function () { + it("should return true when comparing equal quantities", function () { + var qty1 = Qty("1cm"); + var qty2 = Qty("10mm"); + expect(qty1.eq(qty2)).toBe(true); + }); + + it("should compare compatible quantities", function () { + var qty1 = Qty("1cm"); + var qty2 = Qty("1mm"); + var qty3 = Qty("10mm"); + var qty4 = Qty("28A"); + expect(qty1.compareTo(qty2)).toBe(1); + expect(qty2.compareTo(qty1)).toBe(-1); + expect(qty1.compareTo(qty3)).toBe(0); + expect(function () { qty1.compareTo(qty4); }).toThrow("Incompatible units"); + + expect(qty1.lt(qty2)).toBe(false); + expect(qty1.lt(qty3)).toBe(false); + expect(qty1.lte(qty3)).toBe(true); + expect(qty1.gte(qty3)).toBe(true); + expect(qty1.gt(qty2)).toBe(true); + expect(qty2.gt(qty1)).toBe(false); + }); + + it("should compare identical quantities", function () { + var qty1 = Qty("1cm"); + var qty2 = Qty("1cm"); + var qty3 = Qty("10mm"); + expect(qty1.same(qty2)).toBe(true); + expect(qty1.same(qty3)).toBe(false); + }); + + it("should accept strings as parameter", function () { + var qty = Qty("1 cm"); + expect(qty.lt("0.5 cm")).toBe(false); + expect(qty.lte("1 cm")).toBe(true); + expect(qty.gte("3 mm")).toBe(true); + expect(qty.gt("5 m")).toBe(false); + }); + + }); + + describe("non-ASCII character", function () { + describe("µ", function () { + it("should be supported as prefix", function () { + // µ as greek letter + expect(Qty("1 \u03BCm").eq(Qty("1 um"))).toBe(true); + // µ as micro sign + expect(Qty("1 \u00B5m").eq(Qty("1 um"))).toBe(true); + }); + }); + + describe("Ω", function () { + it("should be accepted as unit for ohm", function () { + // Ω as greek letter + expect(Qty("1 \u03A9").eq(Qty("1 ohm"))).toBe(true); + // Ω as ohm sign + expect(Qty("1 \u2126").eq(Qty("1 ohm"))).toBe(true); + }); + }); + }); + + describe("math", function () { + + it("should add quantities", function () { + var qty1 = Qty("2.5m"); + var qty2 = Qty("3m"); + expect(qty1.add(qty2).scalar).toBe(5.5); + + expect(qty1.add("3m").scalar).toBe(5.5); + + qty2 = Qty("3cm"); + var result = qty1.add(qty2); + expect(result.scalar).toBe(2.53); + expect(result.units()).toBe("m"); + + result = qty2.add(qty1); + expect(result.scalar).toBe(253); + expect(result.units()).toBe("cm"); + + // make sure adding 2 of the same non-base units work + result = Qty("5cm").add("3cm"); + expect(result.scalar).toBe(8); + expect(result.units()).toBe("cm"); + }); + + it("should fail to add unlike quantities", function () { + var qty1 = Qty("3m"); + var qty2 = Qty("2s"); + expect(function () { qty1.add(qty2); }).toThrow("Incompatible units"); + expect(function () { qty2.add(qty1); }).toThrow("Incompatible units"); + }); + + it("should fail to add inverse quantities", function () { + var qty1 = Qty("10S"); + var qty2 = qty1.inverse(); + expect(function () { qty1.add(qty2); }).toThrow("Incompatible units"); + expect(function () { qty2.add(qty1); }).toThrow("Incompatible units"); + + qty1 = Qty("10S"); + qty2 = Qty("0.1ohm"); + expect(function () { qty1.add(qty2); }).toThrow("Incompatible units"); + expect(function () { qty2.add(qty1); }).toThrow("Incompatible units"); + }); + + it("should subtract quantities", function () { + var qty1 = Qty("2.5m"); + var qty2 = Qty("3m"); + expect(qty1.sub(qty2).scalar).toBe(-0.5); + + expect(qty1.sub("2m").scalar).toBe(0.5); + expect(qty1.sub("-2m").scalar).toBe(4.5); + + qty2 = Qty("3cm"); + var result = qty1.sub(qty2); + expect(result.scalar).toBe(2.47); + expect(result.units()).toBe("m"); + + result = qty2.sub(qty1); + expect(result.scalar).toBe(-247); + expect(result.units()).toBe("cm"); + }); + + it("should fail to subtract unlike quantities", function () { + var qty1 = Qty("3m"); + var qty2 = Qty("2s"); + expect(function () { qty1.sub(qty2); }).toThrow("Incompatible units"); + expect(function () { qty2.sub(qty1); }).toThrow("Incompatible units"); + }); + + it("should fail to subtract inverse quantities", function () { + var qty1 = Qty("10S"); + var qty2 = qty1.inverse(); + expect(function () { qty1.sub(qty2); }).toThrow("Incompatible units"); + expect(function () { qty2.sub(qty1); }).toThrow("Incompatible units"); + + qty1 = Qty("10S"); + qty2 = Qty("0.1ohm"); + expect(function () { qty1.sub(qty2); }).toThrow("Incompatible units"); + expect(function () { qty2.sub(qty1); }).toThrow("Incompatible units"); + }); + + it("should multiply quantities", function () { + var qty1 = Qty("2.5m"); + var qty2 = Qty("3m"); + var result = qty1.mul(qty2); + expect(result.scalar).toBe(7.5); + expect(result.units()).toBe("m2"); + expect(result.kind()).toBe("area"); + + qty2 = Qty("3cm"); + result = qty1.mul(qty2); + expect(result.scalar).toBe(0.075); + expect(result.units()).toBe("m2"); + + result = qty2.mul(qty1); + expect(result.scalar).toBe(750); + expect(result.units()).toBe("cm2"); + + result = qty1.mul(3.5); + expect(result.scalar).toBe(8.75); + expect(result.units()).toBe("m"); + + result = qty1.mul(0); + expect(result.scalar).toBe(0); + expect(result.units()).toBe("m"); + + result = qty1.mul(Qty("0m")); + expect(result.scalar).toBe(0); + expect(result.units()).toBe("m2"); + + qty2 = Qty("1.458 m"); + result = qty1.mul(qty2); + expect(result.scalar).toBe(3.645); + expect(result.units()).toBe("m2"); + }); + + it("should multiply unlike quantities", function () { + var qty1 = Qty("2.5 m"); + var qty2 = Qty("3 N"); + + var result = qty1.mul(qty2); + expect(result.scalar).toBe(7.5); + + qty1 = Qty("2.5 m^2"); + qty2 = Qty("3 kg/m^2"); + + result = qty1.mul(qty2); + expect(result.scalar).toBe(7.5); + expect(result.units()).toBe("kg"); + }); + + it("should multiply inverse quantities", function () { + var qty1 = Qty("10S"); + var qty2 = Qty(".5S").inverse(); // 2/S + var qty3 = qty1.inverse(); // .1/S + + var result = qty1.mul(qty2); + expect(result.scalar).toBe(20); + expect(result.isUnitless()).toBe(true); + expect(result.units()).toBe(""); + // swapping operands should give the same outcome + result = qty2.mul(qty1); + expect(result.scalar).toBe(20); + expect(result.isUnitless()).toBe(true); + expect(result.units()).toBe(""); + + result = qty1.mul(qty3); + expect(result.scalar).toBe(1); + expect(result.isUnitless()).toBe(true); + expect(result.units()).toBe(""); + // swapping operands should give the same outcome + result = qty3.mul(qty1); + expect(result.scalar).toBe(1); + expect(result.isUnitless()).toBe(true); + expect(result.units()).toBe(""); + }); + + it("should divide quantities", function () { + var qty1 = Qty("2.5m"); + var qty2 = Qty("3m"); + var qty3 = Qty("0m"); + + expect(function () { qty1.div(qty3); }).toThrow("Divide by zero"); + expect(function () { qty1.div(0); }).toThrow("Divide by zero"); + expect(qty3.div(qty1).scalar).toBe(0); + + var result = qty1.div(qty2); + expect(result.scalar).toBe(2.5 / 3); + expect(result.units()).toBe(""); + expect(result.kind()).toBe("unitless"); + + var qty4 = Qty("3cm"); + result = qty1.div(qty4); + expect(result.scalar).toBe(2.5 / 0.03); + expect(result.units()).toBe(""); + + result = qty4.div(qty1); + expect(result.scalar).toBe(0.012); + expect(result.units()).toBe(""); + + result = qty1.div(3.5); + expect(result.scalar).toBe(2.5 / 3.5); + expect(result.units()).toBe("m"); + }); + + it("should divide unlike quantities", function () { + var qty1 = Qty("7.5kg"); + var qty2 = Qty("2.5m^2"); + + var result = qty1.div(qty2); + expect(result.scalar).toBe(3); + expect(result.units()).toBe("kg/m2"); + }); + + it("should divide inverse quantities", function () { + var qty1 = Qty("10 S"); + var qty2 = Qty(".5 S").inverse(); // 2/S + var qty3 = qty1.inverse(); // .1/S + + var result = qty1.div(qty2); + expect(result.scalar).toBe(5); + expect(result.units()).toBe("S2"); + + result = qty2.div(qty1); + expect(result.scalar).toBe(0.2); + expect(result.units()).toBe("1/S2"); + + result = qty1.div(qty3); + expect(result.scalar).toBe(100); + expect(result.units()).toBe("S2"); + + result = qty3.div(qty1); + expect(result.scalar).toBe(0.01); + expect(result.units()).toBe("1/S2"); + }); + + }); + + describe("math with temperatures", function () { + + it("should add temperature degrees", function () { + var qty = Qty("2degC"); + expect(qty.add("3degF").scalar).toBeCloseTo(11 / 3, 10); + expect(qty.add("-1degC").scalar).toBe(1); + + qty = Qty("2 degC"); + var result = qty.add("2 degF"); + expect(result.scalar).toBe(28 / 9); + expect(result.units()).toBe("degC"); + + qty = Qty("2degK"); + result = qty.add("3degC"); + expect(result.scalar).toBe(5); + expect(result.units()).toBe("degK"); + + qty = Qty("2degC"); + result = qty.add("2degK"); + expect(result.scalar).toBe(4); + expect(result.units()).toBe("degC"); + }); + + it("should not add two temperatures", function () { + var qty = Qty("2tempC"); + expect(function () { qty.add("1 tempF"); }).toThrow("Cannot add two temperatures"); + expect(function () { qty.add("1 tempC"); }).toThrow("Cannot add two temperatures"); + }); + + it("should add temperatures to degrees", function () { + var qty = Qty("2degC"); + var result = qty.add("3tempF"); + expect(result.scalar).toBe(33 / 5); + expect(result.units()).toBe("tempF"); + + result = qty.add("-1tempC"); + expect(result.scalar).toBe(1); + expect(result.units()).toBe("tempC"); + + qty = Qty("2 tempC"); + result = qty.add("2 degF"); + expect(result.scalar).toBe(28 / 9); + expect(result.units()).toBe("tempC"); + }); + + it("should subtract degrees from degrees", function () { + var qty = Qty("2degC"); + expect(qty.sub("1.5degK").scalar).toBe(0.5); + expect(qty.sub("-2degC").scalar).toBe(4); + expect(qty.sub("1degF").scalar).toBe(2 - 5 / 9); + expect(qty.sub("-1degC").scalar).toBe(3); + + var result = qty.sub("degC"); + expect(result.scalar).toBe(1); + expect(result.units()).toBe("degC"); + }); + + it("should subtract degrees from temperatures", function () { + var qty = Qty("2tempC"); + expect(qty.sub("1.5degK").scalar).toBe(0.5); + expect(qty.sub("-2degC").scalar).toBe(4); + expect(qty.sub("1degF").scalar).toBe(2 - 5 / 9); + expect(qty.sub("-1degC").scalar).toBe(3); + + var result = qty.sub("degC"); + expect(result.scalar).toBe(1); + expect(result.units()).toBe("tempC"); + }); + + it("should subtract temperatures from temperatures", function () { + var qty = Qty("2tempC"); + + var result = qty.sub("1.5tempK"); + expect(result.scalar).toBe(273.65); + expect(result.units()).toBe("degC"); + + result = qty.sub("-2tempC"); + expect(result.scalar).toBe(4); + expect(result.units()).toBe("degC"); + + result = qty.sub("32tempF"); + expect(result.scalar).toBe(2); + expect(result.units()).toBe("degC"); + }); + + it("should not subtract temperatures from degrees", function () { + var qty = Qty("2degC"); + expect(function () { qty.sub("1 tempF"); }).toThrow("Cannot subtract a temperature from a differential degree unit"); + expect(function () { qty.sub("1 tempC"); }).toThrow("Cannot subtract a temperature from a differential degree unit"); + }); + + it("should multiply temperature degrees", function () { + var qty = Qty("2degF"); + var result = qty.mul(3); + expect(result.scalar).toBe(6); + expect(result.units()).toBe("degF"); + + result = qty.mul("3degF"); + expect(result.scalar).toBe(6); + expect(result.units()).toBe("degF2"); + + // TODO: Should we convert degrees ("2 degK" to "degC") before we do the math? + qty = Qty("2degC"); + result = qty.mul("2degK"); + expect(result.scalar).toBe(4); + expect(result.units()).toBe("degC*degK"); + + qty = Qty("2degC"); + result = qty.mul("degF"); + expect(result.scalar).toBe(2); + expect(result.units()).toBe("degC*degF"); + }); + + it("should not multiply temperatures except by scalar", function () { + var qty = Qty("2tempF"); + expect(function () { qty.mul("1 tempC"); }).toThrow("Cannot multiply by temperatures"); + expect(function () { qty.mul("1 degC"); }).toThrow("Cannot multiply by temperatures"); + expect(function () { Qty("1 tempC*s"); }).toThrow("Cannot multiply by temperatures"); + + var result = qty.mul(2); + expect(result.scalar).toBe(4); + expect(result.units()).toBe("tempF"); + + result = Qty("2").mul(qty); + expect(result.scalar).toBe(4); + expect(result.units()).toBe("tempF"); + }); + + it("should multiply temperature degrees with unlike quantities", function () { + var qty1 = Qty("2.5 degF"); + var qty2 = Qty("3 m"); + + var result = qty1.mul(qty2); + expect(result.scalar).toBe(7.5); + + qty1 = Qty("2.5 degF"); + qty2 = Qty("3 kg/degF"); + + result = qty1.mul(qty2); + expect(result.scalar).toBe(7.5); + expect(result.units()).toBe("kg"); + }); + + it("should divide temperature degrees with unlike quantities", function () { + var qty1 = Qty("7.5degF"); + var qty2 = Qty("2.5m^2"); + + var result = qty1.div(qty2); + expect(result.scalar).toBe(3); + expect(result.units()).toBe("degF/m2"); + }); + + it("should divide temperature degree quantities", function () { + var qty = Qty("2.5 degF"); + + expect(function () { qty.div("0 degF"); }).toThrow("Divide by zero"); + expect(function () { qty.div(0); }).toThrow("Divide by zero"); + expect(Qty("0 degF").div(qty).scalar).toBe(0); + expect(Qty("0 degF").div(qty).units()).toBe(""); + + var result = qty.div("3 degF"); + expect(result.scalar).toBe(2.5 / 3); + expect(result.units()).toBe(""); + expect(result.kind()).toBe("unitless"); + + result = qty.div(3); + expect(result.scalar).toBe(2.5 / 3); + expect(result.units()).toBe("degF"); + expect(result.kind()).toBe("temperature"); + + // TODO: Should we convert "2 degC" to "degF" before we do the math? + result = qty.div("2 degC"); + expect(result.scalar).toBe(1.25); + expect(result.units()).toBe("degF/degC"); + }); + + it("should not divide with temperatures except by scalar", function () { + expect(function () { Qty("tempF").div("1 tempC"); }).toThrow("Cannot divide with temperatures"); + expect(function () { Qty("tempF").div("1 degC"); }).toThrow("Cannot divide with temperatures"); + expect(function () { Qty("2").div("tempF"); }).toThrow("Cannot divide with temperatures"); + expect(function () { Qty("2 tempF/s"); }).toThrow("Cannot divide with temperatures"); + expect(function () { Qty("2 s/tempF"); }).toThrow("Cannot divide with temperatures"); + + // inverse is division: 1/x + expect(function () { Qty("tempF").inverse(); }).toThrow("Cannot divide with temperatures"); + + var result = Qty("4 tempF").div(2); + expect(result.scalar).toBe(2); + expect(result.units()).toBe("tempF"); + }); + + }); + + describe("errors", function () { + it("should be instance of Qty.Error", function () { + try { + Qty("aa"); + } catch (e) { + expect(e instanceof Qty.Error).toBeTruthy(); + } + }); + }); + + describe("utility methods", function () { + + it("should accept string as parameter for compatibility tests", function () { + var qty = Qty("1 mm"); + + expect(qty.isCompatible("2 mm")).toBe(true); + expect(qty.isCompatible("2 mm^3")).toBe(false); + }); + + it("should return kind", function () { + var qty = Qty("1 mm"); + expect(qty.kind()).toBe("length"); + + qty = Qty("1 N"); + expect(qty.kind()).toBe("force"); + }); + + it("should know if a quantity is in base units", function () { + var qty = Qty("100 cm"); + expect(qty.isBase()).toBe(false); + + qty = Qty("1m"); + expect(qty.isBase()).toBe(true); + }); + + it("should return unit part of quantities", function () { + var qty = Qty("1"); + expect(qty.units()).toBe(""); + qty = Qty("1 /s"); + expect(qty.units()).toBe("1/s"); + qty = Qty("100 cm"); + expect(qty.units()).toBe("cm"); + qty = Qty("100 cm/s"); + expect(qty.units()).toBe("cm/s"); + qty = Qty("1 cm^2"); + expect(qty.units()).toBe("cm2"); + qty = Qty("1 cm^2/s^2"); + expect(qty.units()).toBe("cm2/s2"); + qty = Qty("1 cm^2*J^3/s^2*A^2"); + expect(qty.units()).toBe("cm2*J3/s2*A2"); + }); + + }); + + describe("toString", function () { + it("should generate readable human output", function () { + var qty = Qty("2m"); + expect(qty.toString()).toBe("2 m"); + expect(qty.toString("cm")).toBe("200 cm"); + expect(qty.toString("km")).toBe("0.002 km"); + expect(function () { qty.toString("A"); }).toThrow("Incompatible units"); + + qty = Qty("24.5m/s"); + expect(qty.toString()).toBe("24.5 m/s"); + expect(function () { qty.toString("m"); }).toThrow("Incompatible units"); + expect(qty.toString("km/h")).toBe("88.2 km/h"); + + qty = Qty("254kg/m^2"); + expect(qty.toString()).toBe("254 kg/m2"); + + qty = Qty("2"); + expect(qty.toString()).toBe("2"); + }); + + it("should round readable human output when max decimals is specified", function () { + var qty = (Qty("2m")).div(3); + expect(qty.toString("cm", 2)).toBe("66.67 cm"); + + qty = Qty("2.8m"); + expect(qty.toString("m", 0)).toBe("3 m"); + expect(qty.toString("cm", 0)).toBe("280 cm"); + qty = Qty("2.818m"); + expect(qty.toString("cm", 0)).toBe("282 cm"); + }); + + it("should round to max decimals", function () { + var qty = (Qty("2.987654321 m")); + + expect(qty.toString(3)).toBe("2.988 m"); + expect(qty.toString(0)).toBe("3 m"); + }); + + it("should round according to precision passed as quantity", function () { + var qty = Qty("5.17 ft"); + + expect(qty.toString(Qty("ft"))).toBe("5 ft"); + expect(qty.toString(Qty("2 ft"))).toBe("6 ft"); + expect(qty.toString(Qty("0.5 ft"))).toBe("5 ft"); + expect(qty.toString(Qty("0.1 ft"))).toBe("5.2 ft"); + expect(qty.toString(Qty("0.05 ft"))).toBe("5.15 ft"); + expect(qty.toString(Qty("0.01 ft"))).toBe("5.17 ft"); + expect(qty.toString(Qty("0.0001 ft"))).toBe("5.17 ft"); + }); + + it("should return same output with successive calls", function () { + var qty = Qty("123 cm3"); + expect(qty.toString("cm3", 0)).toBe("123 cm3"); + expect(qty.toString("cm3", 0)).toBe("123 cm3"); + }); + + it("should return identical output when called with no parameters or same units", function () { + var qty = Qty("123 cm3"); + expect(qty.toString()).toBe(qty.toString("cm3")); + }); + + }); + + describe("format", function () { + describe("provided default formatter", function () { + it("should be applied to output", function () { + var qty = (Qty("2.987654321 m")); + + expect(qty.format()).toBe("2.987654321 m"); + }); + }); + + describe("custom formatter", function () { + var roundingFormatter = function (maxDecimals: number) { + return function (scalar: number, units: string) { + var pow = Math.pow(10, maxDecimals); + var rounded = Math.round(scalar * pow) / pow; + + return rounded + " " + units; + }; + }; + + it("should be applied to output", function () { + var qty = (Qty("2.987654321 m")); + + expect(qty.format(roundingFormatter(3))).toBe("2.988 m"); + expect(qty.format(roundingFormatter(0))).toBe("3 m"); + }); + + it("should be applied after conversion to target units", function () { + var qty = (Qty("2m")).div(3); + expect(qty.format("cm", roundingFormatter(2))).toBe("66.67 cm"); + + var intRoundingFormatter = roundingFormatter(0); + qty = Qty("2.8m"); + expect(qty.format("m", intRoundingFormatter)).toBe("3 m"); + expect(qty.format("cm", intRoundingFormatter)).toBe("280 cm"); + qty = Qty("2.818m"); + expect(qty.format("cm", intRoundingFormatter)).toBe("282 cm"); + }); + + describe("globally set as default formatter", function () { + var previousFormatter: Qty.Formatter; + + beforeEach(function () { + previousFormatter = Qty.formatter; + Qty.formatter = roundingFormatter(3); + }); + + afterEach(function () { + // Restore previous formatter + Qty.formatter = previousFormatter; + }); + + it("should be applied when no formatter is passed", function () { + var qty = (Qty("2.987654321 m")); + + expect(qty.format()).toBe("2.988 m"); + }); + }); + }); + }); + + describe("precision rounding", function () { + it("should round according to precision passed as quantity with same units", function () { + var qty = Qty("5.17 ft"); + + expect(qty.toPrec(Qty("ft")).toString()).toBe("5 ft"); + expect(qty.toPrec(Qty("2 ft")).toString()).toBe("6 ft"); + expect(qty.toPrec(Qty("10 ft")).toString()).toBe("10 ft"); + expect(qty.toPrec(Qty("0.5 ft")).toString()).toBe("5 ft"); + expect(qty.toPrec(Qty("0.1 ft")).toString()).toBe("5.2 ft"); + expect(qty.toPrec(Qty("0.05 ft")).toString()).toBe("5.15 ft"); + expect(qty.toPrec(Qty("0.01 ft")).toString()).toBe("5.17 ft"); + expect(qty.toPrec(Qty("0.0001 ft")).toString()).toBe("5.17 ft"); + expect(qty.toPrec(Qty("0.25 ft")).toString()).toBe("5.25 ft"); + }); + + it("should allow string as precision parameter", function () { + var qty = Qty("5.17 ft"); + + expect(qty.toPrec("ft").toString()).toBe("5 ft"); + expect(qty.toPrec("0.5 ft").toString()).toBe("5 ft"); + expect(qty.toPrec("0.05 ft").toString()).toBe("5.15 ft"); + }); + + it("should round according to precision passed as quantity with different prefixes", function () { + var qty = Qty("6.3782 m"); + + expect(qty.toPrec(Qty("dm")).toString()).toBe("6.4 m"); + expect(qty.toPrec(Qty("cm")).toString()).toBe("6.38 m"); + expect(qty.toPrec(Qty("mm")).toString()).toBe("6.378 m"); + + expect(qty.toPrec(Qty("5 cm")).toString()).toBe("6.4 m"); + }); + + it("should round according to precision passed as quantity with different compatible units", function () { + var qty = Qty("1.146 MPa"); + expect(qty.toPrec(Qty("0.1 bar")).toString()).toBe("1.15 MPa"); + expect(qty.toPrec(Qty("0.01 MPa")).toString()).toBe("1.15 MPa"); + expect(qty.toPrec(Qty("dbar")).toString()).toBe("1.15 MPa"); + + // Tests below are mainly a safety net because not sure if there is + // any usefulness to do things like that + qty = Qty("5.171234568 ft"); + expect(qty.toPrec(Qty("m")).toString()).toBe("6.561679790026248 ft"); + expect(qty.toPrec(Qty("dm")).toString()).toBe("5.249343832020998 ft"); + expect(qty.toPrec(Qty("cm")).toString()).toBe("5.183727034120736 ft"); + expect(qty.toPrec(Qty("mm")).toString()).toBe("5.170603674540684 ft"); + }); + }); + + describe("mulSafe", function () { + it("should multiply while trying to avoid numerical errors", function () { + expect(Qty.mulSafe(0.1, 0.1)).toBe(0.01); + expect(Qty.mulSafe(1e-11, 123.456789)).toBe(1.23456789e-9); + expect(Qty.mulSafe(6e-12, 100000)).toBe(6e-7); + }); + }); + + describe("divSafe", function () { + it("should divide while trying to avoid numerical errors", function () { + expect(Qty.divSafe(0.000773, 0.000001)).toBe(773); + // TODO uncomment and fix + //expect(Qty.divSafe(24.5, 0.2777777777777778)).toBe(88.2); + }); + }); + + describe("Qty.parse", function () { + it("should not throw if parsed argument is a string", function () { + expect(function () { Qty.parse("foo"); }).not.toThrow("Argument should be a string"); + }); + + it("should return parsed quantity when passing a valid quantity", function () { + expect((Qty.parse("2.5 m") instanceof Qty)).toBe(true); + }); + + it("should return null when passing an invalid quantity", function () { + expect(Qty.parse("aa")).toBeNull(); + }); + }); + + describe("Qty.swiftConverter", function () { + it("should return a function", function () { + expect(typeof Qty.swiftConverter("m/h", "ft/s")).toBe("function"); + }); + + it("should throw when passing incompatible units", function () { + expect(function () { Qty.swiftConverter("m", "s"); }).toThrow("Incompatible units"); + }); + + describe("converter", function () { + describe("single value", function () { + it("should convert value", function () { + // TODO Same test but with m/h -> ft/s triggers rounding issue + // (For the sake of speed, converter does not check and fix rounding issues) + var converter = Qty.swiftConverter("m/h", "m/s"); + + expect(converter(2500)).toEqual(Qty("2500 m/h").to("m/s").scalar); + }); + + it("should returned value unchanged when units are identical", function () { + var converter = Qty.swiftConverter("m/h", "m/h"); + + expect(converter(2500)).toEqual(2500); + }); + + it("should convert temperatures", function () { + var converter = Qty.swiftConverter("tempF", "tempC"); + + expect(converter(32)).toEqual(0); + }); + + it("should convert degrees", function () { + var converter = Qty.swiftConverter("degC", "degF"); + + expect(converter(10)).toEqual(18); + }); + }); + + describe("array of values", function () { + it("should be converted", function () { + var converter = Qty.swiftConverter("MPa", "bar"), + values = [250, 10, 15], + expected = [2500, 100, 150]; + + expect(converter(values)).toEqual(expected); + }); + }); + }); + }); + + describe("Qty.getKinds", function () { + it("should return an array of kind names", function () { + expect(Qty.getKinds()).toContain("resistance"); + }); + + it("should not contain duplicate kind names", function () { + var kinds = Qty.getKinds(); + var map: { [key: string]: number } = {}; + kinds.forEach(function (kind) { + map[kind] = 1; + }); + expect(kinds.length).toEqual(Object.keys(map).length); + }); + }); + + describe("Qty.getUnits", function () { + it("should return an array of units of kind", function () { + expect(Qty.getUnits("currency")).toContain("dollar"); + }); + it("should return an array of all units without arg", function () { + expect(Qty.getUnits()).toContain("sievert"); + }); + it("should throw unknown kind", function () { + expect(function () { Qty.getUnits('bogusKind'); }).toThrow("Kind not recognized"); + }); + }); + + describe("Qty.getAliases", function () { + it("should return array of alternative names for unit", function () { + expect(Qty.getAliases("m")).toContain("meter"); + expect(Qty.getAliases("meter")).toContain("metre"); + expect(Qty.getAliases("N")).toContain("newton"); + }); + }); + + describe("information", function () { + describe("bits and bytes", function () { + it("should have 'information' as kind", function () { + expect(Qty("3 b").kind()).toBe("information"); + expect(Qty("5 B").kind()).toBe("information"); + }); + + it("could be pluralized", function () { + expect(Qty("3 bits").eq(Qty("3 b"))).toBe(true); + expect(Qty("5 bytes").eq(Qty("5 B"))).toBe(true); + }); + }); + + describe("rate", function () { + it("should accept bps and Bps aliases", function () { + expect(Qty("3 bps").eq(Qty("3 b/s"))).toBe(true); + expect(Qty("5 Bps").eq(Qty("5 B/s"))).toBe(true); + }); + + it("should be parsed when prefixed", function () { + expect(Qty("3 kbps").eq(Qty("3 kb/s"))).toBe(true); + expect(Qty("5 MBps").eq(Qty("5 MB/s"))).toBe(true); + }); + + it("should have 'information_rate' as kind", function () { + expect(Qty("3 bps").kind()).toBe("information_rate"); + expect(Qty("5 Bps").kind()).toBe("information_rate"); + }); + }); + }); + + describe("non regression tests", function () { + describe("Wh (#38)", function () { + it("should be parsed", function () { + expect(Qty("Wh").eq(Qty("3600 J"))).toBe(true); + }); + + it("should be parsed when prefixed", function () { + expect(Qty("kWh").eq(Qty("1000 Wh"))).toBe(true); + }); + }); + + describe("Ah (#25)", function () { + it("should be parsed", function () { + expect(Qty("Ah").eq(Qty("3600 C"))).toBe(true); + }); + + it("should be parsed when prefixed", function () { + expect(Qty("mAh").eq(Qty("3.6 C"))).toBe(true); + }); + }); + + describe("Farad (#67)", function () { + it('should be equal to its definition', function () { + expect(Qty("1 F").eq(Qty("1 C").div(Qty("1 V")))).toBe(true); + }); + + it('should not be defined as base unit', function () { + var qty = Qty("F"); + + expect(qty.isBase()).toBe(false); + expect(qty.toBase().units()).toEqual("s4*A2/m2*kg"); + }); + + it('should be parsed when prefixed', function () { + var qty = Qty("100 nF"); + + expect(qty.eq(Qty("100 F").div(1e9))).toBe(true); + expect(qty.baseScalar).toEqual(1e-7); + }); + }); + }); +}); diff --git a/js-quantities/tsconfig.json b/js-quantities/tsconfig.json index efde674e39..1680f0d478 100644 --- a/js-quantities/tsconfig.json +++ b/js-quantities/tsconfig.json @@ -3,7 +3,7 @@ "module": "commonjs", "target": "es6", "noImplicitAny": true, - "strictNullChecks": false, + "strictNullChecks": true, "baseUrl": "../", "typeRoots": [ "../" @@ -16,4 +16,4 @@ "index.d.ts", "js-quantities-tests.ts" ] -} \ No newline at end of file +} diff --git a/js-quantities/tslint.json b/js-quantities/tslint.json new file mode 100644 index 0000000000..f9e30021f4 --- /dev/null +++ b/js-quantities/tslint.json @@ -0,0 +1,3 @@ +{ + "extends": "../tslint.json" +} From d9e5ce085f416c931479bade14fda2623aa2798a Mon Sep 17 00:00:00 2001 From: Sam Bleckley Date: Sun, 1 Jan 2017 16:16:46 -0500 Subject: [PATCH 12/17] d3-selection: Mark before param of insert() as optional (#13090) Selection.insert functions perfectly well without a `before` selector -- it does so in many d3 official examples. This corrects the type signature to mark it as optional. --- d3-selection/d3-selection-tests.ts | 77 ++++++++++++------------------ d3-selection/index.d.ts | 4 +- 2 files changed, 32 insertions(+), 49 deletions(-) diff --git a/d3-selection/d3-selection-tests.ts b/d3-selection/d3-selection-tests.ts index b1f776c442..042fba622a 100644 --- a/d3-selection/d3-selection-tests.ts +++ b/d3-selection/d3-selection-tests.ts @@ -846,60 +846,43 @@ newDiv2 = body.append(function (d, i, g) { // without insert<...> typing returned selection has group element of type BaseType let newParagraph: d3Selection.Selection; newParagraph = body.insert('p', 'p.second-paragraph'); +newParagraph = body.insert('p'); + +// Two arguments; the first can be string, selection , or a + +const typeValueFunction = function ( + this: HTMLBodyElement, + d: BodyDatum, + i: number, + g: HTMLBodyElement[] | d3Selection.ArrayLike +) { + return this.ownerDocument.createElement('p'); // this-type HTMLParagraphElement +} + +const beforeValueFunction = function ( + this: HTMLBodyElement, + d: BodyDatum, + i: number, + g: HTMLBodyElement[] | d3Selection.ArrayLike +) { + return this.children[0]; +} let newParagraph2: d3Selection.Selection; + +// 2 args, with 3 possibilities each, makes 9 possible combinations: newParagraph2 = body.insert('p', 'p.second-paragraph'); +newParagraph2 = body.insert('p', beforeValueFunction); +newParagraph2 = body.insert('p'); newParagraph2 = body.insert(d3Selection.creator('p'), 'p.second-paragraph'); -newParagraph2 = body.insert(function (d, i, g) { - let that: HTMLBodyElement = this; - // let that2: SVGElement = this; // fails, type mismatch - let datum: BodyDatum = d; - let index: number = i; - let group: HTMLBodyElement[] | d3Selection.ArrayLike = g; - console.log('Body element foo property: ', d.foo); // data of type BodyDatum - return this.ownerDocument.createElement('p'); // this-type HTMLParagraphElement -}, 'p.second-paragraph'); +newParagraph2 = body.insert(d3Selection.creator('p'), beforeValueFunction); +newParagraph2 = body.insert(d3Selection.creator('p')); -// newParagraph2 = body.insert(function(d) { -// return this.ownerDocument.createElement('a'); // fails, HTMLParagraphElement expected by type parameter, HTMLAnchorElement returned -// }, 'p.second-paragraph'); +newParagraph2 = body.insert(typeValueFunction, 'p.second-paragraph'); +newParagraph2 = body.insert(typeValueFunction, beforeValueFunction); +newParagraph2 = body.insert(typeValueFunction); -// newParagraph2 = body.insert(function(d) { -// return this.ownerDocument.createElement('a'); // fails, HTMLParagraphElement expected by type inference, HTMLAnchorElement returned -// }, 'p.second-paragraph'); - -newParagraph2 = body.insert(d3Selection.creator('p'), function (d, i, g) { - let that: HTMLBodyElement = this; - // let that2: SVGElement = this; // fails, type mismatch - let datum: BodyDatum = d; - let index: number = i; - let group: HTMLBodyElement[] | d3Selection.ArrayLike = g; - console.log('Body element foo property: ', d.foo); // data of type BodyDatum - return this.children[0]; // this type HTMLBodyElement -}); - -newParagraph2 = body.insert( - // type - function (d, i, g) { - let that: HTMLBodyElement = this; - // let that2: SVGElement = this; // fails, type mismatch - let datum: BodyDatum = d; - let index: number = i; - let group: HTMLBodyElement[] | d3Selection.ArrayLike = g; - console.log('Body element foo property: ', d.foo); // data of type BodyDatum - return this.ownerDocument.createElement('p'); // this-type HTMLParagraphElement - }, - // before - function (d, i, g) { - let that: HTMLBodyElement = this; - // let that2: SVGElement = this; // fails, type mismatch - let datum: BodyDatum = d; - let index: number = i; - let group: HTMLBodyElement[] | d3Selection.ArrayLike = g; - console.log('Body element foo property: ', d.foo); // data of type BodyDatum - return this.children[0]; // this type HTMLBodyElement - }); // sort(...) ----------------------------------------------------------------------------- diff --git a/d3-selection/index.d.ts b/d3-selection/index.d.ts index 0380e10c9d..029a986024 100644 --- a/d3-selection/index.d.ts +++ b/d3-selection/index.d.ts @@ -509,7 +509,7 @@ interface Selection(type: string, before: string): Selection; + insert(type: string, before?: string): Selection; /** * Inserts a new element of the type provided by the element creator function before the element matching the specified "before" * selector string for each selected element. @@ -524,7 +524,7 @@ interface Selection(type: ValueFn, before: string): Selection; + insert(type: ValueFn, before?: string): Selection; /** * Inserts a new element of the specified type (tag name) before the element returned by the "before" child selector function * for each selected element. From 88184efb06f4b176a4aa36c07415e71523acc7c2 Mon Sep 17 00:00:00 2001 From: Fedor Nezhivoi Date: Mon, 2 Jan 2017 01:21:49 +0200 Subject: [PATCH 13/17] [react-intl] bugfix for #12716 (#12906) * fix for issue introduced in https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12716 * injectIntl is now usable as class decorator * fixed test * use inferface instead of type * format document --- react-intl/index.d.ts | 8 +++-- react-intl/react-intl-tests.tsx | 53 +++++++++++++++++---------------- 2 files changed, 33 insertions(+), 28 deletions(-) diff --git a/react-intl/index.d.ts b/react-intl/index.d.ts index 1d6412defa..d4d3d5cfd0 100644 --- a/react-intl/index.d.ts +++ b/react-intl/index.d.ts @@ -1,6 +1,6 @@ // Type definitions for react-intl 2.1.5 // Project: http://formatjs.io/react/ -// Definitions by: Bruno Grieder , Christian Droulers , Fedor Nezhivoi +// Definitions by: Bruno Grieder , Christian Droulers , Fedor Nezhivoi , Till Wolff // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped /// @@ -12,7 +12,7 @@ declare namespace ReactIntl { pluralRuleFunction?: (n: number, ord: boolean) => string; } - function injectIntl(component: React.ComponentClass | React.StatelessComponent): React.ComponentClass; + function injectIntl | React.StatelessComponent>(component: T): T; function addLocaleData(data: Locale[] | Locale): void; @@ -44,6 +44,10 @@ declare namespace ReactIntl { formatHTMLMessage: (messageDescriptor: FormattedMessage.MessageDescriptor, values?: Object) => string; } + interface InjectedIntlProps { + intl?: InjectedIntl + } + namespace IntlComponent { interface DateTimeFormatProps { /* diff --git a/react-intl/react-intl-tests.tsx b/react-intl/react-intl-tests.tsx index cd484c17b4..160a37bc0f 100644 --- a/react-intl/react-intl-tests.tsx +++ b/react-intl/react-intl-tests.tsx @@ -9,20 +9,20 @@ import * as React from "react" import * as reactMixin from "react-mixin" import { -IntlProvider, -InjectedIntl, -addLocaleData, -hasLocaleData, -injectIntl, -intlShape, -defineMessages, -FormattedRelative, -FormattedMessage, -FormattedHTMLMessage, -FormattedNumber, -FormattedPlural, -FormattedDate, -FormattedTime + IntlProvider, + InjectedIntl, + addLocaleData, + hasLocaleData, + injectIntl, + intlShape, + defineMessages, + FormattedRelative, + FormattedMessage, + FormattedHTMLMessage, + FormattedNumber, + FormattedPlural, + FormattedDate, + FormattedTime } from "react-intl" import reactIntlEn = require("react-intl/locale-data/en"); @@ -31,7 +31,8 @@ addLocaleData(reactIntlEn); console.log(hasLocaleData("en")); interface SomeComponentProps { - intl: InjectedIntl + className: string, + intl?: InjectedIntl } class SomeComponent extends React.Component { @@ -47,14 +48,14 @@ class SomeComponent extends React.Component { const formattedPlural = intl.formatPlural(1, { one: "hai!" }); const formattedMessage = intl.formatMessage({ id: "hello", defaultMessage: "Hello {name}!" }, { name: "Roger" }); const formattedHTMLMessage = intl.formatHTMLMessage({ id: "hello", defaultMessage: "Hello {name}!" }, { name: "Roger" }); - return
+ return
+ initialNow={new Date()} /> { many="haiku" /> { timeZoneName="short" /> { {(formattedNum: string) => ( {formattedNum} - ) } - -
+ )} + +
} } @@ -159,9 +160,9 @@ class TestApp extends React.Component<{}, {}> { "hello": "Hello, {name}!" }; return ( - - - + + + ); } } From 36a5697b553e2b9ea3bcd4c746143397da2f3c31 Mon Sep 17 00:00:00 2001 From: Masahiro Wakame Date: Wed, 4 Jan 2017 07:37:51 +0900 Subject: [PATCH 14/17] fix chai-json-schema styling (#13537) --- chai-json-schema/index.d.ts | 24 ++++++++++++------------ chai-json-schema/tslint.json | 6 +----- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/chai-json-schema/index.d.ts b/chai-json-schema/index.d.ts index e3e4934c76..e66e2c96af 100644 --- a/chai-json-schema/index.d.ts +++ b/chai-json-schema/index.d.ts @@ -6,19 +6,19 @@ // // -declare namespace Chai { - export interface Assert { - jsonSchema(value: any, schema: any, msg?: string): void; - notJsonSchema(value: any, schema: any, msg?: string): void; - } +declare global { + namespace Chai { + export interface Assert { + jsonSchema(value: any, schema: any, msg?: string): void; + notJsonSchema(value: any, schema: any, msg?: string): void; + } - export interface LanguageChains { - jsonSchema(schema: any, msg?: string): void; + export interface LanguageChains { + jsonSchema(schema: any, msg?: string): void; + } } } -declare module "chai-json-schema" { - function chaiJsonSchema(chai: any, utils: any): void; - namespace chaiJsonSchema {} - export = chaiJsonSchema; -} +declare function chaiJsonSchema(chai: any, utils: any): void; +declare namespace chaiJsonSchema { } +export = chaiJsonSchema; diff --git a/chai-json-schema/tslint.json b/chai-json-schema/tslint.json index 83a03ce890..377cc837d4 100644 --- a/chai-json-schema/tslint.json +++ b/chai-json-schema/tslint.json @@ -1,5 +1 @@ -{ "extends": "../tslint.json", - "rules": { - "no-single-declare-module": false - } -} +{ "extends": "../tslint.json" } From f914c29ba3a58bc78dd3c235d603c189cc9396e7 Mon Sep 17 00:00:00 2001 From: Grant Hutchins Date: Tue, 3 Jan 2017 16:40:53 -0600 Subject: [PATCH 15/17] googlemaps: Allow Marker.setAnimation(null) and Marker.setMap(null) (#13240) * googlemaps: Allow Marker.setAnimation(null) * Also, turn on strictNullChecks * Allow new google.maps.Map(null) since it's technically possible with Google's example code from the docs Signed-off-by: Iqbal Yusuf * googlemaps: Allow Marker.setMap(null) * Also, add more test code from the Google Maps API documentation Signed-off-by: Grant Hutchins --- googlemaps/google.maps-tests.ts | 95 ++++++++++++++++++++++++++++++--- googlemaps/index.d.ts | 10 ++-- googlemaps/tsconfig.json | 4 +- 3 files changed, 96 insertions(+), 13 deletions(-) diff --git a/googlemaps/google.maps-tests.ts b/googlemaps/google.maps-tests.ts index 9829a23a1a..87fcc424bf 100644 --- a/googlemaps/google.maps-tests.ts +++ b/googlemaps/google.maps-tests.ts @@ -141,19 +141,102 @@ var mapTypeStyle: google.maps.MapTypeStyle ={ stylers: [], }; -// https://developers.google.com/maps/documentation/javascript/adding-a-google-map -function initMap() { - var uluru = {lat: -25.363, lng: 131.044}; +// https://developers.google.com/maps/documentation/javascript/markers +function initMap1() { + var myLatLng = {lat: -25.363, lng: 131.044}; + var map = new google.maps.Map(document.getElementById('map'), { zoom: 4, - center: uluru + center: myLatLng }); + var marker = new google.maps.Marker({ - position: uluru, + position: myLatLng, + map: map, + title: 'Hello World!' + }); +} + +var myLatlng = new google.maps.LatLng(-25.363882,131.044922); +var mapOptions = { + zoom: 4, + center: myLatlng +} +var map = new google.maps.Map(document.getElementById("map"), mapOptions); + +var marker = new google.maps.Marker({ + position: myLatlng, + title:"Hello World!" +}); + +// To add the marker to the map, call setMap(); +marker.setMap(map); + +marker.setMap(null); + +// The following example creates a marker in Stockholm, Sweden using a DROP +// animation. Clicking on the marker will toggle the animation between a BOUNCE +// animation and no animation. + +var marker: google.maps.Marker; + +function initMap2() { + var map = new google.maps.Map(document.getElementById('map'), { + zoom: 13, + center: {lat: 59.325, lng: 18.070} + }); + + marker = new google.maps.Marker({ + map: map, + draggable: true, + animation: google.maps.Animation.DROP, + position: {lat: 59.327, lng: 18.067} + }); + marker.addListener('click', toggleBounce); +} + +function toggleBounce() { + if (marker.getAnimation() !== null) { + marker.setAnimation(null); + } else { + marker.setAnimation(google.maps.Animation.BOUNCE); + } +} + +// In the following example, markers appear when the user clicks on the map. +// Each marker is labeled with a single alphabetical character. +var labels = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; +var labelIndex = 0; + +function initialize() { + var bangalore = { lat: 12.97, lng: 77.59 }; + var map = new google.maps.Map(document.getElementById('map'), { + zoom: 12, + center: bangalore + }); + + // This event listener calls addMarker() when the map is clicked. + google.maps.event.addListener(map, 'click', function(event: any) { + addMarker(event.latLng, map); + }); + + // Add a marker at the center of the map. + addMarker(bangalore, map); +} + +// Adds a marker to the map. +function addMarker(location: google.maps.LatLngLiteral, map: google.maps.Map) { + // Add the marker at the clicked location, and add the next-available label + // from the array of alphabetical characters. + var marker = new google.maps.Marker({ + position: location, + label: labels[labelIndex++ % labels.length], map: map }); } +google.maps.event.addDomListener(window, 'load', initialize); + /***** OverlayView *****/ var div = document.createElement('div'); var overlay = new google.maps.OverlayView(); @@ -165,4 +248,4 @@ panes.markerLayer.appendChild(div); panes.overlayImage.appendChild(div); panes.overlayLayer.appendChild(div); panes.overlayMouseTarget.appendChild(div); -panes.overlayShadow.appendChild(div); +panes.overlayShadow.appendChild(div); \ No newline at end of file diff --git a/googlemaps/index.d.ts b/googlemaps/index.d.ts index 28feff6d03..bccfb51299 100644 --- a/googlemaps/index.d.ts +++ b/googlemaps/index.d.ts @@ -1,6 +1,6 @@ // Type definitions for Google Maps JavaScript API 3.25 // Project: https://developers.google.com/maps/ -// Definitions by: Folia A/S , Chris Wrench , Kiarash Ghiaseddin +// Definitions by: Folia A/S , Chris Wrench , Kiarash Ghiaseddin , Grant Hutchins // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped /* @@ -30,7 +30,7 @@ THE SOFTWARE. declare namespace google.maps { /***** Map *****/ export class Map extends MVCObject { - constructor(mapDiv: Element, opts?: MapOptions); + constructor(mapDiv: Element|null, opts?: MapOptions); fitBounds(bounds: LatLngBounds|LatLngBoundsLiteral): void; getBounds(): LatLngBounds; getCenter(): LatLng; @@ -349,14 +349,14 @@ declare namespace google.maps { getTitle(): string; getVisible(): boolean; getZIndex(): number; - setAnimation(animation: Animation): void; + setAnimation(animation: Animation|null): void; setAttribution(attribution: Attribution): void; setClickable(flag: boolean): void; setCursor(cursor: string): void; setDraggable(flag: boolean): void; setIcon(icon: string|Icon|Symbol): void; setLabel(label: string|MarkerLabel): void; - setMap(map: Map|StreetViewPanorama): void; + setMap(map: Map|StreetViewPanorama|null): void; setOpacity(opacity: number): void; setOptions(options: MarkerOptions): void; setPlace(place: Place): void; @@ -1801,7 +1801,7 @@ declare namespace google.maps { /** Returns a string of the form "lat,lng". We round the lat/lng values to 6 decimal places by default. */ toUrlValue(precision?: number): string; /** Converts to JSON representation. This function is intended to be used via JSON.stringify. */ - toJSON(): LatLngLiteral; + toJSON(): LatLngLiteral; } export type LatLngLiteral = { lat: number; lng: number } diff --git a/googlemaps/tsconfig.json b/googlemaps/tsconfig.json index deafdc4eec..dff0eb7ca3 100644 --- a/googlemaps/tsconfig.json +++ b/googlemaps/tsconfig.json @@ -3,7 +3,7 @@ "module": "commonjs", "target": "es6", "noImplicitAny": true, - "strictNullChecks": false, + "strictNullChecks": true, "baseUrl": "../", "typeRoots": [ "../" @@ -16,4 +16,4 @@ "index.d.ts", "google.maps-tests.ts" ] -} \ No newline at end of file +} From 25ecee95138cb451fd66f25d730dac76e4e0d61a Mon Sep 17 00:00:00 2001 From: Aluan Haddad Date: Wed, 4 Jan 2017 12:20:13 -0500 Subject: [PATCH 16/17] Added the brand property to the StripeCardData and fix style issues, lint (#13084) * Add the "brand" field to StipeCardData Added the StipeCardDataBrand type. Added the `brand` property to the `StripeCardData` declaration with the type `'Visa' | 'American Express' | 'MasterCard' | 'Discover JCB' | 'Diners Club' | 'Unknown'` Reference: https://stripe.com/docs/api#card_object * Run linter, fix issues. set --strictNullChecks. Unsure about ambient declaration: Removed as it seemed to be in error: 1. case was not correct 2. the export was the type of the global which is unconditionally defined. 3. this module does not seem a suitable candidate for a UMD declaration. * Use header version of 0.0; explain Stripe versioning in comments * Restore global * Added tests --- stripe/index.d.ts | 45 +++++++++++++++++++----------------------- stripe/stripe-tests.ts | 25 +++++++++++++++++++++++ stripe/tsconfig.json | 7 ++++--- stripe/tslint.json | 3 +++ 4 files changed, 52 insertions(+), 28 deletions(-) create mode 100644 stripe/stripe-tests.ts create mode 100644 stripe/tslint.json diff --git a/stripe/index.d.ts b/stripe/index.d.ts index 2f8c895298..fdfa1db96e 100644 --- a/stripe/index.d.ts +++ b/stripe/index.d.ts @@ -1,8 +1,10 @@ -// Type definitions for stripe +// Type definitions for stripe 0.0 // Project: https://stripe.com/ // Definitions by: Andy Hawkins , Eric J. Smith , Amrit Kahlon , Adam Cmiel // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +declare const Stripe: StripeStatic; + interface StripeStatic { applePay: StripeApplePay; setPublishableKey(key: string): void; @@ -49,6 +51,8 @@ interface StripeError { param?: string; } +type StripeCardDataBrand = 'Visa' | 'American Express' | 'MasterCard' | 'Discover JCB' | 'Diners Club' | 'Unknown'; + interface StripeCardData { object: string; last4: string; @@ -62,18 +66,17 @@ interface StripeCardData { address_state?: string; address_zip?: string; address_country?: string; + brand?: StripeCardDataBrand; createToken(data: StripeTokenData, responseHandler: (status: number, response: StripeTokenResponse) => void): void; } -interface StripeBankAccount -{ - createToken(params: StripeBankTokenParams, stripeResponseHandler: (status:number, response: StripeBankTokenResponse) => void): void; +interface StripeBankAccount { + createToken(params: StripeBankTokenParams, stripeResponseHandler: (status: number, response: StripeBankTokenResponse) => void): void; validateRoutingNumber(routingNumber: number | string, countryCode: string): boolean; validateAccountNumber(accountNumber: number | string, countryCode: string): boolean; } -interface StripeBankTokenParams -{ +interface StripeBankTokenParams { country: string; currency: string; account_number: number | string; @@ -82,8 +85,7 @@ interface StripeBankTokenParams account_holder_type: string; } -interface StripeBankTokenResponse -{ +interface StripeBankTokenResponse { id: string; bank_account: { country: string; @@ -100,13 +102,7 @@ interface StripeBankTokenResponse error?: StripeError; } -declare var Stripe: StripeStatic; -declare module "Stripe" { - export = StripeStatic; -} - -interface StripeApplePay -{ +interface StripeApplePay { checkAvailability(resopnseHandler: (result: boolean) => void): void; buildSession(data: StripeApplePayPaymentRequest, onSuccessHandler: (result: StripeApplePaySessionResult, completion: ((value: any) => void)) => void, @@ -117,8 +113,7 @@ type StripeApplePayBillingContactField = 'postalAddress' | 'name'; type StripeApplePayShippingContactField = StripeApplePayBillingContactField | 'phone' | 'email'; type StripeApplePayShipping = 'shipping' | 'delivery' | 'storePickup' | 'servicePickup'; -interface StripeApplePayPaymentRequest -{ +interface StripeApplePayPaymentRequest { billingContact: StripeApplePayPaymentContact; countryCode: string; currencyCode: string; @@ -132,30 +127,26 @@ interface StripeApplePayPaymentRequest } // https://developer.apple.com/reference/applepayjs/1916082-applepay_js_data_types -interface StripeApplePayLineItem -{ +interface StripeApplePayLineItem { type: 'pending' | 'final'; label: string; amount: number; } -interface StripeApplePaySessionResult -{ +interface StripeApplePaySessionResult { token: StripeTokenResponse; shippingContact?: StripeApplePayPaymentContact; shippingMethod?: StripeApplePayShippingMethod; } -interface StripeApplePayShippingMethod -{ +interface StripeApplePayShippingMethod { label: string; detail: string; amount: number; identifier: string; } -interface StripeApplePayPaymentContact -{ +interface StripeApplePayPaymentContact { emailAddress: string; phoneNumber: string; givenName: string; @@ -166,3 +157,7 @@ interface StripeApplePayPaymentContact postalCode: string; countryCode: string; } + +// The Stripe client side APIs are not made available to package managers for direct installation. +// As explained compliance reasons. Source: https://github.com/stripe/stripe-node/blob/master/README.md#these-are-serverside-bindings-only +// A release date versioning schema is used to version these APIs. diff --git a/stripe/stripe-tests.ts b/stripe/stripe-tests.ts new file mode 100644 index 0000000000..44aa09d216 --- /dev/null +++ b/stripe/stripe-tests.ts @@ -0,0 +1,25 @@ +function success(card: StripeCardData) { + console.log(card.brand && card.brand.toString()); +} + +const cardNumber = '4242424242424242'; + +const isValid = Stripe.validateCardNumber(cardNumber); +if (isValid) { + const tokenData: StripeTokenData = { + number: cardNumber, + exp_month: 1, + exp_year: 2100, + cvc: '111' + }; + Stripe.card.createToken(tokenData, (status, response) => { + if (response.error) { + console.error(response.error.message); + if (response.error.param) { + console.error(response.error.param); + } + } else { + success(response.card); + } + }); +} diff --git a/stripe/tsconfig.json b/stripe/tsconfig.json index 79b9eb6b27..265882db3c 100644 --- a/stripe/tsconfig.json +++ b/stripe/tsconfig.json @@ -3,7 +3,7 @@ "module": "commonjs", "target": "es6", "noImplicitAny": true, - "strictNullChecks": false, + "strictNullChecks": true, "baseUrl": "../", "typeRoots": [ "../" @@ -13,6 +13,7 @@ "forceConsistentCasingInFileNames": true }, "files": [ - "index.d.ts" + "index.d.ts", + "stripe-tests.ts" ] -} \ No newline at end of file +} diff --git a/stripe/tslint.json b/stripe/tslint.json new file mode 100644 index 0000000000..f9e30021f4 --- /dev/null +++ b/stripe/tslint.json @@ -0,0 +1,3 @@ +{ + "extends": "../tslint.json" +} From dc028e0a39e2d57f2141489f7a9ee569fcb1f38b Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Thu, 5 Jan 2017 12:43:24 -0800 Subject: [PATCH 17/17] Revert "Merge more from `types-2.0` to `master (#13770)" This reverts commit 5bce8fab2ee167fde0b249672bc38ef1c37abec7. --- chai-json-schema/index.d.ts | 24 +- chai-json-schema/tslint.json | 6 +- d3-selection/d3-selection-tests.ts | 77 +- d3-selection/index.d.ts | 2 +- googlemaps/google.maps-tests.ts | 95 +- googlemaps/index.d.ts | 8 +- googlemaps/tsconfig.json | 4 +- js-quantities/index.d.ts | 132 +-- js-quantities/js-quantities-tests.ts | 1503 +------------------------- js-quantities/tsconfig.json | 4 +- js-quantities/tslint.json | 3 - memoizee/index.d.ts | 29 - memoizee/memoizee-tests.ts | 61 -- memoizee/tsconfig.json | 20 - memoizee/tslint.json | 1 - react-intl/index.d.ts | 8 +- react-intl/react-intl-tests.tsx | 53 +- stripe/index.d.ts | 45 +- stripe/stripe-tests.ts | 25 - stripe/tsconfig.json | 7 +- stripe/tslint.json | 3 - 21 files changed, 208 insertions(+), 1902 deletions(-) delete mode 100644 js-quantities/tslint.json delete mode 100644 memoizee/index.d.ts delete mode 100644 memoizee/memoizee-tests.ts delete mode 100644 memoizee/tsconfig.json delete mode 100644 memoizee/tslint.json delete mode 100644 stripe/stripe-tests.ts delete mode 100644 stripe/tslint.json diff --git a/chai-json-schema/index.d.ts b/chai-json-schema/index.d.ts index e66e2c96af..e3e4934c76 100644 --- a/chai-json-schema/index.d.ts +++ b/chai-json-schema/index.d.ts @@ -6,19 +6,19 @@ // // -declare global { - namespace Chai { - export interface Assert { - jsonSchema(value: any, schema: any, msg?: string): void; - notJsonSchema(value: any, schema: any, msg?: string): void; - } +declare namespace Chai { + export interface Assert { + jsonSchema(value: any, schema: any, msg?: string): void; + notJsonSchema(value: any, schema: any, msg?: string): void; + } - export interface LanguageChains { - jsonSchema(schema: any, msg?: string): void; - } + export interface LanguageChains { + jsonSchema(schema: any, msg?: string): void; } } -declare function chaiJsonSchema(chai: any, utils: any): void; -declare namespace chaiJsonSchema { } -export = chaiJsonSchema; +declare module "chai-json-schema" { + function chaiJsonSchema(chai: any, utils: any): void; + namespace chaiJsonSchema {} + export = chaiJsonSchema; +} diff --git a/chai-json-schema/tslint.json b/chai-json-schema/tslint.json index 377cc837d4..83a03ce890 100644 --- a/chai-json-schema/tslint.json +++ b/chai-json-schema/tslint.json @@ -1 +1,5 @@ -{ "extends": "../tslint.json" } +{ "extends": "../tslint.json", + "rules": { + "no-single-declare-module": false + } +} diff --git a/d3-selection/d3-selection-tests.ts b/d3-selection/d3-selection-tests.ts index 042fba622a..b1f776c442 100644 --- a/d3-selection/d3-selection-tests.ts +++ b/d3-selection/d3-selection-tests.ts @@ -846,43 +846,60 @@ newDiv2 = body.append(function (d, i, g) { // without insert<...> typing returned selection has group element of type BaseType let newParagraph: d3Selection.Selection; newParagraph = body.insert('p', 'p.second-paragraph'); -newParagraph = body.insert('p'); - -// Two arguments; the first can be string, selection , or a - -const typeValueFunction = function ( - this: HTMLBodyElement, - d: BodyDatum, - i: number, - g: HTMLBodyElement[] | d3Selection.ArrayLike -) { - return this.ownerDocument.createElement('p'); // this-type HTMLParagraphElement -} - -const beforeValueFunction = function ( - this: HTMLBodyElement, - d: BodyDatum, - i: number, - g: HTMLBodyElement[] | d3Selection.ArrayLike -) { - return this.children[0]; -} let newParagraph2: d3Selection.Selection; - -// 2 args, with 3 possibilities each, makes 9 possible combinations: newParagraph2 = body.insert('p', 'p.second-paragraph'); -newParagraph2 = body.insert('p', beforeValueFunction); -newParagraph2 = body.insert('p'); newParagraph2 = body.insert(d3Selection.creator('p'), 'p.second-paragraph'); -newParagraph2 = body.insert(d3Selection.creator('p'), beforeValueFunction); -newParagraph2 = body.insert(d3Selection.creator('p')); +newParagraph2 = body.insert(function (d, i, g) { + let that: HTMLBodyElement = this; + // let that2: SVGElement = this; // fails, type mismatch + let datum: BodyDatum = d; + let index: number = i; + let group: HTMLBodyElement[] | d3Selection.ArrayLike = g; + console.log('Body element foo property: ', d.foo); // data of type BodyDatum + return this.ownerDocument.createElement('p'); // this-type HTMLParagraphElement +}, 'p.second-paragraph'); -newParagraph2 = body.insert(typeValueFunction, 'p.second-paragraph'); -newParagraph2 = body.insert(typeValueFunction, beforeValueFunction); -newParagraph2 = body.insert(typeValueFunction); +// newParagraph2 = body.insert(function(d) { +// return this.ownerDocument.createElement('a'); // fails, HTMLParagraphElement expected by type parameter, HTMLAnchorElement returned +// }, 'p.second-paragraph'); +// newParagraph2 = body.insert(function(d) { +// return this.ownerDocument.createElement('a'); // fails, HTMLParagraphElement expected by type inference, HTMLAnchorElement returned +// }, 'p.second-paragraph'); + +newParagraph2 = body.insert(d3Selection.creator('p'), function (d, i, g) { + let that: HTMLBodyElement = this; + // let that2: SVGElement = this; // fails, type mismatch + let datum: BodyDatum = d; + let index: number = i; + let group: HTMLBodyElement[] | d3Selection.ArrayLike = g; + console.log('Body element foo property: ', d.foo); // data of type BodyDatum + return this.children[0]; // this type HTMLBodyElement +}); + +newParagraph2 = body.insert( + // type + function (d, i, g) { + let that: HTMLBodyElement = this; + // let that2: SVGElement = this; // fails, type mismatch + let datum: BodyDatum = d; + let index: number = i; + let group: HTMLBodyElement[] | d3Selection.ArrayLike = g; + console.log('Body element foo property: ', d.foo); // data of type BodyDatum + return this.ownerDocument.createElement('p'); // this-type HTMLParagraphElement + }, + // before + function (d, i, g) { + let that: HTMLBodyElement = this; + // let that2: SVGElement = this; // fails, type mismatch + let datum: BodyDatum = d; + let index: number = i; + let group: HTMLBodyElement[] | d3Selection.ArrayLike = g; + console.log('Body element foo property: ', d.foo); // data of type BodyDatum + return this.children[0]; // this type HTMLBodyElement + }); // sort(...) ----------------------------------------------------------------------------- diff --git a/d3-selection/index.d.ts b/d3-selection/index.d.ts index 1d0ab9472c..65703f66ff 100644 --- a/d3-selection/index.d.ts +++ b/d3-selection/index.d.ts @@ -519,7 +519,7 @@ interface Selection( type: string | ValueFn, - before?: string | ValueFn + before: string | ValueFn ): Selection; /** diff --git a/googlemaps/google.maps-tests.ts b/googlemaps/google.maps-tests.ts index 0be531a89f..fd4e10f6e6 100644 --- a/googlemaps/google.maps-tests.ts +++ b/googlemaps/google.maps-tests.ts @@ -141,102 +141,19 @@ var mapTypeStyle: google.maps.MapTypeStyle ={ stylers: [], }; -// https://developers.google.com/maps/documentation/javascript/markers -function initMap1() { - var myLatLng = {lat: -25.363, lng: 131.044}; - +// https://developers.google.com/maps/documentation/javascript/adding-a-google-map +function initMap() { + var uluru = {lat: -25.363, lng: 131.044}; var map = new google.maps.Map(document.getElementById('map'), { zoom: 4, - center: myLatLng + center: uluru }); - var marker = new google.maps.Marker({ - position: myLatLng, - map: map, - title: 'Hello World!' - }); -} - -var myLatlng = new google.maps.LatLng(-25.363882,131.044922); -var mapOptions = { - zoom: 4, - center: myLatlng -} -var map = new google.maps.Map(document.getElementById("map"), mapOptions); - -var marker = new google.maps.Marker({ - position: myLatlng, - title:"Hello World!" -}); - -// To add the marker to the map, call setMap(); -marker.setMap(map); - -marker.setMap(null); - -// The following example creates a marker in Stockholm, Sweden using a DROP -// animation. Clicking on the marker will toggle the animation between a BOUNCE -// animation and no animation. - -var marker: google.maps.Marker; - -function initMap2() { - var map = new google.maps.Map(document.getElementById('map'), { - zoom: 13, - center: {lat: 59.325, lng: 18.070} - }); - - marker = new google.maps.Marker({ - map: map, - draggable: true, - animation: google.maps.Animation.DROP, - position: {lat: 59.327, lng: 18.067} - }); - marker.addListener('click', toggleBounce); -} - -function toggleBounce() { - if (marker.getAnimation() !== null) { - marker.setAnimation(null); - } else { - marker.setAnimation(google.maps.Animation.BOUNCE); - } -} - -// In the following example, markers appear when the user clicks on the map. -// Each marker is labeled with a single alphabetical character. -var labels = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; -var labelIndex = 0; - -function initialize() { - var bangalore = { lat: 12.97, lng: 77.59 }; - var map = new google.maps.Map(document.getElementById('map'), { - zoom: 12, - center: bangalore - }); - - // This event listener calls addMarker() when the map is clicked. - google.maps.event.addListener(map, 'click', function(event: any) { - addMarker(event.latLng, map); - }); - - // Add a marker at the center of the map. - addMarker(bangalore, map); -} - -// Adds a marker to the map. -function addMarker(location: google.maps.LatLngLiteral, map: google.maps.Map) { - // Add the marker at the clicked location, and add the next-available label - // from the array of alphabetical characters. - var marker = new google.maps.Marker({ - position: location, - label: labels[labelIndex++ % labels.length], + position: uluru, map: map }); } -google.maps.event.addDomListener(window, 'load', initialize); - /***** OverlayView *****/ // https://developers.google.com/maps/documentation/javascript/customoverlays var div = document.createElement('div'); @@ -266,4 +183,4 @@ var rectangle = new google.maps.Rectangle({ east: -116.234, west: -116.251 } -}); +}); \ No newline at end of file diff --git a/googlemaps/index.d.ts b/googlemaps/index.d.ts index fefca3ea89..f19480f034 100644 --- a/googlemaps/index.d.ts +++ b/googlemaps/index.d.ts @@ -1,6 +1,6 @@ // Type definitions for Google Maps JavaScript API 3.25 // Project: https://developers.google.com/maps/ -// Definitions by: Folia A/S , Chris Wrench , Kiarash Ghiaseddin , Grant Hutchins +// Definitions by: Folia A/S , Chris Wrench , Kiarash Ghiaseddin // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped /* @@ -30,7 +30,7 @@ THE SOFTWARE. declare namespace google.maps { /***** Map *****/ export class Map extends MVCObject { - constructor(mapDiv: Element|null, opts?: MapOptions); + constructor(mapDiv: Element, opts?: MapOptions); fitBounds(bounds: LatLngBounds|LatLngBoundsLiteral): void; getBounds(): LatLngBounds; getCenter(): LatLng; @@ -536,14 +536,14 @@ declare namespace google.maps { getTitle(): string; getVisible(): boolean; getZIndex(): number; - setAnimation(animation: Animation|null): void; + setAnimation(animation: Animation): void; setAttribution(attribution: Attribution): void; setClickable(flag: boolean): void; setCursor(cursor: string): void; setDraggable(flag: boolean): void; setIcon(icon: string|Icon|Symbol): void; setLabel(label: string|MarkerLabel): void; - setMap(map: Map|StreetViewPanorama|null): void; + setMap(map: Map|StreetViewPanorama): void; setOpacity(opacity: number): void; setOptions(options: MarkerOptions): void; setPlace(place: Place): void; diff --git a/googlemaps/tsconfig.json b/googlemaps/tsconfig.json index 0382e30210..dc12fbf795 100644 --- a/googlemaps/tsconfig.json +++ b/googlemaps/tsconfig.json @@ -4,7 +4,7 @@ "target": "es6", "noImplicitAny": true, "noImplicitThis": true, - "strictNullChecks": true, + "strictNullChecks": false, "baseUrl": "../", "typeRoots": [ "../" @@ -17,4 +17,4 @@ "index.d.ts", "google.maps-tests.ts" ] -} +} \ No newline at end of file diff --git a/js-quantities/index.d.ts b/js-quantities/index.d.ts index 5d4a8df304..a2e3c2d96c 100644 --- a/js-quantities/index.d.ts +++ b/js-quantities/index.d.ts @@ -1,73 +1,79 @@ -// Type definitions for JS-quantities 1.6 +// Type definitions for JS-quantities // Project: http://gentooboontoo.github.io/js-quantities/ -// Definitions by: William Rummler +// Definitions by: William Comartin // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped -declare const Qty: Qty.Type; +declare var Qty: QtyModule.QtyStatic; + +declare namespace QtyModule { + interface QtyStatic { + (value: string): Qty; + (value: number): Qty; + (value: number, unit: string): Qty; + (value: Qty): Qty; + } + + interface Qty { + version: string; + + scalar: number; + baseScalar: number; + + parse(value: string): Qty; + + swiftConverter(srcUnits:string, dstUnits:string): (value:number) => number; + + getkinds(): string[]; + + getUnits(kind:string): string[]; + + getAliases(unitName:string): string[]; + + formatter(scalar:number, units:string):string; -declare interface Qty { - readonly numerator: string[]; - readonly denominator: string[]; - readonly scalar: number; - readonly baseScalar: number; - readonly initValue: string; - units(): string; - isCompatible(value: Qty.UnitSource): boolean; - kind(): string; - isUnitless(): boolean; - isBase(): boolean; - toBase(): Qty; toFloat(): number; - to(value: Qty.UnitSource): Qty; + + isUnitless(): boolean; + + isCompatible(other:string|Qty): boolean; + + isInverse(other:string|Qty): boolean + + kind(): string; + + isBase(): boolean; + + toBase(): Qty; + + units(): string; + + eq(other:Qty): boolean; + lt(other:Qty): boolean; + lte(other:Qty): boolean; + gt(other:Qty): boolean; + gte(other:Qty): boolean; + + toPrec(precQuantity: Qty|string|number): Qty; + + toString(targetUnitsOrMaxDecimalsOrPrec?:number|string|Qty, maxDecimals?: number): string; + + format(targetUnits?:string, formatter?:(scalar:number, units:string) => string): string; + + compareTo(other:Qty|string): number; + + same(other: Qty): boolean; + inverse(): Qty; - eq(value: Qty.UnitSource): boolean; - same(value: Qty.UnitSource): boolean; - lt(value: Qty.UnitSource): boolean; - lte(value: Qty.UnitSource): boolean; - gt(value: Qty.UnitSource): boolean; - gte(value: Qty.UnitSource): boolean; - compareTo(value: Qty): Qty.ComparisonResult; - add(value: Qty.Source): Qty; - sub(value: Qty.Source): Qty; - mul(value: Qty.Source): Qty; - div(value: Qty.Source): Qty; - toPrec(value: Qty.Source): Qty; - toString(valueOrPrecision?: Qty.Source): string; - toString(value: string, precision: number): string; - format(formatter?: Qty.Formatter): string; - format(value: string, formatter?: Qty.Formatter): string; -} -declare namespace Qty { + isDegrees(): boolean; - interface Type { - (value: Source): Qty; - (value: number, unit: string): Qty; - new (value: Source): Qty; - new (value: number, unit: string): Qty; - parse(value: string): Qty; - getKinds(): string[]; - getUnits(kind?: string): string[]; - getAliases(unit: string): string[]; - swiftConverter(sourceUnit: string, targetUnit: string): Converter; - formatter: Formatter; - readonly Error: any; - mulSafe(n1: number, n2: number): number; - divSafe(n1: number, n2: number): number; - } + isTemperature(): boolean; - interface Converter { - (sourceValue: number): number; - (sourceValues: number[]): number[]; - } + to(other:string|Qty): Qty; - type Formatter = (scalar: number, unit: string) => string; - - type ComparisonResult = -1 | 0 | 1; - - type Source = UnitSource | number; - - type UnitSource = Qty | string; -} - -export default Qty; + add(other:string|Qty): Qty; + sub(other:string|Qty): Qty; + mul(other:number|string|Qty): Qty; + div(other:number|string|Qty): Qty; + } +} \ No newline at end of file diff --git a/js-quantities/js-quantities-tests.ts b/js-quantities/js-quantities-tests.ts index b1916bb626..c09867634a 100644 --- a/js-quantities/js-quantities-tests.ts +++ b/js-quantities/js-quantities-tests.ts @@ -1,1502 +1,7 @@ -import "../jasmine"; -import Qty from "."; +var Val1 = Qty('1 m') -// From project readme +var Val2 = Qty(1); -let qty: Qty; +var Val3 = Qty(1, 'm'); -qty = new Qty('23 ft'); // constructor -qty = Qty('23 ft'); // factory - -qty = new Qty(124, 'cm'); // => 1.24 meter -qty = Qty(124, 'cm'); // => 1.24 meter - -qty = Qty('1m'); // => 1 meter -qty = Qty('m'); // => 1 meter (scalar defaults to 1) - -qty = Qty('1 N*m'); -qty = Qty('1 N m'); // * is optional - -qty = Qty('1 m/s'); - -qty = Qty('1 m^2/s^2'); -qty = Qty('1 m^2 s^-2'); // negative powers -qty = Qty('1 m2 s-2'); // ^ is optional - -qty = Qty('1 m^2 kg^2 J^2/s^2 A'); - -qty = Qty('1.5'); // unitless quantity -qty = Qty(1.5); // number as initializing value - -qty = Qty('1 attoparsec/microfortnight'); - -let qtyCopy: Qty; - -qtyCopy = Qty(qty); // quantity could be copied when used as initializing value - -Qty.parse('1 m'); // => 1 meter -Qty.parse('foo'); // => null - -Qty.getKinds(); // => Array of names of every well-known kind of units - -Qty.getUnits('currency'); // => [ 'dollar', 'cents' ] -// Or all alphabetically sorted -Qty.getUnits(); // => [ 'acre','Ah','ampere','AMU','angstrom'] - -Qty.getAliases('m'); // => [ 'm', 'meter', 'meters', 'metre', 'metres' ] - -const qty1 = Qty('1m'); -const qty2 = Qty('2m'); - -qty1.isCompatible(qty2); // => true or false - -qty.kind(); // => 'length', 'area', etc... - -qty.isUnitless(); // => true or false -qty.isBase(); // => true if quantity is represented with base units - -qty.toBase(); // converts to SI units (10 cm => 0.1 m) (new instance) - -qty.toFloat(); // returns scalar of unitless quantity (otherwise throws error) - -qty.to('m'); // converts quantity to meter if compatible or throws an error (new instance) -qty1.to(qty2); // converts quantity to same unit of qty2 if compatible or throws an error (new instance) - -qty.inverse(); // converts quantity to its inverse ('100 m/s' => '.01 s/m') -// Inverses can be used, but there is no special checking to -// rename the units -Qty('10ohm').inverse(); // '.1/ohm' (not '.1S', although they are equivalent) -// however, the 'to' command will convert between inverses also -Qty('10ohm').to('S'); // '.1S' - -var convert = Qty.swiftConverter('m/h', 'ft/s'); // Configures converter - -// Converting single value -var converted = convert(2500); // => 2.278.. - -// Converting large array of values -var convertedSerie = convert([2500, 5000]); // => [2.278.., 4.556.., ...] - -qty1.eq(qty2); // => true if both quantities are equal (1m == 100cm => true) -qty1.same(qty2); // => true if both quantities are same (1m == 100cm => false) -qty1.lt(qty2); // => true if qty1 is stricty less than qty2 -qty1.lte(qty2); // => true if qty1 is less than or equal to qty2 -qty1.gt(qty2); // => true if qty1 is stricty greater than qty2 -qty1.gte(qty2); // => true if qty1 is greater than or equal to qty2 - -qty1.compareTo(qty2); // => -1 if qty1 < qty2, => 0 if qty1 == qty2, => 1 if qty1 > qty2 - -qty = Qty('5.17 ft'); -qty.toPrec('ft'); // => 5 ft -qty.toPrec('0.5 ft'); // => 5 ft -qty.toPrec('0.25 ft'); // => 5.25 ft -qty.toPrec('0.1 ft'); // => 5.2 ft -qty.toPrec('0.05 ft'); // => 5.15 ft -qty.toPrec('0.01 ft'); // => 5.17 ft -qty.toPrec('0.00001 ft'); // => 5.17 ft -qty.toPrec('2 ft'); // => 6 ft -qty.toPrec('2'); // => 6 ft - -qty = Qty('6.3782 m'); -qty.toPrec('dm'); // => 6.4 m -qty.toPrec('cm'); // => 6.38 m -qty.toPrec('mm'); // => 6.378 m -qty.toPrec('5 cm'); // => 6.4 m -qty.toPrec('10 m'); // => 10 m -qty.toPrec(0.1); // => 6.3 m - -qty = Qty('1.146 MPa'); -qty.toPrec('0.1 bar'); // => 1.15 MPa - -qty = Qty('1.146 MPa'); -qty.toString(); // => '1.146 MPa' - -qty = Qty('1.146 MPa'); -qty.toString('bar'); // => '11.46 bar' -qty.to('bar').toString(); // => '11.46 bar' - -qty = Qty('1.146 MPa'); -qty.toPrec(0.1).toString(); // => '1.1 MPa' -qty.to('bar').toPrec(0.1).toString(); // => '11.5 bar' - -qty = Qty('1.1234 m'); -qty.format(); // same units, default formatter => '1.234 m' -qty.format('cm'); // converted to 'cm', default formatter => '123.45 cm' - -var configurableRoundingFormatter = function (maxDecimals: number) { - return function (scalar: number, units: string) { - var pow = Math.pow(10, maxDecimals); - var rounded = Math.round(scalar * pow) / pow; - - return rounded + ' ' + units; - }; -}; - -qty = Qty('1.1234 m'); - -// same units, custom formatter => '1.12 m' -qty.format(configurableRoundingFormatter(2)); - -// convert to 'cm', custom formatter => '123.4 cm' -qty.format('cm', configurableRoundingFormatter(1)); - -Qty.formatter = configurableRoundingFormatter(2); -qty = Qty('1.1234 m'); -qty.format(); // same units, current default formatter => '1.12 m' - -Qty('37 tempC').to('tempF'); // => 98.6 tempF - -let scalar: number = 42; - -Qty('100 tempC').add('10 degC'); // 110 tempC -Qty('100 tempC').sub('10 degC'); // 90 tempC -Qty('100 tempC').add('50 tempC'); // throws error -Qty('100 tempC').sub('50 tempC'); // 50 degC -Qty('50 tempC').sub('100 tempC'); // -50 degC -Qty('100 tempC').mul(scalar); // 100*scalar tempC -Qty('100 tempC').div(scalar); // 100/scalar tempC -Qty('100 tempC').mul(qty); // throws error -Qty('100 tempC').div(qty); // throws error -Qty('100 tempC*unit'); // throws error -Qty('100 tempC/unit'); // throws error -Qty('100 unit/tempC'); // throws error -Qty('100 tempC').inverse(); // throws error - -Qty('100 tempC').to('degC'); // => 100 degC - -Qty('100 degC').to('tempC'); // => -173.15 tempC - -Qty('0 tempC').add('100 degC'); // => 100 tempC - -try { - // code triggering an error inside JS-quantities -} catch (e) { - if (e instanceof Qty.Error) { - // ... - } else { - // ... - } -} - -// From project spec - -describe("js-quantities", function () { - "use strict"; - - describe("initialization", function () { - it("should create unit only", function () { - var qty = Qty("m"); - expect(qty.numerator).toEqual([""]); - expect(qty.scalar).toBe(1); - }); - - it("should create unitless", function () { - var qty = Qty("1"); - expect(qty.toFloat()).toBe(1); - expect(qty.numerator).toEqual(["<1>"]); - expect(qty.denominator).toEqual(["<1>"]); - qty = Qty("1.5"); - expect(qty.toFloat()).toBe(1.5); - expect(qty.numerator).toEqual(["<1>"]); - expect(qty.denominator).toEqual(["<1>"]); - }); - - it("should create unitless from numbers", function () { - var qty = Qty(1.5); - expect(qty.toFloat()).toBe(1.5); - expect(qty.numerator).toEqual(["<1>"]); - expect(qty.denominator).toEqual(["<1>"]); - }); - - it("should create from numbers with explicit units", function () { - var qty = Qty(1.5, "m"); - expect(qty.scalar).toBe(1.5); - expect(qty.numerator).toEqual([""]); - expect(qty.denominator).toEqual(["<1>"]); - }); - - it("temperatures should have base unit in kelvin", function () { - var qty = Qty("1 tempK").toBase(); - expect(qty.scalar).toBe(1); - expect(qty.units()).toBe("tempK"); - - qty = Qty("1 tempR").toBase(); - expect(qty.scalar).toBe(5 / 9); - expect(qty.units()).toBe("tempK"); - - qty = Qty("0 tempC").toBase(); - expect(qty.scalar).toBe(273.15); - expect(qty.units()).toBe("tempK"); - - qty = Qty("0 tempF").toBase(); - expect(qty.scalar).toBeCloseTo(255.372, 3); - expect(qty.units()).toBe("tempK"); - }); - - it("temperature degrees should have base unit in kelvin", function () { - var qty = Qty("1 degK").toBase(); - expect(qty.scalar).toBe(1); - expect(qty.units()).toBe("degK"); - - qty = Qty("1 degR").toBase(); - expect(qty.scalar).toBe(5 / 9); - expect(qty.units()).toBe("degK"); - - qty = Qty("1 degC").toBase(); - expect(qty.scalar).toBe(1); - expect(qty.units()).toBe("degK"); - - qty = Qty("1 degF").toBase(); - expect(qty.scalar).toBe(5 / 9); - expect(qty.units()).toBe("degK"); - }); - - it("should not create temperatures below absolute zero", function () { - expect(function () { Qty("-1 tempK"); }).toThrow("Temperatures must not be less than absolute zero"); - expect(function () { Qty("-273.16 tempC"); }).toThrow("Temperatures must not be less than absolute zero"); - expect(function () { Qty("-459.68 tempF"); }).toThrow("Temperatures must not be less than absolute zero"); - expect(function () { Qty("-1 tempR"); }).toThrow("Temperatures must not be less than absolute zero"); - - var qty = Qty("1 tempK"); - expect(function () { qty.mul("-1"); }).toThrow("Temperatures must not be less than absolute zero"); - - qty = Qty("0 tempK"); - expect(function () { qty.sub("1 degK"); }).toThrow("Temperatures must not be less than absolute zero"); - - qty = Qty("-273.15 tempC"); - expect(function () { qty.sub("1 degC"); }).toThrow("Temperatures must not be less than absolute zero"); - - qty = Qty("-459.67 tempF"); - expect(function () { qty.sub("1 degF"); }).toThrow("Temperatures must not be less than absolute zero"); - - qty = Qty("0 tempR"); - expect(function () { qty.sub("1 degR"); }).toThrow("Temperatures must not be less than absolute zero"); - }); - - it("should create simple", function () { - var qty = Qty("1m"); - expect(qty.scalar).toBe(1); - expect(qty.numerator).toEqual([""]); - expect(qty.denominator).toEqual(["<1>"]); - }); - - it("should create negative", function () { - var qty = Qty("-1m"); - expect(qty.scalar).toBe(-1); - expect(qty.numerator).toEqual([""]); - expect(qty.denominator).toEqual(["<1>"]); - }); - - it("should create compound", function () { - var qty = Qty("1 N*m"); - expect(qty.scalar).toBe(1); - expect(qty.numerator).toEqual(["", ""]); - expect(qty.denominator).toEqual(["<1>"]); - }); - - it("should create pressure units in term of height of water", function () { - var qty = Qty("1 inH2O"); - expect(qty.scalar).toBe(1); - expect(qty.numerator).toEqual([""]); - - qty = Qty("1 cmH2O"); - expect(qty.scalar).toBe(1); - expect(qty.numerator).toEqual([""]); - }); - - it("should create with denominator", function () { - var qty = Qty("1 m/s"); - expect(qty.scalar).toBe(1); - expect(qty.numerator).toEqual([""]); - expect(qty.denominator).toEqual([""]); - }); - - it("should create with denominator only", function () { - var qty = Qty("1 /s"); - expect(qty.scalar).toBe(1); - expect(qty.numerator).toEqual(["<1>"]); - expect(qty.denominator).toEqual([""]); - - qty = Qty("1 1/s"); - expect(qty.scalar).toBe(1); - expect(qty.numerator).toEqual(["<1>"]); - expect(qty.denominator).toEqual([""]); - - qty = Qty("1 s^-1"); - expect(qty.scalar).toBe(1); - expect(qty.numerator).toEqual(["<1>"]); - expect(qty.denominator).toEqual([""]); - }); - - it("should create with powers", function () { - var qty = Qty("1 m^2/s^2"); - expect(qty.scalar).toBe(1); - expect(qty.numerator).toEqual(["", ""]); - expect(qty.denominator).toEqual(["", ""]); - qty = Qty("1 m^2 kg^2 J^2/s^2"); - expect(qty.scalar).toBe(1); - expect(qty.numerator).toEqual(["", "", "", "", "", ""]); - expect(qty.denominator).toEqual(["", ""]); - qty = Qty("1 m^2/s^2*J^3"); - expect(qty.scalar).toBe(1); - expect(qty.numerator).toEqual(["", ""]); - expect(qty.denominator).toEqual(["", "", "", "", ""]); - }); - - it("should create with zero power", function () { - var qty = Qty("1 m^0"); - expect(qty.scalar).toBe(1); - expect(qty.numerator).toEqual(["<1>"]); - expect(qty.denominator).toEqual(["<1>"]); - }); - - it("should create with negative powers", function () { - var qty = Qty("1 m^2 s^-2"); - expect(qty.scalar).toBe(1); - expect(qty.numerator).toEqual(["", ""]); - expect(qty.denominator).toEqual(["", ""]); - expect(qty.same(Qty("1 m^2/s^2"))).toBe(true); - }); - - it("should accept powers without ^ syntax (simple)", function () { - var qty1 = Qty("1 m2"); - var qty2 = Qty("1 m^2"); - expect(qty1.eq(qty2)).toBe(true); - }); - - it("should accept powers without ^ syntax (negative power)", function () { - var qty1 = Qty("1 m-2"); - var qty2 = Qty("1 m^-2"); - expect(qty1.eq(qty2)).toBe(true); - }); - - it("should accept powers without ^ syntax (compound)", function () { - var qty1 = Qty("1 m^2 kg^2 J^2/s^2"); - var qty2 = Qty("1 m2 kg2 J2/s2"); - expect(qty1.eq(qty2)).toBe(true); - }); - - it("should accept powers without ^ syntax (compound and negative power)", function () { - var qty1 = Qty("1 m^2 kg^2 J^2 s^-2"); - var qty2 = Qty("1 m2 kg2 J2 s-2"); - expect(qty1.eq(qty2)).toBe(true); - }); - - it("should throw 'Unit not recognized' error when initializing with an invalid unit", function () { - expect(function () { Qty("aa"); }).toThrow("Unit not recognized"); - expect(function () { Qty("m/aa"); }).toThrow("Unit not recognized"); - expect(function () { Qty("m-"); }).toThrow("Unit not recognized"); - expect(function () { Qty("N*m"); }).not.toThrow("Unit not recognized"); - // mm is millimeter, but mmm is not a valid unit - expect(function () { Qty("mmm"); }).toThrow("Unit not recognized"); - }); - - it("should accept empty string as unitless 1", function () { - expect(Qty("").same(Qty("1"))).toBe(true); - expect(Qty(" ").same(Qty("1"))).toBe(true); - }); - - it("should throw error when passing NaN", function () { - expect( - function () { Qty(NaN); } - ).toThrow("Only string, number or quantity accepted as single " + - "initialization value"); - }); - - it("should throw 'Unit not recognized' error when initializing with an invalid unit and a 0 exponent", function () { - expect(function () { Qty("3p0"); }).toThrow("Unit not recognized"); - expect(function () { Qty("3p-0"); }).toThrow("Unit not recognized"); - }); - - it("should set baseScalar", function () { - var qty = Qty("0.018 MPa"); - expect(qty.baseScalar).toBe(18000); - - qty = Qty("66 cm3"); - expect(qty.baseScalar).toBe(0.000066); - }); - - it("should keep init value as is", function () { - var initValue = " 66 cm3 "; - var qty = Qty(initValue); - - expect(qty.initValue).toEqual(initValue); - }); - - it("should allow whitespace-wrapped value", function () { - expect(function () { Qty(" 2 MPa "); }).not.toThrow(); - }); - - it("should allow whitespaces between sign and scalar", function () { - var qty = Qty("- 1m"); - - expect(qty.scalar).toEqual(-1); - expect(qty.units()).toEqual("m"); - }); - - it("should throw an error when parsing negative quantity " + - "with no scalar", function () { - expect(function () { Qty("-m"); }).toThrow("Unit not recognized"); - }); - }); - - describe("isCompatible", function () { - it("should return true with compatible quantities", function () { - var qty1 = Qty("1 m*kg/s"); - var qty2 = Qty("1 in*pound/min"); - expect(qty1.isCompatible(qty2)).toBe(true); - qty2 = Qty("1 in/min"); - expect(qty1.isCompatible(qty2)).toBe(false); - }); - - it("should return true with dimensionless quantities", function () { - var qty1 = Qty("1"); - var qty2 = Qty("2"); - expect(qty1.isCompatible(qty2)).toBe(true); - }); - }); - - describe("conversion", function () { - it("should convert to base units", function () { - var qty = Qty("100 cm"); - expect(qty.toBase().scalar).toBe(1); - expect(qty.toBase().units()).toBe("m"); - qty = Qty("10 cm"); - expect(qty.toBase().scalar).toBe(0.1); - expect(qty.toBase().units()).toBe("m"); - qty = Qty("0.3 mm^2 ms^-2"); - expect(qty.toBase().scalar).toBe(0.3); - expect(qty.toBase().units()).toBe("m2/s2"); - }); - - it("should convert to compatible units", function () { - var qty = Qty("10 cm"); - expect(qty.to("ft").scalar).toBe(Qty.divSafe(0.1, 0.3048)); - qty = Qty("2m^3"); - expect(qty.to("l").scalar).toBe(2000); - - qty = Qty("10 cm"); - expect(qty.to(Qty("m")).scalar).toBe(0.1); - expect(qty.to(Qty("20m")).scalar).toBe(0.1); - - qty = Qty("1 m3"); - expect(qty.to("cm3").scalar).toBe(1000000); - - qty = Qty("1 cm3"); - expect(qty.to("mm3").scalar).toBe(1000); - - qty = Qty("550 cm3"); - expect(qty.to("cm^3").scalar).toBe(550); - - qty = Qty("0.000773 m3"); - expect(qty.to("cm^3").scalar).toBe(773); - }); - - describe('percents', function () { - it("should convert from % to unitless", function () { - expect(Qty("10 %").to("").same(Qty("0.1"))).toBe(true); - }); - - it("should convert from unitless to %", function () { - expect(Qty("0.1").to("%").same(Qty("10 %"))).toBe(true); - }); - }); - - it("should convert temperatures to compatible units", function () { - var qty = Qty("0 tempK"); - expect(qty.to("tempC").scalar).toBe(-273.15); - - qty = Qty("0 tempF"); - expect(qty.to("tempK").scalar).toBeCloseTo(255.372, 3); - - qty = Qty("32 tempF"); - expect(qty.to("tempC").scalar).toBe(0); - - qty = Qty("0 tempC"); - expect(qty.to("tempF").scalar).toBeCloseTo(32, 10); - }); - - it("should convert temperature degrees to compatible units", function () { - var qty = Qty("0 degK"); - expect(qty.to("degC").scalar).toBe(0); - - qty = Qty("1 degK/s"); - expect(qty.to("degC/min").scalar).toBe(60); - - qty = Qty("100 cm/degF"); - expect(qty.to("m/degF").scalar).toBe(1); - - qty = Qty("10 degC"); - expect(qty.to("degF").scalar).toBe(18); - }); - - it("should convert temperature degrees to temperatures", function () { - // according to ruby-units, deg -> temp conversion adds the degress to 0 kelvin before converting - var qty = Qty("100 degC"); - expect(qty.to("tempC").scalar).toBeCloseTo(-173.15, 10); - - qty = Qty("273.15 degC"); - expect(qty.to("tempC").scalar).toBe(0); - - qty = Qty("460.67 degF"); - expect(qty.to("tempF").scalar).toBeCloseTo(1, 10); - }); - - it("should convert temperatures to temperature degrees", function () { - // according to ruby-units, temp -> deg conversion always uses the 0 relative degrees - var qty = Qty("100 tempC"); - expect(qty.to("degC").scalar).toBe(100); - - qty = Qty("0 tempK"); - expect(qty.to("degC").scalar).toBe(0); - - qty = Qty("0 tempF"); - expect(qty.to("degK").scalar).toBe(0); - - qty = Qty("18 tempF"); - expect(qty.to("degC").scalar).toBe(10); - - qty = Qty("10 tempC"); - expect(qty.to("degF").scalar).toBe(18); - }); - - it("should calculate inverses", function () { - var qty = Qty("1 ohm"); - var result = qty.to("siemens"); - expect(result.scalar).toBe(1); - expect(result.kind()).toBe("conductance"); - - qty = Qty("10 ohm"); - result = qty.to("siemens"); - expect(result.scalar).toBe(0.1); - expect(result.kind()).toBe("conductance"); - - qty = Qty("10 siemens"); - result = qty.to("ohm"); - expect(result.scalar).toBe(0.1); - expect(result.kind()).toBe("resistance"); - - qty = Qty("10 siemens"); - result = qty.inverse(); - expect(result.eq(".1 ohm")).toBe(true); - expect(result.kind()).toBe("resistance"); - - // cannot inverse a quantity with a 0 scalar - qty = Qty("0 ohm"); - expect(function () { qty.inverse(); }).toThrow("Divide by zero"); - - qty = Qty("10 ohm").inverse(); - result = qty.to("S"); - expect(result.scalar).toBe(0.1); - expect(result.kind()).toBe("conductance"); - - qty = Qty("12 in").inverse(); - // TODO: Swap toBeCloseTo with toBe once divSafe is fixed - expect(qty.to("ft").scalar).toBeCloseTo(1, 10); - }); - - it("should return itself if target units are the same", function () { - var qty = Qty("123 cm3"); - - expect(qty.to("cm3")).toBe(qty); - expect(qty.to("cm^3")).toBe(qty); - - qty = Qty("123 mcg"); - expect(qty.to("ug")).toBe(qty); - }); - - it("should be cached", function () { - var qty = Qty("100 m"), - converted = qty.to("ft"); - - expect(qty.to("ft") === converted).toBe(true); - }); - }); - - describe("comparison", function () { - it("should return true when comparing equal quantities", function () { - var qty1 = Qty("1cm"); - var qty2 = Qty("10mm"); - expect(qty1.eq(qty2)).toBe(true); - }); - - it("should compare compatible quantities", function () { - var qty1 = Qty("1cm"); - var qty2 = Qty("1mm"); - var qty3 = Qty("10mm"); - var qty4 = Qty("28A"); - expect(qty1.compareTo(qty2)).toBe(1); - expect(qty2.compareTo(qty1)).toBe(-1); - expect(qty1.compareTo(qty3)).toBe(0); - expect(function () { qty1.compareTo(qty4); }).toThrow("Incompatible units"); - - expect(qty1.lt(qty2)).toBe(false); - expect(qty1.lt(qty3)).toBe(false); - expect(qty1.lte(qty3)).toBe(true); - expect(qty1.gte(qty3)).toBe(true); - expect(qty1.gt(qty2)).toBe(true); - expect(qty2.gt(qty1)).toBe(false); - }); - - it("should compare identical quantities", function () { - var qty1 = Qty("1cm"); - var qty2 = Qty("1cm"); - var qty3 = Qty("10mm"); - expect(qty1.same(qty2)).toBe(true); - expect(qty1.same(qty3)).toBe(false); - }); - - it("should accept strings as parameter", function () { - var qty = Qty("1 cm"); - expect(qty.lt("0.5 cm")).toBe(false); - expect(qty.lte("1 cm")).toBe(true); - expect(qty.gte("3 mm")).toBe(true); - expect(qty.gt("5 m")).toBe(false); - }); - - }); - - describe("non-ASCII character", function () { - describe("µ", function () { - it("should be supported as prefix", function () { - // µ as greek letter - expect(Qty("1 \u03BCm").eq(Qty("1 um"))).toBe(true); - // µ as micro sign - expect(Qty("1 \u00B5m").eq(Qty("1 um"))).toBe(true); - }); - }); - - describe("Ω", function () { - it("should be accepted as unit for ohm", function () { - // Ω as greek letter - expect(Qty("1 \u03A9").eq(Qty("1 ohm"))).toBe(true); - // Ω as ohm sign - expect(Qty("1 \u2126").eq(Qty("1 ohm"))).toBe(true); - }); - }); - }); - - describe("math", function () { - - it("should add quantities", function () { - var qty1 = Qty("2.5m"); - var qty2 = Qty("3m"); - expect(qty1.add(qty2).scalar).toBe(5.5); - - expect(qty1.add("3m").scalar).toBe(5.5); - - qty2 = Qty("3cm"); - var result = qty1.add(qty2); - expect(result.scalar).toBe(2.53); - expect(result.units()).toBe("m"); - - result = qty2.add(qty1); - expect(result.scalar).toBe(253); - expect(result.units()).toBe("cm"); - - // make sure adding 2 of the same non-base units work - result = Qty("5cm").add("3cm"); - expect(result.scalar).toBe(8); - expect(result.units()).toBe("cm"); - }); - - it("should fail to add unlike quantities", function () { - var qty1 = Qty("3m"); - var qty2 = Qty("2s"); - expect(function () { qty1.add(qty2); }).toThrow("Incompatible units"); - expect(function () { qty2.add(qty1); }).toThrow("Incompatible units"); - }); - - it("should fail to add inverse quantities", function () { - var qty1 = Qty("10S"); - var qty2 = qty1.inverse(); - expect(function () { qty1.add(qty2); }).toThrow("Incompatible units"); - expect(function () { qty2.add(qty1); }).toThrow("Incompatible units"); - - qty1 = Qty("10S"); - qty2 = Qty("0.1ohm"); - expect(function () { qty1.add(qty2); }).toThrow("Incompatible units"); - expect(function () { qty2.add(qty1); }).toThrow("Incompatible units"); - }); - - it("should subtract quantities", function () { - var qty1 = Qty("2.5m"); - var qty2 = Qty("3m"); - expect(qty1.sub(qty2).scalar).toBe(-0.5); - - expect(qty1.sub("2m").scalar).toBe(0.5); - expect(qty1.sub("-2m").scalar).toBe(4.5); - - qty2 = Qty("3cm"); - var result = qty1.sub(qty2); - expect(result.scalar).toBe(2.47); - expect(result.units()).toBe("m"); - - result = qty2.sub(qty1); - expect(result.scalar).toBe(-247); - expect(result.units()).toBe("cm"); - }); - - it("should fail to subtract unlike quantities", function () { - var qty1 = Qty("3m"); - var qty2 = Qty("2s"); - expect(function () { qty1.sub(qty2); }).toThrow("Incompatible units"); - expect(function () { qty2.sub(qty1); }).toThrow("Incompatible units"); - }); - - it("should fail to subtract inverse quantities", function () { - var qty1 = Qty("10S"); - var qty2 = qty1.inverse(); - expect(function () { qty1.sub(qty2); }).toThrow("Incompatible units"); - expect(function () { qty2.sub(qty1); }).toThrow("Incompatible units"); - - qty1 = Qty("10S"); - qty2 = Qty("0.1ohm"); - expect(function () { qty1.sub(qty2); }).toThrow("Incompatible units"); - expect(function () { qty2.sub(qty1); }).toThrow("Incompatible units"); - }); - - it("should multiply quantities", function () { - var qty1 = Qty("2.5m"); - var qty2 = Qty("3m"); - var result = qty1.mul(qty2); - expect(result.scalar).toBe(7.5); - expect(result.units()).toBe("m2"); - expect(result.kind()).toBe("area"); - - qty2 = Qty("3cm"); - result = qty1.mul(qty2); - expect(result.scalar).toBe(0.075); - expect(result.units()).toBe("m2"); - - result = qty2.mul(qty1); - expect(result.scalar).toBe(750); - expect(result.units()).toBe("cm2"); - - result = qty1.mul(3.5); - expect(result.scalar).toBe(8.75); - expect(result.units()).toBe("m"); - - result = qty1.mul(0); - expect(result.scalar).toBe(0); - expect(result.units()).toBe("m"); - - result = qty1.mul(Qty("0m")); - expect(result.scalar).toBe(0); - expect(result.units()).toBe("m2"); - - qty2 = Qty("1.458 m"); - result = qty1.mul(qty2); - expect(result.scalar).toBe(3.645); - expect(result.units()).toBe("m2"); - }); - - it("should multiply unlike quantities", function () { - var qty1 = Qty("2.5 m"); - var qty2 = Qty("3 N"); - - var result = qty1.mul(qty2); - expect(result.scalar).toBe(7.5); - - qty1 = Qty("2.5 m^2"); - qty2 = Qty("3 kg/m^2"); - - result = qty1.mul(qty2); - expect(result.scalar).toBe(7.5); - expect(result.units()).toBe("kg"); - }); - - it("should multiply inverse quantities", function () { - var qty1 = Qty("10S"); - var qty2 = Qty(".5S").inverse(); // 2/S - var qty3 = qty1.inverse(); // .1/S - - var result = qty1.mul(qty2); - expect(result.scalar).toBe(20); - expect(result.isUnitless()).toBe(true); - expect(result.units()).toBe(""); - // swapping operands should give the same outcome - result = qty2.mul(qty1); - expect(result.scalar).toBe(20); - expect(result.isUnitless()).toBe(true); - expect(result.units()).toBe(""); - - result = qty1.mul(qty3); - expect(result.scalar).toBe(1); - expect(result.isUnitless()).toBe(true); - expect(result.units()).toBe(""); - // swapping operands should give the same outcome - result = qty3.mul(qty1); - expect(result.scalar).toBe(1); - expect(result.isUnitless()).toBe(true); - expect(result.units()).toBe(""); - }); - - it("should divide quantities", function () { - var qty1 = Qty("2.5m"); - var qty2 = Qty("3m"); - var qty3 = Qty("0m"); - - expect(function () { qty1.div(qty3); }).toThrow("Divide by zero"); - expect(function () { qty1.div(0); }).toThrow("Divide by zero"); - expect(qty3.div(qty1).scalar).toBe(0); - - var result = qty1.div(qty2); - expect(result.scalar).toBe(2.5 / 3); - expect(result.units()).toBe(""); - expect(result.kind()).toBe("unitless"); - - var qty4 = Qty("3cm"); - result = qty1.div(qty4); - expect(result.scalar).toBe(2.5 / 0.03); - expect(result.units()).toBe(""); - - result = qty4.div(qty1); - expect(result.scalar).toBe(0.012); - expect(result.units()).toBe(""); - - result = qty1.div(3.5); - expect(result.scalar).toBe(2.5 / 3.5); - expect(result.units()).toBe("m"); - }); - - it("should divide unlike quantities", function () { - var qty1 = Qty("7.5kg"); - var qty2 = Qty("2.5m^2"); - - var result = qty1.div(qty2); - expect(result.scalar).toBe(3); - expect(result.units()).toBe("kg/m2"); - }); - - it("should divide inverse quantities", function () { - var qty1 = Qty("10 S"); - var qty2 = Qty(".5 S").inverse(); // 2/S - var qty3 = qty1.inverse(); // .1/S - - var result = qty1.div(qty2); - expect(result.scalar).toBe(5); - expect(result.units()).toBe("S2"); - - result = qty2.div(qty1); - expect(result.scalar).toBe(0.2); - expect(result.units()).toBe("1/S2"); - - result = qty1.div(qty3); - expect(result.scalar).toBe(100); - expect(result.units()).toBe("S2"); - - result = qty3.div(qty1); - expect(result.scalar).toBe(0.01); - expect(result.units()).toBe("1/S2"); - }); - - }); - - describe("math with temperatures", function () { - - it("should add temperature degrees", function () { - var qty = Qty("2degC"); - expect(qty.add("3degF").scalar).toBeCloseTo(11 / 3, 10); - expect(qty.add("-1degC").scalar).toBe(1); - - qty = Qty("2 degC"); - var result = qty.add("2 degF"); - expect(result.scalar).toBe(28 / 9); - expect(result.units()).toBe("degC"); - - qty = Qty("2degK"); - result = qty.add("3degC"); - expect(result.scalar).toBe(5); - expect(result.units()).toBe("degK"); - - qty = Qty("2degC"); - result = qty.add("2degK"); - expect(result.scalar).toBe(4); - expect(result.units()).toBe("degC"); - }); - - it("should not add two temperatures", function () { - var qty = Qty("2tempC"); - expect(function () { qty.add("1 tempF"); }).toThrow("Cannot add two temperatures"); - expect(function () { qty.add("1 tempC"); }).toThrow("Cannot add two temperatures"); - }); - - it("should add temperatures to degrees", function () { - var qty = Qty("2degC"); - var result = qty.add("3tempF"); - expect(result.scalar).toBe(33 / 5); - expect(result.units()).toBe("tempF"); - - result = qty.add("-1tempC"); - expect(result.scalar).toBe(1); - expect(result.units()).toBe("tempC"); - - qty = Qty("2 tempC"); - result = qty.add("2 degF"); - expect(result.scalar).toBe(28 / 9); - expect(result.units()).toBe("tempC"); - }); - - it("should subtract degrees from degrees", function () { - var qty = Qty("2degC"); - expect(qty.sub("1.5degK").scalar).toBe(0.5); - expect(qty.sub("-2degC").scalar).toBe(4); - expect(qty.sub("1degF").scalar).toBe(2 - 5 / 9); - expect(qty.sub("-1degC").scalar).toBe(3); - - var result = qty.sub("degC"); - expect(result.scalar).toBe(1); - expect(result.units()).toBe("degC"); - }); - - it("should subtract degrees from temperatures", function () { - var qty = Qty("2tempC"); - expect(qty.sub("1.5degK").scalar).toBe(0.5); - expect(qty.sub("-2degC").scalar).toBe(4); - expect(qty.sub("1degF").scalar).toBe(2 - 5 / 9); - expect(qty.sub("-1degC").scalar).toBe(3); - - var result = qty.sub("degC"); - expect(result.scalar).toBe(1); - expect(result.units()).toBe("tempC"); - }); - - it("should subtract temperatures from temperatures", function () { - var qty = Qty("2tempC"); - - var result = qty.sub("1.5tempK"); - expect(result.scalar).toBe(273.65); - expect(result.units()).toBe("degC"); - - result = qty.sub("-2tempC"); - expect(result.scalar).toBe(4); - expect(result.units()).toBe("degC"); - - result = qty.sub("32tempF"); - expect(result.scalar).toBe(2); - expect(result.units()).toBe("degC"); - }); - - it("should not subtract temperatures from degrees", function () { - var qty = Qty("2degC"); - expect(function () { qty.sub("1 tempF"); }).toThrow("Cannot subtract a temperature from a differential degree unit"); - expect(function () { qty.sub("1 tempC"); }).toThrow("Cannot subtract a temperature from a differential degree unit"); - }); - - it("should multiply temperature degrees", function () { - var qty = Qty("2degF"); - var result = qty.mul(3); - expect(result.scalar).toBe(6); - expect(result.units()).toBe("degF"); - - result = qty.mul("3degF"); - expect(result.scalar).toBe(6); - expect(result.units()).toBe("degF2"); - - // TODO: Should we convert degrees ("2 degK" to "degC") before we do the math? - qty = Qty("2degC"); - result = qty.mul("2degK"); - expect(result.scalar).toBe(4); - expect(result.units()).toBe("degC*degK"); - - qty = Qty("2degC"); - result = qty.mul("degF"); - expect(result.scalar).toBe(2); - expect(result.units()).toBe("degC*degF"); - }); - - it("should not multiply temperatures except by scalar", function () { - var qty = Qty("2tempF"); - expect(function () { qty.mul("1 tempC"); }).toThrow("Cannot multiply by temperatures"); - expect(function () { qty.mul("1 degC"); }).toThrow("Cannot multiply by temperatures"); - expect(function () { Qty("1 tempC*s"); }).toThrow("Cannot multiply by temperatures"); - - var result = qty.mul(2); - expect(result.scalar).toBe(4); - expect(result.units()).toBe("tempF"); - - result = Qty("2").mul(qty); - expect(result.scalar).toBe(4); - expect(result.units()).toBe("tempF"); - }); - - it("should multiply temperature degrees with unlike quantities", function () { - var qty1 = Qty("2.5 degF"); - var qty2 = Qty("3 m"); - - var result = qty1.mul(qty2); - expect(result.scalar).toBe(7.5); - - qty1 = Qty("2.5 degF"); - qty2 = Qty("3 kg/degF"); - - result = qty1.mul(qty2); - expect(result.scalar).toBe(7.5); - expect(result.units()).toBe("kg"); - }); - - it("should divide temperature degrees with unlike quantities", function () { - var qty1 = Qty("7.5degF"); - var qty2 = Qty("2.5m^2"); - - var result = qty1.div(qty2); - expect(result.scalar).toBe(3); - expect(result.units()).toBe("degF/m2"); - }); - - it("should divide temperature degree quantities", function () { - var qty = Qty("2.5 degF"); - - expect(function () { qty.div("0 degF"); }).toThrow("Divide by zero"); - expect(function () { qty.div(0); }).toThrow("Divide by zero"); - expect(Qty("0 degF").div(qty).scalar).toBe(0); - expect(Qty("0 degF").div(qty).units()).toBe(""); - - var result = qty.div("3 degF"); - expect(result.scalar).toBe(2.5 / 3); - expect(result.units()).toBe(""); - expect(result.kind()).toBe("unitless"); - - result = qty.div(3); - expect(result.scalar).toBe(2.5 / 3); - expect(result.units()).toBe("degF"); - expect(result.kind()).toBe("temperature"); - - // TODO: Should we convert "2 degC" to "degF" before we do the math? - result = qty.div("2 degC"); - expect(result.scalar).toBe(1.25); - expect(result.units()).toBe("degF/degC"); - }); - - it("should not divide with temperatures except by scalar", function () { - expect(function () { Qty("tempF").div("1 tempC"); }).toThrow("Cannot divide with temperatures"); - expect(function () { Qty("tempF").div("1 degC"); }).toThrow("Cannot divide with temperatures"); - expect(function () { Qty("2").div("tempF"); }).toThrow("Cannot divide with temperatures"); - expect(function () { Qty("2 tempF/s"); }).toThrow("Cannot divide with temperatures"); - expect(function () { Qty("2 s/tempF"); }).toThrow("Cannot divide with temperatures"); - - // inverse is division: 1/x - expect(function () { Qty("tempF").inverse(); }).toThrow("Cannot divide with temperatures"); - - var result = Qty("4 tempF").div(2); - expect(result.scalar).toBe(2); - expect(result.units()).toBe("tempF"); - }); - - }); - - describe("errors", function () { - it("should be instance of Qty.Error", function () { - try { - Qty("aa"); - } catch (e) { - expect(e instanceof Qty.Error).toBeTruthy(); - } - }); - }); - - describe("utility methods", function () { - - it("should accept string as parameter for compatibility tests", function () { - var qty = Qty("1 mm"); - - expect(qty.isCompatible("2 mm")).toBe(true); - expect(qty.isCompatible("2 mm^3")).toBe(false); - }); - - it("should return kind", function () { - var qty = Qty("1 mm"); - expect(qty.kind()).toBe("length"); - - qty = Qty("1 N"); - expect(qty.kind()).toBe("force"); - }); - - it("should know if a quantity is in base units", function () { - var qty = Qty("100 cm"); - expect(qty.isBase()).toBe(false); - - qty = Qty("1m"); - expect(qty.isBase()).toBe(true); - }); - - it("should return unit part of quantities", function () { - var qty = Qty("1"); - expect(qty.units()).toBe(""); - qty = Qty("1 /s"); - expect(qty.units()).toBe("1/s"); - qty = Qty("100 cm"); - expect(qty.units()).toBe("cm"); - qty = Qty("100 cm/s"); - expect(qty.units()).toBe("cm/s"); - qty = Qty("1 cm^2"); - expect(qty.units()).toBe("cm2"); - qty = Qty("1 cm^2/s^2"); - expect(qty.units()).toBe("cm2/s2"); - qty = Qty("1 cm^2*J^3/s^2*A^2"); - expect(qty.units()).toBe("cm2*J3/s2*A2"); - }); - - }); - - describe("toString", function () { - it("should generate readable human output", function () { - var qty = Qty("2m"); - expect(qty.toString()).toBe("2 m"); - expect(qty.toString("cm")).toBe("200 cm"); - expect(qty.toString("km")).toBe("0.002 km"); - expect(function () { qty.toString("A"); }).toThrow("Incompatible units"); - - qty = Qty("24.5m/s"); - expect(qty.toString()).toBe("24.5 m/s"); - expect(function () { qty.toString("m"); }).toThrow("Incompatible units"); - expect(qty.toString("km/h")).toBe("88.2 km/h"); - - qty = Qty("254kg/m^2"); - expect(qty.toString()).toBe("254 kg/m2"); - - qty = Qty("2"); - expect(qty.toString()).toBe("2"); - }); - - it("should round readable human output when max decimals is specified", function () { - var qty = (Qty("2m")).div(3); - expect(qty.toString("cm", 2)).toBe("66.67 cm"); - - qty = Qty("2.8m"); - expect(qty.toString("m", 0)).toBe("3 m"); - expect(qty.toString("cm", 0)).toBe("280 cm"); - qty = Qty("2.818m"); - expect(qty.toString("cm", 0)).toBe("282 cm"); - }); - - it("should round to max decimals", function () { - var qty = (Qty("2.987654321 m")); - - expect(qty.toString(3)).toBe("2.988 m"); - expect(qty.toString(0)).toBe("3 m"); - }); - - it("should round according to precision passed as quantity", function () { - var qty = Qty("5.17 ft"); - - expect(qty.toString(Qty("ft"))).toBe("5 ft"); - expect(qty.toString(Qty("2 ft"))).toBe("6 ft"); - expect(qty.toString(Qty("0.5 ft"))).toBe("5 ft"); - expect(qty.toString(Qty("0.1 ft"))).toBe("5.2 ft"); - expect(qty.toString(Qty("0.05 ft"))).toBe("5.15 ft"); - expect(qty.toString(Qty("0.01 ft"))).toBe("5.17 ft"); - expect(qty.toString(Qty("0.0001 ft"))).toBe("5.17 ft"); - }); - - it("should return same output with successive calls", function () { - var qty = Qty("123 cm3"); - expect(qty.toString("cm3", 0)).toBe("123 cm3"); - expect(qty.toString("cm3", 0)).toBe("123 cm3"); - }); - - it("should return identical output when called with no parameters or same units", function () { - var qty = Qty("123 cm3"); - expect(qty.toString()).toBe(qty.toString("cm3")); - }); - - }); - - describe("format", function () { - describe("provided default formatter", function () { - it("should be applied to output", function () { - var qty = (Qty("2.987654321 m")); - - expect(qty.format()).toBe("2.987654321 m"); - }); - }); - - describe("custom formatter", function () { - var roundingFormatter = function (maxDecimals: number) { - return function (scalar: number, units: string) { - var pow = Math.pow(10, maxDecimals); - var rounded = Math.round(scalar * pow) / pow; - - return rounded + " " + units; - }; - }; - - it("should be applied to output", function () { - var qty = (Qty("2.987654321 m")); - - expect(qty.format(roundingFormatter(3))).toBe("2.988 m"); - expect(qty.format(roundingFormatter(0))).toBe("3 m"); - }); - - it("should be applied after conversion to target units", function () { - var qty = (Qty("2m")).div(3); - expect(qty.format("cm", roundingFormatter(2))).toBe("66.67 cm"); - - var intRoundingFormatter = roundingFormatter(0); - qty = Qty("2.8m"); - expect(qty.format("m", intRoundingFormatter)).toBe("3 m"); - expect(qty.format("cm", intRoundingFormatter)).toBe("280 cm"); - qty = Qty("2.818m"); - expect(qty.format("cm", intRoundingFormatter)).toBe("282 cm"); - }); - - describe("globally set as default formatter", function () { - var previousFormatter: Qty.Formatter; - - beforeEach(function () { - previousFormatter = Qty.formatter; - Qty.formatter = roundingFormatter(3); - }); - - afterEach(function () { - // Restore previous formatter - Qty.formatter = previousFormatter; - }); - - it("should be applied when no formatter is passed", function () { - var qty = (Qty("2.987654321 m")); - - expect(qty.format()).toBe("2.988 m"); - }); - }); - }); - }); - - describe("precision rounding", function () { - it("should round according to precision passed as quantity with same units", function () { - var qty = Qty("5.17 ft"); - - expect(qty.toPrec(Qty("ft")).toString()).toBe("5 ft"); - expect(qty.toPrec(Qty("2 ft")).toString()).toBe("6 ft"); - expect(qty.toPrec(Qty("10 ft")).toString()).toBe("10 ft"); - expect(qty.toPrec(Qty("0.5 ft")).toString()).toBe("5 ft"); - expect(qty.toPrec(Qty("0.1 ft")).toString()).toBe("5.2 ft"); - expect(qty.toPrec(Qty("0.05 ft")).toString()).toBe("5.15 ft"); - expect(qty.toPrec(Qty("0.01 ft")).toString()).toBe("5.17 ft"); - expect(qty.toPrec(Qty("0.0001 ft")).toString()).toBe("5.17 ft"); - expect(qty.toPrec(Qty("0.25 ft")).toString()).toBe("5.25 ft"); - }); - - it("should allow string as precision parameter", function () { - var qty = Qty("5.17 ft"); - - expect(qty.toPrec("ft").toString()).toBe("5 ft"); - expect(qty.toPrec("0.5 ft").toString()).toBe("5 ft"); - expect(qty.toPrec("0.05 ft").toString()).toBe("5.15 ft"); - }); - - it("should round according to precision passed as quantity with different prefixes", function () { - var qty = Qty("6.3782 m"); - - expect(qty.toPrec(Qty("dm")).toString()).toBe("6.4 m"); - expect(qty.toPrec(Qty("cm")).toString()).toBe("6.38 m"); - expect(qty.toPrec(Qty("mm")).toString()).toBe("6.378 m"); - - expect(qty.toPrec(Qty("5 cm")).toString()).toBe("6.4 m"); - }); - - it("should round according to precision passed as quantity with different compatible units", function () { - var qty = Qty("1.146 MPa"); - expect(qty.toPrec(Qty("0.1 bar")).toString()).toBe("1.15 MPa"); - expect(qty.toPrec(Qty("0.01 MPa")).toString()).toBe("1.15 MPa"); - expect(qty.toPrec(Qty("dbar")).toString()).toBe("1.15 MPa"); - - // Tests below are mainly a safety net because not sure if there is - // any usefulness to do things like that - qty = Qty("5.171234568 ft"); - expect(qty.toPrec(Qty("m")).toString()).toBe("6.561679790026248 ft"); - expect(qty.toPrec(Qty("dm")).toString()).toBe("5.249343832020998 ft"); - expect(qty.toPrec(Qty("cm")).toString()).toBe("5.183727034120736 ft"); - expect(qty.toPrec(Qty("mm")).toString()).toBe("5.170603674540684 ft"); - }); - }); - - describe("mulSafe", function () { - it("should multiply while trying to avoid numerical errors", function () { - expect(Qty.mulSafe(0.1, 0.1)).toBe(0.01); - expect(Qty.mulSafe(1e-11, 123.456789)).toBe(1.23456789e-9); - expect(Qty.mulSafe(6e-12, 100000)).toBe(6e-7); - }); - }); - - describe("divSafe", function () { - it("should divide while trying to avoid numerical errors", function () { - expect(Qty.divSafe(0.000773, 0.000001)).toBe(773); - // TODO uncomment and fix - //expect(Qty.divSafe(24.5, 0.2777777777777778)).toBe(88.2); - }); - }); - - describe("Qty.parse", function () { - it("should not throw if parsed argument is a string", function () { - expect(function () { Qty.parse("foo"); }).not.toThrow("Argument should be a string"); - }); - - it("should return parsed quantity when passing a valid quantity", function () { - expect((Qty.parse("2.5 m") instanceof Qty)).toBe(true); - }); - - it("should return null when passing an invalid quantity", function () { - expect(Qty.parse("aa")).toBeNull(); - }); - }); - - describe("Qty.swiftConverter", function () { - it("should return a function", function () { - expect(typeof Qty.swiftConverter("m/h", "ft/s")).toBe("function"); - }); - - it("should throw when passing incompatible units", function () { - expect(function () { Qty.swiftConverter("m", "s"); }).toThrow("Incompatible units"); - }); - - describe("converter", function () { - describe("single value", function () { - it("should convert value", function () { - // TODO Same test but with m/h -> ft/s triggers rounding issue - // (For the sake of speed, converter does not check and fix rounding issues) - var converter = Qty.swiftConverter("m/h", "m/s"); - - expect(converter(2500)).toEqual(Qty("2500 m/h").to("m/s").scalar); - }); - - it("should returned value unchanged when units are identical", function () { - var converter = Qty.swiftConverter("m/h", "m/h"); - - expect(converter(2500)).toEqual(2500); - }); - - it("should convert temperatures", function () { - var converter = Qty.swiftConverter("tempF", "tempC"); - - expect(converter(32)).toEqual(0); - }); - - it("should convert degrees", function () { - var converter = Qty.swiftConverter("degC", "degF"); - - expect(converter(10)).toEqual(18); - }); - }); - - describe("array of values", function () { - it("should be converted", function () { - var converter = Qty.swiftConverter("MPa", "bar"), - values = [250, 10, 15], - expected = [2500, 100, 150]; - - expect(converter(values)).toEqual(expected); - }); - }); - }); - }); - - describe("Qty.getKinds", function () { - it("should return an array of kind names", function () { - expect(Qty.getKinds()).toContain("resistance"); - }); - - it("should not contain duplicate kind names", function () { - var kinds = Qty.getKinds(); - var map: { [key: string]: number } = {}; - kinds.forEach(function (kind) { - map[kind] = 1; - }); - expect(kinds.length).toEqual(Object.keys(map).length); - }); - }); - - describe("Qty.getUnits", function () { - it("should return an array of units of kind", function () { - expect(Qty.getUnits("currency")).toContain("dollar"); - }); - it("should return an array of all units without arg", function () { - expect(Qty.getUnits()).toContain("sievert"); - }); - it("should throw unknown kind", function () { - expect(function () { Qty.getUnits('bogusKind'); }).toThrow("Kind not recognized"); - }); - }); - - describe("Qty.getAliases", function () { - it("should return array of alternative names for unit", function () { - expect(Qty.getAliases("m")).toContain("meter"); - expect(Qty.getAliases("meter")).toContain("metre"); - expect(Qty.getAliases("N")).toContain("newton"); - }); - }); - - describe("information", function () { - describe("bits and bytes", function () { - it("should have 'information' as kind", function () { - expect(Qty("3 b").kind()).toBe("information"); - expect(Qty("5 B").kind()).toBe("information"); - }); - - it("could be pluralized", function () { - expect(Qty("3 bits").eq(Qty("3 b"))).toBe(true); - expect(Qty("5 bytes").eq(Qty("5 B"))).toBe(true); - }); - }); - - describe("rate", function () { - it("should accept bps and Bps aliases", function () { - expect(Qty("3 bps").eq(Qty("3 b/s"))).toBe(true); - expect(Qty("5 Bps").eq(Qty("5 B/s"))).toBe(true); - }); - - it("should be parsed when prefixed", function () { - expect(Qty("3 kbps").eq(Qty("3 kb/s"))).toBe(true); - expect(Qty("5 MBps").eq(Qty("5 MB/s"))).toBe(true); - }); - - it("should have 'information_rate' as kind", function () { - expect(Qty("3 bps").kind()).toBe("information_rate"); - expect(Qty("5 Bps").kind()).toBe("information_rate"); - }); - }); - }); - - describe("non regression tests", function () { - describe("Wh (#38)", function () { - it("should be parsed", function () { - expect(Qty("Wh").eq(Qty("3600 J"))).toBe(true); - }); - - it("should be parsed when prefixed", function () { - expect(Qty("kWh").eq(Qty("1000 Wh"))).toBe(true); - }); - }); - - describe("Ah (#25)", function () { - it("should be parsed", function () { - expect(Qty("Ah").eq(Qty("3600 C"))).toBe(true); - }); - - it("should be parsed when prefixed", function () { - expect(Qty("mAh").eq(Qty("3.6 C"))).toBe(true); - }); - }); - - describe("Farad (#67)", function () { - it('should be equal to its definition', function () { - expect(Qty("1 F").eq(Qty("1 C").div(Qty("1 V")))).toBe(true); - }); - - it('should not be defined as base unit', function () { - var qty = Qty("F"); - - expect(qty.isBase()).toBe(false); - expect(qty.toBase().units()).toEqual("s4*A2/m2*kg"); - }); - - it('should be parsed when prefixed', function () { - var qty = Qty("100 nF"); - - expect(qty.eq(Qty("100 F").div(1e9))).toBe(true); - expect(qty.baseScalar).toEqual(1e-7); - }); - }); - }); -}); +var Val4 = Qty(Val1); \ No newline at end of file diff --git a/js-quantities/tsconfig.json b/js-quantities/tsconfig.json index c41d2d2197..8c2a810060 100644 --- a/js-quantities/tsconfig.json +++ b/js-quantities/tsconfig.json @@ -4,7 +4,7 @@ "target": "es6", "noImplicitAny": true, "noImplicitThis": true, - "strictNullChecks": true, + "strictNullChecks": false, "baseUrl": "../", "typeRoots": [ "../" @@ -17,4 +17,4 @@ "index.d.ts", "js-quantities-tests.ts" ] -} +} \ No newline at end of file diff --git a/js-quantities/tslint.json b/js-quantities/tslint.json deleted file mode 100644 index f9e30021f4..0000000000 --- a/js-quantities/tslint.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": "../tslint.json" -} diff --git a/memoizee/index.d.ts b/memoizee/index.d.ts deleted file mode 100644 index 456641dc59..0000000000 --- a/memoizee/index.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -// Type definitions for memoizee 0.4 -// Project: https://github.com/medikoo/memoizee -// Definitions by: Juan Picado -// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped - -declare namespace memoizee { - interface Options { - length?: number; - maxAge?: number; - max?: number; - preFetch?: number | true; - promise?: boolean; - dispose?: (value: any) => void; - async?: boolean; - primitive?: boolean; - normalizer?: (value: any) => void; - resolvers?: Array<(arg: any) => any>; - } - - interface Memoized { - delete: F; - clear: F & (() => void); - } -} - -// tslint:disable:forbidden-types -declare function memoizee(f: F, options?: memoizee.Options): F & memoizee.Memoized; - -export = memoizee; diff --git a/memoizee/memoizee-tests.ts b/memoizee/memoizee-tests.ts deleted file mode 100644 index e8e73a2d6a..0000000000 --- a/memoizee/memoizee-tests.ts +++ /dev/null @@ -1,61 +0,0 @@ -import memoize = require('memoizee'); - -var fn = function (one: string, two?: number, three?: any) { /* ... */ }; - -let memoized = memoize(fn); -memoized('foo', 3, 'bar'); -memoized('foo', 3, 'bar'); -memoized = memoize(fn, { length: 2 }); -memoized('foo'); -memoized('foo', undefined); -memoized('foo', 3, {}); -memoized('foo', 3, 13); -memoized('foo', undefined); -memoized('foo', undefined); -memoized('foo', 3, {}); -memoized('foo', 3, 13); -memoized('foo', 3, 13); -memoized = memoize(fn, { primitive: true }); -memoized('/path/one'); -memoized('/path/one'); -memoized = memoize(fn, { dispose: function (value:number) { /*…*/ } }); -var foo3 = memoized('foo', 3); -var bar7 = memoized('bar', 7); -memoized.clear('foo', 3); // Dispose called with foo3 value -memoized.clear('bar', 7); // Dispose called with bar7 value -memoized.delete('foo', 0); -var mFn = memoize(function (hash:any) { - // body of memoized function -}, { normalizer: function (args:any) { - // args is arguments object as accessible in memoized function - return JSON.stringify(args[0]); -} }); - -mFn({ foo: 'bar' }); - -memoized = memoize(fn, { length: 2, resolvers: [String, Boolean] }); -memoized(String(12), [1,2,3].length); -memoized("12", Number(true)); -memoized(String({ toString: function () { return "12"; } }), Number({})); - -{ - var afn = function (a:number, b:number) { - return new Promise(function (res) { res(a + b); }); - }; - let memoized = memoize(afn, { promise: true }); - memoized(3, 7); - memoized(3, 7); -} - -memoized = memoize(fn, { maxAge: 1000, preFetch: 0.6 }); - -memoized('foo', 3); -memoized('foo', 3); - -setTimeout(function () { - memoized('foo', 3); -}, 500); - -setTimeout(function () { - memoized('foo', 3); -}, 1300); diff --git a/memoizee/tsconfig.json b/memoizee/tsconfig.json deleted file mode 100644 index c2ccff1cab..0000000000 --- a/memoizee/tsconfig.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "compilerOptions": { - "module": "commonjs", - "target": "es6", - "noImplicitAny": true, - "noImplicitThis": true, - "strictNullChecks": true, - "baseUrl": "../", - "typeRoots": [ - "../" - ], - "types": [], - "noEmit": true, - "forceConsistentCasingInFileNames": true - }, - "files": [ - "index.d.ts", - "memoizee-tests.ts" - ] -} diff --git a/memoizee/tslint.json b/memoizee/tslint.json deleted file mode 100644 index 2221e40e4a..0000000000 --- a/memoizee/tslint.json +++ /dev/null @@ -1 +0,0 @@ -{ "extends": "../tslint.json" } \ No newline at end of file diff --git a/react-intl/index.d.ts b/react-intl/index.d.ts index e0d9d3f623..80a2372e12 100644 --- a/react-intl/index.d.ts +++ b/react-intl/index.d.ts @@ -1,6 +1,6 @@ // Type definitions for react-intl 2.2.0 // Project: http://formatjs.io/react/ -// Definitions by: Bruno Grieder , Christian Droulers , Fedor Nezhivoi , Till Wolff +// Definitions by: Bruno Grieder , Christian Droulers , Fedor Nezhivoi // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped /// @@ -13,7 +13,7 @@ declare namespace ReactIntl { pluralRuleFunction?: (n: number, ord: boolean) => string; } - function injectIntl | React.StatelessComponent>(component: T): T; + function injectIntl(component: React.ComponentClass | React.StatelessComponent): React.ComponentClass; function addLocaleData(data: Locale[] | Locale): void; @@ -45,10 +45,6 @@ declare namespace ReactIntl { formatHTMLMessage: (messageDescriptor: FormattedMessage.MessageDescriptor, values?: Object) => string; } - interface InjectedIntlProps { - intl?: InjectedIntl - } - namespace IntlComponent { interface DateTimeFormatProps { /* diff --git a/react-intl/react-intl-tests.tsx b/react-intl/react-intl-tests.tsx index 160a37bc0f..cd484c17b4 100644 --- a/react-intl/react-intl-tests.tsx +++ b/react-intl/react-intl-tests.tsx @@ -9,20 +9,20 @@ import * as React from "react" import * as reactMixin from "react-mixin" import { - IntlProvider, - InjectedIntl, - addLocaleData, - hasLocaleData, - injectIntl, - intlShape, - defineMessages, - FormattedRelative, - FormattedMessage, - FormattedHTMLMessage, - FormattedNumber, - FormattedPlural, - FormattedDate, - FormattedTime +IntlProvider, +InjectedIntl, +addLocaleData, +hasLocaleData, +injectIntl, +intlShape, +defineMessages, +FormattedRelative, +FormattedMessage, +FormattedHTMLMessage, +FormattedNumber, +FormattedPlural, +FormattedDate, +FormattedTime } from "react-intl" import reactIntlEn = require("react-intl/locale-data/en"); @@ -31,8 +31,7 @@ addLocaleData(reactIntlEn); console.log(hasLocaleData("en")); interface SomeComponentProps { - className: string, - intl?: InjectedIntl + intl: InjectedIntl } class SomeComponent extends React.Component { @@ -48,14 +47,14 @@ class SomeComponent extends React.Component { const formattedPlural = intl.formatPlural(1, { one: "hai!" }); const formattedMessage = intl.formatMessage({ id: "hello", defaultMessage: "Hello {name}!" }, { name: "Roger" }); const formattedHTMLMessage = intl.formatHTMLMessage({ id: "hello", defaultMessage: "Hello {name}!" }, { name: "Roger" }); - return
+ return
+ initialNow={new Date() } /> { many="haiku" /> { timeZoneName="short" /> { {(formattedNum: string) => ( {formattedNum} - )} - -
+ ) } + +
} } @@ -160,9 +159,9 @@ class TestApp extends React.Component<{}, {}> { "hello": "Hello, {name}!" }; return ( - - - + + + ); } } diff --git a/stripe/index.d.ts b/stripe/index.d.ts index fdfa1db96e..2f8c895298 100644 --- a/stripe/index.d.ts +++ b/stripe/index.d.ts @@ -1,10 +1,8 @@ -// Type definitions for stripe 0.0 +// Type definitions for stripe // Project: https://stripe.com/ // Definitions by: Andy Hawkins , Eric J. Smith , Amrit Kahlon , Adam Cmiel // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped -declare const Stripe: StripeStatic; - interface StripeStatic { applePay: StripeApplePay; setPublishableKey(key: string): void; @@ -51,8 +49,6 @@ interface StripeError { param?: string; } -type StripeCardDataBrand = 'Visa' | 'American Express' | 'MasterCard' | 'Discover JCB' | 'Diners Club' | 'Unknown'; - interface StripeCardData { object: string; last4: string; @@ -66,17 +62,18 @@ interface StripeCardData { address_state?: string; address_zip?: string; address_country?: string; - brand?: StripeCardDataBrand; createToken(data: StripeTokenData, responseHandler: (status: number, response: StripeTokenResponse) => void): void; } -interface StripeBankAccount { - createToken(params: StripeBankTokenParams, stripeResponseHandler: (status: number, response: StripeBankTokenResponse) => void): void; +interface StripeBankAccount +{ + createToken(params: StripeBankTokenParams, stripeResponseHandler: (status:number, response: StripeBankTokenResponse) => void): void; validateRoutingNumber(routingNumber: number | string, countryCode: string): boolean; validateAccountNumber(accountNumber: number | string, countryCode: string): boolean; } -interface StripeBankTokenParams { +interface StripeBankTokenParams +{ country: string; currency: string; account_number: number | string; @@ -85,7 +82,8 @@ interface StripeBankTokenParams { account_holder_type: string; } -interface StripeBankTokenResponse { +interface StripeBankTokenResponse +{ id: string; bank_account: { country: string; @@ -102,7 +100,13 @@ interface StripeBankTokenResponse { error?: StripeError; } -interface StripeApplePay { +declare var Stripe: StripeStatic; +declare module "Stripe" { + export = StripeStatic; +} + +interface StripeApplePay +{ checkAvailability(resopnseHandler: (result: boolean) => void): void; buildSession(data: StripeApplePayPaymentRequest, onSuccessHandler: (result: StripeApplePaySessionResult, completion: ((value: any) => void)) => void, @@ -113,7 +117,8 @@ type StripeApplePayBillingContactField = 'postalAddress' | 'name'; type StripeApplePayShippingContactField = StripeApplePayBillingContactField | 'phone' | 'email'; type StripeApplePayShipping = 'shipping' | 'delivery' | 'storePickup' | 'servicePickup'; -interface StripeApplePayPaymentRequest { +interface StripeApplePayPaymentRequest +{ billingContact: StripeApplePayPaymentContact; countryCode: string; currencyCode: string; @@ -127,26 +132,30 @@ interface StripeApplePayPaymentRequest { } // https://developer.apple.com/reference/applepayjs/1916082-applepay_js_data_types -interface StripeApplePayLineItem { +interface StripeApplePayLineItem +{ type: 'pending' | 'final'; label: string; amount: number; } -interface StripeApplePaySessionResult { +interface StripeApplePaySessionResult +{ token: StripeTokenResponse; shippingContact?: StripeApplePayPaymentContact; shippingMethod?: StripeApplePayShippingMethod; } -interface StripeApplePayShippingMethod { +interface StripeApplePayShippingMethod +{ label: string; detail: string; amount: number; identifier: string; } -interface StripeApplePayPaymentContact { +interface StripeApplePayPaymentContact +{ emailAddress: string; phoneNumber: string; givenName: string; @@ -157,7 +166,3 @@ interface StripeApplePayPaymentContact { postalCode: string; countryCode: string; } - -// The Stripe client side APIs are not made available to package managers for direct installation. -// As explained compliance reasons. Source: https://github.com/stripe/stripe-node/blob/master/README.md#these-are-serverside-bindings-only -// A release date versioning schema is used to version these APIs. diff --git a/stripe/stripe-tests.ts b/stripe/stripe-tests.ts deleted file mode 100644 index 44aa09d216..0000000000 --- a/stripe/stripe-tests.ts +++ /dev/null @@ -1,25 +0,0 @@ -function success(card: StripeCardData) { - console.log(card.brand && card.brand.toString()); -} - -const cardNumber = '4242424242424242'; - -const isValid = Stripe.validateCardNumber(cardNumber); -if (isValid) { - const tokenData: StripeTokenData = { - number: cardNumber, - exp_month: 1, - exp_year: 2100, - cvc: '111' - }; - Stripe.card.createToken(tokenData, (status, response) => { - if (response.error) { - console.error(response.error.message); - if (response.error.param) { - console.error(response.error.param); - } - } else { - success(response.card); - } - }); -} diff --git a/stripe/tsconfig.json b/stripe/tsconfig.json index 7c33ab65c5..cdcaca971c 100644 --- a/stripe/tsconfig.json +++ b/stripe/tsconfig.json @@ -4,7 +4,7 @@ "target": "es6", "noImplicitAny": true, "noImplicitThis": true, - "strictNullChecks": true, + "strictNullChecks": false, "baseUrl": "../", "typeRoots": [ "../" @@ -14,7 +14,6 @@ "forceConsistentCasingInFileNames": true }, "files": [ - "index.d.ts", - "stripe-tests.ts" + "index.d.ts" ] -} +} \ No newline at end of file diff --git a/stripe/tslint.json b/stripe/tslint.json deleted file mode 100644 index f9e30021f4..0000000000 --- a/stripe/tslint.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": "../tslint.json" -}