From 8cb24aefdb909daf8ccc5cab2af7f3dfe554b941 Mon Sep 17 00:00:00 2001 From: Paul Selormey Date: Thu, 25 Jan 2024 08:46:52 +0900 Subject: [PATCH] Added shared library for test application: Svg.Tests.Common - Refactored the shared test codes - Removed Svg.Benchmark dependency on Svg.UnitTests --- Source/Properties/AssemblyInfo.cs | 24 ++-- Source/Svg.sln | 11 +- Tests/Svg.Benchmark/Svg.Benchmark.csproj | 7 +- .../Css/CssQuery.cs | 19 +++ .../Css/SvgElementOps.cs | 0 Tests/Svg.Tests.Common/ExtensionMethods.cs | 123 ++++++++++++++++++ .../Properties/AssemblyInfo.cs | 49 +++++++ .../Svg.Tests.Common/Svg.Tests.Common.csproj | 35 +++++ .../TestsUtils.cs | 6 +- Tests/Svg.Tests.Common/svgkey.snk | Bin 0 -> 596 bytes Tests/Svg.UnitTests/ExCssSelectorTests.cs | 22 +--- Tests/Svg.UnitTests/ImageComparisonTest.cs | 117 +---------------- Tests/Svg.UnitTests/PerformanceTest.cs | 2 + .../Svg.UnitTests/Properties/AssemblyInfo.cs | 8 +- Tests/Svg.UnitTests/Svg.UnitTests.csproj | 6 +- Tests/SvgW3CTestRunner/BitmapExtensions.cs | 117 ----------------- .../Properties/AssemblyInfo.cs | 1 - Tests/SvgW3CTestRunner/RunTestsDialog.cs | 1 + .../SvgW3CTestRunner/SvgW3CTestRunner.csproj | 3 +- Tests/SvgW3CTestRunner/View.cs | 71 +--------- 20 files changed, 270 insertions(+), 352 deletions(-) rename Tests/{Svg.UnitTests => Svg.Tests.Common}/Css/CssQuery.cs (52%) rename Tests/{Svg.UnitTests => Svg.Tests.Common}/Css/SvgElementOps.cs (100%) create mode 100644 Tests/Svg.Tests.Common/ExtensionMethods.cs create mode 100644 Tests/Svg.Tests.Common/Properties/AssemblyInfo.cs create mode 100644 Tests/Svg.Tests.Common/Svg.Tests.Common.csproj rename Tests/{Svg.UnitTests => Svg.Tests.Common}/TestsUtils.cs (97%) create mode 100644 Tests/Svg.Tests.Common/svgkey.snk diff --git a/Source/Properties/AssemblyInfo.cs b/Source/Properties/AssemblyInfo.cs index 451e79446..f3bd79e34 100644 --- a/Source/Properties/AssemblyInfo.cs +++ b/Source/Properties/AssemblyInfo.cs @@ -1,6 +1,7 @@ using System; using System.Reflection; using System.Runtime.InteropServices; +using System.Runtime.CompilerServices; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information @@ -24,16 +25,23 @@ [assembly: CLSCompliant(true)] -[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Svg.UnitTests,PublicKey=" + - "00240000048000009400000006020000002400005253413100040000010001008d4e723a8c76be" + +[assembly:InternalsVisibleTo("Svg.UnitTests,PublicKey=" + +"00240000048000009400000006020000002400005253413100040000010001008d4e723a8c76be" + "e667607d1fca2c0f0cdcc1c1b926ae46669128282ecad43e6d0776497cd8289dca11e4479773d5" + "45fc4c557686de548aadbb8652fa550e21d4c402885fec4c1deebfa79e861adb966fc8f4e78235" + "79a535280ddd3a0168cb4d19522c7591b6693377058675da70e50c7bd6fdceae055cef085f02a0" + "5a7f0cb4")] -[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Svg.Benchmark,PublicKey=" + - "00240000048000009400000006020000002400005253413100040000010001008d4e723a8c76be" + - "e667607d1fca2c0f0cdcc1c1b926ae46669128282ecad43e6d0776497cd8289dca11e4479773d5" + - "45fc4c557686de548aadbb8652fa550e21d4c402885fec4c1deebfa79e861adb966fc8f4e78235" + - "79a535280ddd3a0168cb4d19522c7591b6693377058675da70e50c7bd6fdceae055cef085f02a0" + - "5a7f0cb4")] +[assembly: InternalsVisibleTo("Svg.Benchmark,PublicKey=" + +"00240000048000009400000006020000002400005253413100040000010001008d4e723a8c76be" + +"e667607d1fca2c0f0cdcc1c1b926ae46669128282ecad43e6d0776497cd8289dca11e4479773d5" + +"45fc4c557686de548aadbb8652fa550e21d4c402885fec4c1deebfa79e861adb966fc8f4e78235" + +"79a535280ddd3a0168cb4d19522c7591b6693377058675da70e50c7bd6fdceae055cef085f02a0" + +"5a7f0cb4")] + +[assembly: InternalsVisibleTo("Svg.Tests.Common,PublicKey=" + +"00240000048000009400000006020000002400005253413100040000010001008d4e723a8c76be" + +"e667607d1fca2c0f0cdcc1c1b926ae46669128282ecad43e6d0776497cd8289dca11e4479773d5" + +"45fc4c557686de548aadbb8652fa550e21d4c402885fec4c1deebfa79e861adb966fc8f4e78235" + +"79a535280ddd3a0168cb4d19522c7591b6693377058675da70e50c7bd6fdceae055cef085f02a0" + +"5a7f0cb4")] diff --git a/Source/Svg.sln b/Source/Svg.sln index 74601f96b..2b8f7c7f5 100644 --- a/Source/Svg.sln +++ b/Source/Svg.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.29215.179 +# Visual Studio Version 17 +VisualStudioVersion = 17.8.34408.163 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Svg", "Svg.csproj", "{886A98C5-37C0-4E8B-885E-30C1D2F98B47}" EndProject @@ -40,6 +40,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Generators", "Generators", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Svg.Custom", "..\Svg.Custom\Svg.Custom.csproj", "{6FAA2B79-FE5C-456B-A743-E9290665B223}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Svg.Tests.Common", "..\Tests\Svg.Tests.Common\Svg.Tests.Common.csproj", "{D7C625E8-79EA-4859-A457-2C4A90786790}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -90,6 +92,10 @@ Global {6FAA2B79-FE5C-456B-A743-E9290665B223}.Debug|Any CPU.Build.0 = Debug|Any CPU {6FAA2B79-FE5C-456B-A743-E9290665B223}.Release|Any CPU.ActiveCfg = Release|Any CPU {6FAA2B79-FE5C-456B-A743-E9290665B223}.Release|Any CPU.Build.0 = Release|Any CPU + {D7C625E8-79EA-4859-A457-2C4A90786790}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D7C625E8-79EA-4859-A457-2C4A90786790}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D7C625E8-79EA-4859-A457-2C4A90786790}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D7C625E8-79EA-4859-A457-2C4A90786790}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -104,6 +110,7 @@ Global {9379360C-CB0B-4035-AE8F-8863A420FDCF} = {038E2E7B-BC03-4DA7-AA5F-CA8BD95BD0F2} {BACDD1F4-B97D-4E27-BD09-6957633FF484} = {FAFD6DC7-5203-4CED-A151-66379DD43695} {8DEB3EA7-5915-4EB9-8052-85A7AC4379EC} = {2EC3F3A0-F097-43EF-A603-9B82E3061469} + {D7C625E8-79EA-4859-A457-2C4A90786790} = {2EC3F3A0-F097-43EF-A603-9B82E3061469} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {5096EEB3-8F41-44B5-BCF9-58743A59AB21} diff --git a/Tests/Svg.Benchmark/Svg.Benchmark.csproj b/Tests/Svg.Benchmark/Svg.Benchmark.csproj index 1b2ca5a18..77a488fda 100644 --- a/Tests/Svg.Benchmark/Svg.Benchmark.csproj +++ b/Tests/Svg.Benchmark/Svg.Benchmark.csproj @@ -32,17 +32,12 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - + diff --git a/Tests/Svg.UnitTests/Css/CssQuery.cs b/Tests/Svg.Tests.Common/Css/CssQuery.cs similarity index 52% rename from Tests/Svg.UnitTests/Css/CssQuery.cs rename to Tests/Svg.Tests.Common/Css/CssQuery.cs index 3ca42e19d..deee59b98 100644 --- a/Tests/Svg.UnitTests/Css/CssQuery.cs +++ b/Tests/Svg.Tests.Common/Css/CssQuery.cs @@ -25,5 +25,24 @@ public static int GetSpecificity(this ISelector selector) specificity |= (1 << 4) * selector.Specificity.Tags; return specificity; } + + + public static IEnumerable QuerySelectorExCssAll(NonSvgElement elem, + string selector, SvgElementFactory elementFactory) + { + var stylesheetParser = new StylesheetParser(true, true); + var stylesheet = stylesheetParser.Parse(selector + " {color:black}"); + var exCssSelector = stylesheet.StyleRules.First().Selector; + return elem.QuerySelectorAll(exCssSelector, elementFactory); + } + + public static IEnumerable QuerySelectorFizzlerAll(NonSvgElement elem, + string selector, SvgElementFactory elementFactory) + { + var generator = new SelectorGenerator(new SvgElementOps(elementFactory)); + Fizzler.Parser.Parse(selector, generator); + return generator.Selector(Enumerable.Repeat(elem, 1)); + } + } } diff --git a/Tests/Svg.UnitTests/Css/SvgElementOps.cs b/Tests/Svg.Tests.Common/Css/SvgElementOps.cs similarity index 100% rename from Tests/Svg.UnitTests/Css/SvgElementOps.cs rename to Tests/Svg.Tests.Common/Css/SvgElementOps.cs diff --git a/Tests/Svg.Tests.Common/ExtensionMethods.cs b/Tests/Svg.Tests.Common/ExtensionMethods.cs new file mode 100644 index 000000000..fd1b145f2 --- /dev/null +++ b/Tests/Svg.Tests.Common/ExtensionMethods.cs @@ -0,0 +1,123 @@ +using System; +using System.Drawing.Imaging; +using System.Drawing; +using System.Drawing.Drawing2D; + + +namespace Svg.Tests.Common +{ + /// + /// Taken from https://web.archive.org/web/20130111215043/http://www.switchonthecode.com/tutorials/csharp-tutorial-convert-a-color-image-to-grayscale + /// and slightly modified. + /// Image width and height, default threshold and handling of alpha values have been adapted. + /// + public static class ExtensionMethods + { + private static readonly int ImageWidth = 64; + private static readonly int ImageHeight = 64; + + public static float PercentageDifference(this Image img1, Image img2, byte threshold = 10) + { + byte[,] differences = img1.GetDifferences(img2); + + int diffPixels = 0; + + foreach (byte b in differences) + { + if (b > threshold) { diffPixels++; } + } + + return diffPixels / (float)(differences.GetLength(0) * differences.GetLength(1)); + } + + public static Bitmap Resize(this Image originalImage, int newWidth, int newHeight) + { + if (originalImage.Width > originalImage.Height) + newWidth = originalImage.Width * newHeight / originalImage.Height; + else + newHeight = originalImage.Height * newWidth / originalImage.Width; + + var smallVersion = new Bitmap(newWidth, newHeight); + using (var g = Graphics.FromImage(smallVersion)) + { + g.SmoothingMode = SmoothingMode.HighQuality; + g.InterpolationMode = InterpolationMode.HighQualityBicubic; + g.PixelOffsetMode = PixelOffsetMode.HighQuality; + g.DrawImage(originalImage, 0, 0, smallVersion.Width, smallVersion.Height); + } + + return smallVersion; + } + + public static byte[,] GetGrayScaleValues(this Bitmap img) + { + byte[,] grayScale = new byte[img.Width, img.Height]; + + for (int y = 0; y < grayScale.GetLength(1); y++) + { + for (int x = 0; x < grayScale.GetLength(0); x++) + { + var alpha = img.GetPixel(x, y).A; + var gray = img.GetPixel(x, y).R; + grayScale[x, y] = (byte)Math.Abs(gray * alpha / 255); + } + } + return grayScale; + } + + // the colormatrix needed to grayscale an image + static readonly ColorMatrix ColorMatrix = new ColorMatrix(new float[][] + { + new float[] {.3f, .3f, .3f, 0, 0}, + new float[] {.59f, .59f, .59f, 0, 0}, + new float[] {.11f, .11f, .11f, 0, 0}, + new float[] {0, 0, 0, 1, 0}, + new float[] {0, 0, 0, 0, 1} + }); + + public static Bitmap GetGrayScaleVersion(this Bitmap original) + { + // create a blank bitmap the same size as original + // https://web.archive.org/web/20130111215043/http://www.switchonthecode.com/tutorials/csharp-tutorial-convert-a-color-image-to-grayscale + var newBitmap = new Bitmap(original.Width, original.Height); + + // get a graphics object from the new image + using (var g = Graphics.FromImage(newBitmap)) + // create some image attributes + using (var attributes = new ImageAttributes()) + { + // set the color matrix attribute + attributes.SetColorMatrix(ColorMatrix); + + // draw the original image on the new image + // using the grayscale color matrix + g.DrawImage(original, new Rectangle(0, 0, original.Width, original.Height), + 0, 0, original.Width, original.Height, GraphicsUnit.Pixel, attributes); + } + + return newBitmap; + } + + public static byte[,] GetDifferences(this Image img1, Image img2) + { + using (var resizedThisOne = img1.Resize(ImageWidth, ImageHeight)) + using (var thisOne = resizedThisOne.GetGrayScaleVersion()) + using (var resizedTheOtherOne = img2.Resize(ImageWidth, ImageHeight)) + using (var theOtherOne = resizedTheOtherOne.GetGrayScaleVersion()) + { + byte[,] differences = new byte[thisOne.Width, thisOne.Height]; + byte[,] firstGray = thisOne.GetGrayScaleValues(); + byte[,] secondGray = theOtherOne.GetGrayScaleValues(); + + for (int y = 0; y < differences.GetLength(1); y++) + { + for (int x = 0; x < differences.GetLength(0); x++) + { + differences[x, y] = (byte)Math.Abs(firstGray[x, y] - secondGray[x, y]); + } + } + return differences; + } + } + } +} diff --git a/Tests/Svg.Tests.Common/Properties/AssemblyInfo.cs b/Tests/Svg.Tests.Common/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..0aa24d4c4 --- /dev/null +++ b/Tests/Svg.Tests.Common/Properties/AssemblyInfo.cs @@ -0,0 +1,49 @@ +using System.Reflection; +using System.Runtime.InteropServices; +using System.Runtime.CompilerServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Svg.Tests.Common")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Svg.Tests.Common")] +[assembly: AssemblyCopyright("Copyright © 2024")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("6ab1d266-f201-46c0-9d14-523768eb18db")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] + +[assembly: InternalsVisibleTo("Svg.Benchmark,PublicKey=" + +"00240000048000009400000006020000002400005253413100040000010001008d4e723a8c76be" + +"e667607d1fca2c0f0cdcc1c1b926ae46669128282ecad43e6d0776497cd8289dca11e4479773d5" + +"45fc4c557686de548aadbb8652fa550e21d4c402885fec4c1deebfa79e861adb966fc8f4e78235" + +"79a535280ddd3a0168cb4d19522c7591b6693377058675da70e50c7bd6fdceae055cef085f02a0" + +"5a7f0cb4")] + +[assembly: InternalsVisibleTo("Svg.UnitTests,PublicKey=" + +"00240000048000009400000006020000002400005253413100040000010001008d4e723a8c76be" + +"e667607d1fca2c0f0cdcc1c1b926ae46669128282ecad43e6d0776497cd8289dca11e4479773d5" + +"45fc4c557686de548aadbb8652fa550e21d4c402885fec4c1deebfa79e861adb966fc8f4e78235" + +"79a535280ddd3a0168cb4d19522c7591b6693377058675da70e50c7bd6fdceae055cef085f02a0" + +"5a7f0cb4")] diff --git a/Tests/Svg.Tests.Common/Svg.Tests.Common.csproj b/Tests/Svg.Tests.Common/Svg.Tests.Common.csproj new file mode 100644 index 000000000..35ccfeac6 --- /dev/null +++ b/Tests/Svg.Tests.Common/Svg.Tests.Common.csproj @@ -0,0 +1,35 @@ + + + + net6.0;netcoreapp3.1;net462 + False + False + False + True + svgkey.snk + false + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tests/Svg.UnitTests/TestsUtils.cs b/Tests/Svg.Tests.Common/TestsUtils.cs similarity index 97% rename from Tests/Svg.UnitTests/TestsUtils.cs rename to Tests/Svg.Tests.Common/TestsUtils.cs index 325961beb..ba3679811 100644 --- a/Tests/Svg.UnitTests/TestsUtils.cs +++ b/Tests/Svg.Tests.Common/TestsUtils.cs @@ -1,16 +1,14 @@ using System; -using System.Collections.Generic; using System.Linq; -using System.Text; using System.Threading.Tasks; using System.Net; using System.Net.Http; using System.IO; using System.IO.Compression; -namespace Svg.UnitTests +namespace Svg.Tests.Common { - internal static class TestsUtils + public static class TestsUtils { private const string FixImage = "smiley.png"; diff --git a/Tests/Svg.Tests.Common/svgkey.snk b/Tests/Svg.Tests.Common/svgkey.snk new file mode 100644 index 0000000000000000000000000000000000000000..b933e314435d7601f228b29c0cb8d9f6b622a18d GIT binary patch literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50097vPI5YocE09kV0|CTEDsFa!NIvEu102& zC@3z<)IMzoc1e8LD4og?(0^yh*#d8IWd4c$5cXv<9*QY>|mwrMkW1%`FnaODhp*8R?|1zhh4Ujm?7e+;x! z{vu>xg6TaH41n0nR6U<^3Om=w1%A*_sO-a=P7@<^3NgD-LGg*HJ#(r9_1AC^RhaH9 zIP-JSUO+TS$;s`XBP&>t9T?eyQIKu|nLQ9qc?w8jFF_Ol|tTmM2h#K{55Z_Y*3pYqo8~j zOH(~ng_d7}rrzxoG;s7U#y$guq)acKBzp;a1HgTBUYLHv#VCR&sj&_~i&dF!wGln5 z9I%Aw438pw+8vM3(dlXHcI9qGyDMJ_ImcYUtO_VH`9P7e0m=&j>NuYJp3kOMi|c-J zckeGrJ@s9OK{URc3qzxn0_BLIua%rr!+;e>uy)sS=R^=t91iIe-(-9Gf)mHAM*mr3 z#~}&nIqfYe7h%-#1NBt4UL(%cowY**>WL`&?ShNW2e~B-ZPa+AP=Bf!z?Y8|Ym@m* z0b4k@gj;NX$2GlCB^C_n^w$od(kt#b@7Ei>Ib*!e+_X-JfJ-xFV7~(I^H9Hn+W+}W iA>=4`anBxnUz5Y~f67j(*~8S@LM=jTOU1JA-%YBP&>9W^ literal 0 HcmV?d00001 diff --git a/Tests/Svg.UnitTests/ExCssSelectorTests.cs b/Tests/Svg.UnitTests/ExCssSelectorTests.cs index 95c8fa057..5e5a5af1c 100644 --- a/Tests/Svg.UnitTests/ExCssSelectorTests.cs +++ b/Tests/Svg.UnitTests/ExCssSelectorTests.cs @@ -6,9 +6,10 @@ using System.Linq; using System.Xml; using ExCSS; -using Fizzler; using Svg.Css; +using Svg.Tests.Common; + namespace Svg.UnitTests { [TestFixture] @@ -290,7 +291,7 @@ private void TestSelector(string selector, NonSvgElement rootNode, SvgElementFac try { Debug.WriteLine("Fizzler:\r\n"); - fizzlerElements = QuerySelectorFizzlerAll(rootNode, selector, elementFactory).OrderBy(f => f.ElementName).ToList(); + fizzlerElements = CssQuery.QuerySelectorFizzlerAll(rootNode, selector, elementFactory).OrderBy(f => f.ElementName).ToList(); Debug.WriteLine(Environment.NewLine); } catch (Exception ex) @@ -300,7 +301,7 @@ private void TestSelector(string selector, NonSvgElement rootNode, SvgElementFac } Debug.WriteLine("ExCss:\r\n"); - var exCssElements = QuerySelectorExCssAll(rootNode, selector, elementFactory).OrderBy(f => f.ElementName).ToList(); + var exCssElements = CssQuery.QuerySelectorExCssAll(rootNode, selector, elementFactory).OrderBy(f => f.ElementName).ToList(); Debug.WriteLine(Environment.NewLine); if (fizzler) @@ -313,21 +314,6 @@ private void TestSelector(string selector, NonSvgElement rootNode, SvgElementFac Assert.Inconclusive("Fizzler can't handle this selector"); } } - - private IEnumerable QuerySelectorExCssAll(NonSvgElement elem, string selector, SvgElementFactory elementFactory) - { - var stylesheetParser = new StylesheetParser(true, true); - var stylesheet = stylesheetParser.Parse(selector + " {color:black}"); - var exCssSelector = stylesheet.StyleRules.First().Selector; - return elem.QuerySelectorAll(exCssSelector, elementFactory); - } - - private IEnumerable QuerySelectorFizzlerAll(NonSvgElement elem, string selector, SvgElementFactory elementFactory) - { - var generator = new SelectorGenerator(new SvgElementOps(elementFactory)); - Fizzler.Parser.Parse(selector, generator); - return generator.Selector(Enumerable.Repeat(elem, 1)); - } } public class TestSvg diff --git a/Tests/Svg.UnitTests/ImageComparisonTest.cs b/Tests/Svg.UnitTests/ImageComparisonTest.cs index f67ec3db2..6536b6f3f 100644 --- a/Tests/Svg.UnitTests/ImageComparisonTest.cs +++ b/Tests/Svg.UnitTests/ImageComparisonTest.cs @@ -7,6 +7,8 @@ using System.IO; using System.Linq; +using Svg.Tests.Common; + namespace Svg.UnitTests { /// @@ -181,121 +183,6 @@ private static SvgDocument LoadSvgDocument(string svgPath) } } - /// - /// Taken from https://web.archive.org/web/20130111215043/http://www.switchonthecode.com/tutorials/csharp-tutorial-convert-a-color-image-to-grayscale - /// and slightly modified. - /// Image width and height, default threshold and handling of alpha values have been adapted. - /// - static class ExtensionMethods - { - private static readonly int ImageWidth = 64; - private static readonly int ImageHeight = 64; - - public static float PercentageDifference(this Image img1, Image img2, byte threshold = 10) - { - byte[,] differences = img1.GetDifferences(img2); - - int diffPixels = 0; - - foreach (byte b in differences) - { - if (b > threshold) { diffPixels++; } - } - - return diffPixels / (float)(differences.GetLength(0) * differences.GetLength(1)); - } - - public static Bitmap Resize(this Image originalImage, int newWidth, int newHeight) - { - if (originalImage.Width > originalImage.Height) - newWidth = originalImage.Width * newHeight / originalImage.Height; - else - newHeight = originalImage.Height * newWidth / originalImage.Width; - - var smallVersion = new Bitmap(newWidth, newHeight); - using (var g = Graphics.FromImage(smallVersion)) - { - g.SmoothingMode = SmoothingMode.HighQuality; - g.InterpolationMode = InterpolationMode.HighQualityBicubic; - g.PixelOffsetMode = PixelOffsetMode.HighQuality; - g.DrawImage(originalImage, 0, 0, smallVersion.Width, smallVersion.Height); - } - - return smallVersion; - } - - public static byte[,] GetGrayScaleValues(this Bitmap img) - { - byte[,] grayScale = new byte[img.Width, img.Height]; - - for (int y = 0; y < grayScale.GetLength(1); y++) - { - for (int x = 0; x < grayScale.GetLength(0); x++) - { - var alpha = img.GetPixel(x, y).A; - var gray = img.GetPixel(x, y).R; - grayScale[x, y] = (byte)Math.Abs(gray * alpha / 255); - } - } - return grayScale; - } - - // the colormatrix needed to grayscale an image - static readonly ColorMatrix ColorMatrix = new ColorMatrix(new float[][] - { - new float[] {.3f, .3f, .3f, 0, 0}, - new float[] {.59f, .59f, .59f, 0, 0}, - new float[] {.11f, .11f, .11f, 0, 0}, - new float[] {0, 0, 0, 1, 0}, - new float[] {0, 0, 0, 0, 1} - }); - - public static Bitmap GetGrayScaleVersion(this Bitmap original) - { - // create a blank bitmap the same size as original - // https://web.archive.org/web/20130111215043/http://www.switchonthecode.com/tutorials/csharp-tutorial-convert-a-color-image-to-grayscale - var newBitmap = new Bitmap(original.Width, original.Height); - - // get a graphics object from the new image - using (var g = Graphics.FromImage(newBitmap)) - // create some image attributes - using (var attributes = new ImageAttributes()) - { - // set the color matrix attribute - attributes.SetColorMatrix(ColorMatrix); - - // draw the original image on the new image - // using the grayscale color matrix - g.DrawImage(original, new Rectangle(0, 0, original.Width, original.Height), - 0, 0, original.Width, original.Height, GraphicsUnit.Pixel, attributes); - } - - return newBitmap; - } - - public static byte[,] GetDifferences(this Image img1, Image img2) - { - using (var resizedThisOne = img1.Resize(ImageWidth, ImageHeight)) - using (var thisOne = resizedThisOne.GetGrayScaleVersion()) - using (var resizedTheOtherOne = img2.Resize(ImageWidth, ImageHeight)) - using (var theOtherOne = resizedTheOtherOne.GetGrayScaleVersion()) - { - byte[,] differences = new byte[thisOne.Width, thisOne.Height]; - byte[,] firstGray = thisOne.GetGrayScaleValues(); - byte[,] secondGray = theOtherOne.GetGrayScaleValues(); - - for (int y = 0; y < differences.GetLength(1); y++) - { - for (int x = 0; x < differences.GetLength(0); x++) - { - differences[x, y] = (byte)Math.Abs(firstGray[x, y] - secondGray[x, y]); - } - } - return differences; - } - } - } - /// /// Helper class to read the datasource for the image tests. /// The datasource will read the embedded resource with the Tests and will pass a TestData class with the data to test. diff --git a/Tests/Svg.UnitTests/PerformanceTest.cs b/Tests/Svg.UnitTests/PerformanceTest.cs index c687ad474..2915214c9 100644 --- a/Tests/Svg.UnitTests/PerformanceTest.cs +++ b/Tests/Svg.UnitTests/PerformanceTest.cs @@ -7,6 +7,8 @@ using NUnit.Framework; using System.Linq; +using Svg.Tests.Common; + namespace Svg.UnitTests { [TestFixture] diff --git a/Tests/Svg.UnitTests/Properties/AssemblyInfo.cs b/Tests/Svg.UnitTests/Properties/AssemblyInfo.cs index df90ebd6d..4fcfb65fd 100644 --- a/Tests/Svg.UnitTests/Properties/AssemblyInfo.cs +++ b/Tests/Svg.UnitTests/Properties/AssemblyInfo.cs @@ -1,5 +1,6 @@ using System.Reflection; using System.Runtime.InteropServices; +using System.Runtime.CompilerServices; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information @@ -32,10 +33,3 @@ // by using the '*' as shown below: [assembly: AssemblyVersion("2.4.5.0")] [assembly: AssemblyFileVersion("2.4.5.0")] - -[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Svg.Benchmark,PublicKey=" + - "00240000048000009400000006020000002400005253413100040000010001008d4e723a8c76be" + - "e667607d1fca2c0f0cdcc1c1b926ae46669128282ecad43e6d0776497cd8289dca11e4479773d5" + - "45fc4c557686de548aadbb8652fa550e21d4c402885fec4c1deebfa79e861adb966fc8f4e78235" + - "79a535280ddd3a0168cb4d19522c7591b6693377058675da70e50c7bd6fdceae055cef085f02a0" + - "5a7f0cb4")] diff --git a/Tests/Svg.UnitTests/Svg.UnitTests.csproj b/Tests/Svg.UnitTests/Svg.UnitTests.csproj index 45ede109a..18742e445 100644 --- a/Tests/Svg.UnitTests/Svg.UnitTests.csproj +++ b/Tests/Svg.UnitTests/Svg.UnitTests.csproj @@ -58,15 +58,11 @@ - - - - - + diff --git a/Tests/SvgW3CTestRunner/BitmapExtensions.cs b/Tests/SvgW3CTestRunner/BitmapExtensions.cs index d8478748a..5eeeefbad 100644 --- a/Tests/SvgW3CTestRunner/BitmapExtensions.cs +++ b/Tests/SvgW3CTestRunner/BitmapExtensions.cs @@ -1,7 +1,6 @@ using System; using System.Drawing.Imaging; using System.Drawing; -using System.Drawing.Drawing2D; namespace SvgW3CTestRunner { @@ -62,120 +61,4 @@ public int Reserved } } } - - /// - /// Taken from https://web.archive.org/web/20130111215043/http://www.switchonthecode.com/tutorials/csharp-tutorial-convert-a-color-image-to-grayscale - /// and slightly modified. - /// Image width and height, default threshold and handling of alpha values have been adapted. - /// - static class ExtensionMethods - { - private static readonly int ImageWidth = 64; - private static readonly int ImageHeight = 64; - - public static float PercentageDifference(this Image img1, Image img2, byte threshold = 10) - { - byte[,] differences = img1.GetDifferences(img2); - - int diffPixels = 0; - - foreach (byte b in differences) - { - if (b > threshold) { diffPixels++; } - } - - return diffPixels / (float)(differences.GetLength(0) * differences.GetLength(1)); - } - - public static Bitmap Resize(this Image originalImage, int newWidth, int newHeight) - { - if (originalImage.Width > originalImage.Height) - newWidth = originalImage.Width * newHeight / originalImage.Height; - else - newHeight = originalImage.Height * newWidth / originalImage.Width; - - var smallVersion = new Bitmap(newWidth, newHeight); - using (var g = Graphics.FromImage(smallVersion)) - { - g.SmoothingMode = SmoothingMode.HighQuality; - g.InterpolationMode = InterpolationMode.HighQualityBicubic; - g.PixelOffsetMode = PixelOffsetMode.HighQuality; - g.DrawImage(originalImage, 0, 0, smallVersion.Width, smallVersion.Height); - } - - return smallVersion; - } - - public static byte[,] GetGrayScaleValues(this Bitmap img) - { - byte[,] grayScale = new byte[img.Width, img.Height]; - - for (int y = 0; y < grayScale.GetLength(1); y++) - { - for (int x = 0; x < grayScale.GetLength(0); x++) - { - var alpha = img.GetPixel(x, y).A; - var gray = img.GetPixel(x, y).R; - grayScale[x, y] = (byte)Math.Abs(gray * alpha / 255); - } - } - return grayScale; - } - - // the colormatrix needed to grayscale an image - static readonly ColorMatrix ColorMatrix = new ColorMatrix(new float[][] - { - new float[] {.3f, .3f, .3f, 0, 0}, - new float[] {.59f, .59f, .59f, 0, 0}, - new float[] {.11f, .11f, .11f, 0, 0}, - new float[] {0, 0, 0, 1, 0}, - new float[] {0, 0, 0, 0, 1} - }); - - public static Bitmap GetGrayScaleVersion(this Bitmap original) - { - // create a blank bitmap the same size as original - // https://web.archive.org/web/20130111215043/http://www.switchonthecode.com/tutorials/csharp-tutorial-convert-a-color-image-to-grayscale - var newBitmap = new Bitmap(original.Width, original.Height); - - // get a graphics object from the new image - using (var g = Graphics.FromImage(newBitmap)) - // create some image attributes - using (var attributes = new ImageAttributes()) - { - // set the color matrix attribute - attributes.SetColorMatrix(ColorMatrix); - - // draw the original image on the new image - // using the grayscale color matrix - g.DrawImage(original, new Rectangle(0, 0, original.Width, original.Height), - 0, 0, original.Width, original.Height, GraphicsUnit.Pixel, attributes); - } - - return newBitmap; - } - - public static byte[,] GetDifferences(this Image img1, Image img2) - { - using (var resizedThisOne = img1.Resize(ImageWidth, ImageHeight)) - using (var thisOne = resizedThisOne.GetGrayScaleVersion()) - using (var resizedTheOtherOne = img2.Resize(ImageWidth, ImageHeight)) - using (var theOtherOne = resizedTheOtherOne.GetGrayScaleVersion()) - { - byte[,] differences = new byte[thisOne.Width, thisOne.Height]; - byte[,] firstGray = thisOne.GetGrayScaleValues(); - byte[,] secondGray = theOtherOne.GetGrayScaleValues(); - - for (int y = 0; y < differences.GetLength(1); y++) - { - for (int x = 0; x < differences.GetLength(0); x++) - { - differences[x, y] = (byte)Math.Abs(firstGray[x, y] - secondGray[x, y]); - } - } - return differences; - } - } - } - } diff --git a/Tests/SvgW3CTestRunner/Properties/AssemblyInfo.cs b/Tests/SvgW3CTestRunner/Properties/AssemblyInfo.cs index ed10e589e..7934a66cb 100644 --- a/Tests/SvgW3CTestRunner/Properties/AssemblyInfo.cs +++ b/Tests/SvgW3CTestRunner/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following diff --git a/Tests/SvgW3CTestRunner/RunTestsDialog.cs b/Tests/SvgW3CTestRunner/RunTestsDialog.cs index 5f7e91100..7314c78c7 100644 --- a/Tests/SvgW3CTestRunner/RunTestsDialog.cs +++ b/Tests/SvgW3CTestRunner/RunTestsDialog.cs @@ -7,6 +7,7 @@ using System.Windows.Forms; using Svg; +using Svg.Tests.Common; namespace SvgW3CTestRunner { diff --git a/Tests/SvgW3CTestRunner/SvgW3CTestRunner.csproj b/Tests/SvgW3CTestRunner/SvgW3CTestRunner.csproj index 563df5242..73a030143 100644 --- a/Tests/SvgW3CTestRunner/SvgW3CTestRunner.csproj +++ b/Tests/SvgW3CTestRunner/SvgW3CTestRunner.csproj @@ -29,12 +29,11 @@ - - + diff --git a/Tests/SvgW3CTestRunner/View.cs b/Tests/SvgW3CTestRunner/View.cs index 4e6fa9343..62c20ef32 100755 --- a/Tests/SvgW3CTestRunner/View.cs +++ b/Tests/SvgW3CTestRunner/View.cs @@ -3,16 +3,14 @@ using System.Diagnostics; using System.Drawing; using System.IO; -using System.IO.Compression; using System.Linq; -using System.Net; -using System.Net.Http; using System.Threading.Tasks; using System.Runtime.InteropServices; using System.Text.RegularExpressions; using System.Windows.Forms; using Svg; +using Svg.Tests.Common; namespace SvgW3CTestRunner { @@ -97,74 +95,13 @@ protected override bool ProcessCmdKey(ref Message msg, Keys keyData) return base.ProcessCmdKey(ref msg, keyData); } - private static bool IsTestSuiteAvailable() - { - if (Directory.Exists(_svgW3CBasePath) == false) - { - return false; - } - if (Directory.Exists(_pngW3CBasePath) == false) - { - return false; - } - string svgDir = Path.GetFullPath(_svgW3CBasePath); - if (!Directory.Exists(svgDir) || IsDirectoryEmpty(svgDir) == true) - { - return false; - } - string pngDir = Path.Combine(_pngW3CBasePath); - if (!Directory.Exists(pngDir) || IsDirectoryEmpty(pngDir) == true) - { - return false; - } - - return true; - } - - private static async Task DownloadW3CTestSuite(string downloadedFilePath) - { - ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; - - using (HttpClient client = new HttpClient()) - { - using (Stream streamToReadFrom = await client.GetStreamAsync(W3CTestSuiteUrl)) - { - using (Stream streamToWriteTo = new FileStream(downloadedFilePath, FileMode.CreateNew)) - { - await streamToReadFrom.CopyToAsync(streamToWriteTo); - } - } - } - } - private async void OnFormLoad(object sender, EventArgs e) { - if (!IsTestSuiteAvailable()) - { - string svgDir = Path.GetFullPath(_svgW3CBasePath); - var downloadedFilePath = Path.GetFullPath(Path.Combine(svgDir, "..", "Svg11.zip")); - string destinationDirectory = Path.GetDirectoryName(downloadedFilePath); - - if (File.Exists(downloadedFilePath)) - { - File.Delete(downloadedFilePath); - } - - await DownloadW3CTestSuite(downloadedFilePath); - - await Task.Delay(100); + string testsRoot = Path.GetDirectoryName(Path.GetDirectoryName(_svgW3CBasePath)); - ZipFile.ExtractToDirectory(downloadedFilePath, destinationDirectory); + await TestsUtils.EnsureTestsExists(testsRoot); - var sourceImage = Path.Combine(destinationDirectory, "images", FixImage); - var destImage = Path.Combine(destinationDirectory, "svg", FixImage); - File.Copy(sourceImage, destImage); - - if (File.Exists(downloadedFilePath)) - { - File.Delete(downloadedFilePath); - } - } + await Task.Delay(100); this.LoadW3CTestSuite(); this.LoadIssuesAndPullRequests();