Skip to content

Commit 7aef403

Browse files
committed
test generates HTML table
1 parent 4eb87da commit 7aef403

File tree

3 files changed

+114
-183
lines changed

3 files changed

+114
-183
lines changed

isType.mjs.js

Lines changed: 9 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -23,39 +23,6 @@ const TYPES = {
2323
weakset: { class: WeakSet },
2424
};
2525

26-
const PROPERTY_NAMES = [
27-
"array",
28-
"bigint",
29-
"boolean",
30-
"date",
31-
"defined",
32-
"empty",
33-
"error",
34-
"falsy",
35-
"function",
36-
"infinite",
37-
"map",
38-
"nan",
39-
"nonempty",
40-
"null",
41-
"nullish",
42-
"number",
43-
"numberish",
44-
"object",
45-
"objectish",
46-
"primitive",
47-
"promise",
48-
"real",
49-
"regex",
50-
"set",
51-
"string",
52-
"symbol",
53-
"truthy",
54-
"undefined",
55-
"weakmap",
56-
"weakset"
57-
];
58-
5926
/**
6027
* A collection of boolean properties set according to the type, and sometimes value, of the argument.
6128
* @class TypeTest
@@ -128,6 +95,9 @@ class TypeTest {
12895
this.empty = value.size === 0;
12996
this.nonempty = !this.empty;
13097
}
98+
else{
99+
this.empty = this.nonempty = void 0;
100+
}
131101
}
132102

133103
toString(){
@@ -138,10 +108,11 @@ class TypeTest {
138108
class Is extends TypeTest {
139109

140110
constructor(value){
141-
142111
super(value);
143-
144-
this.type = this.toString();
112+
}
113+
114+
get type(){
115+
return this.toString();
145116
}
146117

147118
all(...propNames){
@@ -163,8 +134,8 @@ function is(value){
163134
return new Is(value);
164135
}
165136

166-
PROPERTY_NAMES.forEach((propName)=>{
137+
for(const propName in new TypeTest()){
167138
is[propName] = propName;
168-
});
139+
}
169140

170141
export { is as default };

test/test.htm

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,20 @@
2020
display: block;
2121
color: #888;
2222
}
23+
24+
#types th {
25+
position: relative;
26+
padding: 0 1.25em;
27+
border: none;
28+
}
29+
#types th div {
30+
position: absolute;
31+
transform-origin: top left;
32+
transform: rotate(-60deg);
33+
left: calc(50% - 1.25em* cos(30deg));
34+
line-height: 1.25;
35+
top: calc(-1em* sin(30deg));
36+
}
2337
</style>
2438

2539
<script src="test.js" type="module"></script>

test/test.js

Lines changed: 91 additions & 145 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,104 @@
11
import is from "../isType.mjs.js";
22

3+
let testResults = [];
34

4-
function _is(value, pseudocodeHTML, expectedType, expectedIsObject){
5+
{
6+
_is(()=>(void 0), is.undefined, is.primitive, is.nullish, is.falsy);
7+
_is(()=>(new Number(Infinity)), is.number, is.defined, is.object, is.objectish, is.truthy, is.infinite, is.numberish);
8+
}
9+
10+
document.addEventListener("DOMContentLoaded", ()=>{document.body.innerHTML += createTable()});
11+
12+
/**
13+
* Perform a test and add the result details to the `testResults` array.
14+
*
15+
* @param {function} fn - An arrow function returning the value to be tested. The function body is saved as a string for later use.
16+
* @param {string} type - The expected type of the test value.
17+
* @param {...string} [trues] - Names of all additional properties of the test result that are expected to evaluate as `true`.
18+
*/
19+
function _is(fn, type, ...trues){
520

6-
const actualType = is(value);
7-
//console.log(actualType);
21+
trues.unshift(type);
22+
const code = fn.toString().slice(5,-1);
23+
const value = fn();
24+
const test = is(value);
825

9-
const tbody = document.getElementById("type_results");
10-
const tr = document.createElement("tr");
11-
tr.innerHTML = `<td>${pseudocodeHTML}</td>`;
12-
createCell(actualType, expectedType);
13-
tbody.appendChild(tr);
14-
createCell(actualType.object, expectedIsObject);
15-
tbody.appendChild(tr);
26+
const testResult = {
27+
code: code,
28+
type: {
29+
expected: type,
30+
actual: test.type
31+
},
32+
properties: {},
33+
};
1634

17-
let props = "";
18-
for(const name in actualType){
19-
if(actualType[name]) props += `, ${name}`;
35+
for(const propName in is){
36+
37+
const expected = trues.includes(propName);
38+
const actual = test[propName];
39+
40+
testResult.properties[propName] = {
41+
expected: expected,
42+
actual: actual
43+
};
2044
}
21-
tr.innerHTML += `<td>${props.slice(2)}</td>`;
2245

23-
function createCell(actual, expected){
24-
const td = document.createElement("td");
25-
td.dataset.expected = expected === void 0 ? "undefined" : expected;
26-
td.innerHTML = actual === void 0 ? `<i>undefined</i>` : actual.toString() === "" ? `<i>empty string</i>` : actual;
27-
if(actual != expected) td.classList.add("fail");
28-
tr.appendChild(td);
46+
testResults.push(testResult);
47+
}
48+
49+
/**
50+
* Create a table to show the results.
51+
*/
52+
function createTable(){
53+
54+
let rows = "";
55+
for(const result of testResults){
56+
rows += createRow(result);
57+
}
58+
59+
let header = "<th></th><th><div>type</div></th>";
60+
for(const propName in is){
61+
header += `<th><div>${propName}</div></th>`;
2962
}
63+
64+
return `<table id="types"><thead><tr>${header}</tr></thead><tbody>${rows}</tbody></table>`;
3065
}
3166

32-
{
67+
/**
68+
* Generate a row for the results table.
69+
*
70+
* @param {Object} result - An item in the `testResults` array.
71+
*/
72+
function createRow(result){
73+
74+
let typeMatch = result.type.expected !== result.type.actual;
75+
76+
let code = result.code.replace("&","&amp;").replace("<","&lt;").replace(">","&gt;").replace("\"","&quot;");
77+
78+
let cells = `<td>${code}</td><td ${!typeMatch ? 'class="error"' : ""}>${result.type.actual}`;
79+
if(typeMatch) cells += ` (expected ${result.type.expected})`;
80+
cells += `</td>`;
81+
82+
for(const prop in result.properties){
83+
cells += createCell(result.properties[prop].expected, result.properties[prop].actual);
84+
}
85+
86+
return `<tr>${cells}</tr>`;
87+
}
88+
89+
/**
90+
* Generate a cell for the results table.
91+
*
92+
* @param {boolean} expected
93+
* @param {boolean} actual
94+
*/
95+
function createCell(expected, actual){
96+
97+
if(!(expected || actual)) return `<td></td>`;
98+
return `<td class="${expected === actual ? "match" : "error"}">${expected ? "✔️" : "✖️"}</td>`;
99+
}
100+
101+
/*{
33102
_is([], "[]", "array", true);
34103
_is(new Array(), "new Array()", "array", true);
35104
_is([1,2], "[1,2]", "array", true);
@@ -76,127 +145,4 @@ function _is(value, pseudocodeHTML, expectedType, expectedIsObject){
76145
class Foo { get [Symbol.toStringTag](){ return "Bar"; } }
77146
_is(new Foo(), "<i>class Foo { get [Symbol.toStringTag](){ return \"Bar\"; } }</i><br>new Foo()", "object", true);
78147
}
79-
}
80-
81-
/*
82-
function _tester(value, pseudocode, _testerNames){
83-
84-
const testers = [
85-
"array",
86-
"bigint",
87-
"boolean",
88-
"date",
89-
"defined",
90-
"error",
91-
"falsy",
92-
"function",
93-
"infinite",
94-
"map",
95-
"nan",
96-
"null",
97-
"nullish",
98-
"number",
99-
"numberish",
100-
"object",
101-
"primitive",
102-
"promise",
103-
"real",
104-
"regex",
105-
"set",
106-
"string",
107-
"symbol",
108-
"truthy",
109-
"undefined",
110-
"weakmap",
111-
"weakset",
112-
];
113-
114-
const tbody = document.getElementById("tester_results");
115-
const tr = document.createElement("tr");
116-
tr.innerHTML = `<td>${pseudocode}</td>`;
117-
const matches = [];
118-
for(const tester of testers){
119-
const match = is[tester](value);
120-
if(match) matches.push(tester);
121-
}
122-
createCell(matches.join(", "), _testerNames.sort().join(", "));
123-
tbody.appendChild(tr);
124-
125-
function createCell(actual, expected){
126-
const td = document.createElement("td");
127-
td.dataset.expected = expected;
128-
td.innerHTML = actual;
129-
if(actual !== expected) td.classList.add("fail");
130-
tr.appendChild(td);
131-
}
132-
}
133-
134-
{
135-
_tester([], "[]", ["array", "object", "defined", "truthy"]);
136-
_tester(new Array(), "new Array()", ["array", "object", "defined", "truthy"]);
137-
_tester(5n, "5n", ["bigint", "primitive", "defined", "truthy"]);
138-
_tester(0n, "0n", ["bigint", "primitive", "defined", "falsy"]);
139-
_tester(true, "true", ["boolean", "primitive", "defined", "truthy"]);
140-
_tester(false, "false", ["boolean", "primitive", "defined", "falsy"]);
141-
_tester(new Boolean(), "new Boolean()", ["boolean", "object", "defined", "truthy"]);
142-
_tester(new Date(), "new Date()", ["date", "object", "defined", "truthy"]);
143-
_tester(new Error(), "new Error()", ["error", "object", "defined", "truthy"]);
144-
_tester(new TypeError(), "new TypeError()", ["error", "object", "defined", "truthy"]);
145-
_tester(()=>{}, "()=>{}", ["function", "object", "defined", "truthy"]);
146-
_tester(Object, "Object", ["function", "object", "defined", "truthy"]);
147-
_tester(new Map(), "new Map()", ["map", "object", "defined", "truthy"]);
148-
_tester(NaN, "NaN", ["nan", "numberish", "primitive", "defined", "falsy"]);
149-
_tester(new Number(NaN), "new Number(NaN)", ["nan", "numberish", "object", "defined", "truthy"]);
150-
_tester(new Number('a'), "new Number('a')", ["nan", "numberish", "object", "defined", "truthy"]);
151-
_tester(null, "null", ["null", "nullish", "primitive", "defined", "falsy"]);
152-
_tester(5, "5", ["number", "numberish", "real", "primitive", "defined", "truthy"]);
153-
_tester(0, "0", ["number", "numberish", "real", "primitive", "defined", "falsy"]);
154-
_tester(-0, "-0", ["number", "numberish", "real", "primitive", "defined", "falsy"]);
155-
_tester(Infinity, "Infinity", ["number", "infinite", "numberish", "primitive", "defined", "truthy"]);
156-
_tester(new Number(5), "new Number(5)", ["number", "numberish", "real", "object", "defined", "truthy"]);
157-
_tester(new Number(0), "new Number(0)", ["number", "numberish", "real", "object", "defined", "truthy"]);
158-
_tester({}, "{}", ["object", "defined", "truthy"]);
159-
_tester(new Object(), "new Object()", ["object", "defined", "truthy"]);
160-
_tester(new Promise(()=>{}), "new Promise(()=>{})", ["promise", "object", "defined", "truthy"]);
161-
_tester(/a/, "/a/", ["regex", "object", "defined", "truthy"]);
162-
_tester(new RegExp(), "new RegExp()", ["regex", "object", "defined", "truthy"]);
163-
_tester(new Set(), "new Set()", ["set", "object", "defined", "truthy"]);
164-
_tester("", '""', ["string", "primitive", "defined", "falsy"]);
165-
_tester("a", '"a"', ["string", "primitive", "defined", "truthy"]);
166-
_tester(new String(), "new String()", ["string", "object", "defined", "truthy"]);
167-
_tester(Symbol(), "Symbol()", ["symbol", "primitive", "defined", "truthy"]);
168-
_tester(void 0, "void 0", ["undefined", "nullish", "primitive", "falsy"]);
169-
_tester(new WeakMap(), "new WeakMap()", ["weakmap", "object", "defined", "truthy"]);
170-
_tester(new WeakSet(), "new WeakSet()", ["weakset", "object", "defined", "truthy"]);
171-
_tester(document.all, "document.all", ["object", "nullish", "undefined", "falsy"]);
172-
}
173-
174-
175-
function _more(test, pseudocode, _result){
176-
177-
const tbody = document.getElementById("additional_results");
178-
const tr = document.createElement("tr");
179-
tr.innerHTML = `<td>${pseudocode}</td>`;
180-
createCell(test, _result);
181-
tbody.appendChild(tr);
182-
183-
function createCell(actual, expected){
184-
const td = document.createElement("td");
185-
td.dataset.expected = expected;
186-
td.innerHTML = actual;
187-
if(actual !== expected) td.classList.add("fail");
188-
tr.appendChild(td);
189-
}
190-
}
191-
192-
{
193-
_more(is.empty(""), 'is.empty("")', true);
194-
_more(is.empty("a"), 'is.empty("a")', false);
195-
_more(is.empty([]), "is.empty([])", true);
196-
_more(is.empty([5]), "is.empty([5])", false);
197-
_more(is.empty(new Map()), "is.empty(new Map())", true);
198-
_more(is.empty(new Map([[1, "one"]])), 'is.empty(new Map([[1, "one"]]))', false);
199-
_more(is.of(5, Number), "is.of(5, Number)", false);
200-
_more(is.of(new Number(5), Number), "is.of(new Number(5), Number)", true);
201-
}
202-
*/
148+
}*/

0 commit comments

Comments
 (0)