Skip to content

Instantly share code, notes, and snippets.

@tomhodgins
Last active August 31, 2020 01:03
Show Gist options
  • Save tomhodgins/2531889f0df061613520f275debcc893 to your computer and use it in GitHub Desktop.
Save tomhodgins/2531889f0df061613520f275debcc893 to your computer and use it in GitHub Desktop.
import {Document, DOMParser} from './deno-dom-wasm.ts'
import {assert} from 'https://deno.land/[email protected]/testing/asserts.ts'
const parseIntoHTMLDocument = (string = '') => new DOMParser().parseFromString(
String(string),
'text/html'
)
const html = `
<h1>Dummy HTML Content</h1>
<h2>Just for testing HTML parsers!</h2>
<p>This is some placeholder HTML content</p>
<ul>
<li>one
<li><b>two
<li><i>three</b>
<li>four</i>
</ul>
`
// What is DOMParser?
Deno.test('DOMParser exists', () =>
assert(DOMParser !== undefined)
)
Deno.test('DOMParser is a function', () =>
assert(typeof DOMParser === 'function')
)
Deno.test('DOMParser is constructable with "new"', () => {
try {
new DOMParser
} catch (error) {
throw Error('DOMParser could not be constructed')
}
})
Deno.test('DOMParser has a parseFromString property', () =>
assert(new DOMParser().parseFromString !== undefined)
)
Deno.test('parseFromString is a method', () =>
assert(typeof (new DOMParser().parseFromString) === 'function')
)
// What can parseFromString work with?
Deno.test('parseFromString works with "text/html" mode', () => {
try {
new DOMParser().parseFromString('', 'text/html')
} catch (error) {
throw Error('Parsing error')
}
})
Deno.test('parseFromString does not work with "text/xml" mode', () => {
let result
try {
// Not intended to be supported yet
result = new DOMParser().parseFromString('', 'text/xml')
} catch (error) {}
assert(result === undefined)
})
Deno.test('parseFromString does not work with "application/xml" mode', () => {
let result
try {
// Not intended to be supported yet
result = new DOMParser().parseFromString('', 'application/xml')
} catch (error) {}
assert(result === undefined)
})
// What does an empty HTML document look like?
Deno.test('parseFromString returns a Document object', () => {
assert(
parseIntoHTMLDocument() instanceof Document
)
})
Deno.test('Parsed document has documentElement', () => {
assert(parseIntoHTMLDocument().documentElement !== undefined)
assert(parseIntoHTMLDocument().documentElement.tagName === 'HTML')
})
Deno.test('Parsed document has a head property and element', () => {
assert(parseIntoHTMLDocument().head !== undefined)
assert(parseIntoHTMLDocument().head.tagName === 'HEAD')
assert(parseIntoHTMLDocument().head.parentElement.tagName === 'HTML')
})
Deno.test('Parsed document has a body property and element', () => {
assert(parseIntoHTMLDocument().body !== undefined)
assert(parseIntoHTMLDocument().body.tagName === 'BODY')
assert(parseIntoHTMLDocument().body.parentElement.tagName === 'HTML')
})
Deno.test('Empty parsed document matches expected string', () => {
assert(
parseIntoHTMLDocument().documentElement.outerHTML ===
`<html><head></head><body></body></html>`
)
})
// How are attributes parsed?
Deno.test('Unquoted attribute value parses okay', () => {
assert(
parseIntoHTMLDocument(`<html data-test=example>`)
.documentElement
.getAttribute('data-test') === 'example'
)
})
Deno.test('Single quoted attribute value parses okay', () => {
assert(
parseIntoHTMLDocument(`<html data-test='example'>`)
.documentElement
.getAttribute('data-test') === 'example'
)
})
Deno.test('Double quoted attribute value parses okay', () => {
assert(
parseIntoHTMLDocument(`<html data-test="example">`)
.documentElement
.getAttribute('data-test') === 'example'
)
})
Deno.test('Spaces around attributes okay', () => {
assert(
parseIntoHTMLDocument(`<html data-test
=
"example">`
)
.documentElement
.getAttribute('data-test') === 'example'
)
})
// How are tags parsed?
Deno.test('Custom elements parse okay', () => {
assert(
parseIntoHTMLDocument(`<custom-element></custom-element>`)
.querySelector('custom-element').tagName === 'CUSTOM-ELEMENT'
)
})
Deno.test('Unknown elements parse okay', () => {
assert(
parseIntoHTMLDocument(`<unknown></unknown>`)
.querySelector('unknown').tagName === 'UNKNOWN'
)
})
Deno.test('Self-closing tags parse okay', () => {
assert(
parseIntoHTMLDocument(`<input /><input />`)
.querySelectorAll('input').length === 2
)
})
Deno.test('Accidentally closed void tags parse okay', () => {
assert(
parseIntoHTMLDocument(`<input></input>`)
.querySelectorAll('input').length === 1
)
})
Deno.test('The list of active formatting elements is supported', () => {
assert(
parseIntoHTMLDocument(`
<ul>
<li><b>one</li>
<li><i>two</li>
<li><u>three</li>
<li>four</li>
<li>five</b></li>
<li>six</i></li>
<li>seven</u></li>
</ul>
`).documentElement.outerHTML
=== parseIntoHTMLDocument(`
<ul>
<li><b>one</b></li>
<li><b><i>two</i></b></li>
<li><b><i><u>three</u></i></b></li>
<li><b><i><u>four</u></i></b></li>
<li><b><i><u>five</u></i></b></li>
<li><i><u>six</u></i></li>
<li><u>seven</u></li>
</ul>
`).documentElement.outerHTML
)
})
// How are comments parsed?
Deno.test('Comments parse okay', () => {
assert(
parseIntoHTMLDocument(`<!-- comment -->`)
)
})
Deno.test('Comment after <html> opens parses in the right place', () => {
assert(
Array.from(
parseIntoHTMLDocument('<html><!-- comment -->').childNodes,
({outerHTML, data}) => outerHTML ?? data
).join('\n') === '<html><!-- comment --><head></head><body></body></html>'
)
})
Deno.test('Comments before <html> opens parses in the right place', () => {
assert(
Array.from(
parseIntoHTMLDocument('<!-- comment --><html>').childNodes,
({outerHTML, data}) => outerHTML ?? data
).join('\n') === '<!-- comment --><html><head></head><body></body></html>'
)
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment