asynctest(
  'browser.tinymce.core.FormatterCheckTest',
  [
    'ephox.agar.api.Pipeline',
    'ephox.mcagar.api.LegacyUnit',
    'ephox.mcagar.api.TinyLoader',
    'tinymce.themes.modern.Theme'
  ],
  function (Pipeline, LegacyUnit, TinyLoader, Theme) {
    var success = arguments[arguments.length - 2];
    var failure = arguments[arguments.length - 1];
    var suite = LegacyUnit.createSuite();

    Theme();

    suite.test('Selected style element text', function (editor) {
      editor.formatter.register('bold', { inline: 'b' });
      editor.getBody().innerHTML = '<p><b>1234</b></p>';
      var rng = editor.dom.createRng();
      rng.setStart(editor.dom.select('b')[0].firstChild, 0);
      rng.setEnd(editor.dom.select('b')[0].firstChild, 4);
      editor.selection.setRng(rng);
      LegacyUnit.equal(editor.formatter.match('bold'), true, 'Selected style element text');
    });

    suite.test('Selected style element with css styles', function (editor) {
      editor.formatter.register('color', { inline: 'span', styles: { color: '#ff0000' } });
      editor.getBody().innerHTML = '<p><span style="color:#ff0000">1234</span></p>';
      var rng = editor.dom.createRng();
      rng.setStart(editor.dom.select('span')[0].firstChild, 0);
      rng.setEnd(editor.dom.select('span')[0].firstChild, 4);
      editor.selection.setRng(rng);
      LegacyUnit.equal(editor.formatter.match('color'), true, 'Selected style element with css styles');
    });

    suite.test('Selected style element with css styles indexed', function (editor) {
      editor.formatter.register('color', { inline: 'span', styles: ['color'] });
      editor.getBody().innerHTML = '<p><span style="color:#ff0000">1234</span></p>';
      var rng = editor.dom.createRng();
      rng.setStart(editor.dom.select('span')[0].firstChild, 0);
      rng.setEnd(editor.dom.select('span')[0].firstChild, 4);
      editor.selection.setRng(rng);
      LegacyUnit.equal(editor.formatter.match('color'), true, 'Selected style element with css styles');
    });

    suite.test('Selected style element with attributes', function (editor) {
      editor.formatter.register('fontsize', { inline: 'font', attributes: { size: '7' } });
      editor.getBody().innerHTML = '<p><font size="7">1234</font></p>';
      var rng = editor.dom.createRng();
      rng.setStart(editor.dom.select('font')[0].firstChild, 0);
      rng.setEnd(editor.dom.select('font')[0].firstChild, 4);
      editor.selection.setRng(rng);
      LegacyUnit.equal(editor.formatter.match('fontsize'), true, 'Selected style element with attributes');
    });

    suite.test('Selected style element text multiple formats', function (editor) {
      editor.formatter.register('multiple', [
        { inline: 'b' },
        { inline: 'strong' }
      ]);
      editor.getBody().innerHTML = '<p><strong>1234</strong></p>';
      var rng = editor.dom.createRng();
      rng.setStart(editor.dom.select('strong')[0].firstChild, 0);
      rng.setEnd(editor.dom.select('strong')[0].firstChild, 4);
      editor.selection.setRng(rng);
      LegacyUnit.equal(editor.formatter.match('multiple'), true, 'Selected style element text multiple formats');
    });

    suite.test('Selected complex style element', function (editor) {
      editor.formatter.register('complex', { inline: 'span', styles: { fontWeight: 'bold' } });
      editor.getBody().innerHTML = '<p><span style="color:#ff0000; font-weight:bold">1234</span></p>';
      var rng = editor.dom.createRng();
      rng.setStart(editor.dom.select('span')[0].firstChild, 0);
      rng.setEnd(editor.dom.select('span')[0].firstChild, 4);
      editor.selection.setRng(rng);
      LegacyUnit.equal(editor.formatter.match('complex'), true, 'Selected complex style element');
    });

    suite.test('Selected non style element text', function (editor) {
      editor.formatter.register('bold', { inline: 'b' });
      editor.getBody().innerHTML = '<p>1234</p>';
      var rng = editor.dom.createRng();
      rng.setStart(editor.dom.select('p')[0].firstChild, 0);
      rng.setEnd(editor.dom.select('p')[0].firstChild, 4);
      editor.selection.setRng(rng);
      LegacyUnit.equal(editor.formatter.match('bold'), false, 'Selected non style element text');
    });

    suite.test('Selected partial style element (start)', function (editor) {
      editor.formatter.register('bold', { inline: 'b' });
      editor.getBody().innerHTML = '<p><b>1234</b>5678</p>';
      var rng = editor.dom.createRng();
      rng.setStart(editor.dom.select('b')[0].firstChild, 0);
      rng.setEnd(editor.dom.select('p')[0].lastChild, 4);
      editor.selection.setRng(rng);
      LegacyUnit.equal(editor.formatter.match('bold'), true, 'Selected partial style element (start)');
    });

    suite.test('Selected partial style element (end)', function (editor) {
      editor.formatter.register('bold', { inline: 'b' });
      editor.getBody().innerHTML = '<p>1234<b>5678</b></p>';
      var rng = editor.dom.createRng();
      rng.setStart(editor.dom.select('p')[0].firstChild, 0);
      rng.setEnd(editor.dom.select('b')[0].lastChild, 4);
      editor.selection.setRng(rng);
      LegacyUnit.equal(editor.formatter.match('bold'), false, 'Selected partial style element (end)');
    });

    suite.test('Selected element text with parent inline element', function (editor) {
      editor.formatter.register('bold', { inline: 'b' });
      editor.getBody().innerHTML = '<p><b><em><span>1234</span></em></b></p>';
      var rng = editor.dom.createRng();
      rng.setStart(editor.dom.select('span')[0].firstChild, 0);
      rng.setEnd(editor.dom.select('span')[0].firstChild, 4);
      editor.selection.setRng(rng);
      LegacyUnit.equal(editor.formatter.match('bold'), true, 'Selected element text with parent inline element');
    });

    suite.test('Selected element match with variable', function (editor) {
      editor.formatter.register('complex', { inline: 'span', styles: { color: '%color' } });
      editor.getBody().innerHTML = '<p><span style="color:#ff0000">1234</span></p>';
      var rng = editor.dom.createRng();
      rng.setStart(editor.dom.select('span')[0].firstChild, 0);
      rng.setEnd(editor.dom.select('span')[0].firstChild, 4);
      editor.selection.setRng(rng);
      LegacyUnit.equal(editor.formatter.match('complex', { color: '#ff0000' }), true, 'Selected element match with variable');
    });

    suite.test('Selected element match with variable and function', function (editor) {
      editor.formatter.register('complex', {
        inline: 'span',
        styles: {
          color: function (vars) {
            return vars.color + '00';
          }
        }
      });

      editor.getBody().innerHTML = '<p><span style="color:#ff0000">1234</span></p>';
      var rng = editor.dom.createRng();
      rng.setStart(editor.dom.select('span')[0].firstChild, 0);
      rng.setEnd(editor.dom.select('span')[0].firstChild, 4);
      editor.selection.setRng(rng);
      LegacyUnit.equal(editor.formatter.match('complex', { color: '#ff00' }), true, 'Selected element match with variable and function');
    });

    suite.test('matchAll', function (editor) {
      editor.getBody().innerHTML = '<p><b><i>a</i></b></p>';
      LegacyUnit.setSelection(editor, 'i', 0, 'i', 1);
      LegacyUnit.equal(editor.formatter.matchAll(['bold', 'italic', 'underline']), ['italic', 'bold']);
    });

    suite.test('canApply', function (editor) {
      editor.getBody().innerHTML = '<p>a</p>';
      LegacyUnit.setSelection(editor, 'p', 0, 'p', 1);
      LegacyUnit.equal(editor.formatter.canApply('bold'), true);
    });

    suite.test('Custom onmatch handler', function (editor) {
      editor.formatter.register('format', {
        inline: 'span',
        onmatch: function (elm) {
          return elm.className === 'x';
        }
      });

      editor.setContent('<p><span class="a">a</span><span class="x">b</span></p>');
      LegacyUnit.setSelection(editor, 'span:nth-child(1)', 0, 'span:nth-child(1)', 0);
      LegacyUnit.equal(editor.formatter.match('format'), false, 'Should not match since the onmatch matches on x classes.');
      LegacyUnit.setSelection(editor, 'span:nth-child(2)', 0, 'span:nth-child(2)', 0);
      LegacyUnit.equal(editor.formatter.match('format'), true, 'Should match since the onmatch matches on x classes.');
    });

    suite.test('formatChanged complex format', function (editor) {
      var newState, newArgs;

      editor.formatter.register('complex', { inline: 'span', styles: { color: '%color' } });

      editor.formatter.formatChanged('complex', function (state, args) {
        newState = state;
        newArgs = args;
      }, true);

      editor.getBody().innerHTML = '<p>text</p>';
      LegacyUnit.setSelection(editor, 'p', 0, 'p', 4);

      // Check apply
      editor.formatter.apply('complex', { color: '#FF0000' });
      editor.nodeChanged();
      LegacyUnit.equal(newState, true);
      LegacyUnit.equal(newArgs.format, 'complex');
      LegacyUnit.equalDom(newArgs.node, editor.getBody().firstChild.firstChild);
      LegacyUnit.equal(newArgs.parents.length, 2);

      // Check remove
      editor.formatter.remove('complex', { color: '#FF0000' });
      editor.nodeChanged();
      LegacyUnit.equal(newState, false);
      LegacyUnit.equal(newArgs.format, 'complex');
      LegacyUnit.equalDom(newArgs.node, editor.getBody().firstChild);
      LegacyUnit.equal(newArgs.parents.length, 1);
    });

    suite.test('Selected style element text', function (editor) {
      editor.formatter.register('bold', { inline: 'b' });
      editor.getBody().innerHTML = '<p><b>1234</b></p>';
      var rng = editor.dom.createRng();
      rng.setStart(editor.dom.select('b')[0].firstChild, 0);
      rng.setEnd(editor.dom.select('b')[0].firstChild, 4);
      editor.selection.setRng(rng);
      LegacyUnit.equal(editor.formatter.match('bold'), true, 'Selected style element text');
    });

    TinyLoader.setup(function (editor, onSuccess, onFailure) {
      Pipeline.async({}, suite.toSteps(editor), onSuccess, onFailure);
    }, {
      indent: false,
      extended_valid_elements: 'b,i,span[style|class|contenteditable]',
      entities: 'raw',
      convert_fonts_to_spans: false,
      forced_root_block: false,
      valid_styles: {
        '*': 'color,font-size,font-family,background-color,font-weight,font-style,text-decoration,float,' +
          'margin,margin-top,margin-right,margin-bottom,margin-left,display,text-align'
      },
      skin_url: '/project/src/skins/lightgray/dist/lightgray'
    }, success, failure);
  }
);
