1 | var Parser = require("../lib/tlk-htmlparser");
|
2 | var Tree = require("../lib/htmltree");
|
3 | var JSON = require("../lib/tolojson");
|
4 |
|
5 | describe('htmlparser', function () {
|
6 | function check(content, expected) {
|
7 | try {
|
8 | var txtExpected = JSON.stringify(expected, ' ');
|
9 | var result = Parser.parse(content);
|
10 | var txtResult = JSON.stringify(result, ' ');
|
11 | if (txtExpected != txtResult) {
|
12 | fail(content + "\n"
|
13 | + "======== EXPECTED ========\n"
|
14 | + txtExpected + "\n"
|
15 | + "========= RESULT =========\n"
|
16 | + txtResult + "\n");
|
17 | }
|
18 | }
|
19 | catch (ex) {
|
20 | if (ex.msg) {
|
21 | fail("Exception: " + JSON.stringify(ex));
|
22 | } else {
|
23 | fail(ex + "\n" + ex.stack);
|
24 | }
|
25 | }
|
26 | }
|
27 | it('should deal with simple text', function () {
|
28 | check(
|
29 | 'Hello world!',
|
30 | {children:[{type: Tree.TEXT, text: 'Hello world!'}]}
|
31 | );
|
32 | });
|
33 | it('should deal with simple text with HTML entities', function () {
|
34 | check(
|
35 | 'a<b',
|
36 | {children:[
|
37 | {type: Tree.TEXT, text: 'a'},
|
38 | {type: Tree.ENTITY, text: '<', pos: 1},
|
39 | {type: Tree.TEXT, text: 'b'}
|
40 | ]}
|
41 | );
|
42 | });
|
43 | it('should deal with simple text with HTML entities and spaces', function () {
|
44 | check(
|
45 | 'a < b',
|
46 | {children:[
|
47 | {type: Tree.TEXT, text: 'a '},
|
48 | {type: Tree.ENTITY, text: '<', pos: 2},
|
49 | {type: Tree.TEXT, text: ' b'}
|
50 | ]}
|
51 | );
|
52 | });
|
53 | it('should deal with lonely ampercents', function () {
|
54 | check(
|
55 | 'a&b',
|
56 | {children:[
|
57 | {type: Tree.TEXT, text: 'a&b'}
|
58 | ]}
|
59 | );
|
60 | });
|
61 | it('should deal with simple void elements', function () {
|
62 | ["area", "base", "br", "col", "command", "embed", "hr", "img", "input", "keygen", "link", "meta", "param", "source", "track", "wbr"].forEach(function (name) {
|
63 | check(
|
64 | '<' + name + '>',
|
65 | {children:[{type: Tree.TAG, name: name, attribs: {}, children:[], pos: 0, void: true}]}
|
66 | );
|
67 | });
|
68 | });
|
69 | it('should deal with simple autoclose elements', function () {
|
70 | check(
|
71 | '<$number/>',
|
72 | {children:[
|
73 | {type: Tree.TAG, name: '$number', attribs: {}, children:[], pos: 0, autoclose: true}
|
74 | ]}
|
75 | );
|
76 | });
|
77 | it('should deal with simple autoclose elements with attributes', function () {
|
78 | check(
|
79 | '<$number toto="yes"/>',
|
80 | {children:[
|
81 | {type: Tree.TAG, name: '$number', attribs: {toto: "yes"}, children:[], pos: 0, autoclose: true}
|
82 | ]}
|
83 | );
|
84 | });
|
85 | it('should deal with simple autoclose elements with attributes and space before last slash', function () {
|
86 | check(
|
87 | '<$number toto="yes" />',
|
88 | {children:[
|
89 | {type: Tree.TAG, name: '$number', attribs: {toto: "yes"}, children:[], pos: 0, autoclose: true}
|
90 | ]}
|
91 | );
|
92 | });
|
93 | it('should deal with simple autoclose element in a DIV', function () {
|
94 | check(
|
95 | '<div><$number/></div>',
|
96 | {children:[{
|
97 | type: Tree.TAG, name: "div", attribs: {}, children:[
|
98 | {type: Tree.TAG, name: '$number', attribs: {}, children:[], pos: 5, autoclose: true}
|
99 | ], pos: 0
|
100 | }]}
|
101 | );
|
102 | });
|
103 | it('should deal with simple autoclose elements with namespace', function () {
|
104 | check(
|
105 | '<tag:div/>',
|
106 | {children:[
|
107 | {type: Tree.TAG, name: 'tag:div', attribs: {}, children:[], pos: 0, autoclose: true}
|
108 | ]}
|
109 | );
|
110 | });
|
111 | it('should deal with attributes', function () {
|
112 | check(
|
113 | 'name: <input disabled type="text" size=\'4\'>',
|
114 | {
|
115 | "children": [
|
116 | {"type": 2, "text": "name: "},
|
117 | {
|
118 | "type": 1,
|
119 | "name": "input",
|
120 | "attribs": {"disabled": null, "type": "text", "size": "4"},
|
121 | "children": [],
|
122 | "pos": 6,
|
123 | "void": true
|
124 | }]
|
125 | }
|
126 | );
|
127 | });
|
128 | it('should deal with attributes and nested quotes', function () {
|
129 | check(
|
130 | '<a href="javascript:alert(\\"Yo!\\")">',
|
131 | {
|
132 | "children": [
|
133 | {
|
134 | "type": 1,
|
135 | "name": "a",
|
136 | "attribs": {"href": "javascript:alert(\"Yo!\")"},
|
137 | "children": [],
|
138 | "pos": 0
|
139 | }]
|
140 | }
|
141 | );
|
142 | });
|
143 | it('should deal with nested tags', function () {
|
144 | check(
|
145 | 'a<div>c<b>e</b>d</div>b',
|
146 | {
|
147 | "children": [
|
148 | {"type": 2, "text": "a"},
|
149 | {
|
150 | "type": 1,
|
151 | "name": "div",
|
152 | "attribs": {},
|
153 | "children": [
|
154 | {"type": 2, "text": "c"},
|
155 | {
|
156 | "type": 1,
|
157 | "name": "b",
|
158 | "attribs": {},
|
159 | "children": [{"type": 2, "text": "e"}],
|
160 | "pos": 7
|
161 | },
|
162 | {"type": 2, "text": "d"}],
|
163 | "pos": 1
|
164 | },
|
165 | {"type": 2, "text": "b"}]
|
166 | }
|
167 | );
|
168 | });
|
169 | it('should deal with comments', function () {
|
170 | check(
|
171 | 'Hello<!-- Bouh! -->World!',
|
172 | {
|
173 | "children": [
|
174 | {"type": 2, "text": "Hello"},
|
175 | {"type": 5, "text": " Bouh! ", "pos": 5},
|
176 | {"type": 2, "text": "World!"}]
|
177 | }
|
178 | );
|
179 | });
|
180 | it('should deal with doc types', function () {
|
181 | check(
|
182 | '<!DOCTYPE html>',
|
183 | {
|
184 | "children": [
|
185 | {
|
186 | "type": 6,
|
187 | "name": "DOCTYPE",
|
188 | "attribs": {"html": null},
|
189 | "pos": 0
|
190 | }]
|
191 | } );
|
192 | });
|
193 | it('should deal with processing', function () {
|
194 | check(
|
195 | '<?xml-stylesheet href="default.css" title="Default style"?>',
|
196 | {
|
197 | "children": [
|
198 | {
|
199 | "type": 4,
|
200 | "name": "xml-stylesheet",
|
201 | "attribs": {
|
202 | "href": "default.css",
|
203 | "title": "Default style"
|
204 | },
|
205 | "pos": 0
|
206 | }]
|
207 | }
|
208 | );
|
209 | });
|
210 | });
|
211 |
|
212 |
|