Skip to content

Commit

Permalink
fix(mock-doc): make MockAttributeMap iterable (#2788)
Browse files Browse the repository at this point in the history
  • Loading branch information
simonhaenisch committed Jan 7, 2021
1 parent 9c18fa0 commit 1aa9cae
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 7 deletions.
24 changes: 21 additions & 3 deletions src/mock-doc/attribute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ const attrHandler = {
if (prop in obj) {
return obj[prop];
}
if (!isNaN(prop as any)) {
if (typeof prop !== 'symbol' && !isNaN(prop as any)) {
return (obj as MockAttributeMap).__items[prop as any];
}
return undefined;
},
};

export const createAttributeProxy = (caseInsensitive: boolean) => new Proxy(new MockAttributeMap(caseInsensitive), attrHandler);
export const createAttributeProxy = (caseInsensitive: boolean) =>
new Proxy(new MockAttributeMap(caseInsensitive), attrHandler);

export class MockAttributeMap {
__items: MockAttr[] = [];
Expand Down Expand Up @@ -54,7 +55,9 @@ export class MockAttributeMap {

getNamedItemNS(namespaceURI: string, attrName: string) {
namespaceURI = getNamespaceURI(namespaceURI);
return this.__items.find(attr => attr.name === attrName && getNamespaceURI(attr.namespaceURI) === namespaceURI) || null;
return (
this.__items.find(attr => attr.name === attrName && getNamespaceURI(attr.namespaceURI) === namespaceURI) || null
);
}

removeNamedItem(attr: MockAttr) {
Expand All @@ -69,6 +72,21 @@ export class MockAttributeMap {
}
}
}

[Symbol.iterator]() {
let i = 0;

return {
next: () => ({
done: i === this.length,
value: this.item(i++),
}),
};
}

get [Symbol.toStringTag]() {
return 'MockAttributeMap';
}
}

function getNamespaceURI(namespaceURI: string) {
Expand Down
20 changes: 16 additions & 4 deletions src/mock-doc/test/attribute.spec.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
import { MockAttr, MockAttributeMap } from '../attribute';
import { MockDocument } from '../document';
import { MockElement, MockHTMLElement } from '../node';
import { XLINK_NS } from '../../runtime/runtime-constants';
import { MockImageElement } from '../element';

describe('attributes', () => {
let doc: MockDocument;
beforeEach(() => {
doc = new MockDocument();
});

it('attribute map is iterable', () => {
const map = new MockAttributeMap();
const attr = new MockAttr('attr', 'value');
map.setNamedItem(attr);

expect(Array.from(map)[0]).toBe(attr);
});

it('should get attributes by index', () => {
const element = new MockHTMLElement(doc, 'div');
element.setAttribute('attr-0', 'value-0');
Expand Down Expand Up @@ -67,7 +75,9 @@ describe('attributes', () => {
expect(element.getAttribute('prop5')).toBe('hola');
expect(element.getAttribute('prop6')).toBe('');

expect(element).toEqualHtml(`<div prop1=\"null\" prop2=\"undefined\" prop3=\"0\" prop4=\"1\" prop5=\"hola\" prop6></div>`);
expect(element).toEqualHtml(
`<div prop1=\"null\" prop2=\"undefined\" prop3=\"0\" prop4=\"1\" prop5=\"hola\" prop6></div>`,
);
});

it('should cast attributeNS values to string', () => {
Expand All @@ -86,7 +96,9 @@ describe('attributes', () => {
expect(element.getAttribute('prop5')).toBe('hola');
expect(element.getAttribute('prop6')).toBe('');

expect(element).toEqualHtml(`<div prop1=\"null\" prop2=\"undefined\" prop3=\"0\" prop4=\"1\" prop5=\"hola\" prop6></div>`);
expect(element).toEqualHtml(
`<div prop1=\"null\" prop2=\"undefined\" prop3=\"0\" prop4=\"1\" prop5=\"hola\" prop6></div>`,
);
});

it('attributes are case insensible in HTMLElement', () => {
Expand Down Expand Up @@ -126,7 +138,7 @@ describe('attributes', () => {
});

it('draggable default value', () => {
const div = doc.createElement('div')
const div = doc.createElement('div');
expect(div.draggable).toEqual(false);

const img = doc.createElement('img');
Expand Down

0 comments on commit 1aa9cae

Please sign in to comment.