Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 082cb761c0 | |||
| 0968085084 | |||
| a629482a20 | |||
| c818e56f3e | |||
| 41e794b35d | |||
| 1a3faad442 | |||
| f9d771f079 | |||
| df94f864cf | |||
| 2f9333da54 |
28
.github/workflows/ci.yml
vendored
Normal file
28
.github/workflows/ci.yml
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
name: JavaScriptUtilsVitest
|
||||
run-name: ${{ github.actor}} runs vitest checks
|
||||
|
||||
# on:
|
||||
# push:
|
||||
# branches:
|
||||
# - main
|
||||
# pull_request:
|
||||
# branches:
|
||||
# - main
|
||||
# - staging
|
||||
# - development
|
||||
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
ci-tests:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 23
|
||||
- name: Run `npm install`
|
||||
run: |
|
||||
npm install
|
||||
- name: Run vitest and report issues
|
||||
run: npm run test:run
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1 +1,2 @@
|
||||
node_modules/
|
||||
coverage/*
|
||||
|
||||
13
ReadMe.md
13
ReadMe.md
@@ -141,6 +141,18 @@ vitest is used for all usage tests
|
||||
npx vitest
|
||||
```
|
||||
|
||||
for one stop tests
|
||||
|
||||
```sh
|
||||
npm run test:run
|
||||
```
|
||||
|
||||
To show the full coverate (of all files)
|
||||
|
||||
```sh
|
||||
npm run test:coverage
|
||||
```
|
||||
|
||||
Currently covered:
|
||||
|
||||
- FormatBytes
|
||||
@@ -149,6 +161,7 @@ Currently covered:
|
||||
- UniqIdGenerators (Part)
|
||||
- UrlParser
|
||||
- JavaScriptHelpers
|
||||
- HtmlElementCreator
|
||||
|
||||
TODO:
|
||||
|
||||
|
||||
@@ -4,12 +4,17 @@
|
||||
<script type="text/javascript" src="js/general/jquery.min.js"></script>
|
||||
<!-- <script type="text/javascript" src="js/general/translateTest-ja_JP.UTF-8.js"></script> -->
|
||||
<script type="text/javascript" src="js/output/utils.min.js"></script>
|
||||
<!-- <script type="text/javascript" src="js/output/utils.js"></script> -->
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
<h1>JavaScript Utils Test</h1>
|
||||
<div id="test-div">
|
||||
</div>
|
||||
<div><hr></div>
|
||||
<div id="build-test">
|
||||
</div>
|
||||
<div><hr></div>
|
||||
</div>
|
||||
</body>
|
||||
<script languagae="JavaScript">
|
||||
@@ -17,6 +22,7 @@
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
console.log('JavaScript Utils Test');
|
||||
let el = document.getElementById('test-div');
|
||||
let build_test = document.getElementById('build-test');
|
||||
if (el === null) {
|
||||
throw new Error("element test-div not found");
|
||||
}
|
||||
@@ -30,6 +36,27 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
el.innerHTML += '<div>formatBytes: ' + formatBytes(bytes) + '</div>';
|
||||
el.innerHTML += '<div>formatBytesLong: ' + formatBytesLong(bytes) + '</div>';
|
||||
|
||||
let cel_test = cel('div', 'sample-id', 'Some text', ['css-sample']);
|
||||
el.innerHTML += '<div>cel: ' + JSON.stringify(cel_test) + '</div>';
|
||||
let cel_out = phfo(cel_test);
|
||||
console.log('CEL OUT: %o', cel_out);
|
||||
build_test.innerHTML = cel_out;
|
||||
//
|
||||
let aelx_test = aelx(
|
||||
cel('div', 'container-id', '', ['container-css']),
|
||||
cel('div', 'entry-a-id', 'Entry block: A'),
|
||||
cel('div', 'entry-b-id', 'Entry block: B')
|
||||
);
|
||||
el.innerHTML += '<div>aelx: ' + JSON.stringify(aelx_test) + '</div>';
|
||||
let aelx_out = phfo(aelx_test);
|
||||
console.log('AELX OUT: %o', aelx_out);
|
||||
build_test.innerHTML += aelx_out;
|
||||
|
||||
// console.log("TEST URL: %o", parseQueryString("http://foor.org/?key=value"));
|
||||
console.log("TEST URL: %o", getQueryStringParam('', "http://foor.org/?param=foo¶m=other", true));
|
||||
console.log("TEST URL: %o", parseQueryString("http://foor.org/?param=foo¶m=other", ''));
|
||||
// console.log("TEST URL: %o", getQueryStringParam('', "http://foor.org/?key=value&key=other&key=value&bar="));
|
||||
|
||||
// console.log('TR: %s', l10n.__('Original'));
|
||||
// console.log('TR: %s', l10n.__('Not exists'));
|
||||
});
|
||||
|
||||
1456
package-lock.json
generated
1456
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -4,11 +4,13 @@
|
||||
"main": "",
|
||||
"scripts": {
|
||||
"test": "vitest",
|
||||
"coverage": "vitest run --coverage",
|
||||
"test:run": "vitest run",
|
||||
"test:coverage": "vitest run --coverage",
|
||||
"utils-min-build": "node_modules/esbuild/bin/esbuild utils.min=src/utils.mjs --outdir=build/js/output/ --format=esm --bundle --charset=utf8 --tree-shaking=false --minify-whitespace --minify-syntax --sourcemap",
|
||||
"utils-build": "node_modules/esbuild/bin/esbuild utils=src/utils.mjs --outdir=build/js/output/ --format=esm --bundle --charset=utf8 --tree-shaking=false",
|
||||
"utils-build-all": "npm run utils-min-build && npm run utils-build",
|
||||
"utils-develop": "node_modules/esbuild/bin/esbuild utils=src/utils.mjs --outdir=build/js/output/ --format=esm --bundle --charset=utf8 --tree-shaking=false --watch"
|
||||
"utils-develop": "node_modules/esbuild/bin/esbuild utils=src/utils.mjs --outdir=build/js/output/ --format=esm --bundle --charset=utf8 --tree-shaking=false --watch",
|
||||
"utils-min-develop": "node_modules/esbuild/bin/esbuild utils.min=src/utils.mjs --outdir=build/js/output/ --format=esm --bundle --charset=utf8 --tree-shaking=false --minify-whitespace --minify-syntax --sourcemap --watch"
|
||||
},
|
||||
"author": "Clemens Schwaighofer",
|
||||
"license": "",
|
||||
@@ -16,9 +18,11 @@
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.20.0",
|
||||
"@types/jquery": "^3.5.32",
|
||||
"@vitest/coverage-v8": "^3.0.8",
|
||||
"esbuild": "^0.25.0",
|
||||
"eslint": "^9.20.1",
|
||||
"globals": "^15.15.0",
|
||||
"jsdom": "^26.0.0",
|
||||
"vitest": "^3.0.8"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,7 +197,7 @@ function roundPrecision(number, prec) // eslint-disable-line no-unused-vars
|
||||
// @ts-ignore
|
||||
function formatString(string, ...args) // eslint-disable-line no-unused-vars
|
||||
{
|
||||
return _formatString(string, args);
|
||||
return _formatString(string, ...args);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -775,7 +775,7 @@ function ael(base, attach, id = '') // eslint-disable-line no-unused-vars
|
||||
// @ts-ignore
|
||||
function aelx(base, ...attach) // eslint-disable-line no-unused-vars
|
||||
{
|
||||
return hec.aelx(base, attach);
|
||||
return hec.aelx(base, ...attach);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,7 +5,7 @@ Creator: Clemens Schwaighofer
|
||||
*/
|
||||
|
||||
export { ActionBox };
|
||||
import { keyInObject, getObjectCount } from './JavaScriptHelpers.mjs';
|
||||
import { objectKeyExists, getObjectCount } from './JavaScriptHelpers.mjs';
|
||||
import { exists } from './DomHelpers.mjs';
|
||||
import { setCenter, getWindowSize } from './ResizingAndMove.mjs';
|
||||
|
||||
@@ -155,7 +155,7 @@ class ActionBox {
|
||||
}
|
||||
// adjust zIndex so its above all other and set action box zindex +1
|
||||
$('#overlayBox').show();
|
||||
if (!keyInObject(target_id, this.zIndex.boxes)) {
|
||||
if (!objectKeyExists(this.zIndex.boxes, target_id)) {
|
||||
this.zIndex.boxes[target_id] = this.zIndex.max;
|
||||
// increase by ten
|
||||
this.zIndex.max += 10;
|
||||
@@ -197,7 +197,7 @@ class ActionBox {
|
||||
}
|
||||
// clear storage object
|
||||
if (
|
||||
keyInObject(target_id, this.action_box_storage) && clean === true
|
||||
objectKeyExists(this.action_box_storage, target_id) && clean === true
|
||||
) {
|
||||
this.action_box_storage[target_id] = {};
|
||||
}
|
||||
@@ -249,18 +249,18 @@ class ActionBox {
|
||||
settings = {},
|
||||
show_close = true
|
||||
) {
|
||||
if (!keyInObject(target_id, this.action_box_storage)) {
|
||||
if (!objectKeyExists(this.action_box_storage, target_id)) {
|
||||
this.action_box_storage[target_id] = {};
|
||||
}
|
||||
// settings can have the following
|
||||
// : header_css:[]
|
||||
// : action_box_css:[]
|
||||
let header_css = [];
|
||||
if (keyInObject('header_css', settings)) {
|
||||
if (objectKeyExists(settings, 'header_css')) {
|
||||
header_css = settings.header_css;
|
||||
}
|
||||
let action_box_css = [];
|
||||
if (keyInObject('action_box_css', settings)) {
|
||||
if (objectKeyExists(settings, 'action_box_css')) {
|
||||
action_box_css = settings.action_box_css;
|
||||
}
|
||||
let elements = [];
|
||||
@@ -288,7 +288,7 @@ class ActionBox {
|
||||
// if we have header content, add that here
|
||||
if (getObjectCount(headers) > 0) {
|
||||
// if the element has an entry called "raw_string" then this does not need to be converted
|
||||
if (keyInObject('raw_string', headers)) {
|
||||
if (objectKeyExists(headers, 'raw_string')) {
|
||||
elements.push(headers.raw_string);
|
||||
} else {
|
||||
elements.push(this.hec.phfo(headers));
|
||||
@@ -297,7 +297,7 @@ class ActionBox {
|
||||
// main content part (this should NOT be empty), if empty, add empty _content block
|
||||
if (getObjectCount(contents) > 0) {
|
||||
// if the element has an entry called "raw_string" then this does not need to be converted
|
||||
if (keyInObject('raw_string', contents)) {
|
||||
if (objectKeyExists(contents, 'raw_string')) {
|
||||
elements.push(contents.raw_string);
|
||||
} else {
|
||||
elements.push(this.hec.phfo(contents));
|
||||
|
||||
@@ -19,6 +19,9 @@ function formatBytes(bytes)
|
||||
if (typeof bytes === "bigint") {
|
||||
bytes = Number(bytes);
|
||||
}
|
||||
if (isNaN(bytes)) {
|
||||
return bytes.toString();
|
||||
}
|
||||
do {
|
||||
bytes = bytes / 1024;
|
||||
i++;
|
||||
|
||||
@@ -26,7 +26,8 @@ class HtmlElementCreator {
|
||||
return {
|
||||
tag: tag,
|
||||
id: id,
|
||||
name: options.name, // override name if set [name gets ignored in tree build anyway]
|
||||
// override name if set, else id is used. Only for input/button
|
||||
name: options.name,
|
||||
content: content,
|
||||
css: css,
|
||||
options: options,
|
||||
@@ -46,7 +47,6 @@ class HtmlElementCreator {
|
||||
if (id) {
|
||||
// base id match already
|
||||
if (base.id == id) {
|
||||
// base.sub.push(Object.assign({}, attach));
|
||||
base.sub.push(deepCopyFunction(attach));
|
||||
} else {
|
||||
// sub check
|
||||
@@ -58,7 +58,6 @@ class HtmlElementCreator {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// base.sub.push(Object.assign({}, attach));
|
||||
base.sub.push(deepCopyFunction(attach));
|
||||
}
|
||||
return base;
|
||||
@@ -74,7 +73,6 @@ class HtmlElementCreator {
|
||||
aelx(base, ...attach)
|
||||
{
|
||||
for (var i = 0; i < attach.length; i ++) {
|
||||
// base.sub.push(Object.assign({}, attach[i]));
|
||||
base.sub.push(deepCopyFunction(attach[i]));
|
||||
}
|
||||
return base;
|
||||
@@ -90,7 +88,6 @@ class HtmlElementCreator {
|
||||
aelxar(base, attach)
|
||||
{
|
||||
for (var i = 0; i < attach.length; i ++) {
|
||||
// base.sub.push(Object.assign({}, attach[i]));
|
||||
base.sub.push(deepCopyFunction(attach[i]));
|
||||
}
|
||||
return base;
|
||||
@@ -149,6 +146,7 @@ class HtmlElementCreator {
|
||||
{
|
||||
this.rcssel(_element, rcss);
|
||||
this.acssel(_element, acss);
|
||||
return _element;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,7 +5,8 @@ Creator: Clemens Schwaighofer
|
||||
*/
|
||||
|
||||
export {
|
||||
errorCatch, isFunction, executeFunctionByName,
|
||||
errorCatch, isFunction,
|
||||
executeFunctionByName, runFunction, runFunctionArgsArray,
|
||||
isObject, getObjectCount,
|
||||
keyInObject, objectKeyExists,
|
||||
getKeyByValue, valueInObject, objectValueExists,
|
||||
@@ -77,6 +78,35 @@ function executeFunctionByName(functionName, context /*, args */)
|
||||
return context[func].apply(context, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* call a function by string
|
||||
* call runFunctionArgArray
|
||||
* @param {string} name Function name to call
|
||||
* @param {Array} arguments all next function arguments are passed on as argument to the function
|
||||
* @returns void
|
||||
*/
|
||||
function runFunction(name)
|
||||
{
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
runFunctionArgsArray(name, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* call a function with a string, argumens as array
|
||||
* @param {string} name Function name to call
|
||||
* @param {array} args function arguments as arry
|
||||
* @returns void
|
||||
*/
|
||||
function runFunctionArgsArray(name, args)
|
||||
{
|
||||
var fn = window[name];
|
||||
if(typeof fn !== 'function') {
|
||||
return;
|
||||
}
|
||||
|
||||
fn.apply(window, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* checks if a variable is an object
|
||||
* @param {any} val possible object
|
||||
|
||||
@@ -5,9 +5,10 @@ Creator: Clemens Schwaighofer
|
||||
*/
|
||||
|
||||
export { parseQueryString, getQueryStringParam };
|
||||
import { keyInObject } from './JavaScriptHelpers.mjs';
|
||||
|
||||
/**
|
||||
* NOTE: this original code was wrong, now using URL and parsing through
|
||||
* getQueryStringParam
|
||||
* parses a query string from window.location.search.substring(1)
|
||||
* ALTERNATIVE CODE
|
||||
* var url = new URL(window.location.href);
|
||||
@@ -16,44 +17,13 @@ import { keyInObject } from './JavaScriptHelpers.mjs';
|
||||
* if not set will auto fill
|
||||
* @param {String} [return_key=''] if set only returns this key entry
|
||||
* or empty for none
|
||||
* @param {Boolean} [single=false] if set to true then only the first found
|
||||
* will be returned
|
||||
* @return {Object|String} parameter entry list
|
||||
*/
|
||||
function parseQueryString(query = '', return_key = '')
|
||||
function parseQueryString(query = '', return_key = '', single = false)
|
||||
{
|
||||
if (!query) {
|
||||
query = window.location.search.substring(1);
|
||||
}
|
||||
var vars = query.split('&');
|
||||
var query_string = {};
|
||||
for (var i = 0; i < vars.length; i++) {
|
||||
var pair = vars[i].split('=');
|
||||
var key = decodeURIComponent(pair[0]);
|
||||
var value = decodeURIComponent(pair[1]);
|
||||
// skip over run if there is nothing
|
||||
if (!key || value === 'undefined') {
|
||||
continue;
|
||||
}
|
||||
// If first entry with this name
|
||||
if (typeof query_string[key] === 'undefined') {
|
||||
query_string[key] = decodeURIComponent(value);
|
||||
// If second entry with this name
|
||||
} else if (typeof query_string[key] === 'string') {
|
||||
var arr = [query_string[key], decodeURIComponent(value)];
|
||||
query_string[key] = arr;
|
||||
// If third or later entry with this name
|
||||
} else {
|
||||
query_string[key].push(decodeURIComponent(value));
|
||||
}
|
||||
}
|
||||
if (return_key) {
|
||||
if (keyInObject(return_key, query_string)) {
|
||||
return query_string[return_key];
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
} else {
|
||||
return query_string;
|
||||
}
|
||||
return getQueryStringParam(return_key, query, single);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,6 +7,11 @@ import {
|
||||
} from '../src/utils/FormatBytes.mjs';
|
||||
|
||||
let bytes_map = [
|
||||
{
|
||||
"in": "120MB",
|
||||
"out": "120MB",
|
||||
"out_l": "120MB",
|
||||
},
|
||||
{
|
||||
"in": -123123123,
|
||||
"out": "-120237.42kB",
|
||||
@@ -57,6 +62,7 @@ describe("formatBytes", () => {
|
||||
it('convert bytes to human readable, round up to next set', () => {
|
||||
// expect(formatBytes(1021152)).toBe('0.97MB');
|
||||
for (const bytes of bytes_map) {
|
||||
// @ts-ignore
|
||||
expect(formatBytes(bytes.in)).toBe(bytes.out);
|
||||
}
|
||||
});
|
||||
@@ -66,6 +72,7 @@ describe("formatBytesLong", () => {
|
||||
it('convert bytes to human readable, keep on current set', () => {
|
||||
expect(formatBytesLong(1021152)).toBe('997.22 KB');
|
||||
for (const bytes of bytes_map) {
|
||||
// @ts-ignore
|
||||
expect(formatBytesLong(bytes.in)).toBe(bytes.out_l);
|
||||
}
|
||||
});
|
||||
|
||||
693
tests/HtmlElementCreator.test.js
Normal file
693
tests/HtmlElementCreator.test.js
Normal file
@@ -0,0 +1,693 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
|
||||
import {
|
||||
HtmlElementCreator
|
||||
} from '../src/utils/HtmlElementCreator.mjs';
|
||||
|
||||
let hec = new HtmlElementCreator();
|
||||
/*
|
||||
A cel object
|
||||
{
|
||||
"content": "",
|
||||
"css": [],
|
||||
"id": "",
|
||||
"name": undefined,
|
||||
"options": {},
|
||||
"sub": [],
|
||||
"tag": ""
|
||||
};
|
||||
*/
|
||||
|
||||
/**
|
||||
* build cel block
|
||||
* auto set default if undefined in the in object
|
||||
* @param {Object} cel_in array for creating one entry
|
||||
* @returns {Object}
|
||||
*/
|
||||
function celCreate(cel_in)
|
||||
{
|
||||
let cel_out;
|
||||
if (cel_in.id === undefined) {
|
||||
cel_out = hec.cel(cel_in.tag);
|
||||
} else if (cel_in.content === undefined) {
|
||||
cel_out = hec.cel(
|
||||
cel_in.tag,
|
||||
cel_in.id,
|
||||
);
|
||||
} else if (cel_in.css === undefined) {
|
||||
cel_out = cel_out = hec.cel(
|
||||
cel_in.tag,
|
||||
cel_in.id,
|
||||
cel_in.content,
|
||||
);
|
||||
} else if (cel_in.options === undefined) {
|
||||
cel_out = cel_out = hec.cel(
|
||||
cel_in.tag,
|
||||
cel_in.id,
|
||||
cel_in.content,
|
||||
cel_in.css,
|
||||
);
|
||||
} else {
|
||||
cel_out = hec.cel(
|
||||
cel_in.tag,
|
||||
cel_in.id,
|
||||
cel_in.content,
|
||||
cel_in.css,
|
||||
cel_in.options
|
||||
);
|
||||
}
|
||||
return cel_out;
|
||||
}
|
||||
|
||||
describe("cel", () => {
|
||||
it('should create HTML Element block and return an Object', () => {
|
||||
// test list for various calls
|
||||
let cel_list = [
|
||||
{
|
||||
"id": "tag only",
|
||||
"in": {
|
||||
"tag": "div",
|
||||
},
|
||||
"out": {
|
||||
"content": "",
|
||||
"css": [],
|
||||
"id": "",
|
||||
"name": undefined,
|
||||
"options": {},
|
||||
"sub": [],
|
||||
"tag": "div"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "tag+id only",
|
||||
"in": {
|
||||
"tag": "div",
|
||||
"id": "div-id",
|
||||
},
|
||||
"out": {
|
||||
"content": "",
|
||||
"css": [],
|
||||
"id": "div-id",
|
||||
"name": undefined,
|
||||
"options": {},
|
||||
"sub": [],
|
||||
"tag": "div"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "tag+id+content only",
|
||||
"in": {
|
||||
"tag": "div",
|
||||
"id": "div-id",
|
||||
"content": "text entry",
|
||||
},
|
||||
"out": {
|
||||
"content": "text entry",
|
||||
"css": [],
|
||||
"id": "div-id",
|
||||
"name": undefined,
|
||||
"options": {},
|
||||
"sub": [],
|
||||
"tag": "div"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "tag+id+content+css only",
|
||||
"in": {
|
||||
"tag": "div",
|
||||
"id": "div-id",
|
||||
"content": "text entry",
|
||||
"css": ['css-a', 'css-b'],
|
||||
},
|
||||
"out": {
|
||||
"content": "text entry",
|
||||
"css": ['css-a', 'css-b'],
|
||||
"id": "div-id",
|
||||
"name": undefined,
|
||||
"options": {},
|
||||
"sub": [],
|
||||
"tag": "div"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "tag+id+content+css+options only",
|
||||
"in": {
|
||||
"tag": "div",
|
||||
"id": "div-id",
|
||||
"content": "text entry",
|
||||
"css": ['css-a', 'css-b'],
|
||||
"options": {"onclick": "doThis();"}
|
||||
},
|
||||
"out": {
|
||||
"content": "text entry",
|
||||
"css": ['css-a', 'css-b'],
|
||||
"id": "div-id",
|
||||
"name": undefined,
|
||||
"options": {"onclick": "doThis();"},
|
||||
"sub": [],
|
||||
"tag": "div"
|
||||
}
|
||||
},
|
||||
// various in random
|
||||
{
|
||||
"id": "only css",
|
||||
"in": {
|
||||
"tag": "div",
|
||||
"id": "",
|
||||
"content": "",
|
||||
"css": ["abc"],
|
||||
"options": undefined,
|
||||
},
|
||||
"out": {
|
||||
"content": "",
|
||||
"css": ['abc'],
|
||||
"id": "",
|
||||
"name": undefined,
|
||||
"options": {},
|
||||
"sub": [],
|
||||
"tag": "div"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "set name",
|
||||
"in": {
|
||||
"tag": "div",
|
||||
"id": "foo-bar",
|
||||
"content": "",
|
||||
"css": [],
|
||||
"options": {
|
||||
"name": "baz"
|
||||
},
|
||||
},
|
||||
"out": {
|
||||
"content": "",
|
||||
"css": [],
|
||||
"id": "foo-bar",
|
||||
"name": "baz",
|
||||
"options": {"name": "baz"},
|
||||
"sub": [],
|
||||
"tag": "div"
|
||||
}
|
||||
},
|
||||
];
|
||||
for (const cel_entry of cel_list) {
|
||||
expect(celCreate(cel_entry.in)).toEqual(cel_entry.out);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("ael", () => {
|
||||
it('should attach one HTML Element block to another and return an Object', () => {
|
||||
let ael_block = hec.ael(
|
||||
hec.cel('div'),
|
||||
hec.cel('div')
|
||||
);
|
||||
expect(ael_block).toEqual(
|
||||
{
|
||||
"content": "",
|
||||
"css": [],
|
||||
"id": "",
|
||||
"name": undefined,
|
||||
"options": {},
|
||||
"sub": [
|
||||
{
|
||||
"content": "",
|
||||
"css": [],
|
||||
"id": "",
|
||||
"name": undefined,
|
||||
"options": {},
|
||||
"sub": [],
|
||||
"tag": "div"
|
||||
}
|
||||
],
|
||||
"tag": "div"
|
||||
}
|
||||
);
|
||||
ael_block = hec.ael(
|
||||
ael_block,
|
||||
hec.cel('div')
|
||||
);
|
||||
expect(ael_block).toEqual(
|
||||
{
|
||||
"content": "",
|
||||
"css": [],
|
||||
"id": "",
|
||||
"name": undefined,
|
||||
"options": {},
|
||||
"sub": [
|
||||
{
|
||||
"content": "",
|
||||
"css": [],
|
||||
"id": "",
|
||||
"name": undefined,
|
||||
"options": {},
|
||||
"sub": [],
|
||||
"tag": "div"
|
||||
},
|
||||
{
|
||||
"content": "",
|
||||
"css": [],
|
||||
"id": "",
|
||||
"name": undefined,
|
||||
"options": {},
|
||||
"sub": [],
|
||||
"tag": "div"
|
||||
}
|
||||
],
|
||||
"tag": "div"
|
||||
}
|
||||
);
|
||||
let test_cel = hec.ael(
|
||||
hec.cel('div', 'block-id'),
|
||||
hec.cel('div', 'sub-id'),
|
||||
);
|
||||
expect(hec.ael(test_cel, hec.cel('div', 'new-block'), 'sub-id')).toEqual(
|
||||
{
|
||||
"content": "",
|
||||
"css": [],
|
||||
"id": "block-id",
|
||||
"name": undefined,
|
||||
"options": {},
|
||||
"sub": [
|
||||
{
|
||||
"content": "",
|
||||
"css": [],
|
||||
"id": "sub-id",
|
||||
"name": undefined,
|
||||
"options": {},
|
||||
"sub": [
|
||||
{
|
||||
"content": "",
|
||||
"css": [],
|
||||
"id": "new-block",
|
||||
"name": undefined,
|
||||
"options": {},
|
||||
"sub": [],
|
||||
"tag": "div"
|
||||
}
|
||||
],
|
||||
"tag": "div"
|
||||
}
|
||||
],
|
||||
"tag": "div"
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("aelx", () => {
|
||||
it('should attach one or more HTML Element block to another and return an Object', () => {
|
||||
let ael_block = hec.aelx(
|
||||
hec.cel('div'),
|
||||
hec.cel('div')
|
||||
);
|
||||
expect(ael_block).toEqual(
|
||||
{
|
||||
"content": "",
|
||||
"css": [],
|
||||
"id": "",
|
||||
"name": undefined,
|
||||
"options": {},
|
||||
"sub": [
|
||||
{
|
||||
"content": "",
|
||||
"css": [],
|
||||
"id": "",
|
||||
"name": undefined,
|
||||
"options": {},
|
||||
"sub": [],
|
||||
"tag": "div"
|
||||
}
|
||||
],
|
||||
"tag": "div"
|
||||
}
|
||||
);
|
||||
ael_block = hec.aelx(
|
||||
ael_block,
|
||||
hec.cel('div'),
|
||||
hec.cel('div'),
|
||||
hec.cel('div')
|
||||
);
|
||||
expect(ael_block).toEqual(
|
||||
{
|
||||
"content": "",
|
||||
"css": [],
|
||||
"id": "",
|
||||
"name": undefined,
|
||||
"options": {},
|
||||
"sub": [
|
||||
{
|
||||
"content": "",
|
||||
"css": [],
|
||||
"id": "",
|
||||
"name": undefined,
|
||||
"options": {},
|
||||
"sub": [],
|
||||
"tag": "div"
|
||||
},
|
||||
{
|
||||
"content": "",
|
||||
"css": [],
|
||||
"id": "",
|
||||
"name": undefined,
|
||||
"options": {},
|
||||
"sub": [],
|
||||
"tag": "div"
|
||||
},
|
||||
{
|
||||
"content": "",
|
||||
"css": [],
|
||||
"id": "",
|
||||
"name": undefined,
|
||||
"options": {},
|
||||
"sub": [],
|
||||
"tag": "div"
|
||||
},
|
||||
{
|
||||
"content": "",
|
||||
"css": [],
|
||||
"id": "",
|
||||
"name": undefined,
|
||||
"options": {},
|
||||
"sub": [],
|
||||
"tag": "div"
|
||||
},
|
||||
],
|
||||
"tag": "div"
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("aelxar", () => {
|
||||
it('should attach one or more HTML Element block arrays to another and return an Object', () => {
|
||||
let ael_block = hec.aelxar(
|
||||
hec.cel('div'),
|
||||
[hec.cel('div')]
|
||||
);
|
||||
expect(ael_block).toEqual(
|
||||
{
|
||||
"content": "",
|
||||
"css": [],
|
||||
"id": "",
|
||||
"name": undefined,
|
||||
"options": {},
|
||||
"sub": [
|
||||
{
|
||||
"content": "",
|
||||
"css": [],
|
||||
"id": "",
|
||||
"name": undefined,
|
||||
"options": {},
|
||||
"sub": [],
|
||||
"tag": "div"
|
||||
}
|
||||
],
|
||||
"tag": "div"
|
||||
}
|
||||
);
|
||||
ael_block = hec.aelxar(
|
||||
ael_block,
|
||||
[
|
||||
hec.cel('div'),
|
||||
hec.cel('div'),
|
||||
hec.cel('div')
|
||||
]
|
||||
);
|
||||
expect(ael_block).toEqual(
|
||||
{
|
||||
"content": "",
|
||||
"css": [],
|
||||
"id": "",
|
||||
"name": undefined,
|
||||
"options": {},
|
||||
"sub": [
|
||||
{
|
||||
"content": "",
|
||||
"css": [],
|
||||
"id": "",
|
||||
"name": undefined,
|
||||
"options": {},
|
||||
"sub": [],
|
||||
"tag": "div"
|
||||
},
|
||||
{
|
||||
"content": "",
|
||||
"css": [],
|
||||
"id": "",
|
||||
"name": undefined,
|
||||
"options": {},
|
||||
"sub": [],
|
||||
"tag": "div"
|
||||
},
|
||||
{
|
||||
"content": "",
|
||||
"css": [],
|
||||
"id": "",
|
||||
"name": undefined,
|
||||
"options": {},
|
||||
"sub": [],
|
||||
"tag": "div"
|
||||
},
|
||||
{
|
||||
"content": "",
|
||||
"css": [],
|
||||
"id": "",
|
||||
"name": undefined,
|
||||
"options": {},
|
||||
"sub": [],
|
||||
"tag": "div"
|
||||
},
|
||||
],
|
||||
"tag": "div"
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("rel", () => {
|
||||
it('should reset the sub entry array in an element and return an Object', () => {
|
||||
let ael_block = hec.ael(
|
||||
hec.cel('div'),
|
||||
hec.cel('div')
|
||||
);
|
||||
expect(ael_block).toEqual(
|
||||
{
|
||||
"content": "",
|
||||
"css": [],
|
||||
"id": "",
|
||||
"name": undefined,
|
||||
"options": {},
|
||||
"sub": [
|
||||
{
|
||||
"content": "",
|
||||
"css": [],
|
||||
"id": "",
|
||||
"name": undefined,
|
||||
"options": {},
|
||||
"sub": [],
|
||||
"tag": "div"
|
||||
}
|
||||
],
|
||||
"tag": "div"
|
||||
}
|
||||
);
|
||||
let ael_removed = hec.rel(ael_block);
|
||||
expect(ael_removed).toEqual(
|
||||
{
|
||||
"content": "",
|
||||
"css": [],
|
||||
"id": "",
|
||||
"name": undefined,
|
||||
"options": {},
|
||||
"sub": [],
|
||||
"tag": "div"
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
// grouped CSS together
|
||||
describe("rcssel/acssel/scssel", () => {
|
||||
it('should remove/add/replace css entries in an element and return an object', () => {
|
||||
let cel_entry = hec.cel('div');
|
||||
let css_test = hec.acssel(cel_entry, 'foo');
|
||||
expect(css_test).toEqual(
|
||||
{
|
||||
"content": "",
|
||||
"css": ['foo'],
|
||||
"id": "",
|
||||
"name": undefined,
|
||||
"options": {},
|
||||
"sub": [],
|
||||
"tag": "div"
|
||||
}
|
||||
);
|
||||
css_test = hec.rcssel(cel_entry, 'foo');
|
||||
expect(css_test).toEqual(
|
||||
{
|
||||
"content": "",
|
||||
"css": [],
|
||||
"id": "",
|
||||
"name": undefined,
|
||||
"options": {},
|
||||
"sub": [],
|
||||
"tag": "div"
|
||||
}
|
||||
);
|
||||
css_test = hec.acssel(cel_entry, 'foo');
|
||||
expect(css_test).toEqual(
|
||||
{
|
||||
"content": "",
|
||||
"css": ['foo'],
|
||||
"id": "",
|
||||
"name": undefined,
|
||||
"options": {},
|
||||
"sub": [],
|
||||
"tag": "div"
|
||||
}
|
||||
);
|
||||
cel_entry = hec.scssel(cel_entry, 'foo', 'bar');
|
||||
expect(css_test).toEqual(
|
||||
{
|
||||
"content": "",
|
||||
"css": ['bar'],
|
||||
"id": "",
|
||||
"name": undefined,
|
||||
"options": {},
|
||||
"sub": [],
|
||||
"tag": "div"
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
// render
|
||||
describe("phfo", () => {
|
||||
it('should render an object tree out to HTML', () => {
|
||||
let cel_list = [
|
||||
{
|
||||
"id": "tag only",
|
||||
"in": {
|
||||
"tag": "div",
|
||||
},
|
||||
"out": '<div></div>'
|
||||
},
|
||||
{
|
||||
"id": "tag+id only",
|
||||
"in": {
|
||||
"tag": "div",
|
||||
"id": "div-id",
|
||||
},
|
||||
"out": '<div id="div-id"></div>'
|
||||
},
|
||||
{
|
||||
"id": "tag+id+content only",
|
||||
"in": {
|
||||
"tag": "div",
|
||||
"id": "div-id",
|
||||
"content": "text entry",
|
||||
},
|
||||
"out": '<div id="div-id">text entry</div>'
|
||||
},
|
||||
{
|
||||
"id": "tag+id+content+css only",
|
||||
"in": {
|
||||
"tag": "div",
|
||||
"id": "div-id",
|
||||
"content": "text entry",
|
||||
"css": ['css-a', 'css-b'],
|
||||
},
|
||||
"out": '<div id="div-id" class="css-a css-b">text entry</div>'
|
||||
},
|
||||
{
|
||||
"id": "tag+id+content+css+options only",
|
||||
"in": {
|
||||
"tag": "div",
|
||||
"id": "div-id",
|
||||
"content": "text entry",
|
||||
"css": ['css-a', 'css-b'],
|
||||
"options": {"onclick": "doThis();"}
|
||||
},
|
||||
"out": '<div id="div-id" class="css-a css-b" onclick="doThis();">text entry</div>'
|
||||
},
|
||||
// various in random
|
||||
{
|
||||
"id": "first",
|
||||
"in": {
|
||||
"tag": "div",
|
||||
"id": "",
|
||||
"content": "",
|
||||
"css": ["abc"],
|
||||
"options": undefined,
|
||||
},
|
||||
"out": '<div class="abc"></div>'
|
||||
}
|
||||
];
|
||||
for (const cel_entry of cel_list) {
|
||||
expect(hec.phfo(
|
||||
celCreate(cel_entry.in)
|
||||
)).toEqual(cel_entry.out);
|
||||
}
|
||||
// nested
|
||||
expect(hec.phfo(
|
||||
hec.ael(hec.cel('div', 'B1'),
|
||||
hec.aelx(
|
||||
hec.cel('div', 'A'),
|
||||
hec.cel('div', 'T1'),
|
||||
hec.cel('div', 'T2')
|
||||
)
|
||||
)
|
||||
)).toEqual(
|
||||
'<div id="B1"><div id="A"><div id="T1"></div><div id="T2"></div></div></div>'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("phfa", () => {
|
||||
it('should render an array tree out to HTML', () => {
|
||||
let el_list = [
|
||||
hec.cel('div', 'A'),
|
||||
hec.cel('div', 'B'),
|
||||
hec.cel('div', 'C'),
|
||||
];
|
||||
expect(hec.phfa(el_list)).toEqual(
|
||||
'<div id="A"></div><div id="B"></div><div id="C"></div>'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
// build check
|
||||
describe("phfo", () => {
|
||||
it('should render an object tree out to HTML, extended', () => {
|
||||
let cel_list = [
|
||||
{
|
||||
"id": "text input",
|
||||
"in": hec.cel("input", 'text-id', '', ['abc']),
|
||||
"out": '<input id="text-id" name="text-id" class="abc">'
|
||||
},
|
||||
{
|
||||
"id": "text input, different name",
|
||||
"in": hec.cel("input", 'text-id', '', ['abc'], {"name": "other-name"}),
|
||||
"out": '<input id="text-id" name="other-name" class="abc">'
|
||||
},
|
||||
{
|
||||
"id": "block test",
|
||||
"in": hec.aelx(hec.cel('div', 'outer-id'),
|
||||
hec.aelx(hec.cel('div', 'inner-id'),
|
||||
hec.cel('input', 'some-id', '', ['abc'], {"type": "button", "onclick": "send()"}),
|
||||
hec.cel('div', '', 'content')
|
||||
)
|
||||
),
|
||||
"out": '<div id="outer-id"><div id="inner-id"><input id="some-id" name="some-id" class="abc" type="button" onclick="send()"><div>content</div></div></div>'
|
||||
}
|
||||
];
|
||||
for (const cel_entry of cel_list) {
|
||||
expect(hec.phfo(
|
||||
cel_entry.in
|
||||
)).toEqual(cel_entry.out);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// __END__
|
||||
@@ -24,6 +24,8 @@ describe("roundPrecision", () => {
|
||||
it('should round numbers to a given precision', () => {
|
||||
let val = roundPrecision(10.1234, 2);
|
||||
expect(val).toBe(10.12);
|
||||
// @ts-ignore
|
||||
expect(roundPrecision("abc", 2)).toBe("abc");
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -5,17 +5,99 @@ import {
|
||||
getQueryStringParam,
|
||||
} from '../src/utils/UrlParser.mjs';
|
||||
|
||||
describe("parseQueryString", () => {
|
||||
it('Should parse query string for key', () => {
|
||||
let kv = parseQueryString("http://foor.org?key=value");
|
||||
expect(kv).toEqual({"http://foor.org?key": "value"});
|
||||
});
|
||||
});
|
||||
|
||||
let url_list = [
|
||||
{
|
||||
"id": "no params",
|
||||
"in": {
|
||||
"query": "http://foor.org",
|
||||
"search": "",
|
||||
"single": false
|
||||
},
|
||||
"out": {}
|
||||
},
|
||||
{
|
||||
"id": "no params",
|
||||
"in": {
|
||||
"query": "http://foor.org/?param",
|
||||
"search": "",
|
||||
"single": false
|
||||
},
|
||||
"out": {"param": ""}
|
||||
},
|
||||
{
|
||||
"id": "one params",
|
||||
"in": {
|
||||
"query": "http://foor.org/?param=foo",
|
||||
"search": "",
|
||||
"single": false
|
||||
},
|
||||
"out": {"param": "foo"}
|
||||
},
|
||||
{
|
||||
"id": "two params",
|
||||
"in": {
|
||||
"query": "http://foor.org/?param=foo&bar=other",
|
||||
"search": "",
|
||||
"single": false
|
||||
},
|
||||
"out": {"param": "foo", "bar": "other"}
|
||||
},
|
||||
{
|
||||
"id": "two params, select",
|
||||
"in": {
|
||||
"query": "http://foor.org/?param=foo&bar=other",
|
||||
"search": "bar",
|
||||
"single": false
|
||||
},
|
||||
"out": "other"
|
||||
},
|
||||
{
|
||||
"id": "two params, same",
|
||||
"in": {
|
||||
"query": "http://foor.org/?param=foo¶m=other",
|
||||
"search": "",
|
||||
"single": false
|
||||
},
|
||||
"out": {"param": ["foo", "other"]}
|
||||
},
|
||||
{
|
||||
"id": "two params, same, single but no search",
|
||||
"in": {
|
||||
"query": "http://foor.org/?param=foo¶m=other",
|
||||
"search": "",
|
||||
"single": true
|
||||
},
|
||||
// "out": {"param": ["foo", "other"]}
|
||||
"out": {"param": "foo"}
|
||||
},
|
||||
{
|
||||
"id": "three params, same, search",
|
||||
"in": {
|
||||
"query": "http://foor.org/?param=foo¶m=other&different=1",
|
||||
"search": "param",
|
||||
"single": false
|
||||
},
|
||||
"out": ["foo", "other"]
|
||||
},
|
||||
];
|
||||
describe("getQueryStringParam", () => {
|
||||
it('Should parse query string for key', () => {
|
||||
let kv = getQueryStringParam("key", "http://foor.org?key=value");
|
||||
expect(kv).toEqual("value");
|
||||
for (const url of url_list) {
|
||||
expect(
|
||||
getQueryStringParam(url.in.search, url.in.query, url.in.single)
|
||||
).toEqual(url.out);
|
||||
}
|
||||
});
|
||||
});
|
||||
describe("parseQueryString", () => {
|
||||
it('Should parse query string for key', () => {
|
||||
// let kv = getQueryStringParam("key", "http://foor.org?key=value");
|
||||
// expect(kv).toEqual("value");
|
||||
for (const url of url_list) {
|
||||
expect(
|
||||
parseQueryString(url.in.query, url.in.search, url.in.single)
|
||||
).toEqual(url.out);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
20
vitest.config.js
Normal file
20
vitest.config.js
Normal file
@@ -0,0 +1,20 @@
|
||||
|
||||
import { defineConfig } from 'vitest/config';
|
||||
|
||||
export default defineConfig({
|
||||
test: {
|
||||
environment: 'jsdom',
|
||||
include: [
|
||||
'tests/**/*.{test,spec}.?(c|m)[jt]s?(x)'
|
||||
],
|
||||
// exclude: [],
|
||||
coverage: {
|
||||
include: [
|
||||
'src/',
|
||||
],
|
||||
exclude: [
|
||||
'src/utils.mjs',
|
||||
]
|
||||
}
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user