diff --git a/CHANGELOG.md b/CHANGELOG.md index a99367e..bfe79ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) +## [0.4.0] - 2019-3-11 +### Added +- Float type (check, enforcer, and method) + +### Changed +- Integer coercion is now more strict +- Switching dependencies back to object-agent + ## [0.3.3] - 2019-2-15 ### Changed - Switching dependencies to deep-equal instead of object-agent @@ -27,7 +35,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [0.2.3] - 2019-01-30 ### Changed -- Exporting the check functions as a object +- Exporting the check functions as an object - Exporting individual enforcers and methods ## [0.2.2] - 2019-01-24 @@ -111,7 +119,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Initial enforcers, methods, and documentation -[0.3.2]: https://github.com/DarrenPaulWright/type-enforcer/compare/v0.3.2...c0.3.3 +[0.4.0]: https://github.com/DarrenPaulWright/type-enforcer/compare/v0.3.3...c0.4.0 +[0.3.3]: https://github.com/DarrenPaulWright/type-enforcer/compare/v0.3.2...c0.3.3 [0.3.2]: https://github.com/DarrenPaulWright/type-enforcer/compare/v0.3.1...c0.3.2 [0.3.1]: https://github.com/DarrenPaulWright/type-enforcer/compare/v0.3.0...c0.3.1 [0.3.0]: https://github.com/DarrenPaulWright/type-enforcer/compare/v0.2.4...c0.3.0 diff --git a/docs/checks.md b/docs/checks.md index 564e6d2..8b5b91f 100644 --- a/docs/checks.md +++ b/docs/checks.md @@ -29,6 +29,9 @@ A type enforcement library for javascript
Boolean
Check if a value is a DOM element
Boolean
Check if a value is a finite float
+Boolean
Check if a value is a function
Check if a value is an instance of a constructor. Fixes issues with native instanceOf and primitives Boolean, Number, and String (see example).
Boolean
Check if a value is an integer
+Check if a value is a finite integer
Boolean
Check if a value can be parsed as JSON
@@ -161,6 +164,20 @@ Check if a value is a DOM element **Example** ``` javascript import { isElement } from 'type-enforcer'; isElement(document.createElement('div')); // => true ``` + + +## isFloat(value, [coerce]) ⇒Boolean
+Check if a value is a finite float
+
+**Kind**: global function
+
+| Param | Type | Default | Description |
+| --- | --- | --- | --- |
+| value | \*
| | |
+| [coerce] | Boolean
| false
| If true then see if the value can be coerced into a float |
+
+**Example**
+``` javascript
import { isFloat } from 'type-enforcer';
isFloat(3.14159);
// => true
isFloat('3.14159');
// => false
isFloat('3.14159', true);
// => true
```
## isFunction(value) ⇒ Boolean
@@ -191,7 +208,7 @@ Check if a value is an instance of a constructor. Fixes issues with native insta
## isInteger(value, [coerce]) ⇒ Boolean
-Check if a value is an integer
+Check if a value is a finite integer
**Kind**: global function
@@ -201,7 +218,7 @@ Check if a value is an integer
| [coerce] | Boolean
| false
| If true then see if the value can be coerced into an Integer |
**Example**
-``` javascript
import { isInteger } from 'type-enforcer';
isInteger(42);
// => true
isInteger('42');
// => false
isInteger('42', true);
// => true
```
+``` javascript
import { isInteger } from 'type-enforcer';
isInteger(42);
// => true
isInteger('42');
// => false
isInteger('42', true);
// => true
isInteger('42.5', true);
// => false
```
## isJson(value) ⇒ Boolean
diff --git a/docs/enforce.md b/docs/enforce.md
index e4c2c74..124848a 100644
--- a/docs/enforce.md
+++ b/docs/enforce.md
@@ -23,6 +23,7 @@ Utility functions for enforcing data types.
## Usage
``` javascript
import { en
* [.dockPoint(value, alt, [coerce])](#enforce.dockPoint) ⇒ DockPoint
* [.element(value, alt)](#enforce.element) ⇒ Element
* [.enum(value, enumerable, alt)](#enforce.enum) ⇒ String
+ * [.float(value, alt, [coerce], [minValue], [maxValue])](#enforce.float) ⇒ int
* [.function(value, alt)](#enforce.function) ⇒ function
* [.instance(value, constructor, alt)](#enforce.instance) ⇒ Object
* [.integer(value, alt, [coerce], [minValue], [maxValue])](#enforce.integer) ⇒ int
@@ -138,6 +139,23 @@ Enforce that a value exists in the provided [Enum](docs/Enum.md)
**Example**
``` javascript
import { enforce, Enum } from 'type-enforcer';
const values = new Enum({
a: 'item a',
b: 'item b'
});
enforce.enum(values.a, values, values.b);
// => 'item a'
enforce.enum(values.c, values, values.b);
// => 'item b'
```
+
+
+### enforce.float(value, alt, [coerce], [minValue], [maxValue]) ⇒ int
+Enforce that a value is a finite float. Uses [isFloat](docs/checks.md#isFloat).
+
+**Kind**: static method of [enforce
](#enforce)
+
+| Param | Type | Default | Description |
+| --- | --- | --- | --- |
+| value | \*
| | |
+| alt | int
| | Returned if the value is not the correct type |
+| [coerce] | Boolean
| false
| If true then coerce the value when possible |
+| [minValue] | int
| | |
+| [maxValue] | int
| | |
+
+**Example**
+``` javascript
import { enforce } from 'type-enforcer';
enforce.float(3.14159, 13.2);
// => 3.14159
enforce.float('3.14159', 13.2);
// => 13.2
enforce.float('3.14159', 13.2, true);
// => 3.14159
```
### enforce.function(value, alt) ⇒ function
@@ -170,7 +188,7 @@ Enforce that a value is an instance of a constructor. Uses [isInstanceOf](docs/c
### enforce.integer(value, alt, [coerce], [minValue], [maxValue]) ⇒ int
-Enforce that a value is an integer. Uses [isInteger](docs/checks.md#isInteger).
+Enforce that a value is a finite integer. Uses [isInteger](docs/checks.md#isInteger).
**Kind**: static method of [enforce
](#enforce)
@@ -200,7 +218,7 @@ Enforce that a value is a number (excluding NaN). Uses [isNumber](docs/checks.md
| [maxValue] | Number
| Infinity
| |
**Example**
-``` javascript
import { enforce } from 'type-enforcer';
enforce.number(3.14159, 13.2);
// => 3.14159
enforce.number('3.14159', 13.2);
// => 13.2
enforce.number('3.14159', 13.2, true);
// => 3.14159
```
+``` javascript
import { enforce } from 'type-enforcer';
enforce.number(3.14159, 13.2);
// => 3.14159
enforce.number('3.14159', 13.2);
// => 13.2
enforce.number('3.14159', 13.2, true);
// => 3.14159
enforce.number(Infinity, 13.2, true);
// => Infinity
```
### enforce.object(value, alt, [coerce]) ⇒ Object
diff --git a/docs/method.md b/docs/method.md
index c6d0955..7778357 100644
--- a/docs/method.md
+++ b/docs/method.md
@@ -24,6 +24,7 @@ Enforce data types and remove common boilerplate code on class methods.
## Usag
* [.dockPoint([options])](#method.dockPoint) ⇒ function
* [.element([options])](#method.element) ⇒ function
* [.enum([options])](#method.enum) ⇒ function
+ * [.float([options])](#method.float) ⇒ function
* [.function([options])](#method.function) ⇒ function
* [.instance([options])](#method.instance) ⇒ function
* [.int([options])](#method.int) ⇒ function
@@ -162,6 +163,22 @@ Builds a chainable method for getting/setting an enumerable value in an [Enum](d
| [options.enforce] | function
| enforce.enum
| |
| options.enum | Enum
| | An enum to restrict the values to. |
+
+
+### method.float([options]) ⇒ function
+Builds a chainable method for getting/setting a float
+
+**Kind**: static method of [method
](#method)
+**Extends**: [any
](#method.any)
+
+| Param | Type | Default | Description |
+| --- | --- | --- | --- |
+| [options] | Object
| | Same as [any](#method.any) with the following differences: |
+| [options.enforce] | function
| enforce.float
| |
+| [options.coerce] | Boolean
| false
| If true then coerce the value when possible |
+| [options.min] | Number
| | Passed to enforce.float |
+| [options.max] | Number
| | Passed to enforce.float |
+
### method.function([options]) ⇒ function
@@ -278,7 +295,7 @@ Builds a chainable method that implements a [Queue](docs/Queue.md)
| Param | Type | Description |
| --- | --- | --- |
| [options] | Object
| |
-| [options.set] | function
| Called after a new callback is added to the queue. Provides a reference to the queue, sets the context to the methods constructor. |
+| [options.set] | function
| Called after a new callback is added to the queue. Provides a reference to the queue, the new ID for the callback, the callback, and sets the context to the methods constructor. |
diff --git a/package-lock.json b/package-lock.json
index a0a9803..db33552 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "type-enforcer",
- "version": "0.3.3",
+ "version": "0.4.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -2434,11 +2434,6 @@
"type-detect": "^4.0.0"
}
},
- "deep-equal": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz",
- "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU="
- },
"deep-extend": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
@@ -6065,6 +6060,11 @@
"integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
"dev": true
},
+ "object-agent": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/object-agent/-/object-agent-0.3.1.tgz",
+ "integrity": "sha512-6RXS8xPeJ5Tow0Rpe7NUVYQhB9vboV+iwnh+7BetOshwN9X2ZHdsrsODR+n4pZzFB5sQCsNNV5Nlf1nG61ngeQ=="
+ },
"object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
diff --git a/package.json b/package.json
index 2f1055f..ca62e40 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "type-enforcer",
- "version": "0.3.3",
+ "version": "0.4.0",
"description": "Type enforcement library for javascript",
"main": "src/index.js",
"scripts": {
@@ -40,7 +40,7 @@
},
"homepage": "https://github.com/DarrenPaulWright/type-enforcer#readme",
"dependencies": {
- "deep-equal": "^1.0.1"
+ "object-agent": "^0.3.1"
},
"devDependencies": {
"@babel/core": "^7.2.2",
diff --git a/src/checks/is.js b/src/checks/is.js
index af21439..17c65be 100644
--- a/src/checks/is.js
+++ b/src/checks/is.js
@@ -4,6 +4,7 @@ import isCssSize from './types/isCssSize';
import isDate from './types/isDate';
import isDockPoint from './types/isDockPoint';
import isElement from './types/isElement';
+import isFloat from './types/isFloat';
import isFunction from './types/isFunction';
import isInstanceOf from './types/isInstanceOf';
import isInteger from './types/isInteger';
@@ -37,6 +38,7 @@ export default {
date: isDate,
dockPoint: isDockPoint,
element: isElement,
+ float: isFloat,
function: isFunction,
instanceOf: isInstanceOf,
integer: isInteger,
diff --git a/src/checks/types/isArray.js b/src/checks/types/isArray.js
index 602b165..5f71ff5 100644
--- a/src/checks/types/isArray.js
+++ b/src/checks/types/isArray.js
@@ -25,4 +25,4 @@ import isJson from './isJson';
*
* @returns {Boolean}
*/
-export default buildCheckWithCoerce((item) => Array.isArray(item), (value) => isJson(value) && Array.isArray(JSON.parse(value)));
+export default buildCheckWithCoerce(Array.isArray, (value) => isJson(value) && Array.isArray(JSON.parse(value)));
diff --git a/src/checks/types/isFloat.js b/src/checks/types/isFloat.js
new file mode 100644
index 0000000..806f534
--- /dev/null
+++ b/src/checks/types/isFloat.js
@@ -0,0 +1,33 @@
+import { buildCheckWithCoerce } from './checks';
+import isNumber from './isNumber';
+
+const isFinite = (item) => item !== Infinity && item !== -Infinity;
+
+/**
+ * Check if a value is a finite float
+ *
+ * @example
+ * ``` javascript
+ * import { isFloat } from 'type-enforcer';
+ *
+ * isFloat(3.14159);
+ * // => true
+ *
+ * isFloat('3.14159');
+ * // => false
+ *
+ * isFloat('3.14159', true);
+ * // => true
+ * ```
+ *
+ * @function isFloat
+ *
+ * @arg {*} value
+ * @arg {Boolean} [coerce=false] - If true then see if the value can be coerced into a float
+ *
+ * @returns {Boolean}
+ */
+export default buildCheckWithCoerce((item) => isNumber(item) && item !== Infinity && item !== -Infinity, (value) => {
+ const parsed = parseFloat(value);
+ return !isNaN(value) && parsed !== Infinity && parsed !== -Infinity;
+});
diff --git a/src/checks/types/isInteger.js b/src/checks/types/isInteger.js
index a29a81e..6d54337 100644
--- a/src/checks/types/isInteger.js
+++ b/src/checks/types/isInteger.js
@@ -2,7 +2,7 @@ import { buildCheckWithCoerce } from './checks';
import isNumber from './isNumber';
/**
- * Check if a value is an integer
+ * Check if a value is a finite integer
*
* @example
* ``` javascript
@@ -16,6 +16,9 @@ import isNumber from './isNumber';
*
* isInteger('42', true);
* // => true
+ *
+ * isInteger('42.5', true);
+ * // => false
* ```
*
* @function isInteger
@@ -25,4 +28,7 @@ import isNumber from './isNumber';
*
* @returns {Boolean}
*/
-export default buildCheckWithCoerce((item) => Number.isInteger(item) || isNumber(item) && Number.isInteger(Number.parseFloat(item)), (value) => !isNaN(value) && !isNaN(parseInt(value)));
+export default buildCheckWithCoerce((item) => Number.isInteger(item) || isNumber(item) && Number.isInteger(Number.parseFloat(item)), (value) => {
+ const parsed = parseFloat(value);
+ return !isNaN(value) && parsed === (parsed | 0);
+});
diff --git a/src/checks/types/isObject.js b/src/checks/types/isObject.js
index 6e7d901..4fed214 100644
--- a/src/checks/types/isObject.js
+++ b/src/checks/types/isObject.js
@@ -1,9 +1,7 @@
import { buildCheckWithCoerce } from './checks';
import isJson from './isJson';
-// const isPlainObject = (item) => item && typeof item === 'object' && item instanceof Object;
-// const isPlainObject = (item) => isInstanceOf(item, Object);
-const isPlainObject = (item) => item && typeof item === 'object' && toString.call(item) === '[object Object]' && item.constructor === Object;
+const isPlainObject = (item) => item && item.constructor === Object;
/**
* Check if a value is a plain object
diff --git a/src/enforcer/enforce.js b/src/enforcer/enforce.js
index d78083d..3b71f60 100644
--- a/src/enforcer/enforce.js
+++ b/src/enforcer/enforce.js
@@ -5,6 +5,7 @@ import enforceDate from './types/enforceDate';
import enforceDockPoint from './types/enforceDockPoint';
import enforceElement from './types/enforceElement';
import enforceEnum from './types/enforceEnum';
+import enforceFloat from './types/enforceFloat';
import enforceFunction from './types/enforceFunction';
import enforceInstance from './types/enforceInstance';
import enforceInteger from './types/enforceInteger';
@@ -38,6 +39,7 @@ export default {
dockPoint: enforceDockPoint,
element: enforceElement,
enum: enforceEnum,
+ float: enforceFloat,
function: enforceFunction,
instance: enforceInstance,
integer: enforceInteger,
diff --git a/src/enforcer/types/enforceFloat.js b/src/enforcer/types/enforceFloat.js
new file mode 100644
index 0000000..4810c79
--- /dev/null
+++ b/src/enforcer/types/enforceFloat.js
@@ -0,0 +1,31 @@
+import isFloat from '../../checks/types/isFloat';
+import { numericEnforcer } from './enforcer';
+
+/**
+ * Enforce that a value is a finite float. Uses [isFloat](docs/checks.md#isFloat).
+ *
+ * @example
+ * ``` javascript
+ * import { enforce } from 'type-enforcer';
+ *
+ * enforce.float(3.14159, 13.2);
+ * // => 3.14159
+ *
+ * enforce.float('3.14159', 13.2);
+ * // => 13.2
+ *
+ * enforce.float('3.14159', 13.2, true);
+ * // => 3.14159
+ * ```
+ *
+ * @function enforce.float
+ *
+ * @arg {*} value
+ * @arg {int} alt - Returned if the value is not the correct type
+ * @arg {Boolean} [coerce=false] - If true then coerce the value when possible
+ * @arg {int} [minValue]
+ * @arg {int} [maxValue]
+ *
+ * @returns {int}
+ */
+export default numericEnforcer(isFloat, Number);
diff --git a/src/enforcer/types/enforceInteger.js b/src/enforcer/types/enforceInteger.js
index 85aa14f..105a386 100644
--- a/src/enforcer/types/enforceInteger.js
+++ b/src/enforcer/types/enforceInteger.js
@@ -2,7 +2,7 @@ import isInteger from '../../checks/types/isInteger';
import { numericEnforcer } from './enforcer';
/**
- * Enforce that a value is an integer. Uses [isInteger](docs/checks.md#isInteger).
+ * Enforce that a value is a finite integer. Uses [isInteger](docs/checks.md#isInteger).
*
* @example
* ``` javascript
@@ -28,4 +28,4 @@ import { numericEnforcer } from './enforcer';
*
* @returns {int}
*/
-export default numericEnforcer(isInteger, Number);
+export default numericEnforcer(isInteger, (item) => item - 0);
diff --git a/src/enforcer/types/enforceNumber.js b/src/enforcer/types/enforceNumber.js
index 34d465d..2b4011e 100644
--- a/src/enforcer/types/enforceNumber.js
+++ b/src/enforcer/types/enforceNumber.js
@@ -16,6 +16,9 @@ import { numericEnforcer } from './enforcer';
*
* enforce.number('3.14159', 13.2, true);
* // => 3.14159
+ *
+ * enforce.number(Infinity, 13.2, true);
+ * // => Infinity
* ```
*
* @function enforce.number
diff --git a/src/index.js b/src/index.js
index 7a95348..6a59ada 100644
--- a/src/index.js
+++ b/src/index.js
@@ -52,6 +52,7 @@ export { default as isCssSize } from './checks/types/isCssSize';
export { default as isDate } from './checks/types/isDate';
export { default as isDockPoint } from './checks/types/isDockPoint';
export { default as isElement } from './checks/types/isElement';
+export { default as isFloat } from './checks/types/isFloat';
export { default as isFunction } from './checks/types/isFunction';
export { default as isInstanceOf } from './checks/types/isInstanceOf';
export { default as isInteger } from './checks/types/isInteger';
@@ -72,6 +73,7 @@ export { default as enforceDate } from './enforcer/types/enforceDate';
export { default as enforceDockPoint } from './enforcer/types/enforceDockPoint';
export { default as enforceElement } from './enforcer/types/enforceElement';
export { default as enforceEnum } from './enforcer/types/enforceEnum';
+export { default as enforceFloat } from './enforcer/types/enforceFloat';
export { default as enforceFunction } from './enforcer/types/enforceFunction';
export { default as enforceInstance } from './enforcer/types/enforceInstance';
export { default as enforceInteger } from './enforcer/types/enforceInteger';
@@ -92,6 +94,7 @@ export { default as methodDate } from './methods/types/methodDate';
export { default as methodDockPoint } from './methods/types/methodDockPoint';
export { default as methodElement } from './methods/types/methodElement';
export { default as methodEnum } from './methods/types/methodEnum';
+export { default as methodFloat } from './methods/types/methodFloat';
export { default as methodFunction } from './methods/types/methodFunction';
export { default as methodInstance } from './methods/types/methodInstance';
export { default as methodInteger } from './methods/types/methodInteger';
diff --git a/src/methods/method.js b/src/methods/method.js
index 4df0de1..9a809d1 100644
--- a/src/methods/method.js
+++ b/src/methods/method.js
@@ -6,6 +6,7 @@ import methodDate from './types/methodDate';
import methodDockPoint from './types/methodDockPoint';
import methodElement from './types/methodElement';
import methodEnum from './types/methodEnum';
+import methodFloat from './types/methodFloat';
import methodFunction from './types/methodFunction';
import methodInstance from './types/methodInstance';
import methodInteger from './types/methodInteger';
@@ -65,6 +66,7 @@ export default {
dockPoint: methodDockPoint,
element: methodElement,
enum: methodEnum,
+ float: methodFloat,
function: methodFunction,
integer: methodInteger,
instance: methodInstance,
diff --git a/src/methods/types/methodAny.js b/src/methods/types/methodAny.js
index beb10c9..04e9ed8 100644
--- a/src/methods/types/methodAny.js
+++ b/src/methods/types/methodAny.js
@@ -1,4 +1,4 @@
-import deepEqual from 'deep-equal';
+import { deepEqual } from 'object-agent';
import isArray from '../../checks/types/isArray';
import enforceBoolean from '../../enforcer/types/enforceBoolean';
import before from '../variants/before';
diff --git a/src/methods/types/methodFloat.js b/src/methods/types/methodFloat.js
new file mode 100644
index 0000000..5351ec3
--- /dev/null
+++ b/src/methods/types/methodFloat.js
@@ -0,0 +1,20 @@
+import enforceFloat from '../../enforcer/types/enforceFloat';
+import { buildMethod, mapEnforcerNumeric } from './methodAny';
+
+/**
+ * Builds a chainable method for getting/setting a float
+ *
+ * @function method.float
+ * @extends method.any
+ *
+ * @arg {Object} [options] - Same as {@link method.any} with the following differences:
+ * @arg {Function} [options.enforce=enforce.float]
+ * @arg {Boolean} [options.coerce=false] - If true then coerce the value when possible
+ * @arg {Number} [options.min] - Passed to enforce.float
+ * @arg {Number} [options.max] - Passed to enforce.float
+ *
+ * @returns {Function}
+ */
+export default buildMethod({
+ enforce: mapEnforcerNumeric(enforceFloat)
+});
diff --git a/src/methods/types/methodKeyValue.js b/src/methods/types/methodKeyValue.js
index 84bda17..85cb7f4 100644
--- a/src/methods/types/methodKeyValue.js
+++ b/src/methods/types/methodKeyValue.js
@@ -1,5 +1,5 @@
+import { forOwn } from 'object-agent';
import isObject from '../../checks/types/isObject';
-import forOwn from '../../utility/forOwn';
/**
* Builds a chainable method that accepts either:
diff --git a/src/types/CssSize.js b/src/types/CssSize.js
index e389e8a..bd07bcf 100644
--- a/src/types/CssSize.js
+++ b/src/types/CssSize.js
@@ -1,3 +1,4 @@
+import isFloat from '../checks/types/isFloat';
import methodElement from '../methods/types/methodElement';
import isElementInDom from '../utility/isElementInDom';
import throttle from '../utility/throttle';
@@ -94,7 +95,7 @@ const getMeasurement = (save, units, unit, element) => {
return save[unit];
};
-const isNonZeroNumber = (size) => !!size && size !== ZERO_PIXELS && !isNaN(size);
+const isNonZeroNumber = (size) => !!size && size !== ZERO_PIXELS && isFloat(size, true);
let currentWindowWidth;
let currentWindowHeight;
diff --git a/src/types/Enum.js b/src/types/Enum.js
index a549661..8bda78b 100644
--- a/src/types/Enum.js
+++ b/src/types/Enum.js
@@ -1,4 +1,4 @@
-import forOwn from '../utility/forOwn';
+import { forOwn } from 'object-agent';
const KEYS = Symbol();
const VALUES = Symbol();
diff --git a/src/types/Queue.js b/src/types/Queue.js
index 0b34a9e..c14bb77 100644
--- a/src/types/Queue.js
+++ b/src/types/Queue.js
@@ -1,5 +1,5 @@
+import { forOwn } from 'object-agent';
import isFunction from '../checks/types/isFunction';
-import forOwn from '../utility/forOwn';
const CALLBACKS = Symbol();
const CURRENT_ID = Symbol();
diff --git a/src/utility/forOwn.js b/src/utility/forOwn.js
deleted file mode 100644
index 3f1eda9..0000000
--- a/src/utility/forOwn.js
+++ /dev/null
@@ -1,2 +0,0 @@
-export default (object, callback) => !(!object || !Object.keys(object)
- .some((key) => key in object ? callback(object[key], key) : false));
diff --git a/tests/TestUtil.js b/tests/TestUtil.js
index a7f8f3e..1c7d2cc 100644
--- a/tests/TestUtil.js
+++ b/tests/TestUtil.js
@@ -1,6 +1,6 @@
import { assert } from 'chai';
+import { forOwn } from 'object-agent';
import { isObject } from '../src';
-import forOwn from '../src/utility/forOwn';
export const eachPair = (array1, array2, callback, isUnique = false) => {
let i;
diff --git a/tests/checks/isFloat.Test.js b/tests/checks/isFloat.Test.js
new file mode 100644
index 0000000..efc8ae9
--- /dev/null
+++ b/tests/checks/isFloat.Test.js
@@ -0,0 +1,44 @@
+import { assert } from 'chai';
+import { is, isFloat } from '../../src';
+import { multiTest } from '../TestUtil';
+import { floatData as data } from '../testValues';
+
+describe('isFloat', () => {
+ it('should exist in the exported "is" object', () => {
+ assert.deepEqual(isFloat, is.float);
+ });
+
+ multiTest({
+ values: data.true,
+ test: (value) => isFloat(value),
+ assertion: 'isTrue'
+ });
+ multiTest({
+ values: data.false,
+ test: (value) => isFloat(value),
+ assertion: 'isFalse'
+ });
+ multiTest({
+ values: data.coerceTrue,
+ test: (value) => isFloat(value),
+ assertion: 'isFalse'
+ });
+
+ describe('coerce', () => {
+ multiTest({
+ values: data.true,
+ test: (value) => isFloat(value, true),
+ assertion: 'isTrue'
+ });
+ multiTest({
+ values: data.coerceTrue,
+ test: (value) => isFloat(value, true),
+ assertion: 'isTrue'
+ });
+ multiTest({
+ values: data.coerceFalse,
+ test: (value) => isFloat(value, true),
+ assertion: 'isFalse'
+ });
+ });
+});
diff --git a/tests/checks/isInteger.Test.js b/tests/checks/isInteger.Test.js
index 8a64559..b672805 100644
--- a/tests/checks/isInteger.Test.js
+++ b/tests/checks/isInteger.Test.js
@@ -23,19 +23,22 @@ describe('isInteger', () => {
test: (value) => isInteger(value),
assertion: 'isFalse'
});
- multiTest({
- values: data.true,
- test: (value) => isInteger(value, true),
- assertion: 'isTrue'
- });
- multiTest({
- values: data.coerceTrue,
- test: (value) => isInteger(value, true),
- assertion: 'isTrue'
- });
- multiTest({
- values: data.coerceFalse,
- test: (value) => isInteger(value, true),
- assertion: 'isFalse'
+
+ describe('coerce', () => {
+ multiTest({
+ values: data.true,
+ test: (value) => isInteger(value, true),
+ assertion: 'isTrue'
+ });
+ multiTest({
+ values: data.coerceTrue,
+ test: (value) => isInteger(value, true),
+ assertion: 'isTrue'
+ });
+ multiTest({
+ values: data.coerceFalse,
+ test: (value) => isInteger(value, true),
+ assertion: 'isFalse'
+ });
});
});
diff --git a/tests/checks/isNumber.Test.js b/tests/checks/isNumber.Test.js
index 4e80644..0437c53 100644
--- a/tests/checks/isNumber.Test.js
+++ b/tests/checks/isNumber.Test.js
@@ -23,19 +23,22 @@ describe('isNumber', () => {
test: (value) => isNumber(value),
assertion: 'isFalse'
});
- multiTest({
- values: data.true,
- test: (value) => isNumber(value, true),
- assertion: 'isTrue'
- });
- multiTest({
- values: data.coerceTrue,
- test: (value) => isNumber(value, true),
- assertion: 'isTrue'
- });
- multiTest({
- values: data.coerceFalse,
- test: (value) => isNumber(value, true),
- assertion: 'isFalse'
+
+ describe('coerce', () => {
+ multiTest({
+ values: data.true,
+ test: (value) => isNumber(value, true),
+ assertion: 'isTrue'
+ });
+ multiTest({
+ values: data.coerceTrue,
+ test: (value) => isNumber(value, true),
+ assertion: 'isTrue'
+ });
+ multiTest({
+ values: data.coerceFalse,
+ test: (value) => isNumber(value, true),
+ assertion: 'isFalse'
+ });
});
});
diff --git a/tests/enforcer/types/enforceFloat.Test.js b/tests/enforcer/types/enforceFloat.Test.js
new file mode 100644
index 0000000..60f7015
--- /dev/null
+++ b/tests/enforcer/types/enforceFloat.Test.js
@@ -0,0 +1,67 @@
+import { assert } from 'chai';
+import { enforce, enforceFloat } from '../../../src';
+import { multiTest } from '../../TestUtil';
+import { floatData as data } from '../../testValues';
+import { runNegativeTests } from '../enforceTestUtility';
+
+const validInt = 11;
+const validFloat = 34.23463456;
+
+describe('enforce', () => {
+ describe('.float', () => {
+ it('should exist in the exported "enforce" object', () => {
+ assert.deepEqual(enforceFloat, enforce.float);
+ });
+
+ it('should return the setter value when an float is provided', () => {
+ assert.deepEqual(enforce.float(validInt, validFloat), validInt);
+ });
+ it('should return the setter value when a float is provided', () => {
+ assert.deepEqual(enforce.float(validFloat, validInt), validFloat);
+ });
+ it('should return the min value when a float less than the min value is provided', () => {
+ assert.deepEqual(enforce.float(-12, validInt, false, 0, 5), 0);
+ });
+ it('should return the max value when a float greater than the max value is provided', () => {
+ assert.deepEqual(enforce.float(12, validInt, false, 0, 5), 5);
+ });
+
+ multiTest({
+ values: data.coerceTrue.map((item) => {
+ return {
+ input: item,
+ output: Number(item)
+ };
+ }),
+ message: (input) => `should return a coerced ${input} when coerce is true`,
+ test: (value) => enforce.float(value, value, true),
+ inputKey: 'input',
+ outputKey: 'output',
+ assertion: 'deepEqual'
+ });
+
+ multiTest({
+ values: data.coerceTrue.map((item) => {
+ return {
+ input: item,
+ output: item
+ };
+ }),
+ message: (input) => `should NOT return a coerced ${input} when coerce is false`,
+ test: (value) => enforce.float(value, value, false),
+ inputKey: 'input',
+ outputKey: 'output',
+ assertion: 'deepEqual'
+ });
+
+ multiTest({
+ values: data.coerceFalse,
+ message: (input) => `should return the alt value when ${input} is provided and coerce is true`,
+ test: (value) => enforce.float(value, 'testAlt', true),
+ output: 'testAlt',
+ assertion: 'deepEqual'
+ });
+
+ runNegativeTests('float', validInt);
+ });
+});
diff --git a/tests/methods/types/methodFloat.Test.js b/tests/methods/types/methodFloat.Test.js
new file mode 100644
index 0000000..d3501c1
--- /dev/null
+++ b/tests/methods/types/methodFloat.Test.js
@@ -0,0 +1,27 @@
+import { assert } from 'chai';
+import { method, methodFloat } from '../../../src';
+import { floatData as data } from '../../testValues';
+import { testMethodType } from '../methodTestUtility';
+
+describe('method', () => {
+ describe('.float', () => {
+ it('should exist in the exported "method" object', () => {
+ assert.deepEqual(methodFloat, method.float);
+ });
+
+ testMethodType(Object.assign({}, data, {
+ extraProps: {
+ min: 1.2,
+ max: 10.5
+ },
+ coerce: [{
+ value: 30.874,
+ coerced: 10.5
+ }, {
+ value: -3,
+ coerced: 1.2
+ }]
+ }));
+ });
+});
+
diff --git a/tests/testValues.js b/tests/testValues.js
index 2eda565..4585626 100644
--- a/tests/testValues.js
+++ b/tests/testValues.js
@@ -41,7 +41,8 @@ export const validFunctions = [function() {
}, () => {
}];
export const validIntegers = [1, 5, new Number(42), Number(11)];
-export const validNumbers = [1.3, 2.5, -10.00000001, 3.14159, new Number(42.2), Number(11.3)];
+export const validFloats = [1.3, 2.5, -10.00000001, 3.14159, new Number(42.2), Number(11.3)];
+export const validInfinities = [Infinity, -Infinity];
export const validObjects = [{}, {
test1: 1
}, new Object(), Object()];
@@ -115,7 +116,7 @@ const coerceInfinity = [
'Infinity',
'-Infinity'
];
-const coerceNumberTrue = [
+const coerceIntegerTrue = [
'0',
'1',
'1.00',
@@ -132,16 +133,17 @@ const coerceNumberTrue = [
'+0',
'+0.0',
'0.00',
- '999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999',
'0x0',
'0xffffffff',
'0xffffffffffffffff',
'0xabad1dea',
- '123456789012345678901234567890123456789',
'01000',
'08',
- '09',
- '2.2250738585072011e-308'];
+ '09'];
+const coerceFloatTrue = [
+ '3.2',
+ '10.5'
+];
const coerceNumberFalse = [
'$1.00',
'1/2',
@@ -201,7 +203,8 @@ export const testValues = [].concat(
validElements,
validFunctions,
validIntegers,
- validNumbers,
+ validFloats,
+ validInfinities,
validObjects,
validRegExps,
validStrings,
@@ -234,7 +237,7 @@ export const cssSizeData = {
true: validCssSizes,
false: difference(testValues, validCssSizes),
coerceTrue: validCssValues.map((item) => item.size),
- coerceFalse: difference(testValues, validCssSizes, validIntegers, validNumbers)
+ coerceFalse: difference(testValues, validCssSizes, validIntegers, validFloats)
};
export const dateData = {
value: Date,
@@ -242,7 +245,7 @@ export const dateData = {
true: validDates,
false: difference(testValues, validDates),
coerceTrue: ['10/12/1980', 'January 8, 2014'],
- coerceFalse: difference(testValues, validDates, validArrays, validNumbers, validIntegers, validRegExps, validPoints)
+ coerceFalse: difference(testValues, validDates, validArrays, validFloats, validIntegers, validRegExps, validPoints)
};
export const dockPointData = {
value: DockPoint,
@@ -270,18 +273,27 @@ export const functionData = {
};
export const integerData = {
name: 'integer',
- skip: ['number'],
+ skip: ['number', 'float'],
true: validIntegers,
- false: difference(testValues, validIntegers),
- coerceTrue: coerceNumberTrue,
- coerceFalse: [].concat(coerceNumberFalse, coerceInfinity)
+ false: difference(testValues, validIntegers, validInfinities),
+ coerceTrue: coerceIntegerTrue,
+ coerceFalse: coerceNumberFalse.concat(coerceFloatTrue, coerceInfinity)
+};
+export const floatData = {
+ name: 'float',
+ skip: ['number', 'integer'],
+ true: validFloats,
+ false: difference(testValues, validFloats, validIntegers, validInfinities),
+ coerceTrue: coerceIntegerTrue.concat(coerceFloatTrue),
+ coerceFalse: coerceNumberFalse.concat(coerceInfinity)
};
export const numberData = {
value: Number,
name: 'number',
- true: validNumbers,
- false: difference(testValues, validNumbers, validIntegers),
- coerceTrue: [].concat(coerceNumberTrue, coerceInfinity),
+ skip: ['integer', 'float'],
+ true: validFloats.concat(validIntegers, validInfinities),
+ false: difference(testValues, validFloats, validIntegers, validInfinities),
+ coerceTrue: coerceIntegerTrue.concat(coerceInfinity),
coerceFalse: coerceNumberFalse
};
export const objectData = {
@@ -328,7 +340,7 @@ export const thicknessData = {
true: validThicknesses,
false: difference(testValues, validThicknesses),
coerceTrue: ['1px', '1px 2px 3px 4px'],
- coerceFalse: difference(testValues, validThicknesses, validCssSizes, validIntegers, validNumbers, validArrays)
+ coerceFalse: difference(testValues, validThicknesses, validCssSizes, validIntegers, validFloats, validArrays)
};
export const vectorData = {
value: Vector,
@@ -348,6 +360,7 @@ export const testTypes = [
elementData,
functionData,
integerData,
+ floatData,
numberData,
objectData,
pointData,
diff --git a/tests/types/CssSize.Test.js b/tests/types/CssSize.Test.js
index 1ed638f..da9c35e 100644
--- a/tests/types/CssSize.Test.js
+++ b/tests/types/CssSize.Test.js
@@ -272,7 +272,7 @@ describe('CssSize', () => {
const isValid = (value1, value2) => {
return (value1 !== value2 &&
!(value1.size === 0 && value2.size === '0' || value1.size === '0' && value2.size === 0) &&
- !(value1.size + PIXELS === value2.size || value1.size === value2.size + PIXELS))
+ !(value1.size + PIXELS === value2.size || value1.size === value2.size + PIXELS));
};
multiTest({