Skip to content
Permalink
Browse files

merge master into branch

  • Loading branch information
JoviDeCroock committed Apr 28, 2019
2 parents 9d1ca02 + cc4b770 commit 5d8b3d55497c6c84a84d89d3c5c4a6cf04a5c27b
@@ -1,2 +1,3 @@
test/fixtures
test/ts/
*.ts
@@ -1,5 +1,8 @@
sudo: false

notifications:
email: false

language: node_js

node_js:
@@ -16,6 +16,7 @@
"$_prevVNode": "__t",
"$__html": "__html",
"$_ancestorComponent": "__a",
"$_pendingError": "__E",
"$_processingException": "__p"
}
}
@@ -1,11 +1,11 @@
import { Ref } from '../../src/index';
import { Ref } from '../..';
import {
Component as PreactComponent,
VNode as PreactVNode,
FunctionalComponent as PreactFunctionalComponent
} from '../../src/internal';

export { ComponentChildren } from '../../src/index';
export { ComponentChildren } from '../..';

export { PreactElement } from '../../src/internal';

@@ -28,6 +28,7 @@
"$_prevVNode": "__t",
"$__html": "__html",
"$_ancestorComponent": "__a",
"$_pendingError": "__E",
"$_processingException": "__p"
}
}
@@ -101,6 +101,12 @@ export function initDebug() {
if (oldBeforeDiff) oldBeforeDiff(vnode);
};

options.hook = (comp) => {
if (!comp) {
throw new Error('Hook can only be invoked from render methods.');
}
};

const warn = (property, err) => ({
get() {
throw new Error(`getting vnode.${property} is deprecated, ${err}`);
@@ -124,19 +130,19 @@ export function initDebug() {
options.diffed = (vnode) => {
if (vnode._component && vnode._component.__hooks) {
let hooks = vnode._component.__hooks;
if (hooks._list.length > 0) {
hooks._list.forEach(hook => {
if (hook._callback && (!hook._args || !Array.isArray(hook._args))) {
console.warn(
`In ${vnode.type.name || vnode.type} you are calling useMemo/useCallback without passing arguments.\n` +
`This is a noop since it will not be able to memoize, it will execute it every render.`
);
}
});
}
hooks._list.forEach(hook => {
if (hook._callback && (!hook._args || !Array.isArray(hook._args))) {
/* istanbul ignore next */
console.warn(
`In ${vnode.type.name || vnode.type} you are calling useMemo/useCallback without passing arguments.\n` +
`This is a noop since it will not be able to memoize, it will execute it every render.`
);
}
});
if (hooks._pendingEffects.length > 0) {
hooks._pendingEffects.forEach((effect) => {
if (!effect._args || !Array.isArray(effect._args)) {
/* istanbul ignore next */
throw new Error('You should provide an array of arguments as the second argument to the "useEffect" hook.\n\n' +
'Not doing so will invoke this effect on every render.\n\n' +
'This effect can be found in the render of ' + (vnode.type.name || vnode.type) + '.');
@@ -146,6 +152,7 @@ export function initDebug() {
if (hooks._pendingLayoutEffects.length > 0) {
hooks._pendingLayoutEffects.forEach((layoutEffect) => {
if (!layoutEffect._args || !Array.isArray(layoutEffect._args)) {
/* istanbul ignore next */
throw new Error('You should provide an array of arguments as the second argument to the "useEffect" hook.\n\n' +
'Not doing so will invoke this effect on every render.\n\n' +
'This effect can be found in the render of ' + (vnode.type.name || vnode.type) + '.');
@@ -1,5 +1,6 @@
import { createElement as h, options, render, createRef, Component, Fragment } from 'preact';
import { useState, useEffect, useLayoutEffect, useMemo, useCallback } from 'preact/hooks';
import { act } from 'preact/test-utils';
import { setupScratch, teardown, clearOptions, serializeHtml } from '../../../test/_util/helpers';
import { serializeVNode, initDebug } from '../../src/debug';
import * as PropTypes from 'prop-types';
@@ -76,6 +77,30 @@ describe('debug', () => {
expect(fn).to.throw(/createElement/);
});

it('should print an error on invalid object component', () => {
let fn = () => render(h({}), scratch);
expect(fn).to.throw(/createElement/);
});

it('should throw an error when using a hook outside a render', () => {
class App extends Component {
componentWillMount() {
useState();
}

render() {
return <p>test</p>;
}
}
const fn = () => act(() => render(<App />, scratch));
expect(fn).to.throw(/Hook can only be invoked from render/);
});

it('should throw an error when invoked outside of a component', () => {
const fn = () => act(() => useState());
expect(fn).to.throw(/Hook can only be invoked from render/);
});

it('should throw an error for argumentless useEffect hooks', () => {
const App = () => {
const [state] = useState('test');
@@ -84,7 +109,7 @@ describe('debug', () => {
<p>{state}</p>
);
};
const fn = () => render(<App />, scratch);
const fn = () => act(() => render(<App />, scratch));
expect(fn).to.throw(/You should provide an array of arguments/);
});

@@ -96,7 +121,7 @@ describe('debug', () => {
<p>{state}</p>
);
};
const fn = () => render(<App />, scratch);
const fn = () => act(() => render(<App />, scratch));
expect(fn).to.throw(/You should provide an array of arguments/);
});

@@ -109,7 +134,7 @@ describe('debug', () => {
<p>{state}</p>
);
};
const fn = () => render(<App />, scratch);
const fn = () => act(() => render(<App />, scratch));
expect(fn).to.not.throw();
});

@@ -152,6 +177,15 @@ describe('debug', () => {
expect(warnings.length).to.equal(2);
});

it('should warn when non-array args is passed', () => {
const App = () => {
const foo = useMemo(() => 'foo', 12);
return <p>{foo}</p>;
};
render(<App />, scratch);
expect(warnings[0]).to.match(/without passing arguments/);
});

it('should print an error on invalid refs', () => {
let fn = () => render(<div ref="a" />, scratch);
expect(fn).to.throw(/createRef/);
@@ -13,6 +13,7 @@ import ProfilerDemo from './profiler';
import KeyBug from './key_bug';
import StateOrderBug from './stateOrderBug';
import PeopleBrowser from './people';
import StyledComp from './styled-components';
import { initDevTools } from 'preact/debug/src/devtools';
import { initDebug } from 'preact/debug/src/debug';
import DevtoolsDemo from './devtools';
@@ -69,6 +70,7 @@ class App extends Component {
<Link href="/empty-fragment" activeClassName="active">Empty Fragment</Link>
<Link href="/people" activeClassName="active">People Browser</Link>
<Link href="/state-order" activeClassName="active">State Order</Link>
<Link href="/styled-components" activeClassName="active">Styled Components</Link>
</nav>
</header>
<main>
@@ -96,6 +98,7 @@ class App extends Component {
<DevtoolsDemo path="/devtools" />
<EmptyFragment path="/empty-fragment" />
<PeopleBrowser path="/people/:user?" />
<StyledComp path="/styled-components" />
</Router>
</main>
</div>

0 comments on commit 5d8b3d5

Please sign in to comment.
You can’t perform that action at this time.