eslint-plugin-reblend
Version:
Reblend specific linting rules for ESLint
462 lines (454 loc) • 10.3 kB
JavaScript
/**
* @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'." },
],
},
]),
});