blob: 24d74701a4768eb0bb12c803bb05f28edc9b5645 [file] [log] [blame]
// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:html';
import 'dart:svg' as svg;
import 'package:expect/minitest.dart';
main() {
var isSvgSvgElement =
predicate((x) => x is svg.SvgSvgElement, 'is a SvgSvgElement');
List<String> _nodeStrings(Iterable<Node> input) {
final List<String> out = [];
for (Node n in input) {
if (n is Element) {
Element e = n;
out.add(e.tagName);
} else {
out.add(n.text!);
}
}
return out;
}
testConstructor(String tagName, Function isExpectedClass,
[bool expectation = true, allowsInnerHtml = true]) {
test(tagName, () {
expect(isExpectedClass(new svg.SvgElement.tag(tagName)), expectation);
if (allowsInnerHtml) {
expect(isExpectedClass(new svg.SvgElement.svg('<$tagName></$tagName>')),
expectation && allowsInnerHtml);
}
});
}
group('additionalConstructors', () {
test('valid', () {
final svgContent = "<svg version=\"1.1\">\n"
" <circle></circle>\n"
" <path></path>\n"
"</svg>";
final el = new svg.SvgElement.svg(svgContent);
expect(el, isSvgSvgElement);
expect(
el.innerHtml,
anyOf([
"<circle></circle><path></path>",
'<circle '
'xmlns="http://www.w3.org/2000/svg" /><path '
'xmlns="http://www.w3.org/2000/svg" />'
]));
expect(
el.outerHtml,
anyOf([
svgContent,
'<svg xmlns="http://www.w3.org/2000/svg" version="1.1">\n '
'<circle />\n <path />\n</svg>'
]));
});
test('has no parent',
() => expect(new svg.SvgElement.svg('<circle/>').parent, isNull));
test('empty', () {
expect(() => new svg.SvgElement.svg(""), throwsStateError);
});
test('too many elements', () {
expect(() => new svg.SvgElement.svg("<circle></circle><path></path>"),
throwsStateError);
});
});
// Unfortunately, because the filtering mechanism in unittest is a regex done
group('supported_animate', () {
test('supported', () {
expect(svg.AnimateElement.supported, true);
});
});
group('supported_animateMotion', () {
test('supported', () {
expect(svg.AnimateMotionElement.supported, true);
});
});
group('supported_animateTransform', () {
test('supported', () {
expect(svg.AnimateTransformElement.supported, true);
});
});
group('supported_feBlend', () {
test('supported', () {
expect(svg.FEBlendElement.supported, true);
});
});
group('supported_feColorMatrix', () {
test('supported', () {
expect(svg.FEColorMatrixElement.supported, true);
});
});
group('supported_feComponentTransfer', () {
test('supported', () {
expect(svg.FEComponentTransferElement.supported, true);
});
});
group('supported_feConvolveMatrix', () {
test('supported', () {
expect(svg.FEConvolveMatrixElement.supported, true);
});
});
group('supported_feDiffuseLighting', () {
test('supported', () {
expect(svg.FEDiffuseLightingElement.supported, true);
});
});
group('supported_feDisplacementMap', () {
test('supported', () {
expect(svg.FEDisplacementMapElement.supported, true);
});
});
group('supported_feDistantLight', () {
test('supported', () {
expect(svg.FEDistantLightElement.supported, true);
});
});
group('supported_feFlood', () {
test('supported', () {
expect(svg.FEFloodElement.supported, true);
});
});
group('supported_feFuncA', () {
test('supported', () {
expect(svg.FEFuncAElement.supported, true);
});
});
group('supported_feFuncB', () {
test('supported', () {
expect(svg.FEFuncBElement.supported, true);
});
});
group('supported_feFuncG', () {
test('supported', () {
expect(svg.FEFuncGElement.supported, true);
});
});
group('supported_feFuncR', () {
test('supported', () {
expect(svg.FEFuncRElement.supported, true);
});
});
group('supported_feGaussianBlur', () {
test('supported', () {
expect(svg.FEGaussianBlurElement.supported, true);
});
});
group('supported_feImage', () {
test('supported', () {
expect(svg.FEImageElement.supported, true);
});
});
group('supported_feMerge', () {
test('supported', () {
expect(svg.FEMergeElement.supported, true);
});
});
group('supported_feMergeNode', () {
test('supported', () {
expect(svg.FEMergeNodeElement.supported, true);
});
});
group('supported_feOffset', () {
test('supported', () {
expect(svg.FEOffsetElement.supported, true);
});
});
group('supported_feComponentTransfer', () {
test('supported', () {
expect(svg.FEPointLightElement.supported, true);
});
});
group('supported_feSpecularLighting', () {
test('supported', () {
expect(svg.FESpecularLightingElement.supported, true);
});
});
group('supported_feComponentTransfer', () {
test('supported', () {
expect(svg.FESpotLightElement.supported, true);
});
});
group('supported_feTile', () {
test('supported', () {
expect(svg.FETileElement.supported, true);
});
});
group('supported_feTurbulence', () {
test('supported', () {
expect(svg.FETurbulenceElement.supported, true);
});
});
group('supported_filter', () {
test('supported', () {
expect(svg.FilterElement.supported, true);
});
});
group('supported_foreignObject', () {
test('supported', () {
expect(svg.ForeignObjectElement.supported, true);
});
});
group('supported_set', () {
test('supported', () {
expect(svg.SetElement.supported, true);
});
});
group('constructors', () {
testConstructor('a', (e) => e is svg.AElement);
testConstructor('circle', (e) => e is svg.CircleElement);
testConstructor('clipPath', (e) => e is svg.ClipPathElement);
testConstructor('defs', (e) => e is svg.DefsElement);
testConstructor('desc', (e) => e is svg.DescElement);
testConstructor('ellipse', (e) => e is svg.EllipseElement);
testConstructor('g', (e) => e is svg.GElement);
testConstructor('image', (e) => e is svg.ImageElement);
testConstructor('line', (e) => e is svg.LineElement);
testConstructor('linearGradient', (e) => e is svg.LinearGradientElement);
testConstructor('marker', (e) => e is svg.MarkerElement);
testConstructor('mask', (e) => e is svg.MaskElement);
testConstructor('path', (e) => e is svg.PathElement);
testConstructor('pattern', (e) => e is svg.PatternElement);
testConstructor('polygon', (e) => e is svg.PolygonElement);
testConstructor('polyline', (e) => e is svg.PolylineElement);
testConstructor('radialGradient', (e) => e is svg.RadialGradientElement);
testConstructor('rect', (e) => e is svg.RectElement);
test('script', () {
expect(new svg.SvgElement.tag('script') is svg.ScriptElement, isTrue);
});
testConstructor('stop', (e) => e is svg.StopElement);
testConstructor('style', (e) => e is svg.StyleElement);
testConstructor('switch', (e) => e is svg.SwitchElement);
testConstructor('symbol', (e) => e is svg.SymbolElement);
testConstructor('tspan', (e) => e is svg.TSpanElement);
testConstructor('text', (e) => e is svg.TextElement);
testConstructor('textPath', (e) => e is svg.TextPathElement);
testConstructor('title', (e) => e is svg.TitleElement);
testConstructor('use', (e) => e is svg.UseElement);
testConstructor('view', (e) => e is svg.ViewElement);
// TODO(alanknight): Issue 23144
testConstructor('animate', (e) => e is svg.AnimateElement,
svg.AnimateElement.supported);
testConstructor('animateMotion', (e) => e is svg.AnimateMotionElement,
svg.AnimateMotionElement.supported);
testConstructor('animateTransform', (e) => e is svg.AnimateTransformElement,
svg.AnimateTransformElement.supported);
testConstructor('feBlend', (e) => e is svg.FEBlendElement,
svg.FEBlendElement.supported);
testConstructor('feColorMatrix', (e) => e is svg.FEColorMatrixElement,
svg.FEColorMatrixElement.supported);
testConstructor(
'feComponentTransfer',
(e) => e is svg.FEComponentTransferElement,
svg.FEComponentTransferElement.supported);
testConstructor('feConvolveMatrix', (e) => e is svg.FEConvolveMatrixElement,
svg.FEConvolveMatrixElement.supported);
testConstructor(
'feDiffuseLighting',
(e) => e is svg.FEDiffuseLightingElement,
svg.FEDiffuseLightingElement.supported);
testConstructor(
'feDisplacementMap',
(e) => e is svg.FEDisplacementMapElement,
svg.FEDisplacementMapElement.supported);
testConstructor('feDistantLight', (e) => e is svg.FEDistantLightElement,
svg.FEDistantLightElement.supported);
testConstructor('feFlood', (e) => e is svg.FEFloodElement,
svg.FEFloodElement.supported);
testConstructor('feFuncA', (e) => e is svg.FEFuncAElement,
svg.FEFuncAElement.supported);
testConstructor('feFuncB', (e) => e is svg.FEFuncBElement,
svg.FEFuncBElement.supported);
testConstructor('feFuncG', (e) => e is svg.FEFuncGElement,
svg.FEFuncGElement.supported);
testConstructor('feFuncR', (e) => e is svg.FEFuncRElement,
svg.FEFuncRElement.supported);
testConstructor('feGaussianBlur', (e) => e is svg.FEGaussianBlurElement,
svg.FEGaussianBlurElement.supported);
testConstructor('feImage', (e) => e is svg.FEImageElement,
svg.FEImageElement.supported);
testConstructor('feMerge', (e) => e is svg.FEMergeElement,
svg.FEMergeElement.supported);
testConstructor('feMergeNode', (e) => e is svg.FEMergeNodeElement,
svg.FEMergeNodeElement.supported);
testConstructor('feOffset', (e) => e is svg.FEOffsetElement,
svg.FEOffsetElement.supported);
testConstructor('fePointLight', (e) => e is svg.FEPointLightElement,
svg.FEPointLightElement.supported);
testConstructor(
'feSpecularLighting',
(e) => e is svg.FESpecularLightingElement,
svg.FESpecularLightingElement.supported);
testConstructor('feSpotLight', (e) => e is svg.FESpotLightElement,
svg.FESpotLightElement.supported);
testConstructor(
'feTile', (e) => e is svg.FETileElement, svg.FETileElement.supported);
testConstructor('feTurbulence', (e) => e is svg.FETurbulenceElement,
svg.FETurbulenceElement.supported);
testConstructor(
'filter', (e) => e is svg.FilterElement, svg.FilterElement.supported);
testConstructor('foreignObject', (e) => e is svg.ForeignObjectElement,
svg.ForeignObjectElement.supported, false);
testConstructor('metadata', (e) => e is svg.MetadataElement);
testConstructor(
'set', (e) => e is svg.SetElement, svg.SetElement.supported);
});
group('outerHtml', () {
test('outerHtml', () {
final el = new svg.SvgSvgElement();
el.children.add(new svg.CircleElement());
el.children.add(new svg.PathElement());
expect(
[
'<svg version="1.1"><circle></circle><path></path></svg>',
'<svg xmlns="http://www.w3.org/2000/svg" version="1.1">'
'<circle /><path /></svg>',
].contains(el.outerHtml),
true);
});
});
group('innerHtml', () {
test('get', () {
final el = new svg.SvgSvgElement();
el.children.add(new svg.CircleElement());
el.children.add(new svg.PathElement());
// Allow for odd IE serialization.
expect(
[
'<circle></circle><path></path>',
'<circle xmlns="http://www.w3.org/2000/svg" />'
'<path xmlns="http://www.w3.org/2000/svg" />'
].contains(el.innerHtml),
true);
});
test('set', () {
final el = new svg.SvgSvgElement();
el.children.add(new svg.CircleElement());
el.children.add(new svg.PathElement());
el.innerHtml = '<rect></rect><a></a>';
expect(_nodeStrings(el.children), ["rect", "a"]);
});
});
group('elementget', () {
test('get', () {
final el = new svg.SvgElement.svg("""
<svg version="1.1">
<circle></circle>
<path></path>
text
</svg>""");
expect(_nodeStrings(el.children), ["circle", "path"]);
});
test('resize', () {
var el = new svg.SvgSvgElement();
var items = [new svg.CircleElement(), new svg.RectElement()];
el.children = items;
expect(el.children.length, 2);
el.children.length = 1;
expect(el.children.length, 1);
expect(el.children.contains(items[0]), true);
expect(el.children.contains(items[1]), false);
el.children.length = 0;
expect(el.children.contains(items[0]), false);
});
});
group('elementset', () {
test('set', () {
final el = new svg.SvgSvgElement();
el.children = [
new svg.SvgElement.tag("circle"),
new svg.SvgElement.tag("path")
];
expect(el.nodes.length, 2);
expect(el.nodes[0] is svg.CircleElement, true);
expect(el.nodes[1] is svg.PathElement, true);
});
});
group('css', () {
test('classes', () {
var el = new svg.CircleElement();
var classes = el.classes;
expect(el.classes.length, 0);
classes.toggle('foo');
expect(el.classes.length, 1);
classes.toggle('foo');
expect(el.classes.length, 0);
});
test('classes-add-bad', () {
var el = new svg.CircleElement();
expect(() => el.classes.add(''), throws);
expect(() => el.classes.add('foo bar'), throws);
});
test('classes-remove-bad', () {
var el = new svg.CircleElement();
expect(() => el.classes.remove(''), throws);
expect(() => el.classes.remove('foo bar'), throws);
});
test('classes-toggle-token', () {
var el = new svg.CircleElement();
expect(() => el.classes.toggle(''), throws);
expect(() => el.classes.toggle('', true), throws);
expect(() => el.classes.toggle('', false), throws);
expect(() => el.classes.toggle('foo bar'), throws);
expect(() => el.classes.toggle('foo bar', true), throws);
expect(() => el.classes.toggle('foo bar', false), throws);
});
test('classes-contains-bad', () {
var el = new svg.CircleElement();
// Non-strings => false, strings must be valid tokens.
expect(el.classes.contains(1), isFalse);
expect(() => el.classes.contains(''), throws);
expect(() => el.classes.contains('foo bar'), throws);
});
});
group('getBoundingClientRect', () {
test('is a Rectangle', () {
var element = new svg.RectElement();
element.attributes['width'] = '100';
element.attributes['height'] = '100';
var root = new svg.SvgSvgElement();
root.append(element);
document.body!.append(root);
var rect = element.getBoundingClientRect();
expect(rect is Rectangle, isTrue);
expect(rect.width, closeTo(100, 1));
expect(rect.height, closeTo(100, 1));
});
});
}