-
Notifications
You must be signed in to change notification settings - Fork 37
Expand file tree
/
Copy pathreact-tools.test.jsx
More file actions
95 lines (87 loc) · 2.86 KB
/
Copy pathreact-tools.test.jsx
File metadata and controls
95 lines (87 loc) · 2.86 KB
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
import { assert, describe, it } from 'vitest'
import React from 'react'
import ReactDOM from 'react'
import { renderToString } from 'react-dom/server'
import { parseXml } from '@rgrove/parse-xml'
import parse from 'html-react-parser'
import { hydrate } from '../srcjs/react-tools'
/**
* Needed by react-tools.js
* In normal operation, these are added to the page as htmlDependencies.
*/
global.React = React;
global.ReactDOM = ReactDOM;
class Shout extends React.Component {
render() {
return <span>{this.props.message.toUpperCase()}</span>;
}
}
const FunctionalShout = ({ message }) => {
return <span>{message.toUpperCase()}</span>;
}
class TodoList extends React.Component {
render() {
return <ol>
{this.props.children.map((child, i) => {
return <li key={i}>{child}</li>;
})}
</ol>
}
}
// Converts a parse-xml style tree to an htmltools::tag style tree of JSON.
function objectToTag(obj) {
return {
name: obj.name,
attribs: obj.attributes,
children: obj.children.map(child => {
if (child.type === 'text') {
return child.text;
} else {
return objectToTag(child);
}
})
}
}
// Converts a string of markup to an htmltools::tag style tree of JSON.
function stringToTag(str) {
return objectToTag(parseXml(str).children[0]);
}
// Compares two parse-xml style trees for "deep" equality
function xmlEqual(x1, x2) {
if (x1.type === 'text'
&& x2.type === 'text'
&& x1.text === x2.text)
return true;
return x1.name === x2.name
// Test attributes for equality
&& Object.keys(x1).length === Object.keys(x2).length
&& Object.keys(x1).every(k => x1[k] === x2[k])
// Test children for equality
&& x1.children.length === x2.children.length
&& x1.children.every((child, i) => xmlEqual(child, x2.children[i]))
}
describe('window.reactR', () => {
describe('#hydrate() with HTML', () => {
it('hydrates an HTML5 component with a text child', () => {
const markup = '<h1>Hello</h1>';
assert.equal(
renderToString(parse(markup)),
renderToString(hydrate({}, stringToTag(markup)))
)
})
it('hydrates nested HTML5 components', () => {
const markup = '<div><h1>Hello</h1><p>Oh, hello.</p></div>'
assert.equal(
renderToString(parse(markup)),
renderToString(hydrate({}, stringToTag(markup)))
)
})
});
describe('#hydrate() with Components', () => {
it('should throw an exception with an unknown component', () => {
assert.throws(() => {
hydrate({ Shout: Shout }, stringToTag('<Bar/>'))
}, Error, /Unknown component/);
});
})
});