import { h, render, rerender, Component } from 'preact'; import assertJsx from 'preact-jsx-chai'; import sinonChai from 'sinon-chai'; chai.use(assertJsx); chai.use(sinonChai); import Markup from 'src'; /*eslint-env browser,mocha*/ /*global sinon,expect,chai*/ describe('Markup', () => { let scratch; before( () => { scratch = document.createElement('div'); (document.body || document.documentElement).appendChild(scratch); }); beforeEach( () => { scratch.innerHTML = ''; }); after( () => { scratch.parentNode.removeChild(scratch); scratch = null; }); it('should render valid JSX', () => { expect( ).to.eql(
hello!

asdflkj

); }); it('should render simple static markup', () => { let markup = `hello!

asdflkj

`; render(, scratch); expect(scratch.firstChild.innerHTML).to.equal(markup); }); it('should render xml', () => { render(, scratch); expect(scratch.firstChild.innerHTML).to.equal('
'); }); it('should call onError for invalid XML', () => { let onError = sinon.spy(); render(, scratch); expect(scratch.firstChild.innerHTML).to.equal(''); expect(onError).to.have.been.calledOnce; expect(onError.firstCall.args[0]) .to.have.property('error') .that.is.an('error') .with.property('message') .that.is.a('string') .that.matches(/(failed|invalid|parse)/i); }); it('should render html', () => { let markup = '
'; render(, scratch); expect(scratch.firstChild.innerHTML).to.equal(markup); }); it('should mercilessly render invalid HTML as one does', () => { let onError = sinon.spy(); render(, scratch); expect(onError).not.to.have.been.called; expect(scratch.firstChild.innerHTML).to.equal('<2-element> <2/>
'); }); it('should render invalid HTML to the correct JSX', () => { expect( ).to.eql(
<2-element> <2/>
); }); it('should render mapped components from XML', () => { const Foo = ({ a, b, camelCasedProperty, children }) => (
{ children }
); expect( ).to.eql(
); let markup = `italicbold`; expect( ).to.eql(
italic bold
); }); it('should correctly map XML properties', () => { const Foo = ({camelCasedProperty, children}) => (
{ children }
); expect( ).to.eql(
); expect( ).to.eql(
); expect( ).to.eql(
); }); it('should correctly map HTML properties', () => { const Foo = ({camelCasedProperty, children}) => (
{ children }
); //Notice that camelCasedProperty is gone in the output cause it's mapped in `prop.camelcasedproperty` // and Foo isn't aware of it expect( ).to.eql(
); expect( ).to.eql(
); expect( ).to.eql(
); }); it('should render mapped components from HTML', () => { const XFoo = ({ p, camelCasedProperty, children }) => (
hello { children }
); expect( ).to.eql(
hello
); let markup = `italicbold`; expect( ).to.eql(
hello{' '} italic bold
); }); describe('allow-scripts option', () => { before( () => { window.stub = sinon.stub(); }); beforeEach( () => { window.stub.reset(); }); after( () => { delete window.stub; }); it('should ignore script tags by default', () => { let markup = `hello!

asdflkj

`; render(, scratch); markup = `hello!

asdflkj

`; render(, scratch); expect(window.stub).not.to.have.been.called; }); it('should allow script tags if allow-scripts is enabled', () => { let markup = `hello!

asdflkj

`; render(, scratch); expect(window.stub).to.have.been.calledOnce; }); }); describe('allow-events option', () => { before( () => { window.stub = sinon.stub(); }); beforeEach( () => { window.stub.reset(); }); after( () => { delete window.stub; }); it('should correctly proxy on* handlers defined as strings', () => { let markup = `
Hello world
`; render(, scratch); let element = scratch.childNodes[0]; let ev = document.createEvent("MouseEvent"); ev.initMouseEvent("click"); expect(window.stub.called,"stub should not be called before click handler").to.equal(false); element.dispatchEvent(ev); expect(window.stub.called,"stub should be called from click handler").to.equal(true); expect(window.stub, "click handler should be supplied event as argument").to.have.been.calledWithExactly(ev); }); it('should NOT proxy on* handlers if allow-events is not enabled', (done) => { let markup = `
Hello world
`; let error = null; render(, scratch); let element = scratch.childNodes[0]; let ev = document.createEvent("MouseEvent"); ev.initMouseEvent("click"); // Errors thrown by dispatchEvent are always uncaught exceptions window.onerror = (e) => { expect(window.stub.called,"stub should NOT be called from click handler").to.equal(false); done(); }; element.dispatchEvent(ev); }); }); it('should pipe parse errors to console', () => { sinon.stub(console, 'error'); let invalidXml = `

Test with & symbol

`; render(, scratch); expect(console.error) .to.have.been.calledOnce .and.calledWithMatch('preact-markup: Error: error on line 2 at column 21: xmlParseEntityRef: no name'); console.error.restore(); }); it('should trim whitespace by default', () => { expect( ).to.eql(
hello! {' '}

asdflkj

); expect( ).to.eql(
{' '}
); }); it('should trim all whitespace for trim="all"', () => { expect( ).to.eql(
hello!

asdflkj

); expect( ).to.eql(
); }); });