Skip to content

Commit

Permalink
Add test, fix PR based on feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
canadaduane committed Nov 7, 2023
1 parent 757abf0 commit 1703b4e
Show file tree
Hide file tree
Showing 2 changed files with 150 additions and 146 deletions.
11 changes: 5 additions & 6 deletions src/dom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@ export const impl: Partial<RendererImpl<Node, string>> = {
scope(
xmlns: string | undefined,
tag: string | symbol,
props: any
props: Record<string, any>

Check failure on line 17 in src/dom.ts

View workflow job for this annotation

GitHub Actions / build

Insert `,`
): string | undefined {
// TODO: Should we handle xmlns???
switch (tag) {
case Portal:
xmlns = undefined;
Expand All @@ -26,7 +25,7 @@ export const impl: Partial<RendererImpl<Node, string>> = {
break;
}

return props?.xmlns ?? xmlns;
return props.xmlns || xmlns;
},

create(
Expand Down Expand Up @@ -74,7 +73,7 @@ export const impl: Partial<RendererImpl<Node, string>> = {
}

// TODO: extract props from nodes
return {props, children};
return { props, children };

Check failure on line 76 in src/dom.ts

View workflow job for this annotation

GitHub Actions / build

Replace `·props,·children·` with `props,·children`
},

patch(
Expand Down Expand Up @@ -106,7 +105,7 @@ export const impl: Partial<RendererImpl<Node, string>> = {
style.cssText = "";
}

for (const styleName in {...(oldValue as {}), ...(value as {})}) {
for (const styleName in { ...(oldValue as {}), ...(value as {}) }) {

Check failure on line 108 in src/dom.ts

View workflow job for this annotation

GitHub Actions / build

Replace `·...(oldValue·as·{}),·...(value·as·{})·` with `...(oldValue·as·{}),·...(value·as·{})`
const styleValue = value && (value as any)[styleName];
if (styleValue == null) {
style.removeProperty(styleName);
Expand Down Expand Up @@ -383,6 +382,6 @@ export const renderer = new DOMRenderer();

declare global {
module Crank {
interface EventMap extends GlobalEventHandlersEventMap {}
interface EventMap extends GlobalEventHandlersEventMap { }

Check failure on line 385 in src/dom.ts

View workflow job for this annotation

GitHub Actions / build

Delete `·`
}
}
285 changes: 145 additions & 140 deletions test/svg.tsx
Original file line number Diff line number Diff line change
@@ -1,172 +1,177 @@
import {suite} from "uvu";
import { suite } from "uvu";

Check failure on line 1 in test/svg.tsx

View workflow job for this annotation

GitHub Actions / build

Replace `·suite·` with `suite`
import * as Assert from "uvu/assert";
import {createElement} from "../src/crank.js";
import {renderer} from "../src/dom.js";
import { createElement } from "../src/crank.js";

Check failure on line 3 in test/svg.tsx

View workflow job for this annotation

GitHub Actions / build

Replace `·createElement·` with `createElement`
import { renderer } from "../src/dom.js";

Check failure on line 4 in test/svg.tsx

View workflow job for this annotation

GitHub Actions / build

Replace `·renderer·` with `renderer`

const test = suite("svg");

test.after.each(() => {
renderer.render(null, document.body);
document.body.innerHTML = "";
renderer.render(null, document.body);

Check failure on line 9 in test/svg.tsx

View workflow job for this annotation

GitHub Actions / build

Replace `··` with `↹`
document.body.innerHTML = "";

Check failure on line 10 in test/svg.tsx

View workflow job for this annotation

GitHub Actions / build

Replace `··` with `↹`
});

test("simple", () => {
renderer.render(<svg>Hello world</svg>, document.body);
Assert.ok(document.body.firstChild instanceof SVGElement);
Assert.ok(document.body.firstChild!.firstChild instanceof Text);
Assert.is(document.body.firstChild!.firstChild!.nodeValue, "Hello world");
renderer.render(<svg>Hello world</svg>, document.body);

Check failure on line 14 in test/svg.tsx

View workflow job for this annotation

GitHub Actions / build

Replace `··` with `↹`
Assert.ok(document.body.firstChild instanceof SVGElement);
Assert.ok(document.body.firstChild!.firstChild instanceof Text);
Assert.is(document.body.firstChild!.firstChild!.nodeValue, "Hello world");
});

test("mdn example", () => {
renderer.render(
<svg
version="1.1"
baseProfile="full"
width="300"
height="200"
xmlns="http://www.w3.org/2000/svg"
>
<rect width="100%" height="100%" fill="red" />
<circle cx="150" cy="100" r="80" fill="green" />
<text x="150" y="125" font-size="60" text-anchor="middle" fill="white">
SVG
</text>
</svg>,
document.body,
);

let svgRoot = document.body.firstChild;
Assert.ok(document.body.firstChild instanceof SVGElement);

let rect = svgRoot!.childNodes[0] as SVGElement;
Assert.ok(rect instanceof SVGElement);
Assert.is(rect.tagName, "rect");
Assert.is(rect.getAttribute("width"), "100%");
Assert.is(rect.getAttribute("height"), "100%");
Assert.is(rect.getAttribute("fill"), "red");

let circle = svgRoot!.childNodes[1] as SVGElement;
Assert.ok(circle instanceof SVGElement);
Assert.is(circle.tagName, "circle");
Assert.is(circle.getAttribute("cx"), "150");
Assert.is(circle.getAttribute("cy"), "100");
Assert.is(circle.getAttribute("r"), "80");
Assert.is(circle.getAttribute("fill"), "green");

let text = svgRoot!.childNodes[2] as SVGElement;
Assert.ok(text instanceof SVGElement);
Assert.is(text.tagName, "text");
Assert.is(text.getAttribute("x"), "150");
Assert.is(text.getAttribute("y"), "125");
Assert.is(text.getAttribute("font-size"), "60");
Assert.is(text.getAttribute("text-anchor"), "middle");
Assert.is(text.getAttribute("fill"), "white");
renderer.render(
<svg
version="1.1"
baseProfile="full"
width="300"
height="200"
xmlns="http://www.w3.org/2000/svg"
>
<rect width="100%" height="100%" fill="red" />
<circle cx="150" cy="100" r="80" fill="green" />
<text x="150" y="125" font-size="60" text-anchor="middle" fill="white">
SVG
</text>
</svg>,
document.body
);

let svgRoot = document.body.firstChild;
Assert.ok(document.body.firstChild instanceof SVGElement);

let rect = svgRoot!.childNodes[0] as SVGElement;
Assert.ok(rect instanceof SVGElement);
Assert.is(rect.tagName, "rect");
Assert.is(rect.getAttribute("width"), "100%");
Assert.is(rect.getAttribute("height"), "100%");
Assert.is(rect.getAttribute("fill"), "red");

let circle = svgRoot!.childNodes[1] as SVGElement;
Assert.ok(circle instanceof SVGElement);
Assert.is(circle.tagName, "circle");
Assert.is(circle.getAttribute("cx"), "150");
Assert.is(circle.getAttribute("cy"), "100");
Assert.is(circle.getAttribute("r"), "80");
Assert.is(circle.getAttribute("fill"), "green");

let text = svgRoot!.childNodes[2] as SVGElement;
Assert.ok(text instanceof SVGElement);
Assert.is(text.tagName, "text");
Assert.is(text.getAttribute("x"), "150");
Assert.is(text.getAttribute("y"), "125");
Assert.is(text.getAttribute("font-size"), "60");
Assert.is(text.getAttribute("text-anchor"), "middle");
Assert.is(text.getAttribute("fill"), "white");
});

test("foreignObject", () => {
renderer.render(
<svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
<foreignObject x="20" y="20" width="160" height="160">
<div xmlns="http://www.w3.org/1999/xhtml">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed mollis
mollis mi ut ultricies. Nullam magna ipsum, porta vel dui convallis,
rutrum imperdiet eros. Aliquam erat volutpat.
</div>
</foreignObject>
</svg>,
document.body,
);
Assert.ok(document.body.firstChild instanceof SVGElement);
Assert.ok(
document.body.firstChild!.firstChild!.firstChild instanceof HTMLElement,
);
renderer.render(
<svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
<foreignObject x="20" y="20" width="160" height="160">
<div xmlns="http://www.w3.org/1999/xhtml">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed mollis
mollis mi ut ultricies. Nullam magna ipsum, porta vel dui convallis,
rutrum imperdiet eros. Aliquam erat volutpat.
</div>
</foreignObject>
</svg>,
document.body
);
Assert.ok(document.body.firstChild instanceof SVGElement);

const foreignObject = document.body.firstChild!.firstChild!;
Assert.ok(foreignObject instanceof SVGElement);
Assert.is(foreignObject.namespaceURI, "http://www.w3.org/2000/svg");

const div = foreignObject.firstChild! as HTMLElement;
Assert.ok(div instanceof HTMLElement);
Assert.is(div.namespaceURI, "http://www.w3.org/1999/xhtml");
});

test("classes", () => {
renderer.render(
<svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
<rect class="rectClass" x="10" y="10" width="100" height="100" />
<circle class="circleClass" cx="40" cy="50" r="26" />
</svg>,
document.body,
);

const rect = document.body.firstChild!.firstChild as SVGElement;
const circle = rect.nextSibling as SVGElement;
Assert.ok(rect instanceof SVGElement);
Assert.is(rect.tagName, "rect");
Assert.ok(circle instanceof SVGElement);
Assert.is(circle.tagName, "circle");
Assert.is(rect.getAttribute("class"), "rectClass");
Assert.is(circle.getAttribute("class"), "circleClass");
renderer.render(
<svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
<rect class="rectClass" x="10" y="10" width="100" height="100" />
<circle class="circleClass" cx="40" cy="50" r="26" />
</svg>,
document.body
);

const rect = document.body.firstChild!.firstChild as SVGElement;
const circle = rect.nextSibling as SVGElement;
Assert.ok(rect instanceof SVGElement);
Assert.is(rect.tagName, "rect");
Assert.ok(circle instanceof SVGElement);
Assert.is(circle.tagName, "circle");
Assert.is(rect.getAttribute("class"), "rectClass");
Assert.is(circle.getAttribute("class"), "circleClass");
});

test("g", () => {
renderer.render(
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<g fill="white" stroke="green" stroke-width="5">
<path d="M10 10" />
<path d="M 10 10 H 90 V 90 H 10 L 10 10" />
</g>
</svg>,
document.body,
);

const g = document.body.firstChild!.firstChild as SVGElement;
Assert.ok(g instanceof SVGElement);
Assert.is(g.tagName, "g");
Assert.ok(g.childNodes[0] instanceof SVGElement);
Assert.ok(g.childNodes[1] instanceof SVGElement);
renderer.render(
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<g fill="white" stroke="green" stroke-width="5">
<path d="M10 10" />
<path d="M 10 10 H 90 V 90 H 10 L 10 10" />
</g>
</svg>,
document.body
);

const g = document.body.firstChild!.firstChild as SVGElement;
Assert.ok(g instanceof SVGElement);
Assert.is(g.tagName, "g");
Assert.ok(g.childNodes[0] instanceof SVGElement);
Assert.ok(g.childNodes[1] instanceof SVGElement);
});

test("nested", () => {
renderer.render(
<svg width="750" height="500" style="background: gray">
<svg x="200" y="200">
<circle cx="50" cy="50" r="50" style="fill: red" />
</svg>
</svg>,
document.body,
);
const nested = document.body.firstChild!.firstChild as SVGElement;
Assert.ok(nested instanceof SVGElement);
Assert.is(nested.tagName, "svg");
Assert.ok(nested.firstChild instanceof SVGElement);
Assert.is((nested.firstChild as SVGElement).tagName, "circle");
renderer.render(
<svg width="750" height="500" style="background: gray">
<svg x="200" y="200">
<circle cx="50" cy="50" r="50" style="fill: red" />
</svg>
</svg>,
document.body
);
const nested = document.body.firstChild!.firstChild as SVGElement;
Assert.ok(nested instanceof SVGElement);
Assert.is(nested.tagName, "svg");
Assert.ok(nested.firstChild instanceof SVGElement);
Assert.is((nested.firstChild as SVGElement).tagName, "circle");
});

test("non-string values", () => {
renderer.render(
<svg xmlns="http://www.w3.org/2000/svg">
<rect class="rectClass" x={10} y={20.5} width={5000} height={null} />
</svg>,
document.body,
);

const rect = document.body.firstChild!.firstChild! as SVGElement;
Assert.ok(rect instanceof SVGElement);
Assert.is(rect.getAttribute("x"), "10");
Assert.is(rect.getAttribute("y"), "20.5");
Assert.is(rect.getAttribute("width"), "5000");
Assert.is(rect.getAttribute("height"), null);
renderer.render(
<svg xmlns="http://www.w3.org/2000/svg">
<rect class="rectClass" x={10} y={20.5} width={5000} height={null} />
</svg>,
document.body
);

const rect = document.body.firstChild!.firstChild! as SVGElement;
Assert.ok(rect instanceof SVGElement);
Assert.is(rect.getAttribute("x"), "10");
Assert.is(rect.getAttribute("y"), "20.5");
Assert.is(rect.getAttribute("width"), "5000");
Assert.is(rect.getAttribute("height"), null);
});

test("custom attributes", () => {
renderer.render(
<svg xmlns="http://www.w3.org/2000/svg">
<circle cx="25" cy="10" r="5" data-foo="abc" barBaz={true} />
</svg>,
document.body,
);

const circle = document.body.firstChild!.firstChild! as SVGElement;
Assert.ok(circle instanceof SVGElement);
Assert.is(circle.getAttribute("cx"), "25");
Assert.is(circle.getAttribute("cy"), "10");
Assert.is(circle.getAttribute("r"), "5");
Assert.is(circle.getAttribute("data-foo"), "abc");
Assert.is(circle.getAttribute("barBaz"), "");
Assert.is(circle.getAttribute("does-not-exist"), null);
renderer.render(
<svg xmlns="http://www.w3.org/2000/svg">
<circle cx="25" cy="10" r="5" data-foo="abc" barBaz={true} />
</svg>,
document.body
);

const circle = document.body.firstChild!.firstChild! as SVGElement;
Assert.ok(circle instanceof SVGElement);
Assert.is(circle.getAttribute("cx"), "25");
Assert.is(circle.getAttribute("cy"), "10");
Assert.is(circle.getAttribute("r"), "5");
Assert.is(circle.getAttribute("data-foo"), "abc");
Assert.is(circle.getAttribute("barBaz"), "");
Assert.is(circle.getAttribute("does-not-exist"), null);
});

test.run();

0 comments on commit 1703b4e

Please sign in to comment.