SvgTests.cs 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. using System.Reflection;
  2. using System.Xml;
  3. using Drawie.Backend.Core.ColorsImpl;
  4. using PixiEditor.SVG;
  5. using PixiEditor.SVG.Elements;
  6. using PixiEditor.SVG.Utils;
  7. namespace PixiEditor.Tests;
  8. public class SvgTests
  9. {
  10. [Fact]
  11. public void TestThatEmptySvgIsParsedCorrectly()
  12. {
  13. string svg = "<svg></svg>";
  14. SvgDocument document = SvgDocument.Parse(svg);
  15. Assert.Empty(document.Children);
  16. }
  17. [Theory]
  18. [InlineData("<svg viewBox=\"0 0 100 100\"></svg>", 0, 0, 100, 100)]
  19. [InlineData("<svg width=\"100\" height=\"100\"></svg>", 0, 0, 100, 100)]
  20. [InlineData("<svg x=\"0\" y=\"0\" width=\"100\" height=\"100\"></svg>", 0, 0, 100, 100)]
  21. [InlineData("<svg viewBox=\"0 0 100 100\" width=\"50\" height=\"50\"></svg>", 0, 0, 50, 50)]
  22. [InlineData("<svg viewBox=\"-50 -50 128 128\" width=\"100\" x=\"1\"></svg>", 1, -50, 100, 128)]
  23. public void TestThatSvgBoundsAreParsedCorrectly(string svg, double x, double y, double width, double height)
  24. {
  25. SvgDocument document = SvgDocument.Parse(svg);
  26. Assert.Equal(x, document.ViewBox.Unit.Value.Value.X);
  27. Assert.Equal(y, document.ViewBox.Unit.Value.Value.Y);
  28. Assert.Equal(width, document.ViewBox.Unit.Value.Value.Width);
  29. Assert.Equal(height, document.ViewBox.Unit.Value.Value.Height);
  30. }
  31. [Theory]
  32. [InlineData("<svg><rect/></svg>", 1)]
  33. [InlineData("<svg><rect/><circle/></svg>", 2)]
  34. [InlineData("<svg><rect/><circle/><ellipse/></svg>", 3)]
  35. public void TestThatSvgElementsCountIsParsedCorrectly(string svg, int elements)
  36. {
  37. SvgDocument document = SvgDocument.Parse(svg);
  38. Assert.Equal(elements, document.Children.Count);
  39. }
  40. [Theory]
  41. [InlineData("<svg><rect/></svg>", "rect")]
  42. [InlineData("<svg><circle/></svg>", "circle")]
  43. [InlineData("<svg><ellipse/></svg>", "ellipse")]
  44. [InlineData("<svg><someArbitraryElement/></svg>", null)]
  45. public void TestThatSvgElementsAreParsedCorrectly(string svg, string? element)
  46. {
  47. SvgDocument document = SvgDocument.Parse(svg);
  48. if (element == null)
  49. {
  50. Assert.Empty(document.Children);
  51. return;
  52. }
  53. Assert.Equal(element, document.Children[0].TagName);
  54. }
  55. [Theory]
  56. [InlineData("<svg><rect/></svg>", typeof(SvgRectangle))]
  57. [InlineData("<svg><circle/></svg>", typeof(SvgCircle))]
  58. [InlineData("<svg><ellipse/></svg>", typeof(SvgEllipse))]
  59. [InlineData("<svg><g/></svg>", typeof(SvgGroup))]
  60. [InlineData("<svg><line/></svg>", typeof(SvgLine))]
  61. [InlineData("<svg><path/></svg>", typeof(SvgPath))]
  62. [InlineData("<svg><mask/></svg>", typeof(SvgMask))]
  63. [InlineData("<svg><image/></svg>", typeof(SvgImage))]
  64. [InlineData("<svg><someArbitraryElement/></svg>", null)]
  65. public void TestThatSvgElementsAreParsedToCorrectType(string svg, Type? elementType)
  66. {
  67. SvgDocument document = SvgDocument.Parse(svg);
  68. if (elementType == null)
  69. {
  70. Assert.Empty(document.Children);
  71. return;
  72. }
  73. Assert.IsType(elementType, document.Children[0]);
  74. }
  75. [Fact]
  76. public void TestThatRectIsParsedCorrectly()
  77. {
  78. string svg = "<svg><rect x=\"10\" y=\"20\" width=\"30\" height=\"40\"/></svg>";
  79. SvgDocument document = SvgDocument.Parse(svg);
  80. SvgRectangle rect = (SvgRectangle)document.Children[0];
  81. Assert.NotNull(rect);
  82. Assert.NotNull(rect.X.Unit);
  83. Assert.NotNull(rect.Y.Unit);
  84. Assert.NotNull(rect.Width.Unit);
  85. Assert.NotNull(rect.Height.Unit);
  86. Assert.Equal(10, rect.X.Unit.Value.Value);
  87. Assert.Equal(20, rect.Y.Unit.Value.Value);
  88. Assert.Equal(30, rect.Width.Unit.Value.Value);
  89. Assert.Equal(40, rect.Height.Unit.Value.Value);
  90. }
  91. [Fact]
  92. public void TestThatCircleIsParsedCorrectly()
  93. {
  94. string svg = "<svg><circle cx=\"10\" cy=\"20\" r=\"30\"/></svg>";
  95. SvgDocument document = SvgDocument.Parse(svg);
  96. SvgCircle circle = (SvgCircle)document.Children[0];
  97. Assert.NotNull(circle);
  98. Assert.NotNull(circle.Cx.Unit);
  99. Assert.NotNull(circle.Cy.Unit);
  100. Assert.NotNull(circle.R.Unit);
  101. Assert.Equal(10, circle.Cx.Unit.Value.Value);
  102. Assert.Equal(20, circle.Cy.Unit.Value.Value);
  103. Assert.Equal(30, circle.R.Unit.Value.Value);
  104. }
  105. [Fact]
  106. public void TestThatEllipseIsParsedCorrectly()
  107. {
  108. string svg = "<svg><ellipse cx=\"10\" cy=\"20\" rx=\"30\" ry=\"40\"/></svg>";
  109. SvgDocument document = SvgDocument.Parse(svg);
  110. SvgEllipse ellipse = (SvgEllipse)document.Children[0];
  111. Assert.NotNull(ellipse);
  112. Assert.NotNull(ellipse.Cx.Unit);
  113. Assert.NotNull(ellipse.Cy.Unit);
  114. Assert.NotNull(ellipse.Rx.Unit);
  115. Assert.NotNull(ellipse.Ry.Unit);
  116. Assert.Equal(10, ellipse.Cx.Unit.Value.Value);
  117. Assert.Equal(20, ellipse.Cy.Unit.Value.Value);
  118. Assert.Equal(30, ellipse.Rx.Unit.Value.Value);
  119. Assert.Equal(40, ellipse.Ry.Unit.Value.Value);
  120. }
  121. [Fact]
  122. public void TestThatGroupIsParsedCorrectly()
  123. {
  124. string svg = "<svg><g><rect/></g></svg>";
  125. SvgDocument document = SvgDocument.Parse(svg);
  126. SvgGroup group = (SvgGroup)document.Children[0];
  127. Assert.NotNull(group);
  128. Assert.Single(group.Children);
  129. Assert.IsType<SvgRectangle>(group.Children[0]);
  130. }
  131. [Fact]
  132. public void TestThatLineIsParsedCorrectly()
  133. {
  134. string svg = "<svg><line x1=\"10\" y1=\"20\" x2=\"30\" y2=\"40\"/></svg>";
  135. SvgDocument document = SvgDocument.Parse(svg);
  136. SvgLine line = (SvgLine)document.Children[0];
  137. Assert.NotNull(line);
  138. Assert.NotNull(line.X1.Unit);
  139. Assert.NotNull(line.Y1.Unit);
  140. Assert.NotNull(line.X2.Unit);
  141. Assert.NotNull(line.Y2.Unit);
  142. Assert.Equal(10, line.X1.Unit.Value.Value);
  143. Assert.Equal(20, line.Y1.Unit.Value.Value);
  144. Assert.Equal(30, line.X2.Unit.Value.Value);
  145. Assert.Equal(40, line.Y2.Unit.Value.Value);
  146. }
  147. [Fact]
  148. public void TestThatPathIsParsedCorrectly()
  149. {
  150. string svg = "<svg><path d=\"M10 20 L30 40\"/></svg>";
  151. SvgDocument document = SvgDocument.Parse(svg);
  152. SvgPath path = (SvgPath)document.Children[0];
  153. Assert.NotNull(path);
  154. Assert.NotNull(path.PathData.Unit);
  155. Assert.Equal("M10 20 L30 40", path.PathData.Unit.Value.Value);
  156. }
  157. [Fact]
  158. public void TestThatMaskIsParsedCorrectly()
  159. {
  160. string svg = "<svg><mask><rect/></mask></svg>";
  161. SvgDocument document = SvgDocument.Parse(svg);
  162. SvgMask mask = (SvgMask)document.Children[0];
  163. Assert.NotNull(mask);
  164. Assert.Single(mask.Children);
  165. Assert.IsType<SvgRectangle>(mask.Children[0]);
  166. }
  167. [Fact]
  168. public void TestThatImageIsParsedCorrectly()
  169. {
  170. string svg = "<svg><image x=\"10\" y=\"20\" width=\"30\" height=\"40\"/></svg>";
  171. SvgDocument document = SvgDocument.Parse(svg);
  172. SvgImage image = (SvgImage)document.Children[0];
  173. Assert.NotNull(image);
  174. Assert.NotNull(image.X.Unit);
  175. Assert.NotNull(image.Y.Unit);
  176. Assert.NotNull(image.Width.Unit);
  177. Assert.NotNull(image.Height.Unit);
  178. Assert.Equal(10, image.X.Unit.Value.Value);
  179. Assert.Equal(20, image.Y.Unit.Value.Value);
  180. Assert.Equal(30, image.Width.Unit.Value.Value);
  181. Assert.Equal(40, image.Height.Unit.Value.Value);
  182. }
  183. [Fact]
  184. public void TestThatAllAssemblySvgElementsParseData()
  185. {
  186. Assembly assembly = Assembly.GetAssembly(typeof(SvgElement))!;
  187. Type[] types = assembly.GetTypes().Where(t => t.IsSubclassOf(typeof(SvgElement)) && !t.IsAbstract).ToArray();
  188. foreach (Type type in types)
  189. {
  190. SvgElement element = (SvgElement)Activator.CreateInstance(type)!;
  191. using MemoryStream stream = new();
  192. using StreamWriter writer = new(stream);
  193. writer.Write($"<svg><{element.TagName}/></svg>");
  194. using XmlReader reader = XmlReader.Create(stream);
  195. element.ParseData(reader, new SvgDefs());
  196. }
  197. }
  198. [Theory]
  199. [InlineData("red")]
  200. [InlineData("#ff0000")]
  201. [InlineData("rgb(255, 0, 0)")]
  202. [InlineData("hsl(0, 100%, 50%)")]
  203. [InlineData("hsla(0, 100%, 50%, 255)")]
  204. [InlineData("rgba(255, 0, 0, 255)")]
  205. public void TestThatDifferentColorFormatsGetsParsedToTheSameRedValue(string colorInput)
  206. {
  207. if(SvgColorUtility.TryConvertStringToColor(colorInput, out Color color))
  208. {
  209. Assert.Equal(255, color.R);
  210. Assert.Equal(0, color.G);
  211. Assert.Equal(0, color.B);
  212. Assert.Equal(255, color.A);
  213. }
  214. else
  215. {
  216. Assert.Fail();
  217. }
  218. }
  219. }