diff options
Diffstat (limited to 'preact/debug/test/browser/debug-hooks.test.js')
-rw-r--r-- | preact/debug/test/browser/debug-hooks.test.js | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/preact/debug/test/browser/debug-hooks.test.js b/preact/debug/test/browser/debug-hooks.test.js new file mode 100644 index 0000000..84bc028 --- /dev/null +++ b/preact/debug/test/browser/debug-hooks.test.js @@ -0,0 +1,111 @@ +import { createElement, render, Component } from 'preact'; +import { useState, useEffect } from 'preact/hooks'; +import 'preact/debug'; +import { act } from 'preact/test-utils'; +import { setupScratch, teardown } from '../../../test/_util/helpers'; + +/** @jsx createElement */ + +describe('debug with hooks', () => { + let scratch; + let errors = []; + let warnings = []; + + beforeEach(() => { + errors = []; + warnings = []; + scratch = setupScratch(); + sinon.stub(console, 'error').callsFake(e => errors.push(e)); + sinon.stub(console, 'warn').callsFake(w => warnings.push(w)); + }); + + afterEach(() => { + console.error.restore(); + console.warn.restore(); + teardown(scratch); + }); + + it('should throw an error when using a hook outside a render', () => { + class Foo extends Component { + componentWillMount() { + useState(); + } + + render() { + return this.props.children; + } + } + + class App extends Component { + render() { + return <p>test</p>; + } + } + const fn = () => + act(() => + render( + <Foo> + <App /> + </Foo>, + scratch + ) + ); + expect(fn).to.throw(/Hook can only be invoked from render/); + }); + + it('should throw an error when invoked outside of a component', () => { + function foo() { + useEffect(() => {}); // Pretend to use a hook + return <p>test</p>; + } + + const fn = () => + act(() => { + render(foo(), scratch); + }); + expect(fn).to.throw(/Hook can only be invoked from render/); + }); + + it('should throw an error when invoked outside of a component before render', () => { + function Foo(props) { + useEffect(() => {}); // Pretend to use a hook + return props.children; + } + + const fn = () => + act(() => { + useState(); + render(<Foo>Hello!</Foo>, scratch); + }); + expect(fn).to.throw(/Hook can only be invoked from render/); + }); + + it('should throw an error when invoked outside of a component after render', () => { + function Foo(props) { + useEffect(() => {}); // Pretend to use a hook + return props.children; + } + + const fn = () => + act(() => { + render(<Foo>Hello!</Foo>, scratch); + useState(); + }); + expect(fn).to.throw(/Hook can only be invoked from render/); + }); + + it('should throw an error when invoked inside an effect callback', () => { + function Foo(props) { + useEffect(() => { + useState(); + }); + return props.children; + } + + const fn = () => + act(() => { + render(<Foo>Hello!</Foo>, scratch); + }); + expect(fn).to.throw(/Hook can only be invoked from render/); + }); +}); |