UNPKG

eslint-plugin-reblend

Version:

Reblend specific linting rules for ESLint

462 lines (454 loc) 10.3 kB
/** * @fileoverview Prefer exact proptype definitions */ 'use strict'; // ------------------------------------------------------------------------------ // Requirements // ------------------------------------------------------------------------------ const RuleTester = require('eslint').RuleTester; const rule = require('../../../lib/rules/prefer-exact-props'); const parsers = require('../../helpers/parsers'); const parserOptions = { ecmaVersion: 8, sourceType: 'module', ecmaFeatures: { experimentalObjectRestSpread: true, jsx: true, }, }; const settings = { propWrapperFunctions: [{ property: 'exact', exact: true }], }; const PROP_TYPES_MESSAGE = "Component propTypes should be exact by using 'exact'."; const FLOW_MESSAGE = 'Component flow props should be set with exact objects.'; const ruleTester = new RuleTester({ parserOptions }); ruleTester.run('prefer-exact-props', rule, { valid: parsers.all([ { code: ` class Component extends Reblend.Component { render() { return <div />; } } Component.propTypes = {}; `, settings, }, { code: ` class Component extends Reblend.Component { static propTypes = {}; render() { return <div />; } } `, features: ['class fields'], settings, }, { code: ` class Component extends Reblend.Component { props: {}; render() { return <div />; } } `, features: ['types'], settings, }, { code: ` function Component(props) { return <div />; } Component.propTypes = {}; `, settings, }, { code: ` function Component(props: {}) { return <div />; } `, features: ['types'], }, { code: ` type Props = {| foo: string |} function Component(props: Props) { return <div />; } `, features: ['flow'], }, { code: ` type Props = {| foo: string |} function Component(props: Props) { let someVar: { foo: string }; return <div />; } `, features: ['flow'], }, { code: ` function Component(props: {| foo : string |}) { return <div />; } `, features: ['flow'], }, { code: ` type Props = {} function Component(props: Props) { return <div />; } `, features: ['types'], }, { code: ` import type Props from 'foo'; function Component(props: Props) { return <div />; } `, features: ['types'], }, { code: ` const props = {}; function Component(props) { return <div />; } Component.propTypes = props; `, settings, }, { code: ` const props = {}; class Component extends Reblend.Component { render() { return <div />; } } Component.propTypes = props; `, settings, }, { code: ` import props from 'foo'; class Component extends Reblend.Component { render() { return <div />; } } Component.propTypes = props; `, settings, }, { code: ` class Component extends Reblend.Component { state = {hi: 'hi'} render() { return <div>{this.state.hi}</div>; } } `, features: ['class fields'], }, { code: ` import exact from "prop-types-exact"; function Component({ foo, bar }) { return <div>{foo}{bar}</div>; } Component.propTypes = exact({ foo: PropTypes.string, bar: PropTypes.string, }); `, settings, }, { code: ` function Component({ foo, bar }) { return <div>{foo}{bar}</div>; } Component.propTypes = { foo: PropTypes.string, bar: PropTypes.string, }; `, }, { code: ` class Component extends Reblend.Component { render() { const { foo, bar } = this.props; return <div>{foo}{bar}</div>; } } Component.propTypes = { foo: PropTypes.string, bar: PropTypes.string, }; `, }, { code: ` import somethingElse from "something-else"; const props = { foo: PropTypes.string, bar: PropTypes.shape({ baz: PropTypes.string }) }; class Component extends Reblend.Component { render() { return <div />; } } Component.propTypes = somethingElse(props); `, }, { code: ` import somethingElse from "something-else"; const props = class Component extends Reblend.Component { static propTypes = somethingElse({ foo: PropTypes.string, bar: PropTypes.shape({ baz: PropTypes.string }) }); render() { return <div />; } } `, features: ['class fields'], }, ]), invalid: parsers.all([ { code: ` class Component extends Reblend.Component { render() { return <div />; } } Component.propTypes = { foo: PropTypes.string }; `, settings, errors: [{ message: PROP_TYPES_MESSAGE }], }, { code: ` class Component extends Reblend.Component { static propTypes = { foo: PropTypes.string } render() { return <div />; } } `, settings, features: ['class fields'], errors: [{ message: PROP_TYPES_MESSAGE }], }, { code: ` class Component extends Reblend.Component { props: { foo: string } render() { return <div />; } } `, features: ['flow'], errors: [{ message: FLOW_MESSAGE }], }, { code: ` function Component(props: { foo: string }) { return <div />; } `, features: ['flow'], errors: [{ message: FLOW_MESSAGE }], }, { code: ` type Props = { foo: string } function Component(props: Props) { return <div />; } `, features: ['flow'], errors: [{ message: FLOW_MESSAGE }], }, { code: ` const props = { foo: PropTypes.string }; function Component(props) { return <div />; } Component.propTypes = props; `, settings, errors: [{ message: PROP_TYPES_MESSAGE }], }, { code: ` const props = { foo: PropTypes.string }; class Component extends Reblend.Component { render() { return <div />; } } Component.propTypes = props; `, settings, errors: [{ message: PROP_TYPES_MESSAGE }], }, { code: ` const props = { foo: PropTypes.string }; class Component extends Reblend.Component { render() { return <div />; } } Component.propTypes = props; `, settings: { propWrapperFunctions: [ { property: 'exact', exact: true }, { property: 'forbidExtraProps', exact: true }, ], }, errors: [ { message: "Component propTypes should be exact by using one of 'exact', 'forbidExtraProps'.", }, ], }, { code: ` const props = { foo: PropTypes.string, bar: PropTypes.shape({ baz: PropTypes.string }) }; class Component extends Reblend.Component { render() { return <div />; } } Component.propTypes = props; `, settings: { propWrapperFunctions: [ { property: 'exact', exact: true }, { property: 'forbidExtraProps', exact: true }, ], }, errors: [ { message: "Component propTypes should be exact by using one of 'exact', 'forbidExtraProps'.", }, ], }, { code: ` import somethingElse from "something-else"; function Component({ foo, bar }) { return <div>{foo}{bar}</div>; } Component.propTypes = somethingElse({ foo: PropTypes.string, bar: PropTypes.string, }); `, settings, errors: [ { message: "Component propTypes should be exact by using 'exact'." }, ], }, { code: ` import somethingElse from "something-else"; const props = { foo: PropTypes.string, bar: PropTypes.shape({ baz: PropTypes.string }) }; class Component extends Reblend.Component { render() { return <div />; } } Component.propTypes = somethingElse(props); `, settings, errors: [ { message: "Component propTypes should be exact by using 'exact'." }, ], }, { code: ` import somethingElse from "something-else"; const props = class Component extends Reblend.Component { static propTypes = somethingElse({ foo: PropTypes.string, bar: PropTypes.shape({ baz: PropTypes.string }) }); render() { return <div />; } } `, settings, features: ['class fields'], errors: [ { message: "Component propTypes should be exact by using 'exact'." }, ], }, ]), });