예제 #1
0
        private static bool Validate(Bitmap bitmap, ExpectedPixels expectation, StringBuilder report)
        {
            var failMessage = default(string);

            for (var offsetX = 0; offsetX <= expectation.OffsetTolerance.x; offsetX++)
            {
                for (var offsetY = 0; offsetY <= expectation.OffsetTolerance.y; offsetY++)
                {
                    if (ValidatePixels(offsetX, offsetY) ||
                        (offsetX > 0 && ValidatePixels(-offsetX, offsetY)) ||
                        (offsetX > 0 && offsetY > 0 && ValidatePixels(-offsetX, -offsetY)) ||
                        (offsetY > 0 && ValidatePixels(offsetX, -offsetY)))
                    {
                        report.AppendLine("OK");
                        return(true);
                    }
                }
            }

            report.AppendLine(failMessage);
            return(false);

            bool ValidatePixels(int offsetX, int offsetY)
            {
                var isSuccess = true;
                var result    = new StringBuilder();

                for (var lin = 0; lin < expectation.Values.GetLength(0); lin++)
                {
                    for (var col = 0; col < expectation.Values.GetLength(1); col++)
                    {
                        var expectedColor = expectation.Values[lin, col];
                        if (expectedColor.IsEmpty)
                        {
                            continue;
                        }

                        var pixelX = expectation.X + col + offsetX;
                        var pixelY = expectation.Y + lin + offsetY;
                        var pixel  = bitmap.GetPixel(pixelX, pixelY);

                        var expected = ToArgbCode(expectedColor);
                        var actual   = ToArgbCode(pixel);

                        if (!AreSameColor(expectedColor, pixel, expectation.ColorTolerance))
                        {
                            isSuccess = false;
                            result.AppendLine($"{col},{lin}: [{pixelX},{pixelY}] (expected: {expected} | actual: {actual})");
                        }
                    }
                }

                if (failMessage == default)                 // so we keep only for offset 0,0
                {
                    failMessage = result.ToString();
                }

                return(isSuccess);
            }
        }
예제 #2
0
파일: ImageAssert.cs 프로젝트: jokm1/uno-2
        private static bool Validate(ExpectedPixels expectation, Bitmap actualBitmap, double expectedToActualScale, StringBuilder report)
        {
            report?.AppendLine($"{expectation.Name}:");

            bool isSuccess;

            switch (expectation.Tolerance.OffsetKind)
            {
            case LocationToleranceKind.PerRange:
                isSuccess = GetLocationOffsets(expectation)
                            .Any(offset => GetPixelCoordinates(expectation)
                                 .All(pixel => ValidatePixel(actualBitmap, expectation, expectedToActualScale, pixel, offset, report)));
                break;

            case LocationToleranceKind.PerPixel:
                isSuccess = GetPixelCoordinates(expectation)
                            .All(pixel => GetLocationOffsets(expectation)
                                 .Any(offset => ValidatePixel(actualBitmap, expectation, expectedToActualScale, pixel, offset, report)));
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(expectation.Tolerance.OffsetKind));
            }

            if (isSuccess)             // otherwise the report has already been full-filled
            {
                report?.AppendLine("\tOK");
            }
            return(isSuccess);
        }
