/**
 * @fileoverview Validate props indentation in JSX
 * @author Yannick Croissant
 */
'use strict';

// ------------------------------------------------------------------------------
// Requirements
// ------------------------------------------------------------------------------

const rule = require('../../../lib/rules/jsx-indent-props');
const RuleTester = require('eslint').RuleTester;

const parserOptions = {
  ecmaVersion: 8,
  sourceType: 'module',
  ecmaFeatures: {
    experimentalObjectRestSpread: true,
    jsx: true
  }
};

// ------------------------------------------------------------------------------
// Tests
// ------------------------------------------------------------------------------

const ruleTester = new RuleTester({parserOptions});
ruleTester.run('jsx-indent-props', rule, {
  valid: [{
    code: [
      '<App foo',
      '/>'
    ].join('\n')
  }, {
    code: [
      '<App',
      '  foo',
      '/>'
    ].join('\n'),
    options: [2]
  }, {
    code: [
      '<App',
      'foo',
      '/>'
    ].join('\n'),
    options: [0]
  }, {
    code: [
      '  <App',
      'foo',
      '  />'
    ].join('\n'),
    options: [-2]
  }, {
    code: [
      '<App',
      '\tfoo',
      '/>'
    ].join('\n'),
    options: ['tab']
  }, {
    code: [
      '<App/>'
    ].join('\n'),
    options: ['aligned']
  }, {
    code: [
      '<App aaa',
      '     b',
      '     cc',
      '/>'
    ].join('\n'),
    options: ['aligned']
  }, {
    code: [
      'const test = <App aaa',
      '                  b',
      '                  cc',
      '             />'
    ].join('\n'),
    options: ['aligned']
  }, {
    code: [
      '<App aaa',
      '     b',
      '>',
      '    <Child c',
      '           d/>',
      '</App>'
    ].join('\n'),
    options: ['aligned']
  }, {
    code: [
      '<Fragment>',
      '  <App aaa',
      '       b',
      '       cc',
      '  />',
      '  <OtherApp a',
      '            bbb',
      '            c',
      '  />',
      '</Fragment>'
    ].join('\n'),
    options: ['aligned']
  }],

  invalid: [{
    code: [
      '<App',
      '  foo',
      '/>'
    ].join('\n'),
    output: [
      '<App',
      '    foo',
      '/>'
    ].join('\n'),
    errors: [{message: 'Expected indentation of 4 space characters but found 2.'}]
  }, {
    code: [
      '<App',
      '    foo',
      '/>'
    ].join('\n'),
    output: [
      '<App',
      '  foo',
      '/>'
    ].join('\n'),
    options: [2],
    errors: [{message: 'Expected indentation of 2 space characters but found 4.'}]
  }, {
    code: [
      '<App',
      '    foo',
      '/>'
    ].join('\n'),
    output: [
      '<App',
      '\tfoo',
      '/>'
    ].join('\n'),
    options: ['tab'],
    errors: [{message: 'Expected indentation of 1 tab character but found 0.'}]
  }, {
    code: [
      '<App',
      '\t\t\tfoo',
      '/>'
    ].join('\n'),
    output: [
      '<App',
      '\tfoo',
      '/>'
    ].join('\n'),
    options: ['tab'],
    errors: [{message: 'Expected indentation of 1 tab character but found 3.'}]
  }, {
    code: [
      '<App a',
      '  b',
      '/>'
    ].join('\n'),
    output: [
      '<App a',
      '     b',
      '/>'
    ].join('\n'),
    options: ['aligned'],
    errors: [{message: 'Expected indentation of 5 space characters but found 2.'}]
  }, {
    code: [
      '<App  a',
      '   b',
      '/>'
    ].join('\n'),
    output: [
      '<App  a',
      '      b',
      '/>'
    ].join('\n'),
    options: ['aligned'],
    errors: [
      {message: 'Found too much whitespace between tag name and first attribute.'},
      {message: 'Expected indentation of 6 space characters but found 3.'}
    ]
  }, {
    code: [
      '<App',
      '      a',
      '   b',
      '/>'
    ].join('\n'),
    output: [
      '<App',
      '      a',
      '      b',
      '/>'
    ].join('\n'),
    options: ['aligned'],
    errors: [
      {message: 'Found too much whitespace between tag name and first attribute.'},
      {message: 'Expected indentation of 6 space characters but found 3.'}
    ]
  }, {
    code: [
      '<App',
      '  a',
      '  b',
      '/>'
    ].join('\n'),
    output: [
      '<App',
      '     a',
      '     b',
      '/>'
    ].join('\n'),
    options: ['aligned'],
    errors: [
      {message: 'Expected indentation of 5 space characters but found 2.'},
      {message: 'Expected indentation of 5 space characters but found 2.'}
    ]
  }]
});

@@ -1642,32 +1642,340 @@
 , %7B%0A    code: %5B%0A
+      '%3CApp aaa x',%0A      '     b y',%0A      '     cc',%0A      '/%3E'%0A    %5D.join('%5Cn'),%0A    options: %5B'aligned'%5D%0A  %7D, %7B%0A    code: %5B%0A      'const test = %3CApp aaa x',%0A      '                  b y',%0A      '                  cc',%0A      '             /%3E'%0A    %5D.join('%5Cn'),%0A    options: %5B'aligned'%5D%0A  %7D, %7B%0A    code: %5B%0A
       '%3CApp aaa'
@@ -3645,32 +3645,301 @@
 , %7B%0A    code: %5B%0A
+      '%3CApp a x',%0A      '  b y',%0A      '/%3E'%0A    %5D.join('%5Cn'),%0A    output: %5B%0A      '%3CApp a x',%0A      '     b y',%0A      '/%3E'%0A    %5D.join('%5Cn'),%0A    options: %5B'aligned'%5D,%0A    errors: %5B%7Bmessage: 'Expected indentation of 5 space characters but found 2.'%7D%5D%0A  %7D, %7B%0A    code: %5B%0A
       '%3CApp  a',

Add test case for more than one prop in a line