@dolphinweex/himalaya
Version:
HTML to JSON parser
247 lines (233 loc) • 5.38 kB
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))
}
})