Skip to content

Commit d16864d

Browse files
committed
tested, fixed number checks
1 parent f49ec73 commit d16864d

File tree

3 files changed

+216
-136
lines changed

3 files changed

+216
-136
lines changed

isType.mjs.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ function is(value){
113113

114114
if(value === null)
115115
typeName = "null";
116-
else if(Number.isNaN(value))
116+
else if(Number.isNaN(value) || (value instanceof Number && Number.isNaN(value.valueOf())))
117117
typeName = "nan";
118118
else if(!["object", "function"].includes(typeofType))
119119
typeName = typeofType;
@@ -134,7 +134,7 @@ function is(value){
134134

135135
// Create type testers.
136136

137-
for(const name in TYPE_NAMES){
137+
for(const name of TYPE_NAMES){
138138
is[name] = (v)=> is(v).type === name;
139139
}
140140

@@ -148,8 +148,8 @@ is.falsy = (v)=> !v;
148148
is.truthy = (v)=> !!v;
149149

150150
is.numberish = (v)=> (is.number(v) || is.nan(v));
151-
is.real = (v)=> (is.number(v) && Number.isFinite(v));
152-
is.infinite = (v)=> (is.number(v) && !Number.isFinite(v));
151+
is.real = (v)=> (is.number(v) && Number.isFinite(v instanceof Number ? v.valueOf() : v));
152+
is.infinite = (v)=> (is.number(v) && !Number.isFinite(v instanceof Number ? v.valueOf() : v));
153153

154154

155155

test/test.htm

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,60 @@
1-
<html><head><title>isType test</title><script src="test.js" type="module"></script></head><body>
1+
<html lang="en-US">
2+
<head>
3+
<title>isType tests</title>
24

3-
View the console.
5+
<style>
6+
table {
7+
border-collapse: collapse;
8+
margin: 1.25em;
9+
}
10+
th, td {
11+
border: 1px solid #000;
12+
padding: 0.25em 0.5em;
13+
vertical-align: top;
14+
}
15+
td.fail {
16+
background-color: #FEE;
17+
}
18+
td.fail::after {
19+
content: "(expected " attr(data-expected) ")";
20+
display: block;
21+
color: #888;
22+
}
23+
</style>
424

5-
</body></html>
25+
<script src="test.js" type="module"></script>
26+
</head>
27+
<body>
28+
29+
<details><summary>Types</summary>
30+
<table>
31+
<thead>
32+
<tr>
33+
<th rowspan="2">Value</th>
34+
<th colspan="4">Type</th>
35+
</tr>
36+
<tr>
37+
<th>.type</th>
38+
<th>.typeof</th>
39+
<th>.toStringTag</th>
40+
<th>.constructorName</th>
41+
</tr>
42+
</thead>
43+
<tbody id="type_results"></tbody>
44+
</table>
45+
</details>
46+
47+
<details><summary>Type Tester Functions</summary>
48+
<table>
49+
<thead>
50+
<tr>
51+
<th>Value</th>
52+
<th>Successful Type Tester Functions</th>
53+
</tr>
54+
</thead>
55+
<tbody id="tester_results"></tbody>
56+
</table>
57+
</details>
58+
59+
</body>
60+
</html>

test/test.js

Lines changed: 154 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -1,139 +1,164 @@
1-
import is from "../isType.mjs";
1+
import is from "../isType.mjs.js";
22

33

4-
class Number2 extends Number { constructor(val){ super(val); } }
5-
class Number3 extends Number { constructor(val){ super(val); this[Symbol.toStringTag] = "Number3"; } }
6-
7-
let i;
8-
9-
console.group("is()");
10-
i = 1;
11-
12-
try{
13-
const t = is(nonExistentVar);
14-
console.assert(false, `${i++}. ${t} (should have thrown a ReferenceError)`);
15-
}catch(e){
16-
if(!(e instanceof ReferenceError))
17-
console.assert(false, `${i++}. threw a ${Object.prototype.toString.call(e).slice(8,-1)} (should have thrown a ReferenceError)`);
18-
}
19-
20-
function testIs(result, expectedType, expectedObjectType){
21-
console.assert(result.type === expectedType && result.objectType === expectedObjectType,
22-
`${i++}. ${result.type}/${result.objectType} !== ${expectedType}/${expectedObjectType}`);
23-
}
4+
function _is(value, pseudocode, _type, _typeof, _toStringTag, _constructorName){
245

25-
testIs(is({}), "object", "Object");
26-
testIs(is(new Object()), "object", "Object");
6+
const type = is(value);
277

28-
testIs(is(), "undefined");
29-
testIs(is(null), "null");
8+
const tbody = document.getElementById("type_results");
9+
const tr = document.createElement("tr");
10+
tr.innerHTML = `<td>${pseudocode}</td>`;
11+
createCell(type.type, _type);
12+
createCell(type.typeof, _typeof);
13+
createCell(type.toStringTag, _toStringTag);
14+
createCell(type.constructorName, _constructorName);
15+
tbody.appendChild(tr);
3016

31-
testIs(is(5), "number");
32-
testIs(is(new Number(5)), "number", "Number");
33-
testIs(is(1/0), "number");
34-
testIs(is(new Number(1/0)), "number", "Number");
35-
testIs(is(NaN), "number");
36-
testIs(is(new Number(NaN)), "number", "Number");
37-
testIs(is(new Number2(5)), "number", "Number");
38-
testIs(is(new Number3(5)), "number", "Number3");
39-
40-
testIs(is(BigInt(5)), "bigint");
41-
testIs(is(false), "boolean");
42-
testIs(is(new Boolean()), "boolean", "Boolean");
43-
testIs(is(""), "string");
44-
testIs(is(new String("")), "string", "String");
45-
testIs(is(Symbol()), "symbol");
46-
testIs(is(function(){}), "function", "Function");
47-
testIs(is(new Function()), "function", "Function");
48-
testIs(is(()=>{}), "function", "Function");
49-
testIs(is(function*(){}), "function", "Function");
50-
51-
testIs(is([]), "object", "Array");
52-
testIs(is(new Array()), "object", "Array");
53-
testIs(is(new Date()), "object", "Date");
54-
testIs(is(new Error()), "object", "Error");
55-
testIs(is(new ReferenceError()), "object", "Error");
56-
testIs(is(/a/), "object", "RegExp");
57-
testIs(is(new RegExp("a")), "object", "RegExp");
58-
59-
(function (){
60-
testIs(is(arguments), "object", "Arguments");
61-
})();
62-
63-
console.groupEnd();
17+
function createCell(actual, expected){
18+
const td = document.createElement("td");
19+
td.dataset.expected = expected === void 0 ? "undefined" : `"${expected}"`;
20+
td.innerHTML = actual === void 0 ? `<i>undefined</i>` : `"${actual}"`;
21+
if(actual !== expected) td.classList.add("fail");
22+
tr.appendChild(td);
23+
}
24+
}
6425

65-
console.group("is.___()");
66-
i = 1;
67-
function testIsType(result, expected){
68-
console.assert(result === expected, `${i++}. ${result} !== ${expected}`);
26+
{
27+
_is([], "[]", "array", "object", "Array", "Array");
28+
_is(new Array(), "new Array()", "array", "object", "Array", "Array");
29+
_is(5n, "5n", "bigint", "bigint");
30+
_is(true, "true", "boolean", "boolean");
31+
_is(false, "false", "boolean", "boolean");
32+
_is(new Boolean(), "new Boolean()", "boolean", "object", "Boolean", "Boolean");
33+
_is(new Date(), "new Date()", "date", "object", "Date", "Date");
34+
_is(new Error(), "new Error()", "error", "object", "Error", "Error");
35+
_is(new TypeError(), "new TypeError()", "error", "object", "Error", "TypeError");
36+
_is(()=>{}, "()=>{}", "function", "function", "Function", "Function");
37+
_is(Object, "Object", "function", "function", "Function", "Function");
38+
_is(new Map(), "new Map()", "map", "object", "Map", "Map");
39+
_is(NaN, "NaN", "nan", "number");
40+
_is(new Number(NaN), "new Number(NaN)", "nan", "object", "Number", "Number");
41+
_is(new Number('a'), "new Number('a')", "nan", "object", "Number", "Number");
42+
_is(null, "null", "null", "object");
43+
_is(5, "5", "number", "number");
44+
_is(Infinity, "Infinity", "number", "number");
45+
_is(new Number(), "new Number()", "number", "object", "Number", "Number");
46+
_is({}, "{}", "object", "object", "Object", "Object");
47+
_is(new Object(), "new Object()", "object", "object", "Object", "Object");
48+
_is(new Promise(()=>{}), "new Promise(()=>{})", "promise", "object", "Promise", "Promise");
49+
_is(/a/, "/a/", "regex", "object", "RegExp", "RegExp");
50+
_is(new RegExp(), "new RegExp()", "regex", "object", "RegExp", "RegExp");
51+
_is(new Set(), "new Set()", "set", "object", "Set", "Set");
52+
_is("", '""', "string", "string");
53+
_is("a", '"a"', "string", "string");
54+
_is(new String(), "new String()", "string", "object", "String", "String");
55+
_is(Symbol(), "Symbol()", "symbol", "symbol");
56+
_is(void 0, "void 0", "undefined", "undefined");
57+
_is(new WeakMap(), "new WeakMap()", "weakmap", "object", "WeakMap", "WeakMap");
58+
_is(new WeakSet(), "new WeakSet()", "weakset", "object", "WeakSet", "WeakSet");
59+
{
60+
class Foo {}
61+
_is(new Foo(), "<i>class Foo {}</i><br>new Foo()", "object", "object", "Object", "Foo");
6962
}
63+
{
64+
class Foo extends String {}
65+
_is(new Foo(), "<i>class Foo extends String {}</i><br>new Foo()", "string", "object", "String", "Foo");
66+
}
67+
{
68+
class Foo { get [Symbol.toStringTag](){ return "Bar"; } }
69+
_is(new Foo(), "<i>class Foo { get [Symbol.toStringTag](){ return \"Bar\"; } }</i><br>new Foo()", "object", "object", "Bar", "Foo");
70+
}
71+
}
72+
73+
74+
function _tester(value, pseudocode, _testerNames){
7075

71-
testIsType(is.undefined(), true);
72-
testIsType(is.undefined(5), false);
73-
testIsType(is.null(null), true);
74-
testIsType(is.null(5), false);
75-
76-
testIsType(is.number(5), true);
77-
testIsType(is.number(new Number()), true);
78-
testIsType(is.number(1/0), false);
79-
testIsType(is.number(NaN), false);
80-
testIsType(is.number("5"), false);
81-
testIsType(is.infinite(1/0), true);
82-
testIsType(is.infinite(new Number(1/0)), true);
83-
testIsType(is.infinite(5), false);
84-
testIsType(is.infinite(NaN), false);
85-
testIsType(is.infinite("Infinity"), false);
86-
testIsType(is.nan(NaN), true);
87-
testIsType(is.nan(new Number(NaN)), true);
88-
testIsType(is.nan(5), false);
89-
testIsType(is.nan(1/0), false);
90-
testIsType(is.nan("NaN"), false);
91-
testIsType(is.number(""), false);
92-
testIsType(is.number(new Date()), false);
93-
testIsType(is.number(1*(new Date())), true);
94-
testIsType(is.number(new Number2()), true);
95-
testIsType(is.number(new Number3()), true);
96-
97-
testIsType(is.bigint(5n), true);
98-
testIsType(is.bigint(BigInt(5)), true);
99-
testIsType(is.bigint(5), false);
100-
testIsType(is.boolean(false), true);
101-
testIsType(is.boolean(true), true);
102-
testIsType(is.boolean(5), false);
103-
testIsType(is.string(""), true);
104-
testIsType(is.string(new String()), true);
105-
testIsType(is.string(5), false);
106-
testIsType(is.symbol(Symbol.toStringTag), true);
107-
testIsType(is.symbol(Symbol()), true);
108-
testIsType(is.symbol(5), false);
109-
testIsType(is.function(function(){}), true);
110-
testIsType(is.function(new Function()), true);
111-
testIsType(is.function(()=>{}), true);
112-
testIsType(is.function(function*(){}), true);
113-
testIsType(is.function(5), false);
114-
115-
testIsType(is.array([]), true);
116-
testIsType(is.array(new Array()), true);
117-
(function (){
118-
testIsType(is.array(arguments), false);
119-
})();
120-
testIsType(is.date(new Date()), true);
121-
testIsType(is.date(1*(new Date())), false);
122-
testIsType(is.error(new Error()), true);
123-
testIsType(is.error(new ReferenceError()), true);
124-
testIsType(is.regexp(/a/), true);
125-
testIsType(is.regexp(new RegExp("a")), true);
76+
const testers = [
77+
"array",
78+
"bigint",
79+
"boolean",
80+
"date",
81+
"defined",
82+
"error",
83+
"falsy",
84+
"function",
85+
"infinite",
86+
"map",
87+
"nan",
88+
"null",
89+
"nullish",
90+
"number",
91+
"numberish",
92+
"object",
93+
"primitive",
94+
"promise",
95+
"real",
96+
"regex",
97+
"set",
98+
"string",
99+
"symbol",
100+
"truthy",
101+
"undefined",
102+
"weakmap",
103+
"weakset",
104+
];
126105

127-
testIsType(is.object({}), true);
128-
testIsType(is.object(5), false);
129-
testIsType(is.object(new Number()), true);
130-
testIsType(is.object(function(){}), true);
131-
testIsType(is.object([]), true);
132-
testIsType(is.primitive(), true);
133-
testIsType(is.primitive(5), true);
134-
testIsType(is.primitive(new Number()), false);
135-
testIsType(is.primitive(NaN), true);
136-
testIsType(is.primitive(new Number(NaN)), false);
137-
testIsType(is.primitive([]), false);
106+
const tbody = document.getElementById("tester_results");
107+
const tr = document.createElement("tr");
108+
tr.innerHTML = `<td>${pseudocode}</td>`;
109+
const matches = [];
110+
for(const tester of testers){
111+
const match = is[tester](value);
112+
if(match) matches.push(tester);
113+
}
114+
createCell(matches.join(", "), _testerNames.sort().join(", "));
115+
tbody.appendChild(tr);
138116

139-
console.groupEnd();
117+
function createCell(actual, expected){
118+
const td = document.createElement("td");
119+
td.dataset.expected = expected;
120+
td.innerHTML = actual;
121+
if(actual !== expected) td.classList.add("fail");
122+
tr.appendChild(td);
123+
}
124+
}
125+
126+
{
127+
_tester([], "[]", ["array", "object", "defined", "truthy"]);
128+
_tester(new Array(), "new Array()", ["array", "object", "defined", "truthy"]);
129+
_tester(5n, "5n", ["bigint", "primitive", "defined", "truthy"]);
130+
_tester(0n, "0n", ["bigint", "primitive", "defined", "falsy"]);
131+
_tester(true, "true", ["boolean", "primitive", "defined", "truthy"]);
132+
_tester(false, "false", ["boolean", "primitive", "defined", "falsy"]);
133+
_tester(new Boolean(), "new Boolean()", ["boolean", "object", "defined", "truthy"]);
134+
_tester(new Date(), "new Date()", ["date", "object", "defined", "truthy"]);
135+
_tester(new Error(), "new Error()", ["error", "object", "defined", "truthy"]);
136+
_tester(new TypeError(), "new TypeError()", ["error", "object", "defined", "truthy"]);
137+
_tester(()=>{}, "()=>{}", ["function", "object", "defined", "truthy"]);
138+
_tester(Object, "Object", ["function", "object", "defined", "truthy"]);
139+
_tester(new Map(), "new Map()", ["map", "object", "defined", "truthy"]);
140+
_tester(NaN, "NaN", ["nan", "numberish", "primitive", "defined", "falsy"]);
141+
_tester(new Number(NaN), "new Number(NaN)", ["nan", "numberish", "object", "defined", "truthy"]);
142+
_tester(new Number('a'), "new Number('a')", ["nan", "numberish", "object", "defined", "truthy"]);
143+
_tester(null, "null", ["null", "nullish", "primitive", "defined", "falsy"]);
144+
_tester(5, "5", ["number", "numberish", "real", "primitive", "defined", "truthy"]);
145+
_tester(0, "0", ["number", "numberish", "real", "primitive", "defined", "falsy"]);
146+
_tester(-0, "-0", ["number", "numberish", "real", "primitive", "defined", "falsy"]);
147+
_tester(Infinity, "Infinity", ["number", "infinite", "numberish", "primitive", "defined", "truthy"]);
148+
_tester(new Number(5), "new Number(5)", ["number", "numberish", "real", "object", "defined", "truthy"]);
149+
_tester(new Number(0), "new Number(0)", ["number", "numberish", "real", "object", "defined", "truthy"]);
150+
_tester({}, "{}", ["object", "defined", "truthy"]);
151+
_tester(new Object(), "new Object()", ["object", "defined", "truthy"]);
152+
_tester(new Promise(()=>{}), "new Promise(()=>{})", ["promise", "object", "defined", "truthy"]);
153+
_tester(/a/, "/a/", ["regex", "object", "defined", "truthy"]);
154+
_tester(new RegExp(), "new RegExp()", ["regex", "object", "defined", "truthy"]);
155+
_tester(new Set(), "new Set()", ["set", "object", "defined", "truthy"]);
156+
_tester("", '""', ["string", "primitive", "defined", "falsy"]);
157+
_tester("a", '"a"', ["string", "primitive", "defined", "truthy"]);
158+
_tester(new String(), "new String()", ["string", "object", "defined", "truthy"]);
159+
_tester(Symbol(), "Symbol()", ["symbol", "primitive", "defined", "truthy"]);
160+
_tester(void 0, "void 0", ["undefined", "nullish", "primitive", "falsy"]);
161+
_tester(new WeakMap(), "new WeakMap()", ["weakmap", "object", "defined", "truthy"]);
162+
_tester(new WeakSet(), "new WeakSet()", ["weakset", "object", "defined", "truthy"]);
163+
_tester(document.all, "document.all", ["object", "nullish", "undefined", "falsy"]);
164+
}

0 commit comments

Comments
 (0)