suite.test('Whildcard element rule', function () {
    let schema;

    schema = Schema({ valid_elements: '*[id|class]' });
    LegacyUnit.deepEqual(schema.getElementRule('b').attributes, { id: {}, class: {} });
    LegacyUnit.deepEqual(schema.getElementRule('b').attributesOrder, ['id', 'class']);

    schema = Schema({ valid_elements: 'b*[id|class]' });
    LegacyUnit.deepEqual(schema.getElementRule('b').attributes, { id: {}, class: {} });
    LegacyUnit.deepEqual(schema.getElementRule('b').attributesOrder, ['id', 'class']);
    LegacyUnit.deepEqual(schema.getElementRule('body').attributes, { id: {}, class: {} });
    LegacyUnit.deepEqual(schema.getElementRule('body').attributesOrder, ['id', 'class']);
    LegacyUnit.equal(schema.getElementRule('img'), undefined);

    schema = Schema({ valid_elements: 'b?[id|class]' });
    LegacyUnit.deepEqual(schema.getElementRule('b').attributes, { id: {}, class: {} });
    LegacyUnit.deepEqual(schema.getElementRule('b').attributesOrder, ['id', 'class']);
    LegacyUnit.deepEqual(schema.getElementRule('bx').attributes, { id: {}, class: {} });
    LegacyUnit.deepEqual(schema.getElementRule('bx').attributesOrder, ['id', 'class']);
    LegacyUnit.equal(schema.getElementRule('body'), undefined);

    schema = Schema({ valid_elements: 'b+[id|class]' });
    LegacyUnit.deepEqual(schema.getElementRule('body').attributes, { id: {}, class: {} });
    LegacyUnit.deepEqual(schema.getElementRule('body').attributesOrder, ['id', 'class']);
    LegacyUnit.deepEqual(schema.getElementRule('bx').attributes, { id: {}, class: {} });
    LegacyUnit.deepEqual(schema.getElementRule('bx').attributesOrder, ['id', 'class']);
    LegacyUnit.equal(schema.getElementRule('b'), undefined);
  });
  suite.test('Remove internal elements', function () {
    let counter, parser, schema;

    schema = Schema({ valid_elements: 'b' });
    counter = createCounter(writer);
    counter.validate = true;
    counter.remove_internals = true;
    parser = new SaxParser(counter, schema);
    writer.reset();
    parser.parse('<span id="id"><b>text</b></span><span id="id" data-mce-type="something"></span>');
    LegacyUnit.equal(writer.getContent(), '<b>text</b>', 'Remove internal span element without any span schema rule.');

    schema = Schema({ valid_elements: 'b,span[class]' });
    counter = createCounter(writer);
    counter.validate = true;
    counter.remove_internals = true;
    parser = new SaxParser(counter, schema);
    writer.reset();
    parser.parse('<span id="id" class="class"><b>text</b></span><span id="id" data-mce-type="something"></span>');
    LegacyUnit.equal(
      writer.getContent(),
      '<span class="class"><b>text</b></span>',
      'Remove internal span element with a span schema rule.'
    );

    // Reset
    counter.remove_internals = false;
  });
  suite.test('Remove empty elements', function () {
    let schema;

    schema = Schema({ valid_elements: '-span' });
    LegacyUnit.deepEqual(schema.getElementRule('span'), { attributes: {}, attributesOrder: [], removeEmpty: true });

    schema = Schema({ valid_elements: '#span' });
    LegacyUnit.deepEqual(schema.getElementRule('span'), { attributes: {}, attributesOrder: [], paddEmpty: true });
  });
  suite.test('whitespaceElements', function () {
    let schema;

    schema = Schema({ whitespace_elements : 'pre,p' });
    ok(!!schema.getWhiteSpaceElements().pre);
    ok(!schema.getWhiteSpaceElements().span);

    schema = Schema({ whitespace_elements : 'code' });
    ok(!!schema.getWhiteSpaceElements().code);
  });
  suite.test('addValidChildren', function () {
    let schema;

    schema = Schema();
    ok(schema.isValidChild('body', 'p'));
    ok(!schema.isValidChild('body', 'body'));
    ok(!schema.isValidChild('body', 'html'));
    schema.addValidChildren('+body[body|html]');
    ok(schema.isValidChild('body', 'body'));
    ok(schema.isValidChild('body', 'html'));

    schema = Schema();
    ok(schema.isValidChild('body', 'p'));
    schema.addValidChildren('-body[p]');
    ok(!schema.isValidChild('body', 'p'));
  });
 suite.test('Remove empty nodes', function () {
   parser = DomParser({}, Schema({ valid_elements: '-p,-span[id]' }));
   root = parser.parse(
     '<p>a<span></span><span> </span><span id="x">b</span><span id="y"></span></p><p></p><p><span></span></p><p> </p>'
   );
   LegacyUnit.equal(serializer.serialize(root), '<p>a <span id="x">b</span><span id="y"></span></p>');
 });
  suite.test('Parse script elements', function () {
    let counter, parser;

    counter = createCounter(writer);
    parser = new SaxParser(counter, schema);
    writer.reset();
    parser.parse('text1<em><script>// <b>tag</b></s' + 'cript>text2</em>');
    LegacyUnit.equal(writer.getContent(), 'text1<em><script>// <b>tag</b></s' + 'cript>text2</em>', 'Parse script element.');
    LegacyUnit.deepEqual(counter.counts, { start: 2, end: 2, text: 3 }, 'Parse script element counts.');

    counter = createCounter(writer);
    parser = new SaxParser(counter, schema);
    writer.reset();
    parser.parse('text1<em><script id="id">// <b>tag</b></s' + 'cript>text2</em>');
    LegacyUnit.equal(
      writer.getContent(),
      'text1<em><script id="id">// <b>tag</b></s' + 'cript>text2</em>',
      'Parse script element with attributes.'
    );
    LegacyUnit.deepEqual(counter.counts, { start: 2, end: 2, text: 3 }, 'Parse script element with attributes counts.');

    counter = createCounter(writer);
    parser = new SaxParser(counter, schema);
    writer.reset();
    parser.parse('text1<em><script></s' + 'cript>text2</em>');
    LegacyUnit.equal(writer.getContent(), 'text1<em><script></s' + 'cript>text2</em>', 'Parse empty script element.');
    LegacyUnit.deepEqual(counter.counts, { text: 2, start: 2, end: 2 }, 'Parse empty script element counts.');

    counter = createCounter(writer);
    parser = new SaxParser(Tools.extend({ validate: true }, counter), Schema({ invalid_elements: 'script' }));
    writer.reset();
    parser.parse('text1<em><s' + 'cript>text2</s' + 'cript>text3</em>');
    LegacyUnit.equal(writer.getContent(), 'text1<em>text3</em>', 'Parse invalid script element.');
    LegacyUnit.deepEqual(counter.counts, { text: 2, start: 1, end: 1 }, 'Parse invalid script element (count).');
  });
 suite.test('Pad empty with br', function () {
   const schema = Schema();
   const parser = DomParser({ padd_empty_with_br: true }, schema);
   const serializer = Serializer({ padd_empty_with_br: true }, schema);
   const root = parser.parse('<p>a</p><p></p>');
   LegacyUnit.equal(serializer.serialize(root), '<p>a</p><p><br /></p>');
 });
  suite.test('Invalid inline element with space before', function () {
    let parser, root;
    const schema = Schema();

    parser = DomParser({}, schema);
    root = parser.parse('<p><span>1</span> <strong>2</strong></p>');
    LegacyUnit.equal(serializer.serialize(root), '<p>1 <strong>2</strong></p>');
  });
  suite.test('Invalid text blocks within a li', function () {
    let parser, root;
    const schema = Schema({ schema: 'html5', valid_children: '-li[p]' });

    parser = DomParser({}, schema);
    root = parser.parse('<ul><li>1<p>2</p></li><li>a<p>b</p><p>c</p></li></ul>');
    LegacyUnit.equal(serializer.serialize(root), '<ul><li>12</li><li>ab</li><li>c</li></ul>');
  });