Skip to content

Commit

Permalink
Add additional tests to alfa-dom (#93)
Browse files Browse the repository at this point in the history
  • Loading branch information
Búgvi Benjamin Magnussen authored and kasperisager committed Feb 26, 2019
1 parent 06573c1 commit f1e9439
Show file tree
Hide file tree
Showing 8 changed files with 302 additions and 15 deletions.
5 changes: 5 additions & 0 deletions packages/alfa-dom/src/get-owner-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ import { Attribute, Element, Node } from "./types";

const ownerElementMaps = new WeakMap<Node, WeakMap<Attribute, Element>>();

/**
* Given an attribute and a context, get the owner element of that attribute
* within the given context. If no element owns the attribute within
* the context then `null` is returned.
*/
export function getOwnerElement(
attribute: Attribute,
context: Node
Expand Down
79 changes: 71 additions & 8 deletions packages/alfa-dom/test/compare-document-position.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,88 @@
import { jsx } from "@siteimprove/alfa-jsx";
import { test } from "@siteimprove/alfa-test";
import { compareDocumentPosition } from "../src/compare-document-position";
import {
compareDocumentPosition,
DocumentPosition
} from "../src/compare-document-position";

const foo = <em />;
const bar = <strong />;
const em = <em />;
const strong = <strong />;
const span = <span>{em}</span>;

const context = (
<div>
<span>{foo}</span>
{bar}
{span}
{strong}
</div>
);

test("Returns 0 when a node is compared to itself", t => {
t.equal(compareDocumentPosition(foo, foo, context), 0);
t.equal(compareDocumentPosition(em, em, context), 0);
});

test("Returns < 0 when the first node comes before the second", t => {
t(compareDocumentPosition(foo, bar, context) < 0);
t(compareDocumentPosition(em, strong, context) < 0);
});

test("Returns > 0 when the first node comes after the second", t => {
t(compareDocumentPosition(bar, foo, context) > 0);
t(compareDocumentPosition(strong, em, context) > 0);
});

test("Returns Disconnected if the nodes are not in the same tree", t => {
const div = <div />;
const cmp = compareDocumentPosition(strong, div, context);
const revcmp = compareDocumentPosition(div, strong, context);

// Check if nodes are disconnected
const isDisc = cmp & DocumentPosition.Disconnected;
t.equal(isDisc, DocumentPosition.Disconnected);

/*
* The following checks are needed according to the spec
* @see https://www.w3.org/TR/dom/#dom-node-comparedocumentposition
*/

const isPrec = cmp & DocumentPosition.Preceding;
const isFoll = cmp & DocumentPosition.Following;

// check that only the preceding flag xor the following flag is set
t.equal((isPrec >> 1) ^ (isFoll >> 2), 1);
// chech that if strong precedes div then the div should follow strong
if (isPrec === DocumentPosition.Preceding) {
t(
cmp ===
(DocumentPosition.Disconnected |
DocumentPosition.ImplementationSpecific |
DocumentPosition.Preceding) &&
revcmp ===
(DocumentPosition.Disconnected |
DocumentPosition.ImplementationSpecific |
DocumentPosition.Following)
);
} else {
t(
cmp ===
(DocumentPosition.Disconnected |
DocumentPosition.ImplementationSpecific |
DocumentPosition.Following) &&
revcmp ===
(DocumentPosition.Disconnected |
DocumentPosition.ImplementationSpecific |
DocumentPosition.Preceding)
);
}
});

test("Returns ContainedBy and Following as negative value when the other node is contained by the reference node", t => {
t.equal(
compareDocumentPosition(span, em, context),
-1 * (DocumentPosition.ContainedBy | DocumentPosition.Following)
);
});

test("Returns Contains and Preceding when the reference node is contained by the other node", t => {
t.equal(
compareDocumentPosition(em, span, context),
DocumentPosition.Contains | DocumentPosition.Preceding
);
});
64 changes: 57 additions & 7 deletions packages/alfa-dom/test/get-assigned-nodes.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,66 @@ import { jsx } from "@siteimprove/alfa-jsx";
import { test } from "@siteimprove/alfa-test";
import { getAssignedNodes } from "../src/get-assigned-nodes";

const slotInShadow = <slot name="foo" />;
const slotInDiv = <slot name="bar" />;
const element = <span slot="foo">Hello world</span>;
const shadow = <shadow>{slotInShadow}</shadow>;
const div = <div>{slotInDiv}</div>;
const context = (
<div>
{element}
{shadow}
{div}
</div>
);
const contextNoSpan = (
<div>
{shadow}
{div}
</div>
);

test("Gets the assigned nodes of a slot", t => {
const slot = <slot name="foo" />;
const element = <span slot="foo">Hello world</span>;
t.deepEqual(getAssignedNodes(slotInShadow, context), [element]);
});

test("Gets an empty array when element is not slot", t => {
t.deepEqual(getAssignedNodes(element, context), []);
});

test("Gets an empty array when root node is not a shadow node", t => {
t.deepEqual(getAssignedNodes(slotInDiv, context), []);
});

test("Gets the assigned nodes of a slot with flattened traversal", t => {
t.deepEqual(getAssignedNodes(slotInShadow, context, { flattened: true }), [
element
]);
});

const context = (
test("Gets an empty array when root node is not a shadow node with flattened traversal", t => {
t.deepEqual(getAssignedNodes(slotInDiv, context, { flattened: true }), []);
});

test("Gets an empty array when there are no slotables with flattened traversal", t => {
t.deepEqual(
getAssignedNodes(slotInShadow, contextNoSpan, { flattened: true }),
[]
);
});

test("Gets the assigned nodes of a slot with child when there are no slotables with flattened traversal", t => {
const button = <button />;
const slotInShadow = <slot name="foo">{button}</slot>;
const shadow = <shadow>{slotInShadow}</shadow>;
const contextNoSpan = (
<div>
{element}
<shadow>{slot}</shadow>
{shadow}
{div}
</div>
);

t.deepEqual(getAssignedNodes(slot, context), [element]);
t.deepEqual(
getAssignedNodes(slotInShadow, contextNoSpan, { flattened: true }),
[button]
);
});
40 changes: 40 additions & 0 deletions packages/alfa-dom/test/get-next-element-sibling.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { jsx } from "@siteimprove/alfa-jsx";
import { test } from "@siteimprove/alfa-test";
import { getNextElementSibling } from "../src/get-next-element-sibling";

test("Return next sibling that is an element", t => {
const button = <button />;
const span = <span />;
const div = (
<div>
{button}
Hello I am not an element
{span}
</div>
);
t.equal(getNextElementSibling(button, div), span);
});

test("Return null when no next element sibling exists", t => {
const button = <button />;
const div = (
<div>
{button}
Hello I am not an element
</div>
);
t.equal(getNextElementSibling(button, div), null);
});

test("Return null when parent is null", t => {
const button = <button />;
const span = <span />;
const div = (
<div>
{button}
Hello I am not an element
{span}
</div>
);
t.equal(getNextElementSibling(div, div), null);
});
37 changes: 37 additions & 0 deletions packages/alfa-dom/test/get-owner-element.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { jsx } from "@siteimprove/alfa-jsx";
import { test } from "@siteimprove/alfa-test";
import { getOwnerElement } from "../src/get-owner-element";
import { Attribute } from "../src/types";

test("Returns owner element of attribute", t => {
const div1 = <div aria-label="foo" />;
const strong = <strong />;
const div2 = <div aria-label="bar" />;
const att: Attribute = div2.attributes[0];
const body = (
<body>
{div1}
foo
{strong}
{div2}
</body>
);

t.equal(getOwnerElement(att, body), div2);
});

test("Returns null when owner element is not present in the passed context", t => {
const div1 = <div aria-label="foo" />;
const strong = <strong />;
const div2 = <div aria-label="bar" />;
const att: Attribute = div2.attributes[0];
const body = (
<body>
{div1}
foo
{strong}
</body>
);

t.equal(getOwnerElement(att, body), null);
});
25 changes: 25 additions & 0 deletions packages/alfa-dom/test/get-parent-element.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { jsx } from "@siteimprove/alfa-jsx";
import { test } from "@siteimprove/alfa-test";
import { getParentElement } from "../src/get-parent-element";
import { Document } from "../src/types";

test("Returns parent element", t => {
const body = <body />;
const html = <html>{body}</html>;
t.equal(getParentElement(body, html), html);
});

test("Returns null when parent does not exist", t => {
const div = <div />;
t.equal(getParentElement(div, div), null);
});

test("Returns null when parent is not an element", t => {
const document: Document = {
nodeType: 9,
childNodes: [<html />],
compatMode: "CSS1Compat",
styleSheets: []
};
t.equal(getParentElement(document.childNodes[0], document), null);
});
60 changes: 60 additions & 0 deletions packages/alfa-dom/test/get-parent-rule.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { jsx } from "@siteimprove/alfa-jsx";
import { test } from "@siteimprove/alfa-test";
import { getParentRule } from "../src/get-parent-rule";
import {
Document,
MediaRule,
Rule,
StyleDeclaration,
StyleRule,
StyleSheet
} from "../src/types";

test("Returns parent rule", t => {
const childRule: StyleRule = {
type: 1,
selectorText: "button",
style: {
cssText: "background-color:black;"
}
};
const parentRule: MediaRule = {
type: 4,
cssRules: [childRule],
conditionText: "@media foo"
};

const styleSheet: StyleSheet = { cssRules: [parentRule], disabled: false };
const document: Document = {
nodeType: 9,
childNodes: [<div />],
compatMode: "CSS1Compat",
styleSheets: [styleSheet]
};
t.equal(getParentRule(childRule, document), parentRule);
});

test("Returns null when context is not document type", t => {
const div = <div />;
const rule: Rule = { type: 1 };
t.equal(getParentRule(rule, div), null);
});

test("Returns null when parent rule does not exist", t => {
const childStyleDec: StyleDeclaration = {
cssText: "background-color:black;"
};
const childRule: StyleRule = {
type: 1,
selectorText: "button",
style: childStyleDec
};
const styleSheet: StyleSheet = { cssRules: [], disabled: false };
const document: Document = {
nodeType: 9,
childNodes: [<div />],
compatMode: "CSS1Compat",
styleSheets: [styleSheet]
};
t.equal(getParentRule(childRule, document), null);
});
7 changes: 7 additions & 0 deletions packages/alfa-dom/test/get-specificity.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,10 @@ test("A class is more specific than a pseudo-element-selector", t => {
getSpecificity(selector("::first-letter"))
);
});

test("A compound selector with two classes is more specific than one class", t => {
t(
getSpecificity(selector(".foo.bar")) >
getSpecificity(selector(".foo-class"))
);
});

0 comments on commit f1e9439

Please sign in to comment.