예제 #3
0
파일: ImageAssert.cs 프로젝트: jokm1/uno-2
        private static void AreEqualImpl(
            FileInfo expected,
            Rectangle expectedRect,
            FileInfo actual,
            Bitmap actualBitmap,
            Rectangle actualRect,
            double expectedToActualScale,
            PixelTolerance tolerance,
            int line)
        {
            if (expectedRect != FirstQuadrant && actualRect != FirstQuadrant)
            {
                Assert.AreEqual(expectedRect.Size, actualRect.Size, WithContext("Compare rects don't have the same size"));
            }

            using (var expectedBitmap = new Bitmap(expected.FullName))
            {
                if (expectedRect == FirstQuadrant && actualRect == FirstQuadrant)
                {
                    var effectiveExpectedBitmapSize = new Size(
                        (int)(expectedBitmap.Size.Width * expectedToActualScale),
                        (int)(expectedBitmap.Size.Height * expectedToActualScale));
                    Assert.AreEqual(effectiveExpectedBitmapSize, actualBitmap.Size, WithContext("Screenshots don't have the same size"));
                }

                expectedRect = Normalize(expectedRect, expectedBitmap.Size);
                actualRect   = Normalize(actualRect, actualBitmap.Size);

                var expectedPixels = ExpectedPixels
                                     .At(actualRect.Location)
                                     .Pixels(expectedBitmap, expectedRect)
                                     .Named(expected.Name)
                                     .WithTolerance(tolerance);

                var report = GetContext();
                if (Validate(expectedPixels, actualBitmap, expectedToActualScale, report))
                {
                    Console.WriteLine(report.ToString());
                }
                else
                {
                    Assert.Fail(report.ToString());
                }
            }

            StringBuilder GetContext()
            => new StringBuilder()
            .AppendLine($"ImageAssert.AreEqual @ line {line}")
            .AppendLine("pixelTolerance: " + tolerance)
            .AppendLine("expected: " + expected?.Name + (expectedRect == FirstQuadrant ? null : $" in {expectedRect}"))
            .AppendLine("actual  : " + (actual?.Name ?? "--unknown--") + (actualRect == FirstQuadrant ? null : $" in {actualRect}"))
            .AppendLine("====================");

            string WithContext(string message)
            => GetContext()
            .AppendLine(message)
            .ToString();
        }
예제 #4
0
파일: ImageAssert.cs 프로젝트: jokm1/uno-2
        private static IEnumerable <Point> GetPixelCoordinates(ExpectedPixels expectation)
        {
            var stepX = (int)Math.Max(1, expectation.Tolerance.DiscreteValidation.x);
            var stepY = (int)Math.Max(1, expectation.Tolerance.DiscreteValidation.y);

            for (var lin = 0; lin < expectation.Values.GetLength(0); lin += stepY)
            {
                for (var col = 0; col < expectation.Values.GetLength(1); col += stepX)
                {
                    yield return(new Point(col, lin));
                }
            }
        }
