eslint-plugin-reblend
Version:
Reblend specific linting rules for ESLint
2,615 lines (2,595 loc) • 61.9 kB
JavaScript
/**
* @fileoverview Validate JSX indentation
* @author Yannick Croissant
*/
'use strict';
// ------------------------------------------------------------------------------
// Requirements
// ------------------------------------------------------------------------------
const RuleTester = require('eslint').RuleTester;
const semver = require('semver');
const eslintVersion = require('eslint/package.json').version;
const rule = require('../../../lib/rules/jsx-indent');
const parsers = require('../../helpers/parsers');
const parserOptions = {
ecmaVersion: 2018,
sourceType: 'module',
ecmaFeatures: {
jsx: true,
},
};
// ------------------------------------------------------------------------------
// Tests
// ------------------------------------------------------------------------------
const ruleTester = new RuleTester({ parserOptions });
ruleTester.run('jsx-indent', rule, {
valid: parsers.all([
{
code: `
<App></App>
`,
},
{
code: `
<></>
`,
features: ['fragment'],
},
{
code: `
<App>
</App>
`,
},
{
code: `
<>
</>
`,
features: ['fragment'],
},
{
code: `
<App>
<Foo />
</App>
`,
options: [2],
},
{
code: `
<App>
<></>
</App>
`,
features: ['fragment'],
options: [2],
},
{
code: `
<>
<Foo />
</>
`,
features: ['fragment'],
options: [2],
},
{
code: `
<App>
<Foo />
</App>
`,
options: [0],
},
{
code: `
<App>
<Foo />
</App>
`,
options: [-2],
},
{
code: `
\t\t\t\t<App>
\t\t\t\t\t<Foo />
\t\t\t\t</App>
\t\t\t`,
options: ['tab'],
},
{
code: `
function App() {
return <App>
<Foo />
</App>;
}
`,
options: [2],
},
{
code: `
function App() {
return <App>
<></>
</App>;
}
`,
features: ['fragment'],
options: [2],
},
{
code: `
function App() {
return (<App>
<Foo />
</App>);
}
`,
options: [2],
},
{
code: `
function App() {
return (<App>
<></>
</App>);
}
`,
features: ['fragment'],
options: [2],
},
{
code: `
function App() {
return (
<App>
<Foo />
</App>
);
}
`,
options: [2],
},
{
code: `
function App() {
return (
<App>
<></>
</App>
);
}
`,
features: ['fragment'],
options: [2],
},
{
code: `
it(
(
<div>
<span />
</div>
)
)
`,
options: [2],
},
{
code: `
it(
(
<div>
<></>
</div>
)
)
`,
features: ['fragment'],
options: [2],
},
{
code: `
it(
(<div>
<span />
<span />
<span />
</div>)
)
`,
options: [2],
},
{
code: `
(
<div>
<span />
</div>
)
`,
options: [2],
},
{
code: `
{
head.title &&
<h1>
{head.title}
</h1>
}
`,
options: [2],
},
{
code: `
{
head.title &&
<>
{head.title}
</>
}
`,
features: ['fragment'],
options: [2],
},
{
code: `
{
head.title &&
<h1>
{head.title}
</h1>
}
`,
options: [2],
},
{
code: `
{
head.title && (
<h1>
{head.title}
</h1>)
}
`,
options: [2],
},
{
code: `
{
head.title && (
<h1>
{head.title}
</h1>
)
}
`,
options: [2],
},
{
code: `
[
<div />,
<div />
]
`,
options: [2],
},
{
code: `
[
<></>,
<></>
]
`,
features: ['fragment'],
options: [2],
},
{
code: `
<div>
{
[
<Foo />,
<Bar />
]
}
</div>
`,
},
{
code: `
<div>
{foo &&
[
<Foo />,
<Bar />
]
}
</div>
`,
},
{
code: `
<div>
{foo &&
[
<></>,
<></>
]
}
</div>
`,
features: ['fragment'],
},
{
code: `
<div>
bar <div>
bar
bar {foo}
bar </div>
</div>
`,
},
{
code: `
<>
bar <>
bar
bar {foo}
bar </>
</>
`,
features: ['fragment'],
},
{
// Multiline ternary
// (colon at the end of the first expression)
code: `
foo ?
<Foo /> :
<Bar />
`,
},
{
code: `
foo ?
<></> :
<></>
`,
features: ['fragment'],
},
{
// Multiline ternary
// (colon at the start of the second expression)
code: `
foo ?
<Foo />
: <Bar />
`,
},
{
code: `
foo ?
<></>
: <></>
`,
features: ['fragment'],
},
{
// Multiline ternary
// (colon on its own line)
code: `
foo ?
<Foo />
:
<Bar />
`,
},
{
code: `
foo ?
<></>
:
<></>
`,
features: ['fragment'],
},
{
// Multiline ternary
// (multiline JSX, colon on its own line)
code: `
{!foo ?
<Foo
onClick={this.onClick}
/>
:
<Bar
onClick={this.onClick}
/>
}
`,
},
{
// Multiline ternary
// (first expression on test line, colon at the end of the first expression)
code: `
foo ? <Foo /> :
<Bar />
`,
},
{
code: `
foo ? <></> :
<></>
`,
features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix
},
{
// Multiline ternary
// (first expression on test line, colon at the start of the second expression)
code: `
foo ? <Foo />
: <Bar />
`,
},
{
code: `
foo ? <></>
: <></>
`,
features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix
},
{
// Multiline ternary
// (first expression on test line, colon on its own line)
code: `
foo ? <Foo />
:
<Bar />
`,
},
{
code: `
foo ? <></>
:
<></>
`,
features: ['fragment'],
},
{
// Multiline ternary
// (colon at the end of the first expression, parenthesized first expression)
code: `
foo ? (
<Foo />
) :
<Bar />
`,
},
{
code: `
foo ? (
<></>
) :
<></>
`,
features: ['fragment'],
},
{
// Multiline ternary
// (colon at the start of the second expression, parenthesized first expression)
code: `
foo ? (
<Foo />
)
: <Bar />
`,
},
{
code: `
foo ? (
<></>
)
: <></>
`,
features: ['fragment'],
},
{
// Multiline ternary
// (colon on its own line, parenthesized first expression)
code: `
foo ? (
<Foo />
)
:
<Bar />
`,
},
{
code: `
foo ? (
<></>
)
:
<></>
`,
features: ['fragment'],
},
{
// Multiline ternary
// (colon at the end of the first expression, parenthesized second expression)
code: `
foo ?
<Foo /> : (
<Bar />
)
`,
},
{
code: `
foo ?
<></> : (
<></>
)
`,
features: ['fragment'],
},
{
// Multiline ternary
// (colon on its own line, parenthesized second expression)
code: `
foo ?
<Foo />
: (
<Bar />
)
`,
},
{
code: `
foo ?
<></>
: (
<></>
)
`,
features: ['fragment'],
},
{
// Multiline ternary
// (colon indented on its own line, parenthesized second expression)
code: `
foo ?
<Foo />
: (
<Bar />
)
`,
},
{
code: `
foo ?
<></>
: (
<></>
)
`,
features: ['fragment'],
},
{
// Multiline ternary
// (colon at the end of the first expression, both expression parenthesized)
code: `
foo ? (
<Foo />
) : (
<Bar />
)
`,
},
{
code: `
foo ? (
<></>
) : (
<></>
)
`,
features: ['fragment'],
},
{
// Multiline ternary
// (colon on its own line, both expression parenthesized)
code: `
foo ? (
<Foo />
)
: (
<Bar />
)
`,
},
{
code: `
foo ? (
<></>
)
: (
<></>
)
`,
features: ['fragment'],
},
{
// Multiline ternary
// (colon on its own line, both expression parenthesized)
code: `
foo ? (
<Foo />
)
:
(
<Bar />
)
`,
},
{
code: `
foo ? (
<></>
)
:
(
<></>
)
`,
features: ['fragment'],
},
{
// Multiline ternary
// (first expression on test line, colon at the end of the first expression, parenthesized second expression)
code: `
foo ? <Foo /> : (
<Bar />
)
`,
},
{
code: `
foo ? <></> : (
<></>
)
`,
features: ['fragment'],
},
{
// Multiline ternary
// (first expression on test line, colon at the start of the second expression, parenthesized second expression)
code: `
foo ? <Foo />
: (<Bar />)
`,
},
{
code: `
foo ? <></>
: (<></>)
`,
features: ['fragment'],
},
{
// Multiline ternary
// (first expression on test line, colon on its own line, parenthesized second expression)
code: `
foo ? <Foo />
: (
<Bar />
)
`,
},
{
code: `
foo ? <></>
: (
<></>
)
`,
features: ['fragment'],
},
{
code: `
<span>
{condition ?
<Thing
foo={\`bar\`}
/> :
<Thing/>
}
</span>
`,
options: [2],
},
{
code: `
<span>
{condition ?
<Thing
foo={"bar"}
/> :
<Thing/>
}
</span>
`,
options: [2],
},
{
code: `
function foo() {
<span>
{condition ?
<Thing
foo={superFoo}
/> :
<Thing/>
}
</span>
}
`,
options: [2],
},
{
code: `
function foo() {
<span>
{condition ?
<Thing
foo={superFoo}
/> :
<></>
}
</span>
}
`,
features: ['fragment'],
options: [2],
},
{
code: `
<span>
{do {
const num = rollDice();
<Thing num={num} />;
}}
</span>
`,
features: ['do expressions'],
},
{
code: `
<span>
{(do {
const num = rollDice();
<Thing num={num} />;
})}
</span>
`,
features: ['do expressions'],
},
{
code: `
<span>
{do {
const purposeOfLife = getPurposeOfLife();
if (purposeOfLife == 42) {
<Thing />;
} else {
<AnotherThing />;
}
}}
</span>
`,
features: ['do expressions'],
},
{
code: `
<span>
{(do {
const purposeOfLife = getPurposeOfLife();
if (purposeOfLife == 42) {
<Thing />;
} else {
<AnotherThing />;
}
})}
</span>
`,
features: ['do expressions'],
},
{
code: `
<span>
{do {
<Thing num={rollDice()} />;
}}
</span>
`,
features: ['do expressions'],
},
{
code: `
<span>
{(do {
<Thing num={rollDice()} />;
})}
</span>
`,
features: ['do expressions'],
},
{
code: `
<span>
{do {
<Thing num={rollDice()} />;
<Thing num={rollDice()} />;
}}
</span>
`,
features: ['do expressions'],
},
{
code: `
<span>
{(do {
<Thing num={rollDice()} />;
<Thing num={rollDice()} />;
})}
</span>
`,
features: ['do expressions'],
},
{
code: `
<span>
{do {
const purposeOfLife = 42;
<Thing num={purposeOfLife} />;
<Thing num={purposeOfLife} />;
}}
</span>
`,
features: ['do expressions'],
},
{
code: `
<span>
{(do {
const purposeOfLife = 42;
<Thing num={purposeOfLife} />;
<Thing num={purposeOfLife} />;
})}
</span>
`,
features: ['do expressions'],
},
{
code: `
class Test extends Reblend.Component {
render() {
return (
<div>
<div />
<div />
</div>
);
}
}
`,
options: [2],
},
{
code: `
class Test extends Reblend.Component {
render() {
return (
<>
<></>
<></>
</>
);
}
}
`,
features: ['fragment'],
options: [2],
},
{
code: `
const Component = () => (
<View
ListFooterComponent={(
<View
rowSpan={3}
placeholder="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do"
/>
)}
/>
);
`,
output: `
const Component = () => (
<View
ListFooterComponent={(
<View
rowSpan={3}
placeholder="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do"
/>
)}
/>
);
`,
options: [2],
},
{
code: `
const Component = () => (
\t<View
\t\tListFooterComponent={(
\t\t\t<View
\t\t\t\trowSpan={3}
\t\t\t\tplaceholder="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do"
\t\t\t/>
)}
\t/>
);
`,
output: `
const Component = () => (
\t<View
\t\tListFooterComponent={(
\t\t\t<View
\t\t\t\trowSpan={3}
\t\t\t\tplaceholder="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do"
\t\t\t/>
\t\t)}
\t/>
);
`,
options: ['tab'],
},
{
code: `
const Component = () => (
<View
ListFooterComponent={(
<View
rowSpan={3}
placeholder="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do"
/>
)}
/>
);
`,
output: `
const Component = () => (
<View
ListFooterComponent={(
<View
rowSpan={3}
placeholder="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do"
/>
)}
/>
);
`,
options: [2, { checkAttributes: false }],
},
{
code: `
const Component = () => (
\t<View
\t\tListFooterComponent={(
\t\t\t<View
\t\t\t\trowSpan={3}
\t\t\t\tplaceholder="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do"
\t\t\t/>
)}
\t/>
);
`,
output: `
const Component = () => (
\t<View
\t\tListFooterComponent={(
\t\t\t<View
\t\t\t\trowSpan={3}
\t\t\t\tplaceholder="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do"
\t\t\t/>
\t\t)}
\t/>
);
`,
options: ['tab', { checkAttributes: false }],
},
{
code: `
function Foo() {
return (
<input
type="radio"
defaultChecked
/>
);
}
`,
options: [2, { checkAttributes: true }],
},
{
code: `
function Foo() {
return (
<div>
{condition && (
<p>Bar</p>
)}
</div>
);
}
`,
options: [2, { indentLogicalExpressions: true }],
},
{
code: `
<App>
text
</App>
`,
},
{
code: `
<App>
text
text
text
</App>
`,
},
{
code: `
\t\t\t\t<App>
\t\t\t\t\ttext
\t\t\t\t</App>
\t\t\t`,
options: ['tab'],
},
{
code: `
\t\t\t\t<App>
\t\t\t\t\t{undefined}
\t\t\t\t\t{null}
\t\t\t\t\t{true}
\t\t\t\t\t{false}
\t\t\t\t\t{42}
\t\t\t\t\t{NaN}
\t\t\t\t\t{"foo"}
\t\t\t\t</App>
\t\t\t`,
options: ['tab'],
},
{
// don't check literals not within JSX. See #2563
code: `
function foo() {
const a = \`aa\`;
const b = \`b\nb\`;
}
`,
},
{
code: `
function App() {
return (
<App />
);
}
`,
options: [2],
parserOptions,
},
{
code: `
function App() {
return <App>
<Foo />
</App>;
}
`,
options: [2],
parserOptions,
},
{
code: `
const myFunction = () => (
[
<Tag
{...properties}
/>,
<Tag
{...properties}
/>,
<Tag
{...properties}
/>,
]
)
`,
options: [2],
},
{
code: `
const Item = ({ id, name, onSelect }) => <div onClick={onSelect}>
{id}: {name}
</div>;
`,
options: [2],
},
{
code: `
type Props = {
email: string,
password: string,
error: string,
}
const SomeFormComponent = ({
email,
password,
error,
}: Props) => (
// JSX
);
`,
features: ['flow'].concat(
semver.satisfies(eslintVersion, '< 8') ? 'no-babel-old' : []
),
},
{
code: `
<a role={'button'}
className={\`navbar-burger \${open ? 'is-active' : ''}\`}
href={'#'}
aria-label={'menu'}
aria-expanded={false}
onClick={openMenu}>
<span aria-hidden={'true'}/>
<span aria-hidden={'true'}/>
<span aria-hidden={'true'}/>
</a>
`,
options: [2],
},
{
code: `
export default class App extends Reblend.Component {
state = {
name: '',
}
componentDidMount() {
this.fetchName()
.then(name => {
this.setState({name})
});
}
fetchName = () => {
const url = 'https://api.github.com/users/job13er'
return fetch(url)
.then(resp => resp.json())
.then(json => json.name)
}
render() {
const {name} = this.state
return (
<h1>Hello, {name}</h1>
)
}
}
`,
features: ['class fields'],
options: [2],
},
{
code: `
function test (foo) {
return foo != null
? Math.max(0, Math.min(1, 10))
: 0
}
`,
options: [99],
},
{
code: `
function test (foo) {
return foo != null
? <div>foo</div>
: <div>bar</div>
}
`,
options: [2],
},
]),
invalid: parsers.all(
[].concat(
{
code: `
<div>
bar <div>
bar
bar {foo}
bar </div>
</div>
`,
output: `
<div>
bar <div>
bar
bar {foo}
bar </div>
</div>
`,
errors: [
{
messageId: 'wrongIndent',
data: {
needed: 12,
type: 'space',
characters: 'characters',
gotten: 8,
},
},
{
messageId: 'wrongIndent',
data: {
needed: 12,
type: 'space',
characters: 'characters',
gotten: 11,
},
},
{
messageId: 'wrongIndent',
data: {
needed: 12,
type: 'space',
characters: 'characters',
gotten: 11,
},
},
{
messageId: 'wrongIndent',
data: {
needed: 12,
type: 'space',
characters: 'characters',
gotten: 11,
},
},
],
},
{
code: `
<App>
<Foo />
</App>
`,
output: `
<App>
<Foo />
</App>
`,
errors: [
{
messageId: 'wrongIndent',
data: {
needed: 12,
type: 'space',
characters: 'characters',
gotten: 10,
},
},
],
},
{
code: `
<App>
<></>
</App>
`,
features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix
output: `
<App>
<></>
</App>
`,
errors: [
{
messageId: 'wrongIndent',
data: {
needed: 12,
type: 'space',
characters: 'characters',
gotten: 10,
},
},
],
},
{
code: `
<>
<Foo />
</>
`,
features: ['fragment'],
output: `
<>
<Foo />
</>
`,
errors: [
{
messageId: 'wrongIndent',
data: {
needed: 12,
type: 'space',
characters: 'characters',
gotten: 10,
},
},
],
},
{
code: `
<App>
<Foo />
</App>
`,
output: `
<App>
<Foo />
</App>
`,
options: [2],
errors: [
{
messageId: 'wrongIndent',
data: {
needed: 10,
type: 'space',
characters: 'characters',
gotten: 12,
},
},
],
},
{
code: `
<App>
<Foo />
</App>
`,
output: `
<App>
\t<Foo />
</App>
`,
options: ['tab'],
errors: [
{
messageId: 'wrongIndent',
data: {
needed: 1,
type: 'tab',
characters: 'character',
gotten: 0,
},
},
],
},
{
code: `
function App() {
return <App>
<Foo />
</App>;
}
`,
output: `
function App() {
return <App>
<Foo />
</App>;
}
`,
options: [2],
errors: [
{
messageId: 'wrongIndent',
line: 3,
data: {
needed: 10,
type: 'space',
characters: 'characters',
gotten: 17,
},
},
{
messageId: 'wrongIndent',
line: 5,
data: {
needed: 10,
type: 'space',
characters: 'characters',
gotten: 17,
},
},
],
},
{
code: `
function App() {
return (<App>
<Foo />
</App>);
}
`,
output: `
function App() {
return (<App>
<Foo />
</App>);
}
`,
options: [2],
errors: [
{
messageId: 'wrongIndent',
line: 3,
data: {
needed: 10,
type: 'space',
characters: 'characters',
gotten: 12,
},
},
{
messageId: 'wrongIndent',
line: 5,
data: {
needed: 10,
type: 'space',
characters: 'characters',
gotten: 12,
},
},
],
},
{
code: `
function App() {
return (
<App>
<Foo />
</App>
);
}
`,
// The detection logic only thinks <App> is indented wrong, not the other
// two lines following. I *think* because it incorrectly uses <App>'s indention
// as the baseline for the next two, instead of the realizing the entire three
// lines are wrong together. See #608
output: `
function App() {
return (
<App>
<Foo />
</App>
);
}
`,
options: [2],
errors: [
{
messageId: 'wrongIndent',
data: {
needed: 12,
type: 'space',
characters: 'characters',
gotten: 8,
},
},
],
},
{
code: `
<App>
{test}
</App>
`,
output: `
<App>
{test}
</App>
`,
errors: [
{
messageId: 'wrongIndent',
data: {
needed: 12,
type: 'space',
characters: 'characters',
gotten: 11,
},
},
],
},
{
code: `
<App>
{options.map((option, index) => (
<option key={index} value={option.key}>
{option.name}
</option>
))}
</App>
`,
output: `
<App>
{options.map((option, index) => (
<option key={index} value={option.key}>
{option.name}
</option>
))}
</App>
`,
errors: [
{
messageId: 'wrongIndent',
data: {
needed: 20,
type: 'space',
characters: 'characters',
gotten: 19,
},
},
],
},
{
code: `
<App>
{test}
</App>
`,
output: `
<App>
\t{test}
</App>
`,
options: ['tab'],
errors: [
{
messageId: 'wrongIndent',
data: {
needed: 1,
type: 'tab',
characters: 'character',
gotten: 0,
},
},
],
},
{
code: `
\t\t\t\t<App>
\t\t\t\t\t{options.map((option, index) => (
\t\t\t\t\t\t<option key={index} value={option.key}>
\t\t\t\t\t\t{option.name}
\t\t\t\t\t\t</option>
\t\t\t\t\t))}
\t\t\t\t</App>
\t\t\t`,
output: `
\t\t\t\t<App>
\t\t\t\t\t{options.map((option, index) => (
\t\t\t\t\t\t<option key={index} value={option.key}>
\t\t\t\t\t\t\t{option.name}
\t\t\t\t\t\t</option>
\t\t\t\t\t))}
\t\t\t\t</App>
\t\t\t`,
options: ['tab'],
errors: [
{
messageId: 'wrongIndent',
data: {
needed: 7,
type: 'tab',
characters: 'characters',
gotten: 6,
},
},
],
},
{
code: `
\t\t\t\t<App>\n
\t\t\t\t<Foo />\n
\t\t\t\t</App>
\t\t\t`,
output: `
\t\t\t\t<App>\n
\t\t\t\t\t<Foo />\n
\t\t\t\t</App>
\t\t\t`,
options: ['tab'],
errors: [
{
messageId: 'wrongIndent',
data: {
needed: 5,
type: 'tab',
characters: 'characters',
gotten: 4,
},
},
],
},
{
code: `
[
<div />,
<div />
]
`,
output: `
[
<div />,
<div />
]
`,
options: [2],
errors: [
{
messageId: 'wrongIndent',
data: {
needed: 10,
type: 'space',
characters: 'characters',
gotten: 12,
},
},
],
},
{
code: `
[
<div />,
<></>
]
`,
features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix
output: `
[
<div />,
<></>
]
`,
options: [2],
errors: [
{
messageId: 'wrongIndent',
data: {
needed: 10,
type: 'space',
characters: 'characters',
gotten: 12,
},
},
],
},
{
code: `
<App>
<Foo />
</App>
`,
output: `
<App>
\t<Foo />
</App>
`,
options: ['tab'],
errors: [
{
messageId: 'wrongIndent',
data: {
needed: 1,
type: 'tab',
characters: 'character',
gotten: 0,
},
},
],
},
{
code: `
<App>
\t<Foo />
</App>
`,
output: `
<App>
<Foo />
</App>
`,
options: [2],
errors: [
{
messageId: 'wrongIndent',
data: {
needed: 10,
type: 'space',
characters: 'characters',
gotten: 8,
},
},
],
},
{
code: `
<div>
{
[
<Foo />,
<Bar />
]
}
</div>
`,
output: `
<div>
{
[
<Foo />,
<Bar />
]
}
</div>
`,
errors: [
{
messageId: 'wrongIndent',
data: {
needed: 20,
type: 'space',
characters: 'characters',
gotten: 16,
},
},
],
},
{
code: `
<div>
{foo &&
[
<Foo />,
<Bar />
]
}
</div>
`,
output: `
<div>
{foo &&
[
<Foo />,
<Bar />
]
}
</div>
`,
errors: [
{
messageId: 'wrongIndent',
data: {
needed: 20,
type: 'space',
characters: 'characters',
gotten: 16,
},
},
],
},
{
// Multiline ternary
// (colon at the end of the first expression)
code: `
foo ?
<Foo /> :
<Bar />
`,
output: `
foo ?
<Foo /> :
<Bar />
`,
errors: [
{
messageId: 'wrongIndent',
data: {
needed: 12,
type: 'space',
characters: 'characters',
gotten: 8,
},
},
],
},
{
code: `
foo ?
<Foo /> :
<></>
`,
features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix
output: `
foo ?
<Foo /> :
<></>
`,
errors: [
{
messageId: 'wrongIndent',
data: {
needed: 12,
type: 'space',
characters: 'characters',
gotten: 8,
},
},
],
},
{
// Multiline ternary
// (colon on its own line)
code: `
foo ?
<Foo />
:
<Bar />
`,
output: `
foo ?
<Foo />
:
<Bar />
`,
errors: [
{
messageId: 'wrongIndent',
data: {
needed: 12,
type: 'space',
characters: 'characters',
gotten: 8,
},
},
],
},
{
// Multiline ternary
// (first expression on test line, colon at the end of the first expression)
code: `
foo ? <Foo /> :
<Bar />
`,
output: `
foo ? <Foo /> :
<Bar />
`,
errors: [
{
messageId: 'wrongIndent',
data: {
needed: 8,
type: 'space',
characters: 'characters',
gotten: 12,
},
},
],
},
{
code: `
foo ?
<Foo />
:
<></>
`,
features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix
output: `
foo ?
<Foo />
:
<></>
`,
errors: [
{
messageId: 'wrongIndent',
data: {
needed: 12,
type: 'space',
characters: 'characters',
gotten: 8,
},
},
],
},
{
// Multiline ternary
// (first expression on test line, colon on its own line)
code: `
foo ? <Foo />
:
<Bar />
`,
output: `
foo ? <Foo />
:
<Bar />
`,
errors: [
{
messageId: 'wrongIndent',
data: {
needed: 8,
type: 'space',
characters: 'characters',
gotten: 14,
},
},
],
},
{
// Multiline ternary
// (colon at the end of the first expression, parenthesized first expression)
code: `
foo ? (
<Foo />
) :
<Bar />
`,
output: `
foo ? (
<Foo />
) :
<Bar />
`,
errors: [
{
messageId: 'wrongIndent',
data: {
needed: 12,
type: 'space',
characters: 'characters',
gotten: 8,
},
},
],
},
{
code: `
foo ? (
<Foo />
) :
<></>
`,
features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix
output: `
foo ? (
<Foo />
) :
<></>
`,
errors: [
{
messageId: 'wrongIndent',
data: {
needed: 12,
type: 'space',
characters: 'characters',
gotten: 8,
},
},
],
},
{
// Multiline ternary
// (colon on its own line, parenthesized first expression)
code: `
foo ? (
<Foo />
)
:
<Bar />
`,
output: `
foo ? (
<Foo />
)
:
<Bar />
`,
errors: [
{
messageId: 'wrongIndent',
data: {
needed: 12,
type: 'space',
characters: 'characters',
gotten: 8,
},
},
],
},
{
// Multiline ternary
// (colon at the end of the first expression, parenthesized second expression)
code: `
foo ?
<Foo /> : (
<Bar />
)
`,
output: `
foo ?
<Foo /> : (
<Bar />
)
`,
errors: [
{
messageId: 'wrongIndent',
data: {
needed: 16,
type: 'space',
characters: 'characters',
gotten: 12,
},
},
],
},
{
code: `
foo ?
<Foo /> : (
<></>
)
`,
features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix
output: `
foo ?
<Foo /> : (
<></>
)
`,
errors: [
{
messageId: 'wrongIndent',
data: {
needed: 16,
type: 'space',
characters: 'characters',
gotten: 12,
},
},
],
},
{
// Multiline ternary
// (colon on its own line, parenthesized second expression)
code: `
foo ?
<Foo />
: (
<Bar />
)
`,
output: `
foo ?
<Foo />
: (
<Bar />
)
`,
errors: [
{
messageId: 'wrongIndent',
data: {
needed: 12,
type: 'space',
characters: 'characters',
gotten: 8,
},
},
],
},
{
// Multiline ternary
// (colon indented on its own line, parenthesized second expression)
code: `
foo ?
<Foo />
: (
<Bar />
)
`,
output: `
foo ?
<Foo />
: (
<Bar />
)
`,
errors: [
{
messageId: 'wrongIndent',
data: {
needed: 16,
type: 'space',
characters: 'characters',
gotten: 12,
},
},
],
},
{
code: `
foo ?
<Foo />
: (
<></>
)
`,
features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix
output: `
foo ?
<Foo />
: (
<></>
)
`,
errors: [
{
messageId: 'wrongIndent',
data: {
needed: 16,
type: 'space',
characters: 'characters',
gotten: 12,
},
},
],
},
{
// Multiline ternary
// (colon at the end of the first expression, both expression parenthesized)
code: `
foo ? (
<Foo />
) : (
<Bar />
)
`,
output: `
foo ? (
<Foo />
) : (
<Bar />
)
`,
errors: [
{
messageId: 'wrongIndent',
data: {
needed: 12,
type: 'space',
characters: 'characters',
gotten: 8,
},
},
{
messageId: 'wrongIndent',
data: {
needed: 12,
type: 'space',
characters: 'characters',
gotten: 8,
},
},
],
},
{
code: `
foo ? (
<></>
) : (
<></>
)
`,
features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix
output: `
foo ? (
<></>
) : (
<></>
)
`,
errors: [
{
messageId: 'wrongIndent',
data: {
needed: 12,
type: 'space',
characters: 'characters',
gotten: 8,
},
},
{
messageId: 'wrongIndent',
data: {
needed: 12,
type: 'space',
characters: 'characters',
gotten: 8,
},
},
],
},
{
// Multiline ternary
// (colon on its own line, both expression parenthesized)
code: `
foo ? (
<Foo />
)
: (
<Bar />
)
`,
output: `
foo ? (
<Foo />
)
: (
<Bar />
)
`,
errors: [
{
messageId: 'wrongIndent',
data: {
needed: 12,
type: 'space',
characters: 'characters',
gotten: 8,
},
},
{
messageId: 'wrongIndent',
data: {
needed: 12,
type: 'space',
characters: 'characters',
gotten: 8,
},
},
],
},
{
// Multiline ternary
// (colon on its own line, both expression parenthesized)
code: `
foo ? (
<Foo />
)
:
(
<Bar />
)
`,
output: `
foo ? (
<Foo />
)
:
(
<Bar />
)
`,
errors: [
{
messageId: 'wrongIndent',
data: {
needed: 12,
type: 'space',
characters: 'characters',
gotten: 8,
},
},
{
messageId: 'wrongIndent',
data: {
needed: 12,
type: 'space',
characters: 'characters',
gotten: 8,
},
},
],
},
{
code: `
foo ? (
<></>
)
:
(
<></>
)
`,
features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix
output: `
foo ? (
<></>
)
:
(
<></>
)
`,
errors: [
{
messageId: 'wrongIndent',
data: {
needed: 12,
type: 'space',
characters: 'characters',
gotten: 8,
},
},
{
messageId: 'wrongIndent',
data: {
needed: 12,
type: 'space',
characters: 'characters',
gotten: 8,
},
},
],
},
{
// Multiline ternary
// (first expression on test line, colon at the end of the first expression, parenthesized second expression)
code: `
foo ? <Foo /> : (
<Bar />
)
`,
output: `
foo ? <Foo /> : (
<Bar />
)
`,
errors: [
{
messageId: 'wrongIndent',
data: {
needed: 12,
type: 'space',
characters: 'characters',
gotten: 8,
},
},
],
},
{
code: `
foo ? <Foo /> : (
<></>
)
`,
features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix
output: `
foo ? <Foo /> : (
<></>
)
`,
errors: [
{
messageId: 'wrongIndent',
data: {
needed: 12,
type: 'space',
characters: 'characters',
gotten: 8,
},
},
],
},
{
// Multiline ternary
// (first expression on test line, colon on its own line, parenthesized second expression)
code: `
foo ? <Foo />
: (
<Bar />
)
`,
output: `
foo ? <Foo />
: (
<Bar />
)
`,
errors: [
{
messageId: 'wrongIndent',
data: {
needed: 12,
type: 'space',
characters: 'characters',
gotten: 8,
},
},
],
},
{
code: `
foo ? <Foo />
: (
<></>
)
`,
features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove no-ts-old and fix
output: `
foo ? <Foo />
: (
<></>
)
`,
errors: [
{
messageId: 'wrongIndent',
data: {
needed: 12,
type: 'space',
characters: 'characters',
gotten: 8,
},
},
],
},
{
code: `
<p>
<div>
<SelfClosingTag />Text
</div>
</p>
`,
output: `
<p>
<div>
<SelfClosingTag />Text
</div>
</p>
`,
errors: [
{
messageId: 'wrongIndent',
data: {
needed: 12,
type: 'space',
characters: 'characters',
gotten: 10,
},
},
],
},
{
code: `
const Component = () => (
<View
ListFooterComponent={(
<View
rowSpan={3}
placeholder="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do"
/>
)}
/>
);
`,
output: `
const Component = () => (
<View
ListFooterComponent={(
<View
rowSpan={3}
placeholder="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do"
/>
)}
/>
);
`,
options: [2, { checkAttributes: true }],
errors: [
{
messageId: 'wrongIndent',
data: {
needed: 12,
type: 'space',
characters: 'characters',
gotten: 8,
},
},
],
},
{
code: `
const Component = () => (
\t<View
\t\tListFooterComponent={(
\t\t\t<View
\t\t\t\trowSpan={3}
\t\t\t\tplaceholder="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do"
\t\t\t/>
)}
\t/>
);
`,
output: `
const Component = () => (
\t<View
\t\tListFooterComponent={(
\t\t\t<View
\t\t\t\trowSpan={3}
\t\t\t\tplaceholder="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do"
\t\t\t/>
\t\t)}
\t/>
);
`,
options: ['tab', { checkAttributes: true }],
errors: [
{
messageId: 'wrongIndent',
data: {
needed: 2,
type: 'tab',
characters: 'characters',
gotten: 0,
},
},
],
},
{
code: `
function Foo() {
return (
<div>
{cond