Skip to content
This repository was archived by the owner on Sep 1, 2024. It is now read-only.

Commit 90c8c47

Browse files
committed
[Fix] fix crash when a custom propType return lacks .data; call hasOwnProperty properly
Fixes #369
1 parent b93deca commit 90c8c47

5 files changed

+116
-1
lines changed

__tests__/PropTypesDevelopmentReact15.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1385,6 +1385,37 @@ describe('PropTypesDevelopmentReact15', () => {
13851385
);
13861386
expectWarningInDevelopment(PropTypes.element, <div />);
13871387
});
1388+
1389+
it('works with oneOfType', () => {
1390+
typeCheckPass(
1391+
PropTypes.exact({ foo: PropTypes.oneOfType([PropTypes.number, PropTypes.string]) }),
1392+
{ foo: 42 }
1393+
);
1394+
typeCheckPass(
1395+
PropTypes.exact({ foo: PropTypes.oneOfType([PropTypes.number, PropTypes.string]) }),
1396+
{ foo: '42' }
1397+
);
1398+
typeCheckFail(
1399+
PropTypes.exact({ foo: PropTypes.oneOfType([PropTypes.number, PropTypes.string]) }),
1400+
{ foo: 42, bar: 'what is 6 * 7' },
1401+
`Warning: Failed prop type: Invalid prop \`testProp\` key \`bar\` supplied to \`testComponent\`.
1402+
Bad object: {
1403+
"foo": 42,
1404+
"bar": "what is 6 * 7"
1405+
}
1406+
Valid keys: [
1407+
"foo"
1408+
]`
1409+
);
1410+
});
1411+
1412+
it('works with a custom propType', () => {
1413+
typeCheckFail(
1414+
PropTypes.oneOfType([() => new Error('hi')]),
1415+
{},
1416+
'Warning: Failed prop type: Invalid prop `testProp` supplied to `testComponent`.'
1417+
)
1418+
});
13881419
});
13891420

13901421
describe('Symbol Type', () => {

__tests__/PropTypesDevelopmentStandalone-test.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1456,6 +1456,37 @@ describe('PropTypesDevelopmentStandalone', () => {
14561456
);
14571457
expectThrowsInDevelopment(PropTypes.element, <div />);
14581458
});
1459+
1460+
it('works with oneOfType', () => {
1461+
typeCheckPass(
1462+
PropTypes.exact({ foo: PropTypes.oneOfType([PropTypes.number, PropTypes.string]) }),
1463+
{ foo: 42 }
1464+
);
1465+
typeCheckPass(
1466+
PropTypes.exact({ foo: PropTypes.oneOfType([PropTypes.number, PropTypes.string]) }),
1467+
{ foo: '42' }
1468+
);
1469+
typeCheckFail(
1470+
PropTypes.exact({ foo: PropTypes.oneOfType([PropTypes.number, PropTypes.string]) }),
1471+
{ foo: 42, bar: 'what is 6 * 7' },
1472+
`Warning: Failed prop type: Invalid prop \`testProp\` key \`bar\` supplied to \`testComponent\`.
1473+
Bad object: {
1474+
"foo": 42,
1475+
"bar": "what is 6 * 7"
1476+
}
1477+
Valid keys: [
1478+
"foo"
1479+
]`
1480+
);
1481+
});
1482+
1483+
it('works with a custom propType', () => {
1484+
typeCheckFail(
1485+
PropTypes.oneOfType([() => new Error('hi')]),
1486+
{},
1487+
'Warning: Failed prop type: Invalid prop `testProp` supplied to `testComponent`.'
1488+
)
1489+
});
14591490
});
14601491

14611492
describe('Symbol Type', () => {

__tests__/PropTypesProductionReact15-test.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1112,6 +1112,28 @@ describe('PropTypesProductionReact15', () => {
11121112
);
11131113
expectNoop(PropTypes.element, <div />);
11141114
});
1115+
1116+
it('works with oneOfType', () => {
1117+
expectNoop(
1118+
PropTypes.exact({ foo: PropTypes.oneOfType([PropTypes.number, PropTypes.string]) }),
1119+
{ foo: 42 }
1120+
);
1121+
expectNoop(
1122+
PropTypes.exact({ foo: PropTypes.oneOfType([PropTypes.number, PropTypes.string]) }),
1123+
{ foo: '42' }
1124+
);
1125+
expectNoop(
1126+
PropTypes.exact({ foo: PropTypes.oneOfType([PropTypes.number, PropTypes.string]) }),
1127+
{ foo: 42, bar: 'what is 6 * 7' }
1128+
);
1129+
});
1130+
1131+
it('works with a custom propType', () => {
1132+
expectNoop(
1133+
PropTypes.oneOfType([() => new Error('hi')]),
1134+
{}
1135+
)
1136+
});
11151137
});
11161138

11171139
describe('Symbol Type', () => {

__tests__/PropTypesProductionStandalone-test.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,37 @@ describe('PropTypesProductionStandalone', () => {
326326
PropTypes.exact({key: PropTypes.number}).isRequired,
327327
);
328328
});
329+
330+
it('works with oneOfType', () => {
331+
typeCheckPass(
332+
PropTypes.exact({ foo: PropTypes.oneOfType([PropTypes.number, PropTypes.string]) }),
333+
{ foo: 42 }
334+
);
335+
typeCheckPass(
336+
PropTypes.exact({ foo: PropTypes.oneOfType([PropTypes.number, PropTypes.string]) }),
337+
{ foo: '42' }
338+
);
339+
expectThrowsInProduction(
340+
PropTypes.exact({ foo: PropTypes.oneOfType([PropTypes.number, PropTypes.string]) }),
341+
{ foo: 42, bar: 'what is 6 * 7' },
342+
`Warning: Failed prop type: Invalid prop \`testProp\` key \`bar\` supplied to \`testComponent\`.
343+
Bad object: {
344+
"foo": 42,
345+
"bar": "what is 6 * 7"
346+
}
347+
Valid keys: [
348+
"foo"
349+
]`
350+
);
351+
});
352+
353+
it('works with a custom propType', () => {
354+
expectThrowsInProduction(
355+
PropTypes.oneOfType([() => new Error('hi')]),
356+
{},
357+
'Warning: Failed prop type: Invalid prop `testProp` supplied to `testComponent`.'
358+
)
359+
});
329360
});
330361

331362
describe('Symbol Type', () => {

factoryWithTypeCheckers.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ module.exports = function(isValidElement, throwOnDirectAccess) {
390390
if (checkerResult == null) {
391391
return null;
392392
}
393-
if (checkerResult.data.hasOwnProperty('expectedType')) {
393+
if (checkerResult.data && has(checkerResult.data, 'expectedType')) {
394394
expectedTypes.push(checkerResult.data.expectedType);
395395
}
396396
}

0 commit comments

Comments
 (0)