-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Create a function to check for invalid values (#38)
Invent a recursive function that checks against NaN input in <Table> and <Cell> props
- Loading branch information
Showing
5 changed files
with
143 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import { describe, expect, it, run } from 'https://deno.land/x/tincan@1.0.1/mod.ts'; | ||
|
||
import { checkForForbiddenParameters, isValidNumber } from './parameter-checking.ts'; | ||
|
||
describe('Checking for bad object parameters', () => { | ||
type fakeNestedType = { | ||
first: string, | ||
second: number, | ||
third: boolean | ||
}; | ||
type fakeType = { | ||
first: number, | ||
second: number, | ||
third: fakeNestedType, | ||
fourth: number | ||
}; | ||
|
||
const passingInnerObject: fakeNestedType = { | ||
first: 'darkness', | ||
second: 4, | ||
third: false, | ||
}; | ||
|
||
const failingInnerObject: fakeNestedType = { | ||
first: 'darkness', | ||
second: NaN, | ||
third: true, | ||
}; | ||
|
||
const passingOuterObject: fakeType = { | ||
first: 0xA4, | ||
second: 123, | ||
third: passingInnerObject, | ||
fourth: 0b111, | ||
}; | ||
|
||
const failingOuterObject: fakeType = { | ||
first: 1, | ||
second: 2, | ||
third: failingInnerObject, | ||
fourth: 3 | ||
} | ||
|
||
it('ensure that NaN is caught when used as a parameter of type number', () => { | ||
const objTest = checkForForbiddenParameters( | ||
passingOuterObject, | ||
isValidNumber, | ||
true, | ||
); | ||
expect(objTest).toBe(true); | ||
|
||
|
||
expect( | ||
() => checkForForbiddenParameters( | ||
failingOuterObject, | ||
isValidNumber, | ||
true | ||
) | ||
).toThrow() | ||
}); | ||
}); | ||
|
||
run(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
/** | ||
* A function that can be used to test that all the parameters of an object pass | ||
* a particular test. This can be used to check that no values in an object are NaN, | ||
* or could be used to check that values are inside a particular range. | ||
* | ||
* @param objectToCheck An object whose parameters we want to validate. | ||
* | ||
* @param callback A callback function that we use to check the values of our object. | ||
* The callback will be used recursively if objectToCheck has nested values. | ||
* | ||
* @param callbackFailureValue The boolean value that will indicate a failure of the callback function. | ||
* | ||
* @returns Returns `true` if all the object's values pass the check between the callback function and | ||
* the value that determines a failure. Otherwise, throws an error. | ||
* | ||
* @todo Add a better means of validating that the values used to generate ooxml are, in fact, | ||
* constrained in the ways we think they should be. | ||
*/ | ||
|
||
export function checkForForbiddenParameters<ObjectToCheck>( | ||
objectToCheck: ObjectToCheck, | ||
callback: (object: unknown) => boolean, | ||
callbackFailureValue: boolean, | ||
): true { | ||
type propObject = { prop: string, value: unknown }; | ||
const values: propObject[] = []; | ||
// Recurse through an object and flatten it to key-value pairs. | ||
const flattenedObject = (deepObject: unknown, accumulator: propObject[]) => { | ||
if (typeof deepObject === 'object') { | ||
for (const key in deepObject) { | ||
if (typeof deepObject[key as keyof unknown] === 'object') { | ||
flattenedObject(deepObject[key as keyof unknown], accumulator); | ||
} else { | ||
accumulator.push({ prop: key, value: deepObject[key as keyof unknown] }); | ||
} | ||
} | ||
} | ||
return accumulator; | ||
}; | ||
|
||
// Iterate over an object's values until we hit one that causes the callback | ||
// function to equal the failure value. | ||
const flattenedObjectArray = flattenedObject(objectToCheck, values); | ||
flattenedObjectArray.forEach(entry => { | ||
const { prop, value } = entry; | ||
if (callback(value) === callbackFailureValue) { | ||
throw new Error( | ||
`Error when checking parameters.\nCallback for { ${prop}: ${value} } returned ${callback(value)}.`, | ||
); | ||
} | ||
}); | ||
return true; | ||
} | ||
|
||
/** | ||
* A function to check if any arbitrary property of an object is `NaN`. Intended to be used as a | ||
* possible callback for the `checkForForbiddenParameters` function in case we want to detect `NaN`. | ||
*/ | ||
export function isValidNumber(objectProperty: unknown): boolean { | ||
return typeof objectProperty === 'number' && Number.isNaN(objectProperty); | ||
} |