summaryrefslogtreecommitdiff
path: root/preact/debug/test/browser/debug-hooks.test.js
diff options
context:
space:
mode:
Diffstat (limited to 'preact/debug/test/browser/debug-hooks.test.js')
-rw-r--r--preact/debug/test/browser/debug-hooks.test.js111
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/);
+ });
+});