Skip to content

Commit

Permalink
Merge 4cfb8dc into 98f0d7e
Browse files Browse the repository at this point in the history
  • Loading branch information
JoviDeCroock committed Apr 5, 2019
2 parents 98f0d7e + 4cfb8dc commit 0857d92
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 0 deletions.
5 changes: 5 additions & 0 deletions debug/src/debug.js
Expand Up @@ -2,6 +2,7 @@ import { checkPropTypes } from 'prop-types';
import { getDisplayName } from './devtools/custom';
import { options, toChildArray } from 'preact';
import { ELEMENT_NODE, DOCUMENT_NODE, DOCUMENT_FRAGMENT_NODE } from './constants';
import debugTable from './debugTable';

export function initDebug() {
/* eslint-disable no-console */
Expand Down Expand Up @@ -46,6 +47,10 @@ export function initDebug() {
throw new Error('Invalid type passed to createElement(): '+(Array.isArray(type) ? 'array' : type));
}

if (type==='table') {
debugTable(children);
}

if (
vnode.ref!==undefined &&
typeof vnode.ref!=='function' &&
Expand Down
35 changes: 35 additions & 0 deletions debug/src/debugTable.js
@@ -0,0 +1,35 @@
import { toChildArray } from 'preact';

const FIRST_LEVEL_TAGS = ['tbody', 'thead', 'tfoot'];

export default function debugTable(children) {
const firstLevelChildren = toChildArray(children);
for (let i = 0; i<firstLevelChildren.length; i++) {
const child = firstLevelChildren[i];
if (FIRST_LEVEL_TAGS.indexOf(child.type)===-1) {
console.error('Expected a <tbody>, <thead> or <tfoot> as the first child of <table>.');
return;
}
const isHead = child.type === 'thead';
const secondLevelChildren = toChildArray(child.props.children);
for (let j = 0; j<secondLevelChildren.length; j++) {
const secondLevelChild = secondLevelChildren[j];
if (secondLevelChild.type!=='tr') {
console.error('Expected a <tr> as a child of <tbody>,...');
return;
}
const thirthLevelChildren = toChildArray(secondLevelChild.props.children);
for (let k = 0; k<thirthLevelChildren.length; k++) {
const thirthLevelChild = thirthLevelChildren[k];
if (isHead && thirthLevelChild.type!=='th') {
console.error('Expected a <th> as a child of <thead.tr>');
return;
}
else if (!isHead && thirthLevelChild.type!=='td') {
console.error('Expected a <td> as a child of <tbody/tfoot.tr>');
return;
}
}
}
}
}
76 changes: 76 additions & 0 deletions debug/test/browser/debug.test.js
Expand Up @@ -291,6 +291,82 @@ describe('debug', () => {
});
});

describe('table markup', () => {
it('missing <tbody>/<thead>/<tfoot>', () => {
const Table = () => (
<table>
<td>Hi</td>
</table>
);
render(<Table />, scratch);
expect(console.error).to.be.calledOnce;
});

it('missing <tr>', () => {
const Table = () => (
<table>
<tbody>
<td>Hi</td>
</tbody>
</table>
);
render(<Table />, scratch);
expect(console.error).to.be.calledOnce;
});

it('missing <td>', () => {
const Table = () => (
<table>
<tbody>
<tr>
<div />
</tr>
</tbody>
</table>
);
render(<Table />, scratch);
expect(console.error).to.be.calledOnce;
});

it('Using <td> instead of <th> in <thead>', () => {
const Table = () => (
<table>
<thead>
<tr>
<td>Hi</td>
</tr>
</thead>
</table>
);
render(<Table />, scratch);
expect(console.error).to.be.calledOnce;
});

it('Accepts well formed table', () => {
const Table = () => (
<table>
<thead>
<tr>
<th>Head</th>
</tr>
</thead>
<tbody>
<tr>
<td>Body</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>Body</td>
</tr>
</tfoot>
</table>
);
render(<Table />, scratch);
expect(console.error).to.not.be.called;
});
});

describe('PropTypes', () => {
it('should fail if props don\'t match prop-types', () => {
function Foo(props) {
Expand Down

0 comments on commit 0857d92

Please sign in to comment.