@davidsouther/jiffies 2026.4.0 → 2026.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -3
- package/package.json +13 -6
- package/src/404.html +1 -1
- package/src/components/accordion.ts +25 -0
- package/src/components/alert.ts +47 -0
- package/src/components/card.ts +54 -0
- package/src/components/children.ts +11 -0
- package/src/components/form.ts +25 -0
- package/src/components/index.ts +22 -0
- package/src/components/link.ts +22 -0
- package/src/components/modal.ts +15 -0
- package/src/components/nav.ts +42 -0
- package/src/components/property.ts +32 -0
- package/src/components/tabs.ts +82 -0
- package/src/components/virtual_scroll.ts +1 -1
- package/src/dom/README.md +8 -3
- package/src/dom/SKILL.md +201 -0
- package/src/dom/dom.ts +192 -41
- package/src/dom/fc.ts +7 -3
- package/src/dom/form/form.app.ts +35 -41
- package/src/dom/form/form.ts +79 -10
- package/src/dom/form/index.html +2 -2
- package/src/dom/html.ts +1 -1
- package/src/dom/hydrate.ts +206 -0
- package/src/dom/navigation/index.ts +349 -0
- package/src/dom/render.ts +41 -0
- package/src/dom/router/router.ts +1 -1
- package/src/dom/svg.ts +6 -2
- package/src/fs_node.ts +2 -2
- package/src/log.ts +154 -2
- package/src/server/http/response.ts +6 -3
- package/src/server/http/sitemap.ts +10 -34
- package/src/server/http/static.ts +0 -2
- package/src/server/live-reload.ts +208 -0
- package/src/server/main.ts +14 -7
- package/src/server/ws/frame.ts +36 -0
- package/src/server/ws/handshake.ts +42 -0
- package/src/server/ws/index.ts +100 -0
- package/src/ssg/bundle.ts +85 -0
- package/src/ssg/copy-public.ts +44 -0
- package/src/ssg/discover.ts +143 -0
- package/src/ssg/main.ts +168 -0
- package/src/ssg/rewrite.ts +18 -0
- package/src/ssg/ssg.ts +134 -0
- package/src/components/test.ts +0 -5
- package/src/components/virtual_scroll.test.ts +0 -30
- package/src/context.test.ts +0 -58
- package/src/context.ts +0 -67
- package/src/diff.test.ts +0 -48
- package/src/dom/fc.test.ts +0 -43
- package/src/dom/form/form.test.ts +0 -0
- package/src/dom/html.test.ts +0 -74
- package/src/dom/observable.test.ts +0 -43
- package/src/dom/test.ts +0 -11
- package/src/equal.test.ts +0 -23
- package/src/flags.test.ts +0 -43
- package/src/flags.ts +0 -53
- package/src/fs.test.ts +0 -106
- package/src/fs_win.test.ts +0 -11
- package/src/generator.test.ts +0 -27
- package/src/index.html +0 -82
- package/src/is_browser.js +0 -1
- package/src/lock.test.ts +0 -17
- package/src/observable/observable.test.ts +0 -73
- package/src/pico/_variables.scss +0 -66
- package/src/pico/components/_accordion.scss +0 -112
- package/src/pico/components/_button-group.scss +0 -51
- package/src/pico/components/_card.scss +0 -47
- package/src/pico/components/_dropdown.scss +0 -203
- package/src/pico/components/_modal.scss +0 -181
- package/src/pico/components/_nav.scss +0 -79
- package/src/pico/components/_progress.scss +0 -70
- package/src/pico/components/_property.scss +0 -34
- package/src/pico/content/_button.scss +0 -152
- package/src/pico/content/_code.scss +0 -63
- package/src/pico/content/_embedded.scss +0 -0
- package/src/pico/content/_form-alt.scss +0 -276
- package/src/pico/content/_form.scss +0 -259
- package/src/pico/content/_misc.scss +0 -0
- package/src/pico/content/_table.scss +0 -28
- package/src/pico/content/_toggle.scss +0 -132
- package/src/pico/content/_typography.scss +0 -232
- package/src/pico/layout/_container.scss +0 -40
- package/src/pico/layout/_document.scss +0 -0
- package/src/pico/layout/_flex.scss +0 -46
- package/src/pico/layout/_grid.scss +0 -24
- package/src/pico/layout/_scroller.scss +0 -16
- package/src/pico/layout/_section.scss +0 -8
- package/src/pico/layout/_sectioning.scss +0 -55
- package/src/pico/pico.scss +0 -60
- package/src/pico/reset/_accessibility.scss +0 -34
- package/src/pico/reset/_button.scss +0 -17
- package/src/pico/reset/_code.scss +0 -15
- package/src/pico/reset/_document.scss +0 -48
- package/src/pico/reset/_embedded.scss +0 -39
- package/src/pico/reset/_form.scss +0 -97
- package/src/pico/reset/_misc.scss +0 -23
- package/src/pico/reset/_nav.scss +0 -5
- package/src/pico/reset/_progress.scss +0 -4
- package/src/pico/reset/_table.scss +0 -8
- package/src/pico/reset/_typography.scss +0 -25
- package/src/pico/themes/default/_colors.scss +0 -65
- package/src/pico/themes/default/_dark.scss +0 -148
- package/src/pico/themes/default/_light.scss +0 -149
- package/src/pico/themes/default/_styles.scss +0 -272
- package/src/pico/themes/default.scss +0 -34
- package/src/pico/utilities/_accessibility.scss +0 -3
- package/src/pico/utilities/_loading.scss +0 -52
- package/src/pico/utilities/_reduce-motion.scss +0 -27
- package/src/pico/utilities/_tooltip.scss +0 -101
- package/src/result.test.ts +0 -101
- package/src/scope/describe.ts +0 -81
- package/src/scope/display/console.ts +0 -26
- package/src/scope/display/dom.ts +0 -36
- package/src/scope/display/junit.ts +0 -64
- package/src/scope/execute.ts +0 -110
- package/src/scope/expect.ts +0 -169
- package/src/scope/fix.ts +0 -30
- package/src/scope/index.ts +0 -11
- package/src/scope/scope.ts +0 -21
- package/src/scope/state.ts +0 -13
- package/src/test.mjs +0 -33
- package/src/test_all.ts +0 -35
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { State } from "../dom/fc.ts";
|
|
2
|
-
import { div } from "../dom/html.ts";
|
|
3
|
-
import { describe, expect, it } from "../scope/index.ts";
|
|
4
|
-
import VirtualScroll, {
|
|
5
|
-
arrayAdapter,
|
|
6
|
-
type VirtualScrollProps,
|
|
7
|
-
} from "./virtual_scroll.ts";
|
|
8
|
-
|
|
9
|
-
describe("VirtualScroll", () => {
|
|
10
|
-
it("tracks scroll position", () => {
|
|
11
|
-
const data = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
|
12
|
-
|
|
13
|
-
const props: VirtualScrollProps<number, HTMLDivElement> = {
|
|
14
|
-
settings: { count: 3, startIndex: 2 },
|
|
15
|
-
get: arrayAdapter(data),
|
|
16
|
-
row: (i) => div(`${i}`),
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
const scroll = VirtualScroll(
|
|
20
|
-
// @ts-expect-error
|
|
21
|
-
props,
|
|
22
|
-
);
|
|
23
|
-
|
|
24
|
-
expect(scroll[State]?.bufferedItems).toBe(9);
|
|
25
|
-
expect(scroll[State]?.data).toEqual([0, 1, 2, 3, 4]);
|
|
26
|
-
//expect(scroll.state.topPaddingHeight).toBe(0);
|
|
27
|
-
expect(scroll[State]?.viewportHeight).toBe(60);
|
|
28
|
-
//expect(scroll.state.totalHeight).toBe(200);
|
|
29
|
-
});
|
|
30
|
-
});
|
package/src/context.test.ts
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { type Context, Enter, Exit, using } from "./context.ts";
|
|
2
|
-
import { Err, isErr, isOk, Ok, unwrap } from "./result.ts";
|
|
3
|
-
import { describe, it } from "./scope/describe.ts";
|
|
4
|
-
import { expect } from "./scope/expect.ts";
|
|
5
|
-
|
|
6
|
-
describe("Context", () => {
|
|
7
|
-
it("performs an operation using a context", () => {
|
|
8
|
-
const context = TestContext();
|
|
9
|
-
const result = using(context, () => Ok(5));
|
|
10
|
-
expect(unwrap(result)).toBe(5);
|
|
11
|
-
expect(context.initialized).toBe(true);
|
|
12
|
-
expect(context.completed).toBe(true);
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
it("reports the result of a thrown error", () => {
|
|
16
|
-
const context = TestContext();
|
|
17
|
-
|
|
18
|
-
const result = using(context, () => {
|
|
19
|
-
throw new Error("Failed");
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
expect(isErr(result)).toBe(true);
|
|
23
|
-
expect(Err(result as Err<Error>)).toMatchObject({
|
|
24
|
-
message: "Failed",
|
|
25
|
-
});
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
it("passes the context to the operation", () => {
|
|
29
|
-
const op = using(TestContext, ({ initialized, completed }) => ({
|
|
30
|
-
initialized,
|
|
31
|
-
completed,
|
|
32
|
-
}));
|
|
33
|
-
|
|
34
|
-
expect(isOk(op)).toBe(true);
|
|
35
|
-
const { completed, initialized } = unwrap(op);
|
|
36
|
-
expect(initialized).toBe(true);
|
|
37
|
-
expect(completed).toBe(false);
|
|
38
|
-
});
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
interface TestContext {
|
|
42
|
-
initialized: boolean;
|
|
43
|
-
completed: boolean;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
function TestContext(): Context & TestContext {
|
|
47
|
-
const context = {
|
|
48
|
-
[Enter]: () => {
|
|
49
|
-
context.initialized = true;
|
|
50
|
-
},
|
|
51
|
-
[Exit]: () => {
|
|
52
|
-
context.completed = true;
|
|
53
|
-
},
|
|
54
|
-
initialized: false,
|
|
55
|
-
completed: false,
|
|
56
|
-
};
|
|
57
|
-
return context;
|
|
58
|
-
}
|
package/src/context.ts
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import { Err, isResult, Ok, type Result } from "./result.ts";
|
|
2
|
-
|
|
3
|
-
export const Enter = Symbol("Context Enter");
|
|
4
|
-
export const Exit = Symbol("Context Exit");
|
|
5
|
-
|
|
6
|
-
export interface Context {
|
|
7
|
-
[Enter]: () => void;
|
|
8
|
-
[Exit]: () => void;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export type Operation<T, E extends Error, C extends Context> = (
|
|
12
|
-
c: C,
|
|
13
|
-
) => T | Result<T, E>;
|
|
14
|
-
|
|
15
|
-
export type AsyncOperation<T, E extends Error, C extends Context> = (
|
|
16
|
-
c: C,
|
|
17
|
-
) => Promise<T | Result<T, E>>;
|
|
18
|
-
|
|
19
|
-
export function using<T, E extends Error, C extends Context>(
|
|
20
|
-
context: C | (() => C) | Operation<T, E, C>,
|
|
21
|
-
operation?: Operation<T, E, C>,
|
|
22
|
-
normalizeError: (e: Error | unknown) => Err<E> = (e) =>
|
|
23
|
-
// @ts-expect-error
|
|
24
|
-
Err(e),
|
|
25
|
-
): Result<T, E> {
|
|
26
|
-
if (typeof context === "function") {
|
|
27
|
-
if (context.length === 1) {
|
|
28
|
-
operation = context as Operation<T, E, C>;
|
|
29
|
-
context = {} as C;
|
|
30
|
-
} else {
|
|
31
|
-
context = (context as () => C)() as C;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
let result: Result<T, E>;
|
|
35
|
-
try {
|
|
36
|
-
context[Enter]();
|
|
37
|
-
const op = operation?.(context);
|
|
38
|
-
result = isResult(op as Result<T, E>) ? (op as Result<T, E>) : Ok(op as T);
|
|
39
|
-
} catch (e) {
|
|
40
|
-
result = normalizeError(e);
|
|
41
|
-
} finally {
|
|
42
|
-
context[Exit]();
|
|
43
|
-
}
|
|
44
|
-
return result;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export async function asyncUsing<T, E extends Error, C extends Context>(
|
|
48
|
-
context: C | (() => Promise<C>),
|
|
49
|
-
operation: AsyncOperation<T, E, C>,
|
|
50
|
-
normalizeError: (e: E) => Err<E> = (e: E) => Err(e),
|
|
51
|
-
): Promise<Result<T, E>> {
|
|
52
|
-
context = typeof context === "function" ? await context() : context;
|
|
53
|
-
let result: Result<T, E>;
|
|
54
|
-
try {
|
|
55
|
-
context[Enter]();
|
|
56
|
-
const op = await operation(context);
|
|
57
|
-
result = isResult(op as Result<T, E>) ? (op as Result<T, E>) : Ok(op as T);
|
|
58
|
-
} catch (e) {
|
|
59
|
-
result = normalizeError(
|
|
60
|
-
// @ts-expect-error
|
|
61
|
-
e,
|
|
62
|
-
);
|
|
63
|
-
} finally {
|
|
64
|
-
context[Exit]();
|
|
65
|
-
}
|
|
66
|
-
return result;
|
|
67
|
-
}
|
package/src/diff.test.ts
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { diff } from "./diff.ts";
|
|
2
|
-
import { describe, it } from "./scope/describe.ts";
|
|
3
|
-
import { expect } from "./scope/expect.ts";
|
|
4
|
-
|
|
5
|
-
describe("diff", () => {
|
|
6
|
-
it("diffs primitives", () => {
|
|
7
|
-
const diffed = diff(1, 2);
|
|
8
|
-
expect(diffed).toEqual([{ key: "", left: 1, right: 2 }]);
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
it("diffs objects", () => {
|
|
12
|
-
const diffed = diff({ a: 1, b: 2 }, { a: 2, b: 2 });
|
|
13
|
-
expect(diffed).toEqual([{ key: "a", left: 1, right: 2 }]);
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
it("diffs nested objects", () => {
|
|
17
|
-
const diffed = diff({ a: { c: 1 }, b: 2 }, { a: { c: 2 }, b: 2 });
|
|
18
|
-
expect(diffed).toEqual([
|
|
19
|
-
{ key: "a", children: [{ key: "c", left: 1, right: 2 }] },
|
|
20
|
-
]);
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
it("diffs missing sides", () => {
|
|
24
|
-
const diffed = diff<{ a?: number; b?: number }>({ a: 1 }, { b: 2 });
|
|
25
|
-
expect(diffed).toEqual([
|
|
26
|
-
{ key: "a", left: 1, right: undefined },
|
|
27
|
-
{ key: "b", left: undefined, right: 2 },
|
|
28
|
-
]);
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
it("diffs arrays", () => {
|
|
32
|
-
const diffed = diff<number[]>([1, 2, 3], [1, 4, 3]);
|
|
33
|
-
expect(diffed).toEqual([{ key: 1, left: 2, right: 4 }]);
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
it("diffs objects in an array", () => {
|
|
37
|
-
const diffed = diff(
|
|
38
|
-
[{ a: { b: 1 } }, { a: { b: 2 } }, { a: { b: 3 } }],
|
|
39
|
-
[{ a: { b: 1 } }, { a: { b: 4 } }, { a: { b: 3 } }],
|
|
40
|
-
);
|
|
41
|
-
expect(diffed).toEqual([
|
|
42
|
-
{
|
|
43
|
-
key: 1,
|
|
44
|
-
children: [{ key: "a", children: [{ key: "b", left: 2, right: 4 }] }],
|
|
45
|
-
},
|
|
46
|
-
]);
|
|
47
|
-
});
|
|
48
|
-
});
|
package/src/dom/fc.test.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "../scope/index.ts";
|
|
2
|
-
import { FC } from "./fc.ts";
|
|
3
|
-
import { button, div, form, input, label, small } from "./html.ts";
|
|
4
|
-
|
|
5
|
-
describe("FC", () => {
|
|
6
|
-
it("creates FCs", () => {
|
|
7
|
-
const Input = FC<{
|
|
8
|
-
placeholder: string;
|
|
9
|
-
name: string;
|
|
10
|
-
required?: boolean;
|
|
11
|
-
type?: string;
|
|
12
|
-
}>("fc-input", (_el, attrs, children) =>
|
|
13
|
-
label(attrs.placeholder ?? attrs.name, input(attrs), ...children),
|
|
14
|
-
);
|
|
15
|
-
|
|
16
|
-
const f = form(
|
|
17
|
-
{ action: "#", method: "POST" },
|
|
18
|
-
div(
|
|
19
|
-
{ class: "grid" },
|
|
20
|
-
Input({
|
|
21
|
-
name: "firstName",
|
|
22
|
-
placeholder: "First Name",
|
|
23
|
-
required: true,
|
|
24
|
-
}),
|
|
25
|
-
Input({
|
|
26
|
-
name: "lastName",
|
|
27
|
-
placeholder: "Last Name",
|
|
28
|
-
required: true,
|
|
29
|
-
}),
|
|
30
|
-
),
|
|
31
|
-
Input(
|
|
32
|
-
{ name: "email", type: "email", placeholder: "E-Mail" },
|
|
33
|
-
small("We'll never share your information."),
|
|
34
|
-
),
|
|
35
|
-
button({ type: "submit" }, "Submit"),
|
|
36
|
-
);
|
|
37
|
-
|
|
38
|
-
// document.body.appendChild(f);
|
|
39
|
-
expect(f.children.length).toBe(3);
|
|
40
|
-
expect(f.querySelectorAll("input[required]").length).toBe(2);
|
|
41
|
-
expect(f.querySelectorAll('input[name="firstName"]').length).toBe(1);
|
|
42
|
-
});
|
|
43
|
-
});
|
|
File without changes
|
package/src/dom/html.test.ts
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import { describe, it } from "../scope/describe.ts";
|
|
2
|
-
import { expect } from "../scope/expect.ts";
|
|
3
|
-
import { button, table, tbody, td, th, thead, tr } from "./html.ts";
|
|
4
|
-
|
|
5
|
-
describe("html", () => {
|
|
6
|
-
it("creates HTML Elements", () => {
|
|
7
|
-
const tableBody = tbody();
|
|
8
|
-
const tableHead = thead(tr(th("Col A"), th("Col B")));
|
|
9
|
-
const myTable = table(tableHead, tableBody);
|
|
10
|
-
for (let x = 1; x <= 3; x++) {
|
|
11
|
-
tableBody.appendChild(tr(td(`${x}`), td(`${x * 2}`)));
|
|
12
|
-
}
|
|
13
|
-
expect(myTable.textContent).toEqual("Col ACol B122436");
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
it("attaches event handlers", () => {
|
|
17
|
-
let clicked = 0;
|
|
18
|
-
const btn = button({
|
|
19
|
-
events: {
|
|
20
|
-
click: () => {
|
|
21
|
-
clicked += 1;
|
|
22
|
-
},
|
|
23
|
-
},
|
|
24
|
-
});
|
|
25
|
-
btn.dispatchEvent(new Event("click"));
|
|
26
|
-
expect(clicked).toBe(1);
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
it("removes event handlers", () => {
|
|
30
|
-
let clicked = 0;
|
|
31
|
-
const btn = button({
|
|
32
|
-
events: {
|
|
33
|
-
click: () => {
|
|
34
|
-
clicked += 1;
|
|
35
|
-
},
|
|
36
|
-
},
|
|
37
|
-
});
|
|
38
|
-
btn.dispatchEvent(new Event("click"));
|
|
39
|
-
|
|
40
|
-
expect(clicked).toBe(1);
|
|
41
|
-
|
|
42
|
-
btn.update({ events: { click: null } });
|
|
43
|
-
btn.dispatchEvent(new Event("click"));
|
|
44
|
-
expect(clicked).toBe(1);
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it("sets style properties", () => {
|
|
48
|
-
const btn = button({
|
|
49
|
-
style: { flexDirection: "column" },
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
expect(btn.style.flexDirection).toBe("column");
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it("sets style, attributes, and events together", () => {
|
|
56
|
-
let clicked = false;
|
|
57
|
-
const btn = button({
|
|
58
|
-
class: "test-class",
|
|
59
|
-
style: { flexDirection: "column" },
|
|
60
|
-
events: {
|
|
61
|
-
click: () => {
|
|
62
|
-
clicked = true;
|
|
63
|
-
},
|
|
64
|
-
},
|
|
65
|
-
});
|
|
66
|
-
btn.dispatchEvent(new Event("click"));
|
|
67
|
-
|
|
68
|
-
expect(btn.classList.contains("test-class")).toBe(true);
|
|
69
|
-
expect((btn as unknown as HTMLButtonElement).style.flexDirection).toBe(
|
|
70
|
-
"column",
|
|
71
|
-
);
|
|
72
|
-
expect(clicked).toBe(true);
|
|
73
|
-
});
|
|
74
|
-
});
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { map, Subject } from "../observable/observable.ts";
|
|
2
|
-
import { describe, it } from "../scope/describe.ts";
|
|
3
|
-
import { expect } from "../scope/expect.ts";
|
|
4
|
-
import type { DOMUpdates } from "./dom.ts";
|
|
5
|
-
import { div, span } from "./html.ts";
|
|
6
|
-
import { O } from "./observable.ts";
|
|
7
|
-
|
|
8
|
-
describe("DOM Observable", () => {
|
|
9
|
-
it("updates a dom node with observable results", async () => {
|
|
10
|
-
const subject = new Subject<string>();
|
|
11
|
-
const observable = subject.pipe(map((s) => [s]));
|
|
12
|
-
|
|
13
|
-
const element = O(div(), observable);
|
|
14
|
-
|
|
15
|
-
expect(element.innerText).toEqual("");
|
|
16
|
-
await subject.next("H");
|
|
17
|
-
expect(element.innerText).toEqual("H");
|
|
18
|
-
await subject.next("He");
|
|
19
|
-
expect(element.innerText).toEqual("He");
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
it("updates a dom node's attributes", async () => {
|
|
23
|
-
const classes = new Subject<string[]>();
|
|
24
|
-
const observable = classes.map<DOMUpdates>((c) => [{ class: c.join(" ") }]);
|
|
25
|
-
|
|
26
|
-
const element = O(span(), observable);
|
|
27
|
-
|
|
28
|
-
expect(element.classList.contains("warning")).toBe(false);
|
|
29
|
-
expect(element.classList.contains("error")).toBe(false);
|
|
30
|
-
|
|
31
|
-
await classes.next(["warning"]);
|
|
32
|
-
expect(element.classList.contains("warning")).toBe(true);
|
|
33
|
-
expect(element.classList.contains("error")).toBe(false);
|
|
34
|
-
|
|
35
|
-
await classes.next(["error"]);
|
|
36
|
-
expect(element.classList.contains("warning")).toBe(true);
|
|
37
|
-
expect(element.classList.contains("error")).toBe(true);
|
|
38
|
-
|
|
39
|
-
await classes.next(["!warning", "!error"]);
|
|
40
|
-
expect(element.classList.contains("warning")).toBe(false);
|
|
41
|
-
expect(element.classList.contains("error")).toBe(false);
|
|
42
|
-
});
|
|
43
|
-
});
|
package/src/dom/test.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { IsBrowser } from "../is_browser.js";
|
|
2
|
-
|
|
3
|
-
export async function loadTests() {
|
|
4
|
-
if (!IsBrowser) return;
|
|
5
|
-
if (process?.env.CI?.toLowerCase() === "true") return;
|
|
6
|
-
await Promise.all([
|
|
7
|
-
import("./html.test.js"),
|
|
8
|
-
import("./fc.test.js"),
|
|
9
|
-
import("./observable.test.js"),
|
|
10
|
-
]);
|
|
11
|
-
}
|
package/src/equal.test.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { equalArrays, equals, matchArrays } from "./equal.ts";
|
|
2
|
-
import { describe, expect, it } from "./scope/index.ts";
|
|
3
|
-
|
|
4
|
-
describe("Equality", () => {
|
|
5
|
-
it("compares objects", () => {
|
|
6
|
-
expect(equals({ a: 1, b: 2 }, { b: 2, a: 1 })).toBe(true);
|
|
7
|
-
expect(equals({ a: 1, b: 2 }, { b: 1, a: 2 })).toBe(false);
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
it("compares primitives", () => {
|
|
11
|
-
expect(equals(1, 1)).toBe(true);
|
|
12
|
-
expect(equals(1, -1)).toBe(false);
|
|
13
|
-
expect(equals(0, -0)).toBe(false);
|
|
14
|
-
expect(equals(Number.NaN, Number.NaN)).toBe(true);
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
it("compares arrays", () => {
|
|
18
|
-
expect(equalArrays([1, 2, 3], [1, 2, 3])).toBe(true);
|
|
19
|
-
expect(equalArrays([1], [2, 3])).toBe(false);
|
|
20
|
-
expect(equalArrays([{ a: 1 }], [{ a: 1 }])).toBe(false);
|
|
21
|
-
expect(matchArrays([{ a: 1 }], [{ a: 1 }])).toBe(true);
|
|
22
|
-
});
|
|
23
|
-
});
|
package/src/flags.test.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { parse } from "./flags.ts";
|
|
2
|
-
import { describe, expect, it } from "./scope/index.ts";
|
|
3
|
-
|
|
4
|
-
const TEST_CASES = {
|
|
5
|
-
SIMPLE: "program",
|
|
6
|
-
NODE: "/usr/local/bin/node program",
|
|
7
|
-
ONE_FLAG: "program --fun",
|
|
8
|
-
ONE_PARAM: "program --fun=100",
|
|
9
|
-
ONE_ARG: "program cat",
|
|
10
|
-
ONE_NO_FLAG: "program --no-fun",
|
|
11
|
-
MIXED: "program --fun=dog cat --port=8080 mouse --hamster --no-bird",
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
const makeFlags = (commandLine: string) => {
|
|
15
|
-
return parse(commandLine.split(" "));
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
describe("Flags", () => {
|
|
19
|
-
it("stores the program name", () => {
|
|
20
|
-
const flags = makeFlags(TEST_CASES.SIMPLE);
|
|
21
|
-
|
|
22
|
-
expect(flags.argv0).toEqual("program");
|
|
23
|
-
expect(flags.args).toEqual([]);
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
it("stores the program name ignoring node", () => {
|
|
27
|
-
const flags = makeFlags(TEST_CASES.NODE);
|
|
28
|
-
|
|
29
|
-
expect(flags.argv0).toEqual("program");
|
|
30
|
-
expect(flags.args).toEqual([]);
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
it("parses a flag", () => {
|
|
34
|
-
const flags = makeFlags(TEST_CASES.ONE_FLAG);
|
|
35
|
-
expect(flags.get("fun")).toBe(true);
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
it("parses a flag with a default value", () => {
|
|
39
|
-
const flags = makeFlags(TEST_CASES.SIMPLE);
|
|
40
|
-
expect(flags.get("missing")).toBe(false);
|
|
41
|
-
expect(flags.get("missing", true)).toBe(true);
|
|
42
|
-
});
|
|
43
|
-
});
|
package/src/flags.ts
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
export const parse = (parseArgs: string[]) => {
|
|
2
|
-
const fromNode = parseArgs[0].endsWith("node");
|
|
3
|
-
const argv = parseArgs[fromNode ? 1 : 0];
|
|
4
|
-
const params = new Map<string, string>();
|
|
5
|
-
const flags = new Map<string, boolean>();
|
|
6
|
-
const args: string[] = [];
|
|
7
|
-
|
|
8
|
-
let index = fromNode ? 2 : 1;
|
|
9
|
-
const hasNext = () => index < parseArgs.length;
|
|
10
|
-
const peek = () => parseArgs[index];
|
|
11
|
-
const advance = () => parseArgs[index++];
|
|
12
|
-
|
|
13
|
-
const parseLong = (arg: string) => {
|
|
14
|
-
if (arg.substring(0, 3) === "no-") {
|
|
15
|
-
flags.set(arg.substring(3), false);
|
|
16
|
-
} else if (!arg.includes("=")) {
|
|
17
|
-
flags.set(arg, true);
|
|
18
|
-
} else {
|
|
19
|
-
const [param, ...value] = arg.split("=");
|
|
20
|
-
params.set(param, value.join("="));
|
|
21
|
-
}
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
while (hasNext()) {
|
|
25
|
-
if (peek().substr(0, 2) === "--") {
|
|
26
|
-
parseLong(advance().substr(2));
|
|
27
|
-
} else {
|
|
28
|
-
args.push(advance());
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
return {
|
|
33
|
-
get argv0() {
|
|
34
|
-
return argv;
|
|
35
|
-
},
|
|
36
|
-
|
|
37
|
-
get args(): ReadonlyArray<string> {
|
|
38
|
-
return args;
|
|
39
|
-
},
|
|
40
|
-
|
|
41
|
-
get(flag: string, def = false) {
|
|
42
|
-
return flags.get(flag) ?? def;
|
|
43
|
-
},
|
|
44
|
-
|
|
45
|
-
asNumber(param: string, def = 0): number {
|
|
46
|
-
return Number.parseFloat(params.get(param) ?? `${def}`);
|
|
47
|
-
},
|
|
48
|
-
|
|
49
|
-
asString(param: string, def = ""): string {
|
|
50
|
-
return params.get(param) ?? def;
|
|
51
|
-
},
|
|
52
|
-
};
|
|
53
|
-
};
|
package/src/fs.test.ts
DELETED
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
FileSystem,
|
|
3
|
-
ObjectFileSystemAdapter,
|
|
4
|
-
RecordFileSystemAdapter,
|
|
5
|
-
} from "./fs.ts";
|
|
6
|
-
import { beforeEach, describe, expect, it } from "./scope/index.ts";
|
|
7
|
-
import { cleanState } from "./scope/state.ts";
|
|
8
|
-
|
|
9
|
-
describe("FileSystem", () => {
|
|
10
|
-
describe("Writing", () => {
|
|
11
|
-
it("Writes files", async () => {
|
|
12
|
-
const fsObj = {};
|
|
13
|
-
const fs = new FileSystem(new RecordFileSystemAdapter(fsObj));
|
|
14
|
-
await fs.writeFile("hello", "world");
|
|
15
|
-
|
|
16
|
-
expect(fsObj).toEqual({ "/hello": "world" });
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
it("Writes deep files", async () => {
|
|
20
|
-
const fsObj = {};
|
|
21
|
-
const fs = new FileSystem(new RecordFileSystemAdapter(fsObj));
|
|
22
|
-
await fs.writeFile("deep/hello", "world");
|
|
23
|
-
|
|
24
|
-
expect(fsObj).toEqual({ "/deep/hello": "world" });
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
it("Writes deep files from root", async () => {
|
|
28
|
-
const fsObj = {};
|
|
29
|
-
const fs = new FileSystem(new RecordFileSystemAdapter(fsObj));
|
|
30
|
-
await fs.writeFile("/root/deep/hello", "world");
|
|
31
|
-
|
|
32
|
-
expect(fsObj).toEqual({ "/root/deep/hello": "world" });
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
it("Writes files after cd", async () => {
|
|
36
|
-
const fsObj = {};
|
|
37
|
-
const fs = new FileSystem(new RecordFileSystemAdapter(fsObj));
|
|
38
|
-
await fs.cd("deep");
|
|
39
|
-
await fs.writeFile("hello", "world");
|
|
40
|
-
|
|
41
|
-
expect(fsObj).toEqual({ "/deep/hello": "world" });
|
|
42
|
-
});
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
describe("directory", () => {
|
|
46
|
-
it("returns directory listing", async () => {
|
|
47
|
-
const fsObj = {
|
|
48
|
-
"/deep/hello": "world",
|
|
49
|
-
"/deep/bonjour": "monde",
|
|
50
|
-
"/other/file": "text",
|
|
51
|
-
};
|
|
52
|
-
const fs = new FileSystem(new RecordFileSystemAdapter(fsObj));
|
|
53
|
-
|
|
54
|
-
const dir = await fs.readdir("deep");
|
|
55
|
-
expect(dir.sort()).toEqual(["bonjour", "hello"]);
|
|
56
|
-
});
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
describe("stat", () => {
|
|
60
|
-
const state = cleanState(() => {
|
|
61
|
-
const fsObj = {
|
|
62
|
-
"/deep/hello": "world",
|
|
63
|
-
"/deep/bonjour": "monde",
|
|
64
|
-
"/other/file": "text",
|
|
65
|
-
};
|
|
66
|
-
return { fs: new FileSystem(new RecordFileSystemAdapter(fsObj)) };
|
|
67
|
-
}, beforeEach);
|
|
68
|
-
|
|
69
|
-
it("stats a directory", async () => {
|
|
70
|
-
const deep = await state.fs.stat("/deep");
|
|
71
|
-
expect(deep.isDirectory()).toBe(true);
|
|
72
|
-
expect(deep.isFile()).toBe(false);
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
it("stats a file", async () => {
|
|
76
|
-
const deep = await state.fs.stat("/deep/hello");
|
|
77
|
-
expect(deep.isDirectory()).toBe(false);
|
|
78
|
-
expect(deep.isFile()).toBe(true);
|
|
79
|
-
});
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
describe("ObjectFileSystem", () => {
|
|
83
|
-
it("treats object keys as directories and final values as strings", async () => {
|
|
84
|
-
const fsAdapter = new ObjectFileSystemAdapter({
|
|
85
|
-
deep: {
|
|
86
|
-
hello: "world",
|
|
87
|
-
bonjour: "monde",
|
|
88
|
-
},
|
|
89
|
-
other_file: "text",
|
|
90
|
-
});
|
|
91
|
-
expect([
|
|
92
|
-
...Object.keys(
|
|
93
|
-
(fsAdapter as unknown as { fs: Record<string, string> }).fs,
|
|
94
|
-
),
|
|
95
|
-
]).toEqual(["/deep/hello", "/deep/bonjour", "/other_file"]);
|
|
96
|
-
const fs = new FileSystem(fsAdapter);
|
|
97
|
-
|
|
98
|
-
const deep = await fs.stat("/deep");
|
|
99
|
-
expect(deep.isDirectory()).toBe(true);
|
|
100
|
-
expect(deep.isFile()).toBe(false);
|
|
101
|
-
|
|
102
|
-
const deep_bonjour = await fs.readFile("/deep/bonjour");
|
|
103
|
-
expect(deep_bonjour).toBe("monde");
|
|
104
|
-
});
|
|
105
|
-
});
|
|
106
|
-
});
|
package/src/fs_win.test.ts
DELETED
package/src/generator.test.ts
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { takeWhile } from "./generator.ts";
|
|
2
|
-
import { describe, expect, it } from "./scope/index.ts";
|
|
3
|
-
|
|
4
|
-
describe("Generator", () => {
|
|
5
|
-
it("takes from a generator until a predicate", () => {
|
|
6
|
-
const generator = function* () {
|
|
7
|
-
let i = 1;
|
|
8
|
-
while (true) {
|
|
9
|
-
i = i * 2;
|
|
10
|
-
yield i;
|
|
11
|
-
}
|
|
12
|
-
};
|
|
13
|
-
const filter = () => {
|
|
14
|
-
let previousValue = 0;
|
|
15
|
-
return (n: number) => {
|
|
16
|
-
if (previousValue < 100) {
|
|
17
|
-
previousValue = n;
|
|
18
|
-
return true;
|
|
19
|
-
}
|
|
20
|
-
return false;
|
|
21
|
-
};
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
const values = [...takeWhile(filter(), generator())];
|
|
25
|
-
expect(values).toEqual([2, 4, 8, 16, 32, 64, 128]);
|
|
26
|
-
});
|
|
27
|
-
});
|