boolean-prop-naming.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777
  1. /**
  2. * @fileoverview Enforces consistent naming for boolean props
  3. * @author Ev Haus
  4. */
  5. 'use strict';
  6. // ------------------------------------------------------------------------------
  7. // Requirements
  8. // ------------------------------------------------------------------------------
  9. const rule = require('../../../lib/rules/boolean-prop-naming');
  10. const RuleTester = require('eslint').RuleTester;
  11. require('babel-eslint');
  12. const parserOptions = {
  13. ecmaVersion: 2018,
  14. sourceType: 'module',
  15. ecmaFeatures: {
  16. jsx: true
  17. }
  18. };
  19. // ------------------------------------------------------------------------------
  20. // Tests
  21. // ------------------------------------------------------------------------------
  22. const ruleTester = new RuleTester({parserOptions});
  23. ruleTester.run('boolean-prop-naming', rule, {
  24. valid: [{
  25. // Should support both `is` and `has` prefixes by default
  26. code: `
  27. var Hello = createReactClass({
  28. propTypes: {isSomething: PropTypes.bool, hasValue: PropTypes.bool},
  29. render: function() { return <div />; }
  30. });
  31. `
  32. }, {
  33. // createReactClass components with PropTypes
  34. code: `
  35. var Hello = createReactClass({
  36. propTypes: {isSomething: PropTypes.bool},
  37. render: function() { return <div />; }
  38. });
  39. `,
  40. options: [{
  41. rule: '^is[A-Z]([A-Za-z0-9]?)+'
  42. }]
  43. }, {
  44. // createReactClass components with React.PropTypes
  45. code: `
  46. var Hello = createReactClass({
  47. propTypes: {isSomething: React.PropTypes.bool},
  48. render: function() { return <div />; }
  49. });
  50. `,
  51. options: [{
  52. rule: '^is[A-Z]([A-Za-z0-9]?)+'
  53. }]
  54. }, {
  55. // React.createClass components with PropTypes
  56. code: `
  57. var Hello = React.createClass({
  58. propTypes: {isSomething: PropTypes.bool},
  59. render: function() { return <div />; }
  60. });
  61. `,
  62. options: [{
  63. rule: '^is[A-Z]([A-Za-z0-9]?)+'
  64. }],
  65. settings: {
  66. react: {
  67. createClass: 'createClass'
  68. }
  69. }
  70. }, {
  71. // React.createClass components with non-boolean PropTypes
  72. code: `
  73. var Hello = React.createClass({
  74. propTypes: {something: PropTypes.any},
  75. render: function() { return <div />; }
  76. });
  77. `,
  78. options: [{
  79. rule: '^is[A-Z]([A-Za-z0-9]?)+'
  80. }],
  81. settings: {
  82. react: {
  83. createClass: 'createClass'
  84. }
  85. }
  86. }, {
  87. // ES6 components as React.Component with boolean PropTypes
  88. code: `
  89. class Hello extends React.Component {
  90. render () { return <div />; }
  91. }
  92. Hello.propTypes = {isSomething: PropTypes.bool}
  93. `,
  94. options: [{
  95. rule: '^is[A-Z]([A-Za-z0-9]?)+'
  96. }]
  97. }, {
  98. // ES6 components as React.Component with non-boolean PropTypes
  99. code: `
  100. class Hello extends React.Component {
  101. render () { return <div />; }
  102. }
  103. Hello.propTypes = wrap({ a: PropTypes.bool })
  104. `,
  105. options: [{
  106. rule: '^is[A-Z]([A-Za-z0-9]?)+'
  107. }]
  108. }, {
  109. code: `
  110. class Hello extends React.Component {
  111. render () { return <div />; }
  112. }
  113. Hello.propTypes = {something: PropTypes.any}
  114. `,
  115. options: [{
  116. rule: '^is[A-Z]([A-Za-z0-9]?)+'
  117. }]
  118. }, {
  119. // ES6 components as Component with boolean PropTypes
  120. code: `
  121. class Hello extends Component {
  122. render () { return <div />; }
  123. }
  124. Hello.propTypes = {isSomething: PropTypes.bool}
  125. `,
  126. options: [{
  127. rule: '^is[A-Z]([A-Za-z0-9]?)+'
  128. }]
  129. }, {
  130. // ES6 components with static class properties and PropTypes
  131. code: `
  132. class Hello extends React.Component {
  133. static propTypes = {isSomething: PropTypes.bool};
  134. render () { return <div />; }
  135. }
  136. `,
  137. options: [{
  138. rule: '^is[A-Z]([A-Za-z0-9]?)+'
  139. }],
  140. parser: 'babel-eslint'
  141. }, {
  142. // ES6 components with static class properties and Object.spread syntax in PropTypes
  143. code: `
  144. const spreadProps = { aSpreadProp: PropTypes.string };
  145. class Hello extends React.Component {
  146. static propTypes = {isSomething: PropTypes.bool, ...spreadProps};
  147. render () { return <div />; }
  148. }
  149. `,
  150. options: [{
  151. rule: '^is[A-Z]([A-Za-z0-9]?)+'
  152. }],
  153. parser: 'babel-eslint'
  154. }, {
  155. // ES6 components as Component with boolean PropTypes and Object.spread syntax in PropTypes
  156. code: `
  157. const spreadProps = { aSpreadProp: PropTypes.string };
  158. class Hello extends Component {
  159. render () { return <div />; }
  160. }
  161. Hello.propTypes = {isSomething: PropTypes.bool, ...spreadProps}
  162. `,
  163. options: [{
  164. rule: '^is[A-Z]([A-Za-z0-9]?)+'
  165. }]
  166. }, {
  167. // ES6 components with static class properties and React.PropTypes
  168. code: `
  169. class Hello extends React.Component {
  170. static propTypes = {isSomething: React.PropTypes.bool};
  171. render () { return <div />; }
  172. }
  173. `,
  174. options: [{
  175. rule: '^is[A-Z]([A-Za-z0-9]?)+'
  176. }],
  177. parser: 'babel-eslint'
  178. }, {
  179. // ES6 components with static class properties an non-booleans
  180. code: `
  181. class Hello extends React.Component {
  182. static propTypes = {something: PropTypes.any};
  183. render () { return <div />; }
  184. }
  185. `,
  186. options: [{
  187. rule: '^is[A-Z]([A-Za-z0-9]?)+'
  188. }],
  189. parser: 'babel-eslint'
  190. }, {
  191. // ES6 components and Flowtype booleans
  192. code: `
  193. class Hello extends React.Component {
  194. props: {isSomething: boolean};
  195. render () { return <div />; }
  196. }
  197. `,
  198. options: [{
  199. rule: '^is[A-Z]([A-Za-z0-9]?)+'
  200. }],
  201. parser: 'babel-eslint'
  202. }, {
  203. // ES6 components and Flowtype non-booleans
  204. code: `
  205. class Hello extends React.Component {
  206. props: {something: any};
  207. render () { return <div />; }
  208. }
  209. `,
  210. options: [{
  211. rule: '^is[A-Z]([A-Za-z0-9]?)+'
  212. }],
  213. parser: 'babel-eslint'
  214. }, {
  215. // Stateless components
  216. code: `
  217. var Hello = ({isSomething}) => { return <div /> }
  218. Hello.propTypes = {isSomething: PropTypes.bool};
  219. `,
  220. options: [{
  221. rule: '^is[A-Z]([A-Za-z0-9]?)+'
  222. }],
  223. parser: 'babel-eslint'
  224. }, {
  225. // Functional components and Flowtype booleans
  226. code: `
  227. type Props = {
  228. isSomething: boolean;
  229. };
  230. function Hello(props: Props): React.Element { return <div /> }
  231. `,
  232. options: [{
  233. rule: '^is[A-Z]([A-Za-z0-9]?)+'
  234. }],
  235. parser: 'babel-eslint'
  236. }, {
  237. // Custom `propTypeNames` option
  238. code: `
  239. class Hello extends React.Component {
  240. static propTypes = {
  241. isSomething: PropTypes.mutuallyExclusiveTrueProps,
  242. something: PropTypes.bool
  243. };
  244. render () { return <div />; }
  245. }
  246. `,
  247. options: [{
  248. propTypeNames: ['mutuallyExclusiveTrueProps'],
  249. rule: '^is[A-Z]([A-Za-z0-9]?)+'
  250. }],
  251. parser: 'babel-eslint'
  252. }, {
  253. // Custom PropTypes that are specified as variables
  254. code: `
  255. class Hello extends React.Component {
  256. static propTypes = {
  257. isSomething: mutuallyExclusiveTrueProps,
  258. isSomethingElse: bool
  259. };
  260. render () { return <div />; }
  261. }
  262. `,
  263. options: [{
  264. propTypeNames: ['bool', 'mutuallyExclusiveTrueProps'],
  265. rule: '^is[A-Z]([A-Za-z0-9]?)+'
  266. }],
  267. parser: 'babel-eslint'
  268. }, {
  269. // Ensure rule doesn't crash on destructured objects [Issue #1369]
  270. code: `
  271. var x = {a: 1}
  272. var y = {...x}
  273. `,
  274. options: [{
  275. rule: '^is[A-Z]([A-Za-z0-9]?)+'
  276. }],
  277. parser: 'babel-eslint'
  278. }, {
  279. // Ensure rule doesn't crash on on components reference old-style Flow props
  280. code: `
  281. class Hello extends PureComponent {
  282. props: PropsType;
  283. render () { return <div /> }
  284. }
  285. `,
  286. options: [{
  287. rule: '^is[A-Z]([A-Za-z0-9]?)+'
  288. }],
  289. parser: 'babel-eslint'
  290. }, {
  291. // No propWrapperFunctions setting
  292. code: `
  293. function Card(props) {
  294. return <div>{props.showScore ? 'yeh' : 'no'}</div>;
  295. }
  296. Card.propTypes = merge({}, Card.propTypes, {
  297. showScore: PropTypes.bool
  298. });`,
  299. options: [{
  300. rule: '^(is|has)[A-Z]([A-Za-z0-9]?)+'
  301. }]
  302. }, {
  303. // Ensure the rule does not throw when a prop isRequired when ES5.
  304. code: `
  305. var Hello = createReactClass({
  306. propTypes: {isSomething: PropTypes.bool.isRequired, hasValue: PropTypes.bool.isRequired},
  307. render: function() { return <div />; }
  308. });
  309. `
  310. }, {
  311. // Ensure the rule does not throw when a prop isRequired when ES6 with static properties.
  312. code: `
  313. class Hello extends React.Component {
  314. static propTypes = {
  315. isSomething: PropTypes.bool.isRequired,
  316. hasValue: PropTypes.bool.isRequired
  317. };
  318. render() {
  319. return (
  320. <div />
  321. );
  322. }
  323. }
  324. `,
  325. parser: 'babel-eslint'
  326. }, {
  327. // Ensure the rule does not throw when a prop isRequired when ES6 without static properties.
  328. code: `
  329. class Hello extends React.Component {
  330. render() {
  331. return (
  332. <div />
  333. );
  334. }
  335. }
  336. Hello.propTypes = {
  337. isSomething: PropTypes.bool.isRequired,
  338. hasValue: PropTypes.bool.isRequired
  339. }
  340. `
  341. }, {
  342. // Ensure the rule does not throw when a shape prop isRequired.
  343. code: `
  344. var Hello = createReactClass({
  345. propTypes: {something: PropTypes.shape({}).isRequired},
  346. render: function() { return <div />; }
  347. });
  348. `,
  349. options: [{
  350. rule: '^is[A-Z]([A-Za-z0-9]?)+'
  351. }]
  352. }],
  353. invalid: [{
  354. // createReactClass components with PropTypes
  355. code: `
  356. var Hello = createReactClass({
  357. propTypes: {something: PropTypes.bool},
  358. render: function() { return <div />; }
  359. });
  360. `,
  361. options: [{
  362. rule: '^is[A-Z]([A-Za-z0-9]?)+'
  363. }],
  364. errors: [{
  365. message: 'Prop name (something) doesn\'t match rule (^is[A-Z]([A-Za-z0-9]?)+)'
  366. }]
  367. }, {
  368. // createReactClass components with React.PropTypes
  369. code: `
  370. var Hello = createReactClass({
  371. propTypes: {something: React.PropTypes.bool},
  372. render: function() { return <div />; }
  373. });
  374. `,
  375. options: [{
  376. rule: '^is[A-Z]([A-Za-z0-9]?)+'
  377. }],
  378. errors: [{
  379. message: 'Prop name (something) doesn\'t match rule (^is[A-Z]([A-Za-z0-9]?)+)'
  380. }]
  381. }, {
  382. // React.createClass components with PropTypes
  383. code: `
  384. var Hello = React.createClass({
  385. propTypes: {something: PropTypes.bool},
  386. render: function() { return <div />; }
  387. });
  388. `,
  389. options: [{
  390. rule: '^is[A-Z]([A-Za-z0-9]?)+'
  391. }],
  392. settings: {
  393. react: {
  394. createClass: 'createClass'
  395. }
  396. },
  397. errors: [{
  398. message: 'Prop name (something) doesn\'t match rule (^is[A-Z]([A-Za-z0-9]?)+)'
  399. }]
  400. }, {
  401. // ES6 components as React.Component with boolean PropTypes
  402. code: `
  403. class Hello extends React.Component {
  404. render () { return <div />; }
  405. }
  406. Hello.propTypes = {something: PropTypes.bool}
  407. `,
  408. options: [{
  409. rule: '^is[A-Z]([A-Za-z0-9]?)+'
  410. }],
  411. errors: [{
  412. message: 'Prop name (something) doesn\'t match rule (^is[A-Z]([A-Za-z0-9]?)+)'
  413. }]
  414. }, {
  415. // ES6 components as Component with non-boolean PropTypes
  416. code: `
  417. class Hello extends Component {
  418. render () { return <div />; }
  419. }
  420. Hello.propTypes = {something: PropTypes.bool}
  421. `,
  422. options: [{
  423. rule: '^is[A-Z]([A-Za-z0-9]?)+'
  424. }],
  425. errors: [{
  426. message: 'Prop name (something) doesn\'t match rule (^is[A-Z]([A-Za-z0-9]?)+)'
  427. }]
  428. }, {
  429. // ES6 components as React.Component with non-boolean PropTypes
  430. code: `
  431. class Hello extends React.Component {
  432. static propTypes = {something: PropTypes.bool};
  433. render () { return <div />; }
  434. }
  435. `,
  436. options: [{
  437. rule: '^is[A-Z]([A-Za-z0-9]?)+'
  438. }],
  439. parser: 'babel-eslint',
  440. errors: [{
  441. message: 'Prop name (something) doesn\'t match rule (^is[A-Z]([A-Za-z0-9]?)+)'
  442. }]
  443. }, {
  444. // ES6 components as React.Component with non-boolean PropTypes and Object.spread syntax
  445. code: `
  446. const spreadProps = { aSpreadProp: PropTypes.string };
  447. class Hello extends Component {
  448. render () { return <div />; }
  449. }
  450. Hello.propTypes = {something: PropTypes.bool, ...spreadProps}
  451. `,
  452. options: [{
  453. rule: '^is[A-Z]([A-Za-z0-9]?)+'
  454. }],
  455. errors: [{
  456. message: 'Prop name (something) doesn\'t match rule (^is[A-Z]([A-Za-z0-9]?)+)'
  457. }]
  458. }, {
  459. // ES6 components as React.Component with static class property, non-boolean PropTypes, and Object.spread syntax
  460. code: `
  461. const spreadProps = { aSpreadProp: PropTypes.string };
  462. class Hello extends React.Component {
  463. static propTypes = {something: PropTypes.bool, ...spreadProps};
  464. render () { return <div />; }
  465. }
  466. `,
  467. options: [{
  468. rule: '^is[A-Z]([A-Za-z0-9]?)+'
  469. }],
  470. parser: 'babel-eslint',
  471. errors: [{
  472. message: 'Prop name (something) doesn\'t match rule (^is[A-Z]([A-Za-z0-9]?)+)'
  473. }]
  474. }, {
  475. // ES6 components as React.Component with non-boolean PropTypes
  476. code: `
  477. class Hello extends React.Component {
  478. props: {something: boolean};
  479. render () { return <div />; }
  480. }
  481. `,
  482. options: [{
  483. rule: '^is[A-Z]([A-Za-z0-9]?)+'
  484. }],
  485. parser: 'babel-eslint',
  486. errors: [{
  487. message: 'Prop name (something) doesn\'t match rule (^is[A-Z]([A-Za-z0-9]?)+)'
  488. }]
  489. }, {
  490. code: `
  491. var Hello = ({something}) => { return <div /> }
  492. Hello.propTypes = {something: PropTypes.bool};
  493. `,
  494. options: [{
  495. rule: '^is[A-Z]([A-Za-z0-9]?)+'
  496. }],
  497. parser: 'babel-eslint',
  498. errors: [{
  499. message: 'Prop name (something) doesn\'t match rule (^is[A-Z]([A-Za-z0-9]?)+)'
  500. }]
  501. }, {
  502. code: `
  503. type Props = {
  504. something: boolean;
  505. };
  506. function Hello(props: Props): React.Element { return <div /> }
  507. `,
  508. options: [{
  509. rule: '^is[A-Z]([A-Za-z0-9]?)+'
  510. }],
  511. parser: 'babel-eslint',
  512. errors: [{
  513. message: 'Prop name (something) doesn\'t match rule (^is[A-Z]([A-Za-z0-9]?)+)'
  514. }]
  515. }, {
  516. // ES6 components and Flowtype non-booleans
  517. code: `
  518. class Hello extends React.Component {
  519. static propTypes = {something: PropTypes.mutuallyExclusiveTrueProps};
  520. render () { return <div />; }
  521. }
  522. `,
  523. options: [{
  524. propTypeNames: ['bool', 'mutuallyExclusiveTrueProps'],
  525. rule: '^is[A-Z]([A-Za-z0-9]?)+'
  526. }],
  527. parser: 'babel-eslint',
  528. errors: [{
  529. message: 'Prop name (something) doesn\'t match rule (^is[A-Z]([A-Za-z0-9]?)+)'
  530. }]
  531. }, {
  532. code: `
  533. class Hello extends React.Component {
  534. static propTypes = {
  535. something: PropTypes.mutuallyExclusiveTrueProps,
  536. somethingElse: PropTypes.bool
  537. };
  538. render () { return <div />; }
  539. }
  540. `,
  541. options: [{
  542. propTypeNames: ['bool', 'mutuallyExclusiveTrueProps'],
  543. rule: '^is[A-Z]([A-Za-z0-9]?)+'
  544. }],
  545. parser: 'babel-eslint',
  546. errors: [{
  547. message: 'Prop name (something) doesn\'t match rule (^is[A-Z]([A-Za-z0-9]?)+)'
  548. }, {
  549. message: 'Prop name (somethingElse) doesn\'t match rule (^is[A-Z]([A-Za-z0-9]?)+)'
  550. }]
  551. }, {
  552. code: `
  553. class Hello extends React.Component {
  554. static propTypes = {
  555. something: mutuallyExclusiveTrueProps,
  556. somethingElse: bool
  557. };
  558. render () { return <div />; }
  559. }
  560. `,
  561. options: [{
  562. propTypeNames: ['bool', 'mutuallyExclusiveTrueProps'],
  563. rule: '^is[A-Z]([A-Za-z0-9]?)+'
  564. }],
  565. parser: 'babel-eslint',
  566. errors: [{
  567. message: 'Prop name (something) doesn\'t match rule (^is[A-Z]([A-Za-z0-9]?)+)'
  568. }, {
  569. message: 'Prop name (somethingElse) doesn\'t match rule (^is[A-Z]([A-Za-z0-9]?)+)'
  570. }]
  571. }, {
  572. code: `
  573. function Card(props) {
  574. return <div>{props.showScore ? 'yeh' : 'no'}</div>;
  575. }
  576. Card.propTypes = merge({}, Card.propTypes, {
  577. showScore: PropTypes.bool
  578. });`,
  579. settings: {
  580. propWrapperFunctions: ['merge']
  581. },
  582. options: [{
  583. rule: '^(is|has)[A-Z]([A-Za-z0-9]?)+'
  584. }],
  585. errors: [{
  586. message: 'Prop name (showScore) doesn\'t match rule (^(is|has)[A-Z]([A-Za-z0-9]?)+)'
  587. }]
  588. }, {
  589. code: `
  590. function Card(props) {
  591. return <div>{props.showScore ? 'yeh' : 'no'}</div>;
  592. }
  593. Card.propTypes = Object.assign({}, Card.propTypes, {
  594. showScore: PropTypes.bool
  595. });`,
  596. settings: {
  597. propWrapperFunctions: ['Object.assign']
  598. },
  599. options: [{
  600. rule: '^(is|has)[A-Z]([A-Za-z0-9]?)+'
  601. }],
  602. errors: [{
  603. message: 'Prop name (showScore) doesn\'t match rule (^(is|has)[A-Z]([A-Za-z0-9]?)+)'
  604. }]
  605. }, {
  606. code: `
  607. function Card(props) {
  608. return <div>{props.showScore ? 'yeh' : 'no'}</div>;
  609. }
  610. Card.propTypes = _.assign({}, Card.propTypes, {
  611. showScore: PropTypes.bool
  612. });`,
  613. settings: {
  614. propWrapperFunctions: ['_.assign']
  615. },
  616. options: [{
  617. rule: '^(is|has)[A-Z]([A-Za-z0-9]?)+'
  618. }],
  619. errors: [{
  620. message: 'Prop name (showScore) doesn\'t match rule (^(is|has)[A-Z]([A-Za-z0-9]?)+)'
  621. }]
  622. }, {
  623. code: `
  624. function Card(props) {
  625. return <div>{props.showScore ? 'yeh' : 'no'}</div>;
  626. }
  627. Card.propTypes = forbidExtraProps({
  628. showScore: PropTypes.bool
  629. });`,
  630. settings: {
  631. propWrapperFunctions: ['forbidExtraProps']
  632. },
  633. options: [{
  634. rule: '^(is|has)[A-Z]([A-Za-z0-9]?)+'
  635. }],
  636. errors: [{
  637. message: 'Prop name (showScore) doesn\'t match rule (^(is|has)[A-Z]([A-Za-z0-9]?)+)'
  638. }]
  639. }, {
  640. code: `
  641. class Card extends React.Component {
  642. render() {
  643. return <div>{props.showScore ? 'yeh' : 'no'}</div>;
  644. }
  645. }
  646. Card.propTypes = forbidExtraProps({
  647. showScore: PropTypes.bool
  648. });`,
  649. settings: {
  650. propWrapperFunctions: ['forbidExtraProps']
  651. },
  652. options: [{
  653. rule: '^(is|has)[A-Z]([A-Za-z0-9]?)+'
  654. }],
  655. errors: [{
  656. message: 'Prop name (showScore) doesn\'t match rule (^(is|has)[A-Z]([A-Za-z0-9]?)+)'
  657. }]
  658. }, {
  659. code: `
  660. class Card extends React.Component {
  661. static propTypes = forbidExtraProps({
  662. showScore: PropTypes.bool
  663. });
  664. render() {
  665. return <div>{props.showScore ? 'yeh' : 'no'}</div>;
  666. }
  667. }`,
  668. parser: 'babel-eslint',
  669. settings: {
  670. propWrapperFunctions: ['forbidExtraProps']
  671. },
  672. options: [{
  673. rule: '^(is|has)[A-Z]([A-Za-z0-9]?)+'
  674. }],
  675. errors: [{
  676. message: 'Prop name (showScore) doesn\'t match rule (^(is|has)[A-Z]([A-Za-z0-9]?)+)'
  677. }]
  678. }, {
  679. // If a custom message is provided, use it.
  680. code: `
  681. class Hello extends React.Component {
  682. render () { return <div />; }
  683. }
  684. Hello.propTypes = {something: PropTypes.bool}
  685. `,
  686. options: [{
  687. rule: '^is[A-Z]([A-Za-z0-9]?)+',
  688. message: 'Boolean prop names must begin with either \'is\' or \'has\''
  689. }],
  690. errors: [{
  691. message: 'Boolean prop names must begin with either \'is\' or \'has\''
  692. }]
  693. }, {
  694. // Custom messages use ESLint string templating.
  695. code: `
  696. class Hello extends React.Component {
  697. render () { return <div />; }
  698. }
  699. Hello.propTypes = {something: PropTypes.bool}
  700. `,
  701. options: [{
  702. rule: '^is[A-Z]([A-Za-z0-9]?)+',
  703. message: 'It is better if your prop ({{ propName }}) matches this pattern: ({{ pattern }})'
  704. }],
  705. errors: [{
  706. message: 'It is better if your prop (something) matches this pattern: (^is[A-Z]([A-Za-z0-9]?)+)'
  707. }]
  708. }, {
  709. // Works when a prop isRequired in ES5.
  710. code: `
  711. var Hello = createReactClass({
  712. propTypes: {something: PropTypes.bool.isRequired},
  713. render: function() { return <div />; }
  714. });
  715. `,
  716. options: [{
  717. rule: '^is[A-Z]([A-Za-z0-9]?)+'
  718. }],
  719. errors: [{
  720. message: 'Prop name (something) doesn\'t match rule (^is[A-Z]([A-Za-z0-9]?)+)'
  721. }]
  722. }, {
  723. // Works when a prop isRequired in ES6 with static properties.
  724. code: `
  725. class Hello extends React.Component {
  726. static propTypes = {
  727. something: PropTypes.bool.isRequired
  728. };
  729. render() {
  730. return (
  731. <div />
  732. );
  733. }
  734. }
  735. `,
  736. options: [{
  737. rule: '^is[A-Z]([A-Za-z0-9]?)+'
  738. }],
  739. parser: 'babel-eslint',
  740. errors: [{
  741. message: 'Prop name (something) doesn\'t match rule (^is[A-Z]([A-Za-z0-9]?)+)'
  742. }]
  743. }, {
  744. // Works when a prop isRequired in ES6 without static properties.
  745. code: `
  746. class Hello extends React.Component {
  747. render() {
  748. return (
  749. <div />
  750. );
  751. }
  752. }
  753. Hello.propTypes = {
  754. something: PropTypes.bool.isRequired
  755. }
  756. `,
  757. options: [{
  758. rule: '^is[A-Z]([A-Za-z0-9]?)+'
  759. }],
  760. errors: [{
  761. message: 'Prop name (something) doesn\'t match rule (^is[A-Z]([A-Za-z0-9]?)+)'
  762. }]
  763. }]
  764. });