Skip to content

Commit 598c8f8

Browse files
author
Todd Kloots
committed
[fixed] Label test should require a label for placeholder anchors (resolves #68)
[fixed] Label assertion errors if label is a number (resolves #67)
1 parent 9e8b71a commit 598c8f8

2 files changed

Lines changed: 42 additions & 27 deletions

File tree

lib/__tests__/index-test.js

Lines changed: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -183,39 +183,39 @@ describe('tags', () => {
183183
describe('placeholder links without href', () => {
184184
it('does not warn', () => {
185185
doNotExpectWarning(assertions.tags.a.HASH_HREF_NEEDS_BUTTON.msg, () => {
186-
<a class="foo" />;
186+
<a class="foo"/>;
187187
});
188188
});
189189
});
190190

191191
describe('placeholder links without tabindex', () => {
192192
it('does not warn', () => {
193193
doNotExpectWarning(assertions.tags.a.TABINDEX_NEEDS_BUTTON.msg, () => {
194-
<a class="foo" />;
194+
<a class="foo"/>;
195195
});
196196
});
197197
});
198198

199199
describe('with [href="#"]', () => {
200200
it('warns', () => {
201201
expectWarning(assertions.tags.a.HASH_HREF_NEEDS_BUTTON.msg, () => {
202-
<a onClick={k} href="#" />;
202+
<a onClick={k} href="#"/>;
203203
});
204204
});
205205
});
206206

207207
describe('with [tabIndex="0"] and no href', () => {
208208
it('warns', () => {
209209
expectWarning(assertions.tags.a.TABINDEX_NEEDS_BUTTON.msg, () => {
210-
<a onClick={k} tabIndex="0" />;
210+
<a onClick={k} tabIndex="0"/>;
211211
});
212212
});
213213
});
214214

215215
describe('with a real href', () => {
216216
it('does not warn', () => {
217217
doNotExpectWarning(assertions.tags.a.HASH_HREF_NEEDS_BUTTON.msg, () => {
218-
<a onClick={k} href="/foo/bar" />;
218+
<a onClick={k} href="/foo/bar"/>;
219219
});
220220
});
221221
});
@@ -248,55 +248,67 @@ describe('labels', () => {
248248

249249
it('warns if there is no label on an interactive element', () => {
250250
expectWarning(assertions.render.NO_LABEL.msg, () => {
251-
<button />;
251+
<button/>;
252+
});
253+
});
254+
255+
it('warns if there is no label on a placeholder link', () => {
256+
expectWarning(assertions.render.NO_LABEL.msg, () => {
257+
<a/>;
258+
});
259+
});
260+
261+
it('does not warn when a placeholder link has a label', () => {
262+
doNotExpectWarning(assertions.render.NO_LABEL.msg, () => {
263+
<a>foo</a>;
252264
});
253265
});
254266

255267
it('warns if there is no label on an element with an ARIA role', () => {
256268
expectWarning(assertions.render.NO_LABEL.msg, () => {
257-
<span role="button" />;
269+
<span role="button"/>;
258270
});
259271
});
260272

261273
it('does not warn when `role="presentation"`', () => {
262274
doNotExpectWarning(assertions.render.NO_LABEL.msg, () => {
263-
<img role="presentation" />;
275+
<img role="presentation"/>;
264276
});
265277
});
266278

267279
it('does not warn when `role="none"`', () => {
268280
doNotExpectWarning(assertions.render.NO_LABEL.msg, () => {
269-
<img role="none" />;
281+
<img role="none"/>;
270282
});
271283
});
272284

273285
it('does not warn when `aria-hidden="true"`', () => {
274286
doNotExpectWarning(assertions.render.NO_LABEL.msg, () => {
275-
<button aria-hidden="true" />;
287+
<button aria-hidden="true"/>;
276288
});
277289
});
278290

279291
it('warns when `aria-hidden="false"`', () => {
280292
expectWarning(assertions.render.NO_LABEL.msg, () => {
281-
<button aria-hidden="false" />;
293+
<button aria-hidden="false"/>;
282294
});
283295
});
284296

285297
it('does not warn if the element is not interactive', () => {
286298
doNotExpectWarning(assertions.render.NO_LABEL.msg, () => {
287-
<div />;
299+
<div/>;
288300
});
289301
});
290302

291303
it('does not warn if there is an aria-label', () => {
292304
doNotExpectWarning(assertions.render.NO_LABEL.msg, () => {
293-
<button aria-label="foo" />;
305+
<button aria-label="foo"/>;
294306
});
295307
});
296308

297309
it('does not warn if there is an aria-labelled-by', () => {
298310
doNotExpectWarning(assertions.render.NO_LABEL.msg, () => {
299-
<button aria-labelled-by="foo" />;
311+
<button aria-labelled-by="foo"/>;
300312
});
301313
});
302314

@@ -355,12 +367,6 @@ describe('labels', () => {
355367
});
356368
});
357369

358-
it('does not warn if an anchor has no href', () => {
359-
doNotExpectWarning(assertions.render.NO_LABEL.msg, () => {
360-
<a/>;
361-
});
362-
});
363-
364370
it('warns if an anchor has a tabIndex but no href', () => {
365371
expectWarning(assertions.render.NO_LABEL.msg, () => {
366372
<a tabIndex="0"/>;
@@ -438,7 +444,7 @@ describe('labels', () => {
438444
render: function() {
439445
return (
440446
<div className="foo">
441-
<span><span><img /></span></span>
447+
<span><span><img/></span></span>
442448
</div>
443449
);
444450
}
@@ -454,7 +460,7 @@ describe('labels', () => {
454460
render: function() {
455461
return (
456462
<div className="foo">
457-
<span><span>Foo <img /></span></span>
463+
<span><span>Foo <img/></span></span>
458464
</div>
459465
);
460466
}
@@ -521,11 +527,10 @@ describe('labels', () => {
521527
});
522528

523529
expectWarning(assertions.render.NO_LABEL.msg, () => {
524-
React.render(<div role="button"><Bar/><div /><Foo/></div>, fixture);
530+
React.render(<div role="button"><Bar/><div/><Foo/></div>, fixture);
525531
});
526532
});
527533

528-
529534
it('does not error when the component has a componentDidMount callback', () => {
530535
var Bar = React.createClass({
531536
_privateProp: 'bar',
@@ -545,6 +550,11 @@ describe('labels', () => {
545550
});
546551
});
547552

553+
it('does not warn when the label is a number', () => {
554+
doNotExpectWarning(assertions.render.NO_LABEL.msg, () => {
555+
<a>{1111}</a>;
556+
});
557+
});
548558
});
549559

550560
describe('filterFn', () => {

lib/assertions.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,11 +87,11 @@ var hasChildTextNode = (props, children, failureCB) => {
8787
return;
8888
else if (typeof child === 'undefined')
8989
return;
90-
else if (typeof child === 'string')
90+
else if (typeof child === 'string' || typeof child === 'number')
9191
hasText = true;
9292
else if (child.type === 'img' && child.props.alt)
9393
hasText = true;
94-
else if (child.props.children)
94+
else if (child.props && child.props.children)
9595
hasText = hasChildTextNode(child.props, child.props.children, failureCB);
9696
else if (typeof child.type === 'function') {
9797
// There can be false negatives if one of the children is a Component,
@@ -231,7 +231,12 @@ exports.render = {
231231
if (isHiddenFromAT(props) || presentationRoles.has(props.role))
232232
return;
233233

234-
if (!(isInteractive(tagName, props) || props.role))
234+
if (!(
235+
isInteractive(tagName, props) ||
236+
(tagName == 'a' && !props.href) ||
237+
props.role
238+
)
239+
)
235240
return;
236241

237242
var failed = !(

0 commit comments

Comments
 (0)