using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using System.Diagnostics; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Xml; namespace Svg.UnitTests { public abstract class SvgTestHelper { /// /// Test file path. /// [Obsolete("Try not to use the file loader, please use the resource loader to ensure working of tests on all systems")] protected virtual string TestFile { get { const string msg = "Test file not overridden."; Assert.Inconclusive(msg); throw new NotImplementedException(msg); } } /// /// Full Unit Test resource string for test file. /// /// /// For the full Unit Test resource string you can use . /// protected virtual string TestResource { get { const string msg = "Test resource not overridden."; Assert.Inconclusive(msg); throw new NotImplementedException(msg); } } /// /// Expected size of svg file after drawing. /// protected virtual int ExpectedSize { get { const string msg = "Expected size not overridden."; Assert.Inconclusive(msg); throw new NotImplementedException(msg); } } /// /// Get full Unit Test resource string. /// /// Resource path. /// Full resource string. /// /// var s = GetFullResourceString("Issue204_PrivateFont.Text.svg"); /// // s content: "Svg.UnitTests.Resources.Issue204_PrivateFont.Text.svg" /// protected virtual string GetFullResourceString(string resourcePath) { const string DefaultResourcesDir = "Resources"; return string.Format("{0}.{1}.{2}", this.GetType().Assembly.GetName().Name, DefaultResourcesDir, resourcePath); } /// /// Get embedded resource as stream from Unit Test resources. /// /// Full Unit Test resource string. /// Embedded resource data steam. /// Do not forget to close, dispose the stream. protected virtual Stream GetResourceStream(string fullResourceString) { Trace.WriteLine("Get resource data."); var s = this.GetType().Assembly.GetManifestResourceStream(fullResourceString); if (s == null) Assert.Fail("Unable to find embedded resource", fullResourceString); Trace.WriteLine("Done getting resource data."); return s; } /// /// Get embedded resource as byte array from Unit Test resources. /// /// Full Unit Test resource string. /// Embedded resource data bytes. protected virtual byte[] GetResourceBytes(string fullResourceString) { using (var s = GetResourceStream(fullResourceString)) { var resource = new byte[s.Length]; s.Read(resource, 0, (int)s.Length); return resource; } } /// /// Get embedded resource as xml document from Unit Test resources. /// /// Full Unit Test resource string. /// Embedded resource data xml document. protected virtual XmlDocument GetResourceXmlDoc(string fullResourceString) { using (var s = GetResourceStream(fullResourceString)) { Trace.WriteLine("Load XmlDocument from resource data."); var xmlDoc = new XmlDocument(); xmlDoc.Load(s); Trace.WriteLine("Done XmlDocument loading from resource data."); return xmlDoc; } } /// /// Get xml document from . /// /// File data as xml document. [Obsolete("Try not to use the file loader, please use the resource loader to ensure working of tests on all systems")] protected virtual XmlDocument GetXMLDocFromFile() { return GetXMLDocFromFile(TestFile); } /// /// Get xml document from file. /// /// File to load. /// File data as xml document. [Obsolete("Try not to use the file loader, please use the resource loader to ensure working of tests on all systems")] protected virtual XmlDocument GetXMLDocFromFile(string file) { if (!File.Exists(file)) Assert.Fail("Test file missing.", file); var xmlDoc = new XmlDocument(); xmlDoc.LoadXml(File.ReadAllText(file)); return xmlDoc; } /// /// Get xml document from . /// /// Resource data as xml document. protected virtual XmlDocument GetXMLDocFromResource() { return GetResourceXmlDoc(TestResource); } /// /// Get xml document from resource. /// /// Full Unit Test resource string. /// Resource data as xml document. protected virtual XmlDocument GetXMLDocFromResource(string fullResourceString) { return GetResourceXmlDoc(fullResourceString); } /// /// Load, draw and check svg file. /// /// Svg file data. protected virtual void LoadSvg(XmlDocument xml) { Trace.WriteLine("SvgDocument open xml."); var svgDoc = OpenSvg(xml); Trace.WriteLine("Done SvgDocument open xml."); Trace.WriteLine("Draw svg."); var img = DrawSvg(svgDoc); Trace.WriteLine("Done drawing."); CheckSvg(svgDoc, img); } /// /// Open SVG document from XML document. /// /// XML document. /// Open SVG document. protected virtual SvgDocument OpenSvg(XmlDocument xml) { return SvgDocument.Open(xml); } /// /// Draw SVG. /// /// SVG document to draw. /// SVG as image. protected virtual Image DrawSvg(SvgDocument svgDoc) { return svgDoc.Draw(); } /// /// Check svg file data. /// /// Svg document. /// Image of svg file from . protected virtual void CheckSvg(SvgDocument svgDoc, Image img) { using (var ms = new MemoryStream()) { img.Save(ms, ImageFormat.Png); ms.Flush(); Assert.IsTrue(ms.Length >= ExpectedSize, "Svg file does not match expected minimum size."); } } /// /// Compare Images. /// /// Image 1. /// Image 2. /// If images are completely equal: true; otherwise: false protected virtual bool ImagesAreEqual(Bitmap img1, Bitmap img2) { float imgEqualPercentage; // To ignore. return ImagesAreEqual(img1, img2, out imgEqualPercentage); } /// /// Compare Images. /// /// Image 1. /// Image 2. /// Image equal value in percentage. 0.0% == completely unequal. 100.0% == completely equal. /// If images are completely equal: true; otherwise: false protected virtual bool ImagesAreEqual(Bitmap img1, Bitmap img2, out float imgEqualPercentage) { Bitmap imgDiff; // To ignore. return ImagesAreEqual(img1, img2, out imgEqualPercentage, out imgDiff); } /// /// Compare Images. /// /// Image 1. /// Image 2. /// Image equal value in percentage. 0.0% == completely unequal. 100.0% == completely equal. /// Image with red pixel where and are unequal. /// If images are completely equal: true; otherwise: false protected virtual bool ImagesAreEqual(Bitmap img1, Bitmap img2, out float imgEqualPercentage, out Bitmap imgDiff) { // Defaults. var diffColor = Color.Red; // Reset. imgEqualPercentage = 0; imgDiff = null; // Requirements. if (img1 == null) return false; if (img2 == null) return false; if (img1.Size.Width < 1 && img1.Height < 1) return false; if (!img1.Size.Equals(img2.Size)) return false; // Compare bitmaps. imgDiff = new Bitmap(img1.Size.Width, img1.Size.Height); int diffPixelCount = 0; for (int i = 0; i < img1.Width; ++i) { for (int j = 0; j < img1.Height; ++j) { Color color; if ((color = img1.GetPixel(i, j)) == img2.GetPixel(i, j)) { imgDiff.SetPixel(i, j, color); } else { ++diffPixelCount; imgDiff.SetPixel(i, j, diffColor); } } } // Calculate percentage. int totalPixelCount = img1.Width * img1.Height; var imgDiffFactor = ((float)diffPixelCount / totalPixelCount); imgEqualPercentage = imgDiffFactor * 100; return (imgDiffFactor == 1f); } } }