예제 #5
0
        private static (bool areEqual, string context) EqualityCheck(
            ScreenshotInfo expected,
            Rectangle expectedRect,
            ScreenshotInfo actual,
            Bitmap actualBitmap,
            Rectangle actualRect,
            double expectedToActualScale,
            PixelTolerance tolerance,
            [CallerLineNumber] int line = 0)
        {
            if (expectedRect != FirstQuadrant && actualRect != FirstQuadrant)
            {
                Assert.AreEqual(expectedRect.Size, actualRect.Size, WithContext("Compare rects don't have the same size"));
            }

            using (var expectedBitmap = new Bitmap(expected.File.FullName))
            {
                if (expectedRect == FirstQuadrant && actualRect == FirstQuadrant)
                {
                    var effectiveExpectedBitmapSize = new Size(
                        (int)(expectedBitmap.Size.Width * expectedToActualScale),
                        (int)(expectedBitmap.Size.Height * expectedToActualScale));
                    Assert.AreEqual(effectiveExpectedBitmapSize, actualBitmap.Size, WithContext("Screenshots don't have the same size"));
                }

                expectedRect = Normalize(expectedRect, expectedBitmap.Size);
                actualRect   = Normalize(actualRect, actualBitmap.Size);

                var expectedPixels = ExpectedPixels
                                     .At(actualRect.Location)
                                     .Pixels(expectedBitmap, expectedRect)
                                     .Named(expected.StepName)
                                     .WithTolerance(tolerance);

                var report = GetContext();
                var result = Validate(expectedPixels, actualBitmap, expectedToActualScale, report);

                return(result, report.ToString());
            }

            StringBuilder GetContext()
            => new StringBuilder()
            .AppendLine($"ImageAssert.AreEqual @ line {line}")
            .AppendLine("pixelTolerance: " + tolerance)
            .AppendLine($"expected: {expected?.StepName} ({expected?.File.Name}){(expectedRect == FirstQuadrant ? null : $" in {expectedRect}")}")
예제 #6
0
파일: ImageAssert.cs 프로젝트: jokm1/uno-2
        private static IEnumerable <(int x, int y)> GetLocationOffsets(ExpectedPixels expectation)
        {
            for (var offsetX = 0; offsetX <= expectation.Tolerance.Offset.x; offsetX++)
            {
                for (var offsetY = 0; offsetY <= expectation.Tolerance.Offset.y; offsetY++)
                {
                    yield return(offsetX, offsetY);

                    if (offsetX > 0)
                    {
                        yield return(-offsetX, offsetY);
                    }
                    if (offsetY > 0)
                    {
                        yield return(offsetX, -offsetY);
                    }
                    if (offsetX > 0 && offsetY > 0)
                    {
                        yield return(-offsetX, -offsetY);
                    }
                }
            }
        }
예제 #7
0
        private static bool Validate(Bitmap bitmap, ExpectedPixels expectation, StringBuilder report)
        {
            var failMessage = default(string);

            for (var offsetX = 0; offsetX <= expectation.OffsetTolerance.x; offsetX++)
            {
                for (var offsetY = 0; offsetY <= expectation.OffsetTolerance.y; offsetY++)
                {
                    if (ValidatePixels(offsetX, offsetY) ||
                        (offsetX > 0 && ValidatePixels(-offsetX, offsetY)) ||
                        (offsetX > 0 && offsetY > 0 && ValidatePixels(-offsetX, -offsetY)) ||
                        (offsetY > 0 && ValidatePixels(offsetX, -offsetY)))
                    {
                        report.AppendLine("OK");
                        return(true);
                    }
                }
            }

            report.AppendLine(failMessage);
            return(false);

            bool ValidatePixels(int offsetX, int offsetY)
            {
                var isSuccess = true;
                var result    = new StringBuilder();

                for (var lin = 0; lin < expectation.Values.GetLength(0); lin++)
                {
                    for (var col = 0; col < expectation.Values.GetLength(1); col++)
                    {
                        var expectedColor = expectation.Values[lin, col];
                        if (expectedColor.IsEmpty)
                        {
                            continue;
                        }

                        var pixelX = expectation.X + col + offsetX;
                        var pixelY = expectation.Y + lin + offsetY;
                        var pixel  = bitmap.GetPixel(pixelX, pixelY);

                        var expected = ToArgbCode(expectedColor);
                        var actual   = ToArgbCode(pixel);

                        //Convert to ARGB value, because 'named colors' are not considered equal to their unnamed equivalents(!)
                        if (Math.Abs(pixel.A - expectedColor.A) > expectation.ColorTolerance)
                        {
                            isSuccess = false;
                            result.AppendLine($"{col},{lin}: [{pixelX},{pixelY}] Alpha (expected: {expected} | actual: {actual})");
                        }
                        if (Math.Abs(pixel.R - expectedColor.R) > expectation.ColorTolerance)
                        {
                            isSuccess = false;
                            result.AppendLine($"{col},{lin}: [{pixelX},{pixelY}] Red (expected: {expected} | actual: {actual})");
                        }
                        if (Math.Abs(pixel.G - expectedColor.G) > expectation.ColorTolerance)
                        {
                            isSuccess = false;
                            result.AppendLine($"{col},{lin}: [{pixelX},{pixelY}] Green (expected: {expected} | actual: {actual})");
                        }
                        if (Math.Abs(pixel.B - expectedColor.B) > expectation.ColorTolerance)
                        {
                            isSuccess = false;
                            result.AppendLine($"{col},{lin}: [{pixelX},{pixelY}] Blue (expected: {expected} | actual: {actual})");
                        }
                    }
                }

                if (failMessage == default)                 // so we keep only for offset 0,0
                {
                    failMessage = result.ToString();
                }

                return(isSuccess);
            }
        }
예제 #8
0
파일: ImageAssert.cs 프로젝트: jokm1/uno-2
 private static bool ValidatePixel(
     Bitmap actualBitmap,
     ExpectedPixels expectation,
     double expectedToActualScale,
     Point pixel,
     (int x, int y) offset,