import 'package:petitparser/core.dart';
import 'package:petitparser/matcher.dart';
import 'package:test/test.dart';
import 'package:xml/src/xml/utils/character_data_parser.dart';
import 'package:xml/xml.dart';
void testDefaultMapping(XmlEntityMapping entityMapping) {
group('decode', () {
test('HHHH;', () {
expect(entityMapping.decode('A'), 'A');
expect(entityMapping.decode('a'), 'a');
expect(entityMapping.decode('z'), 'z');
});
test('dddd;', () {
expect(entityMapping.decode('A'), 'A');
expect(entityMapping.decode('a'), 'a');
expect(entityMapping.decode('z'), 'z');
});
test('&named;', () {
expect(entityMapping.decode('<'), '<');
expect(entityMapping.decode('>'), '>');
expect(entityMapping.decode('&'), '&');
expect(entityMapping.decode('''), '\'');
expect(entityMapping.decode('"'), '"');
});
test('invalid', () {
expect(entityMapping.decode('&Invalid;'), '&Invalid;');
expect(entityMapping.decode('Invalid;'), 'Invalid;');
expect(entityMapping.decode('Invalid;'), 'Invalid;');
expect(entityMapping.decode('Invalid;'), 'Invalid;');
});
test('unicode', () {
// https://www.compart.com/en/unicode/U+0000
expect(entityMapping.decode(''), '\u0000');
expect(entityMapping.decode(''), '\u0000');
// https://www.compart.com/en/unicode/U+10FFFF
expect(entityMapping.decode(''), '\uDBFF\uDFFF');
expect(entityMapping.decode(''), '\uDBFF\uDFFF');
});
test('unicode invalid', () {
expect(entityMapping.decode('-1;'), '-1;');
expect(entityMapping.decode('-1;'), '-1;');
expect(entityMapping.decode(''), '');
expect(entityMapping.decode(''), '');
});
test('incomplete', () {
expect(entityMapping.decode('&'), '&');
expect(entityMapping.decode('&'), '&');
expect(entityMapping.decode('a&b'), 'a&b');
expect(entityMapping.decode('&>'), '&>');
});
test('empty', () {
expect(entityMapping.decode('&;'), '&;');
});
test('none', () {
expect(entityMapping.decode(''), '');
expect(entityMapping.decode('Hello'), 'Hello');
expect(entityMapping.decode('Hello World'), 'Hello World');
});
test('surrounded', () {
expect(entityMapping.decode('a&b'), 'a&b');
expect(entityMapping.decode('&a&'), '&a&');
expect(entityMapping.decode('a&b&c'), 'a&b&c');
expect(entityMapping.decode('&a&b&'), '&a&b&');
expect(entityMapping.decode('a&b&c&d'), 'a&b&c&d');
});
test('sequence', () {
expect(entityMapping.decode('&&'), '&&');
expect(entityMapping.decode('<&>'), '<&>');
});
test('document', () {
final document = XmlDocument.parse(
'a&b',
entityMapping: entityMapping,
);
expect(document.rootElement.innerText, 'a&b');
});
test('fragment', () {
final fragment = XmlDocumentFragment.parse(
'a&b',
entityMapping: entityMapping,
);
expect(fragment.innerText, 'a&b');
});
});
group('encode', () {
test('text', () {
expect(entityMapping.encodeText('<'), '<');
expect(entityMapping.encodeText('&'), '&');
expect(
entityMapping.encodeText('\u0000\u0008\u0009\u0084\u0085\u0086'),
'\u0000\u0009\u0085',
);
expect(entityMapping.encodeText('hello'), 'hello');
expect(entityMapping.encodeText(''), '<foo &>');
});
test('attribute (single quote)', () {
expect(
entityMapping.encodeAttributeValue("'", XmlAttributeType.SINGLE_QUOTE),
''',
);
expect(
entityMapping.encodeAttributeValue('"', XmlAttributeType.SINGLE_QUOTE),
'"',
);
expect(
entityMapping.encodeAttributeValue('\t', XmlAttributeType.SINGLE_QUOTE),
' ',
);
expect(
entityMapping.encodeAttributeValue('\n', XmlAttributeType.SINGLE_QUOTE),
'
',
);
expect(
entityMapping.encodeAttributeValue('\r', XmlAttributeType.SINGLE_QUOTE),
'
',
);
expect(
entityMapping.encodeAttributeValue(
'\u0000\u0008\u0009\u0084\u0085\u0086',
XmlAttributeType.SINGLE_QUOTE,
),
'\u0000 \u0085',
);
expect(
entityMapping.encodeAttributeValue(
'hello',
XmlAttributeType.SINGLE_QUOTE,
),
'hello',
);
expect(
entityMapping.encodeAttributeValue(
"'hello'",
XmlAttributeType.SINGLE_QUOTE,
),
''hello'',
);
expect(
entityMapping.encodeAttributeValue(
'"hello"',
XmlAttributeType.SINGLE_QUOTE,
),
'"hello"',
);
});
test('encode attribute (double quote)', () {
expect(
entityMapping.encodeAttributeValue("'", XmlAttributeType.DOUBLE_QUOTE),
"'",
);
expect(
entityMapping.encodeAttributeValue('"', XmlAttributeType.DOUBLE_QUOTE),
'"',
);
expect(
entityMapping.encodeAttributeValue('\t', XmlAttributeType.DOUBLE_QUOTE),
' ',
);
expect(
entityMapping.encodeAttributeValue('\n', XmlAttributeType.DOUBLE_QUOTE),
'
',
);
expect(
entityMapping.encodeAttributeValue('\r', XmlAttributeType.DOUBLE_QUOTE),
'
',
);
expect(
entityMapping.encodeAttributeValue(
'\u0000\u0008\u0009\u0084\u0085\u0086',
XmlAttributeType.DOUBLE_QUOTE,
),
'\u0000 \u0085',
);
expect(
entityMapping.encodeAttributeValue(
'hello',
XmlAttributeType.DOUBLE_QUOTE,
),
'hello',
);
expect(
entityMapping.encodeAttributeValue(
"'hello'",
XmlAttributeType.DOUBLE_QUOTE,
),
"'hello'",
);
expect(
entityMapping.encodeAttributeValue(
'"hello"',
XmlAttributeType.DOUBLE_QUOTE,
),
'"hello"',
);
});
});
}
void main() {
group('xml', () {
testDefaultMapping(defaultEntityMapping);
});
group('html', () {
const entityMapping = XmlDefaultEntityMapping.html();
testDefaultMapping(entityMapping);
test('special', () {
expect(entityMapping.decode('é'), 'é');
expect(entityMapping.decode('É'), 'É');
});
});
group('html5', () {
const entityMapping = XmlDefaultEntityMapping.html5();
testDefaultMapping(entityMapping);
test('special', () {
expect(entityMapping.decode('★'), '★');
expect(entityMapping.decode('█'), '█');
});
});
group('custom', () {
const entityMapping = XmlDefaultEntityMapping({'joy': '😂', 'tears': '😢'});
test('basic', () {
expect(entityMapping.decodeEntity('joy'), '😂');
expect(entityMapping.decodeEntity('tears'), '😢');
});
test('entities', () {
expect(entityMapping.decode('&joy;'), '😂');
expect(entityMapping.decode('&tears;'), '😢');
});
test('document', () {
final document = XmlDocument.parse(
'&joy; and &tears;',
entityMapping: entityMapping,
);
expect(document.rootElement.innerText, '😂 and 😢');
});
test('fragment', () {
final fragment = XmlDocumentFragment.parse(
'&joy; and &tears;',
entityMapping: entityMapping,
);
expect(fragment.innerText, '😂 and 😢');
});
});
group('null', () {
const entityMapping = XmlNullEntityMapping();
group('decode', () {
test('basic', () {
expect(entityMapping.decodeEntity(''), isNull);
expect(entityMapping.decodeEntity('amp'), isNull);
expect(entityMapping.decodeEntity('#X41'), isNull);
expect(entityMapping.decodeEntity('#65'), isNull);
});
test('entities', () {
expect(entityMapping.decode('A'), 'A');
expect(entityMapping.decode('A'), 'A');
expect(entityMapping.decode('&'), '&');
});
test('invalid entities', () {
expect(entityMapping.decode('&;'), '&;');
expect(entityMapping.decode('&invalid;'), '&invalid;');
expect(entityMapping.decode('&incomplete'), '&incomplete');
});
test('combinations', () {
expect(entityMapping.decode('a&b'), 'a&b');
expect(entityMapping.decode('&x&'), '&x&');
expect(entityMapping.decode('&&'), '&&');
});
});
group('encode', () {
test('text', () {
expect(entityMapping.encodeText('<'), '<');
expect(entityMapping.encodeText('&'), '&');
expect(entityMapping.encodeText('hello'), 'hello');
expect(entityMapping.encodeText(''), '');
});
test('attribute', () {
expect(
entityMapping.encodeAttributeValue(
'<>&\'"',
XmlAttributeType.SINGLE_QUOTE,
),
'<>&\'"',
);
expect(
entityMapping.encodeAttributeValue(
'<>&\'"',
XmlAttributeType.DOUBLE_QUOTE,
),
'<>&\'"',
);
});
});
});
group('character parser', () {
final parser = XmlCharacterDataParser('*', 1);
test('parse without stopper', () {
final result1 = parser.parse('');
expect(result1 is Failure, isTrue);
expect(result1.position, 0);
final result2 = parser.parse('a');
expect(result2 is Success, isTrue);
expect(result2.position, 1);
expect(result2.value, 'a');
final result3 = parser.parse('ab');
expect(result3 is Success, isTrue);
expect(result3.position, 2);
expect(result3.value, 'ab');
});
test('parse with stopper', () {
final result1 = parser.parse('*');
expect(result1 is Failure, isTrue);
expect(result1.position, 0);
final result2 = parser.parse('a*');
expect(result2 is Success, isTrue);
expect(result2.position, 1);
expect(result2.value, 'a');
final result3 = parser.parse('ab*');
expect(result3 is Success, isTrue);
expect(result3.position, 2);
expect(result3.value, 'ab');
});
test('fast parse without stopper', () {
expect(parser.accept(''), isFalse);
expect(parser.accept('a'), isTrue);
expect(parser.accept('ab'), isTrue);
});
test('fast parse with stopper', () {
expect(parser.accept('*'), isFalse);
expect(parser.accept('a*'), isTrue);
expect(parser.accept('ab*'), isTrue);
});
test('copy and equality', () {
expect(parser.isEqualTo(parser), isTrue);
expect(parser.isEqualTo(parser.copy()), isTrue);
expect(parser.isEqualTo(XmlCharacterDataParser('%', 1)), isFalse);
expect(parser.isEqualTo(XmlCharacterDataParser('*', 2)), isFalse);
});
});
}