304 lines
6.2 KiB
JavaScript
304 lines
6.2 KiB
JavaScript
import test from 'ava'
|
|
import { parse, parseDefaults } from '../lib'
|
|
import { formatAttributes } from '../lib/format'
|
|
|
|
test('formatAttributes() should return a key-value array', (t) => {
|
|
const attributes = ['foo="bar"', 'disabled', "cake='man'"]
|
|
t.deepEqual(formatAttributes(attributes), [
|
|
{ key: 'foo', value: 'bar' },
|
|
{ key: 'disabled', value: null },
|
|
{ key: 'cake', value: 'man' },
|
|
])
|
|
})
|
|
|
|
test('parse() should emit positions if includePositions is true', (t) => {
|
|
t.deepEqual(
|
|
parse(
|
|
'<h1>Hello world</h1>',
|
|
Object.assign({}, parseDefaults, { includePositions: true }),
|
|
),
|
|
[
|
|
{
|
|
type: 'element',
|
|
tagName: 'h1',
|
|
attributes: [],
|
|
children: [
|
|
{
|
|
type: 'text',
|
|
content: 'Hello world',
|
|
position: {
|
|
start: {
|
|
index: 4,
|
|
line: 0,
|
|
column: 4,
|
|
},
|
|
end: {
|
|
index: 15,
|
|
line: 0,
|
|
column: 15,
|
|
},
|
|
},
|
|
},
|
|
],
|
|
position: {
|
|
start: {
|
|
index: 0,
|
|
line: 0,
|
|
column: 0,
|
|
},
|
|
end: {
|
|
index: 20,
|
|
line: 0,
|
|
column: 20,
|
|
},
|
|
},
|
|
},
|
|
],
|
|
)
|
|
})
|
|
|
|
/*
|
|
These tests ensure the parser and v1 formatting align.
|
|
|
|
These tests mainly serve as a gauntlet for generic use.
|
|
Do not add any more of these kinds of tests, instead
|
|
test the more granular bits.
|
|
*/
|
|
|
|
test('parse() should pass the Hello World case', (t) => {
|
|
const html = '<html><h1>Hello, World</h1></html>'
|
|
const data = [
|
|
{
|
|
type: 'element',
|
|
tagName: 'html',
|
|
attributes: [],
|
|
children: [
|
|
{
|
|
type: 'element',
|
|
tagName: 'h1',
|
|
attributes: [],
|
|
children: [
|
|
{
|
|
type: 'text',
|
|
content: 'Hello, World',
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
]
|
|
t.deepEqual(data, parse(html, parseDefaults))
|
|
})
|
|
|
|
test('parse() should work for mixed attributes', (t) => {
|
|
const html =
|
|
"<div class='section widget'><b disabled>Poop</b><p>Pee</p></div>"
|
|
const data = [
|
|
{
|
|
type: 'element',
|
|
tagName: 'div',
|
|
attributes: [
|
|
{
|
|
key: 'class',
|
|
value: 'section widget',
|
|
},
|
|
],
|
|
children: [
|
|
{
|
|
type: 'element',
|
|
tagName: 'b',
|
|
attributes: [
|
|
{
|
|
key: 'disabled',
|
|
value: null,
|
|
},
|
|
],
|
|
children: [
|
|
{
|
|
type: 'text',
|
|
content: 'Poop',
|
|
},
|
|
],
|
|
},
|
|
{
|
|
type: 'element',
|
|
tagName: 'p',
|
|
attributes: [],
|
|
children: [
|
|
{
|
|
type: 'text',
|
|
content: 'Pee',
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
]
|
|
t.deepEqual(data, parse(html, parseDefaults))
|
|
})
|
|
|
|
test('parse() should work for commented html', (t) => {
|
|
const html = '<b><!--comment text-->words</b>'
|
|
const data = [
|
|
{
|
|
type: 'element',
|
|
tagName: 'b',
|
|
attributes: [],
|
|
children: [
|
|
{
|
|
type: 'comment',
|
|
content: 'comment text',
|
|
},
|
|
{
|
|
type: 'text',
|
|
content: 'words',
|
|
},
|
|
],
|
|
},
|
|
]
|
|
t.deepEqual(data, parse(html, parseDefaults))
|
|
})
|
|
|
|
test('parse() should work for style properties', (t) => {
|
|
const html =
|
|
"<div style='width: 360px; height: 120px; background-color: #fff'></div>"
|
|
const data = [
|
|
{
|
|
type: 'element',
|
|
tagName: 'div',
|
|
attributes: [
|
|
{
|
|
key: 'style',
|
|
value: 'width: 360px; height: 120px; background-color: #fff',
|
|
},
|
|
],
|
|
children: [],
|
|
},
|
|
]
|
|
t.deepEqual(data, parse(html, parseDefaults))
|
|
})
|
|
|
|
test('parse() should work on data-* attributes', (t) => {
|
|
const html = "<div data-num=0 data-word='poop' data-cake='2'></div>"
|
|
const data = [
|
|
{
|
|
type: 'element',
|
|
tagName: 'div',
|
|
attributes: [
|
|
{
|
|
key: 'data-num',
|
|
value: '0',
|
|
},
|
|
{
|
|
key: 'data-word',
|
|
value: 'poop',
|
|
},
|
|
{
|
|
key: 'data-cake',
|
|
value: '2',
|
|
},
|
|
],
|
|
children: [],
|
|
},
|
|
]
|
|
t.deepEqual(data, parse(html, parseDefaults))
|
|
})
|
|
|
|
test('should work on unclosed tags', (t) => {
|
|
const html = '<p>One two<p>three four'
|
|
const data = [
|
|
{
|
|
type: 'element',
|
|
tagName: 'p',
|
|
attributes: [],
|
|
children: [
|
|
{
|
|
type: 'text',
|
|
content: 'One two',
|
|
},
|
|
],
|
|
},
|
|
{
|
|
type: 'element',
|
|
tagName: 'p',
|
|
attributes: [],
|
|
children: [
|
|
{
|
|
type: 'text',
|
|
content: 'three four',
|
|
},
|
|
],
|
|
},
|
|
]
|
|
t.deepEqual(data, parse(html, parseDefaults))
|
|
})
|
|
|
|
test('should not set custom attrs to zeroes', (t) => {
|
|
const html = "<div custom-attr=''></div>"
|
|
const data = [
|
|
{
|
|
type: 'element',
|
|
tagName: 'div',
|
|
attributes: [
|
|
{
|
|
key: 'custom-attr',
|
|
value: '',
|
|
},
|
|
],
|
|
children: [],
|
|
},
|
|
]
|
|
t.deepEqual(data, parse(html, parseDefaults))
|
|
})
|
|
|
|
test('custom tags should appear in the ast', (t) => {
|
|
{
|
|
const html = '<result>Hello</result>'
|
|
const data = [
|
|
{
|
|
type: 'element',
|
|
tagName: 'result',
|
|
attributes: [],
|
|
children: [
|
|
{
|
|
type: 'text',
|
|
content: 'Hello',
|
|
},
|
|
],
|
|
},
|
|
]
|
|
t.deepEqual(data, parse(html, parseDefaults))
|
|
}
|
|
|
|
{
|
|
const html = `<div><h1>Hi there</h1><result></result></div>`
|
|
const data = [
|
|
{
|
|
type: 'element',
|
|
tagName: 'div',
|
|
attributes: [],
|
|
children: [
|
|
{
|
|
type: 'element',
|
|
tagName: 'h1',
|
|
attributes: [],
|
|
children: [
|
|
{
|
|
type: 'text',
|
|
content: 'Hi there',
|
|
},
|
|
],
|
|
},
|
|
{
|
|
type: 'element',
|
|
tagName: 'result',
|
|
attributes: [],
|
|
children: [],
|
|
},
|
|
],
|
|
},
|
|
]
|
|
t.deepEqual(data, parse(html, parseDefaults))
|
|
}
|
|
})
|