0.5.0 add type casting support and bumbed version

master
David Kebler 2020-03-16 10:24:22 -07:00
parent 0c648f57d8
commit 530d1490b9
8 changed files with 261 additions and 11 deletions

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
/node_modules/
/coverage/
*.lock

View File

@ -1,8 +1,8 @@
{
"name": "@uci-utils/type",
"version": "0.2.3",
"description": "A variable type check utility - extentsion of TypeChecker package",
"main": "src/type.js",
"version": "0.5.0",
"description": "A variable type check and casting utility - extension of typechecker package plus type casting",
"main": "src/",
"scripts": {
"test": "./node_modules/.bin/mocha -r esm --timeout 30000",
"testd": "UCI_ENV=dev ./node_modules/.bin/nodemon --exec './node_modules/.bin/mocha -r esm --timeout 30000' || exit 0",
@ -19,6 +19,8 @@
"keywords": [
"node.js",
"type",
"typecast",
"cast",
"typeof",
"typechecker",
"variables"
@ -28,12 +30,13 @@
},
"homepage": "https://github.com/uCOMmandIt/uci-utils#readme",
"dependencies": {
"typechecker": "^5.0.0"
"@uci-utils/to-boolean": "^0.1.5",
"typechecker": "^6.3.0"
},
"devDependencies": {
"chai": "^4.2.0",
"esm": "^3.2.25",
"mocha": "^6.2.2",
"nodemon": "^1.19.4"
"mocha": "^7.1.0",
"nodemon": "^2.0.2"
}
}

View File

@ -1,3 +1,29 @@
### uCOMmandIt Type Library
Extension of TypeChecker Package
Extends the type checker Library
All includes some simple type casting including using uci to-boolean for boolean type casting.
See type checker api http://master.typechecker.bevry.surge.sh/docs/
exentions are
`.isPromise`
`.isBuffer`
TODO add
import isObservable from 'is-observable'
import isPromise from 'p-is-promise'
```
function isEmitter(emitter) {
if (!emitter) return false
let check = ['on','emit']
return check.reduce((acc,fn)=> acc && typeof emitter[fn] ==='function',true)
}
function isAsync(fn) {
if (typeof fn !== 'function') return false
return (isPromise(fn) || fn.constructor.name === 'AsyncFunction')
}
```

93
src/cast.js Normal file
View File

@ -0,0 +1,93 @@
import { toBoolean } from '@uci-utils/to-boolean'
// adapted from "https://github.com/eivindfjeldstad/const git"
/**
* Cast `val` to `String`
*
* @param {Mixed} val
* @api public
*/
const toString = function (val) {
if (null == val) return ''
return val.toString()
}
/**
* Cast `val` to `Number`
*
* @param {Mixed} val
* @api public
*/
const toNumber = function (val) {
var num = parseFloat(val)
return isNaN(num)
? 0
: num
}
/**
* Cast `val` to a`Date`
*
* @param {Mixed} val
* @api public
*/
const toDate = function () {
var date = new Date(...arguments)
return isNaN(date.getTime())
? new Date(0)
: date
}
/**
* Cast `val` to `Array`
*
* @param {Mixed} val
* @api public
*/
const toArray = function (val) {
if (val == null) return []
if (val instanceof Array) return val
if (typeof val != 'string') return [val]
var arr = val.split(',')
for (var i = 0; i < arr.length; i++) {
arr[i] = arr[i].trim()
}
return arr
}
/**
* Cast given `val` to `type`
*
* @param {Mixed} val
* @param {String} type
* @api public
*/
const typecast={string:toString,number:toNumber,date:toDate,boolean:toBoolean,array:toArray}
function cast (val, type) {
var fn = typecast[type]
if (typeof fn != 'function') throw new Error('cannot cast to ' + type)
return fn(val)
}
export { cast, typecast, toBoolean, toArray, toDate, toNumber, toString }
// TODO support registering alternative casting functions with a register function
/**
* Cast `val` to `Boolean`
*
* @param {Mixed} val
* @api public
*/
// const toBoolean = function (val) {
// return !! val && val !== 'false' && val !== '0'
// }

View File

@ -1,5 +1,7 @@
import * as typechecker from 'typechecker'
// TODO add observable types and other custom uci types
const customTypeChecker = Object.assign({}, typechecker) // typechecker is frozen
// add custom types
@ -24,4 +26,4 @@ customTypeChecker.getType = function customGetType(value, _typeMap) {
}
export default customTypeChecker
export { customTypeChecker as type }
export { customTypeChecker as check }

6
src/index.js Normal file
View File

@ -0,0 +1,6 @@
// import { cast, typecast, } from './cast'
import check from './check'
export * from './cast'
export { check } from './check'
export default check // default is just the typechecker only

119
test/cast.test.js Normal file
View File

@ -0,0 +1,119 @@
import assert from 'assert'
import { check, typecast, cast, toString, toBoolean } from '../src'
console.log(typecast.boolean)
console.log(toBoolean)
describe('.string()', function () {
it('should return a string', function () {
assert(typecast.string(2) === '2')
assert(check.isString(typecast.string(2)))
})
it('should return an empty string when given a null-ish value', function () {
assert(typecast.string(null) === '')
assert(typecast.string(undefined) === '')
})
it('should support toString', function () {
assert(toString(2) === '2')
assert(check.isString(toString(2)))
})
})
describe('.number()', function () {
it('should return a number', function () {
assert(typecast.number('123') === 123)
})
it('should return 0 if typecasting fails', function () {
assert(typecast.number('abc') === 0)
})
it('should return an 0 when given a null-ish value', function () {
assert(typecast.number(null) === 0)
assert(typecast.number(undefined) === 0)
})
})
const adate = [1995, 11, 17, 3, 24, 0]
const sdate = 'December 17, 1995 03:24:00'
describe('.date()', function () {
it('should return a date from a string', function () {
assert(typecast.date(sdate).getTime() === 819199440000)
})
it('should return a date from an array of values', function () {
assert(typecast.date(...adate).getTime() === 819199440000)
})
it('should return default date if typecasting fails', function () {
assert(typecast.date('abc') instanceof Date)
assert(typecast.date('abc').valueOf() == 0)
})
it('should return default date when given a null-ish value', function () {
assert(typecast.date(null) instanceof Date)
assert(typecast.date(null).valueOf() == 0)
assert(typecast.date(undefined) instanceof Date)
assert(typecast.date(undefined).valueOf() == 0)
})
})
describe('.array()', function () {
it('should return an array', function () {
var arr = [1, 2, 3]
assert(typecast.array(arr) === arr)
assert(typecast.array(1) instanceof Array)
assert(typecast.array('a, b, c').length == 3)
assert(typecast.array('a, b, c')[1] === 'b')
})
it('should preserve non-string objects', function () {
var now = new Date()
assert(Array.isArray(typecast.array(now)))
assert(typecast.array(now).length == 1)
assert(typecast.array(now)[0] === now)
})
it('should return an empty array when given a null-ish value', function () {
assert(Array.isArray(typecast.array(null)))
assert(typecast.array(null).length == 0)
assert(Array.isArray(typecast.array(undefined)))
assert(typecast.array(undefined).length == 0)
})
})
describe('.boolean()', function () {
it('should be using UCI to-boolean', function () {
assert(typecast.boolean('true') === true)
assert(typecast.boolean('nope') === false)
assert(typecast.boolean('sure') === true)
assert(typecast.boolean('bogus') === false)
assert(typecast.boolean() === false) // undefined is false
assert(typecast.boolean(-1) === false)
assert(typecast.boolean(4) === true)
})
})
describe('generic cast function', function () {
it('should work', function () {
assert(cast(123, 'string') === '123')
})
it('should throw when given an invalid type', function () {
var err
try {
typecast(1, 'invalid')
} catch (e) {
err = e
}
assert(err)
})
})

View File

@ -1,7 +1,7 @@
import { expect } from 'chai'
import u from '../src/type'
import u from '../src'
describe('Variable Types Library - ', function () {
describe('Type Check Library - ', function () {
it('Should include custom types', function () {
expect(u.isBuffer(Buffer.from('this is a test'))).to.equal(true)
@ -10,7 +10,7 @@ describe('Variable Types Library - ', function () {
expect(u.getType(Promise.resolve(2))).to.equal('promise')
})
it('Should load typechecker', function () {
it('Should include typechecker methods', function () {
expect(u.isPlainObject([1])).to.equal(false)
expect(u.getType(true)).to.equal('boolean')
expect(u.getObjectType('a string')).to.equal('[object String]')