summaryrefslogtreecommitdiff
path: root/preact/compat/test/browser/cloneElement.test.js
blob: 460ef7774570d325ff32844c8a3efc62848cd49a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import { createElement as preactH } from 'preact';
import React, { createElement, render, cloneElement } from 'preact/compat';
import { setupScratch, teardown } from '../../../test/_util/helpers';

describe('compat cloneElement', () => {
	/** @type {HTMLDivElement} */
	let scratch;

	beforeEach(() => {
		scratch = setupScratch();
	});

	afterEach(() => {
		teardown(scratch);
	});

	it('should clone elements', () => {
		let element = (
			<foo a="b" c="d">
				a<span>b</span>
			</foo>
		);
		const clone = cloneElement(element);
		delete clone._original;
		delete element._original;
		expect(clone).to.eql(element);
	});

	it('should support props.children', () => {
		let element = <foo children={<span>b</span>} />;
		let clone = cloneElement(element);
		delete clone._original;
		delete element._original;
		expect(clone).to.eql(element);
		expect(cloneElement(clone).props.children).to.eql(element.props.children);
	});

	it('children take precedence over props.children', () => {
		let element = (
			<foo children={<span>c</span>}>
				<div>b</div>
			</foo>
		);
		let clone = cloneElement(element);
		delete clone._original;
		delete element._original;
		expect(clone).to.eql(element);
		expect(clone.props.children.type).to.eql('div');
	});

	it('should support children in prop argument', () => {
		let element = <foo />;
		let children = [<span>b</span>];
		let clone = cloneElement(element, { children });
		expect(clone.props.children).to.eql(children);
	});

	it('single child argument takes precedence over props.children', () => {
		let element = <foo />;
		let childrenA = [<span>b</span>];
		let childrenB = [<div>c</div>];
		let clone = cloneElement(element, { children: childrenA }, ...childrenB);
		expect(clone.props.children).to.eql(childrenB[0]);
	});

	it('multiple children arguments take precedence over props.children', () => {
		let element = <foo />;
		let childrenA = [<span>b</span>];
		let childrenB = [<div>c</div>, 'd'];
		let clone = cloneElement(element, { children: childrenA }, ...childrenB);
		expect(clone.props.children).to.eql(childrenB);
	});

	it('children argument takes precedence over props.children even if falsey', () => {
		let element = <foo />;
		let childrenA = [<span>b</span>];
		let clone = cloneElement(element, { children: childrenA }, undefined);
		expect(clone.children).to.eql(undefined);
	});

	it('should skip cloning on invalid element', () => {
		let element = { foo: 42 };
		let clone = cloneElement(element);
		expect(clone).to.eql(element);
	});

	it('should work with jsx constructor from core', () => {
		function Foo(props) {
			return <div>{props.value}</div>;
		}

		let clone = cloneElement(preactH(Foo), { value: 'foo' });
		render(clone, scratch);
		expect(scratch.textContent).to.equal('foo');
	});
});