diff --git a/src/Headless/Avalonia.Headless/Avalonia.Headless.csproj b/src/Headless/Avalonia.Headless/Avalonia.Headless.csproj index b626eaeb68..893cb0074c 100644 --- a/src/Headless/Avalonia.Headless/Avalonia.Headless.csproj +++ b/src/Headless/Avalonia.Headless/Avalonia.Headless.csproj @@ -12,7 +12,16 @@ + + + + + + + + + diff --git a/src/Headless/Avalonia.Headless/HeadlessPlatformRenderInterface.cs b/src/Headless/Avalonia.Headless/HeadlessPlatformRenderInterface.cs index 86be80b3e7..ab157f8062 100644 --- a/src/Headless/Avalonia.Headless/HeadlessPlatformRenderInterface.cs +++ b/src/Headless/Avalonia.Headless/HeadlessPlatformRenderInterface.cs @@ -129,18 +129,30 @@ namespace Avalonia.Headless Point baselineOrigin, Rect bounds) { - return new HeadlessGlyphRunStub(); + return new HeadlessGlyphRunStub(glyphTypeface, fontRenderingEmSize, baselineOrigin, bounds); } - private class HeadlessGlyphRunStub : IGlyphRunImpl + internal class HeadlessGlyphRunStub : IGlyphRunImpl { - public Rect Bounds => new Rect(new Size(8, 12)); + public HeadlessGlyphRunStub( + IGlyphTypeface glyphTypeface, + double fontRenderingEmSize, + Point baselineOrigin, + Rect bounds) + { + GlyphTypeface = glyphTypeface; + FontRenderingEmSize = fontRenderingEmSize; + BaselineOrigin = baselineOrigin; + Bounds =bounds; + } - public Point BaselineOrigin => new Point(0, 8); + public Rect Bounds { get; } - public IGlyphTypeface GlyphTypeface => new HeadlessGlyphTypefaceImpl(); + public Point BaselineOrigin { get; } - public double FontRenderingEmSize => 12; + public IGlyphTypeface GlyphTypeface { get; } + + public double FontRenderingEmSize { get; } public void Dispose() { @@ -235,8 +247,11 @@ namespace Avalonia.Headless private class HeadlessStreamingGeometryStub : HeadlessGeometryStub, IStreamGeometryImpl { + private HeadlessStreamingGeometryContextStub _context; + public HeadlessStreamingGeometryStub() : base(default) { + _context = new HeadlessStreamingGeometryContextStub(this); } public IStreamGeometryImpl Clone() @@ -246,13 +261,18 @@ namespace Avalonia.Headless public IStreamGeometryContextImpl Open() { - return new HeadlessStreamingGeometryContextStub(this); + return _context; + } + + public override bool FillContains(Point point) + { + return _context.FillContains(point); } private class HeadlessStreamingGeometryContextStub : IStreamGeometryContextImpl { private readonly HeadlessStreamingGeometryStub _parent; - private double _x1, _y1, _x2, _y2; + private List points = new List(); public HeadlessStreamingGeometryContextStub(HeadlessStreamingGeometryStub parent) { _parent = parent; @@ -260,19 +280,30 @@ namespace Avalonia.Headless private void Track(Point pt) { - if (_x1 > pt.X) - _x1 = pt.X; - if (_x2 < pt.X) - _x2 = pt.X; - if (_y1 > pt.Y) - _y1 = pt.Y; - if (_y2 < pt.Y) - _y2 = pt.Y; + points.Add(pt); } + public Rect CalculateBounds() + { + var left = double.MaxValue; + var right = double.MinValue; + var top = double.MaxValue; + var bottom = double.MinValue; + + foreach (var p in points) + { + left = Math.Min(p.X, left); + right = Math.Max(p.X, right); + top = Math.Min(p.Y, top); + bottom = Math.Max(p.Y, bottom); + } + + return new Rect(new Point(left, top), new Point(right, bottom)); + } + public void Dispose() { - _parent.Bounds = new Rect(_x1, _y1, _x2 - _x1, _y2 - _y1); + _parent.Bounds = CalculateBounds(); } public void ArcTo(Point point, Size size, double rotationAngle, bool isLargeArc, SweepDirection sweepDirection) @@ -304,6 +335,35 @@ namespace Avalonia.Headless { } + + public bool FillContains(Point point) + { + // Use the algorithm from https://www.blackpawn.com/texts/pointinpoly/default.html + // to determine if the point is in the geometry (since it will always be convex in this situation) + for (int i = 0; i < points.Count; i++) + { + var a = points[i]; + var b = points[(i + 1) % points.Count]; + var c = points[(i + 2) % points.Count]; + + Vector v0 = c - a; + Vector v1 = b - a; + Vector v2 = point - a; + + var dot00 = v0 * v0; + var dot01 = v0 * v1; + var dot02 = v0 * v2; + var dot11 = v1 * v1; + var dot12 = v1 * v2; + + + var invDenom = 1 / (dot00 * dot11 - dot01 * dot01); + var u = (dot11 * dot02 - dot01 * dot12) * invDenom; + var v = (dot00 * dot12 - dot01 * dot02) * invDenom; + if ((u >= 0) && (v >= 0) && (u + v < 1)) return true; + } + return false; + } } } @@ -369,7 +429,7 @@ namespace Avalonia.Headless } } - private class HeadlessDrawingContextStub : IDrawingContextImpl + internal class HeadlessDrawingContextStub : IDrawingContextImpl { public void Dispose() { diff --git a/src/Headless/Avalonia.Headless/HeadlessPlatformStubs.cs b/src/Headless/Avalonia.Headless/HeadlessPlatformStubs.cs index 769fea7c6e..471ea9a6d0 100644 --- a/src/Headless/Avalonia.Headless/HeadlessPlatformStubs.cs +++ b/src/Headless/Avalonia.Headless/HeadlessPlatformStubs.cs @@ -1,8 +1,10 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Linq; +using System.Runtime.InteropServices; using System.Threading.Tasks; using Avalonia.Controls; using Avalonia.Controls.Platform; @@ -11,6 +13,7 @@ using Avalonia.Input.Platform; using Avalonia.Media; using Avalonia.Media.Fonts; using Avalonia.Media.TextFormatting; +using Avalonia.Media.TextFormatting.Unicode; using Avalonia.Platform; using Avalonia.Platform.Storage; using Avalonia.Platform.Storage.FileIO; @@ -82,22 +85,22 @@ namespace Avalonia.Headless { public FontMetrics Metrics => new FontMetrics { - DesignEmHeight = 1, - Ascent = 8, - Descent = 4, + DesignEmHeight = 10, + Ascent = 2, + Descent = 10, + IsFixedPitch = true, LineGap = 0, UnderlinePosition = 2, UnderlineThickness = 1, StrikethroughPosition = 2, - StrikethroughThickness = 1, - IsFixedPitch = true + StrikethroughThickness = 1 }; public int GlyphCount => 1337; - public FontSimulations FontSimulations { get; } + public FontSimulations FontSimulations => FontSimulations.None; - public string FamilyName => "Arial"; + public string FamilyName => "$Default"; public FontWeight Weight => FontWeight.Normal; @@ -111,24 +114,31 @@ namespace Avalonia.Headless public ushort GetGlyph(uint codepoint) { - return 1; + return (ushort)codepoint; } public bool TryGetGlyph(uint codepoint, out ushort glyph) { - glyph = 1; + glyph = 8; return true; } public int GetGlyphAdvance(ushort glyph) { - return 12; + return 8; } public int[] GetGlyphAdvances(ReadOnlySpan glyphs) { - return glyphs.ToArray().Select(x => (int)x).ToArray(); + var advances = new int[glyphs.Length]; + + for (var i = 0; i < advances.Length; i++) + { + advances[i] = 8; + } + + return advances; } public ushort[] GetGlyphs(ReadOnlySpan codepoints) @@ -146,8 +156,8 @@ namespace Avalonia.Headless { metrics = new GlyphMetrics { - Height = 10, - Width = 8 + Width = 10, + Height = 10 }; return true; @@ -161,40 +171,81 @@ namespace Avalonia.Headless var typeface = options.Typeface; var fontRenderingEmSize = options.FontRenderingEmSize; var bidiLevel = options.BidiLevel; + var shapedBuffer = new ShapedBuffer(text, text.Length, typeface, fontRenderingEmSize, bidiLevel); + var textSpan = text.Span; + var textStartIndex = TextTestHelper.GetStartCharIndex(text); + + for (var i = 0; i < shapedBuffer.Length;) + { + var glyphCluster = i + textStartIndex; + + var codepoint = Codepoint.ReadAt(textSpan, i, out var count); + + var glyphIndex = typeface.GetGlyph(codepoint); - return new ShapedBuffer(text, text.Length, typeface, fontRenderingEmSize, bidiLevel); + for (var j = 0; j < count; ++j) + { + shapedBuffer[i + j] = new GlyphInfo(glyphIndex, glyphCluster, 10); + } + + i += count; + } + + return shapedBuffer; } } internal class HeadlessFontManagerStub : IFontManagerImpl { + private readonly string _defaultFamilyName; + + public HeadlessFontManagerStub(string defaultFamilyName = "Default") + { + _defaultFamilyName = defaultFamilyName; + } + + public int TryCreateGlyphTypefaceCount { get; private set; } + public string GetDefaultFontFamilyName() { - return "Arial"; + return _defaultFamilyName; } - public string[] GetInstalledFontFamilyNames(bool checkForUpdates = false) + string[] IFontManagerImpl.GetInstalledFontFamilyNames(bool checkForUpdates) { - return new string[] { "Arial" }; + return new[] { _defaultFamilyName }; } - public bool TryCreateGlyphTypeface(string familyName, FontStyle style, FontWeight weight, FontStretch stretch, out IGlyphTypeface glyphTypeface) + public bool TryMatchCharacter(int codepoint, FontStyle fontStyle, FontWeight fontWeight, + FontStretch fontStretch, + CultureInfo? culture, out Typeface fontKey) { - glyphTypeface= new HeadlessGlyphTypefaceImpl(); + fontKey = new Typeface(_defaultFamilyName); - return true; + return false; } - public bool TryCreateGlyphTypeface(Stream stream, out IGlyphTypeface glyphTypeface) + public virtual bool TryCreateGlyphTypeface(string familyName, FontStyle style, FontWeight weight, + FontStretch stretch, [NotNullWhen(true)] out IGlyphTypeface? glyphTypeface) { - glyphTypeface = new HeadlessGlyphTypefaceImpl(); + glyphTypeface = null; + + TryCreateGlyphTypefaceCount++; + + if (familyName == "Unknown") + { + return false; + } + + glyphTypeface = new HeadlessGlyphTypefaceImpl(); return true; } - public bool TryMatchCharacter(int codepoint, FontStyle fontStyle, FontWeight fontWeight, FontStretch fontStretch, CultureInfo? culture, out Typeface typeface) + public virtual bool TryCreateGlyphTypeface(Stream stream, out IGlyphTypeface glyphTypeface) { - typeface = new Typeface("Arial", fontStyle, fontWeight, fontStretch); + glyphTypeface = new HeadlessGlyphTypefaceImpl(); + return true; } } @@ -249,4 +300,14 @@ namespace Avalonia.Headless return ScreenHelper.ScreenFromWindow(window, AllScreens); } } + + internal static class TextTestHelper + { + public static int GetStartCharIndex(ReadOnlyMemory text) + { + if (!MemoryMarshal.TryGetString(text, out _, out var start, out _)) + throw new InvalidOperationException("text memory should have been a string"); + return start; + } + } } diff --git a/tests/Avalonia.Base.UnitTests/Media/FontManagerTests.cs b/tests/Avalonia.Base.UnitTests/Media/FontManagerTests.cs index 3ccec872d2..adb5431ce6 100644 --- a/tests/Avalonia.Base.UnitTests/Media/FontManagerTests.cs +++ b/tests/Avalonia.Base.UnitTests/Media/FontManagerTests.cs @@ -1,4 +1,5 @@ using System; +using Avalonia.Headless; using Avalonia.Media; using Avalonia.UnitTests; using Xunit; @@ -27,7 +28,7 @@ namespace Avalonia.Base.UnitTests.Media [Fact] public void Should_Throw_When_Default_FamilyName_Is_Null() { - using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface.With(fontManagerImpl: new MockFontManagerImpl(null)))) + using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface.With(fontManagerImpl: new HeadlessFontManagerStub(null!)))) { Assert.Throws(() => FontManager.Current); } @@ -39,7 +40,7 @@ namespace Avalonia.Base.UnitTests.Media var options = new FontManagerOptions { DefaultFamilyName = "MyFont" }; using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface - .With(fontManagerImpl: new MockFontManagerImpl()))) + .With(fontManagerImpl: new HeadlessFontManagerStub()))) { AvaloniaLocator.CurrentMutable.Bind().ToConstant(options); @@ -62,7 +63,7 @@ namespace Avalonia.Base.UnitTests.Media }; using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface - .With(fontManagerImpl: new MockFontManagerImpl()))) + .With(fontManagerImpl: new HeadlessFontManagerStub()))) { AvaloniaLocator.CurrentMutable.Bind().ToConstant(options); diff --git a/tests/Avalonia.Base.UnitTests/Media/GlyphRunTests.cs b/tests/Avalonia.Base.UnitTests/Media/GlyphRunTests.cs index 84ce341e98..c273cc6489 100644 --- a/tests/Avalonia.Base.UnitTests/Media/GlyphRunTests.cs +++ b/tests/Avalonia.Base.UnitTests/Media/GlyphRunTests.cs @@ -1,4 +1,5 @@ using System; +using Avalonia.Headless; using Avalonia.Media; using Avalonia.Media.TextFormatting; using Avalonia.UnitTests; @@ -179,13 +180,13 @@ namespace Avalonia.Base.UnitTests.Media glyphInfos[i] = new GlyphInfo(0, glyphClusters[i], glyphAdvances[i]); } - return new GlyphRun(new MockGlyphTypeface(), 10, new string('a', count).AsMemory(), glyphInfos, biDiLevel: bidiLevel); + return new GlyphRun(new HeadlessGlyphTypefaceImpl(), 10, new string('a', count).AsMemory(), glyphInfos, biDiLevel: bidiLevel); } private static IDisposable Start() { return UnitTestApplication.Start(TestServices.StyledWindow.With( - renderInterface: new MockPlatformRenderInterface())); + renderInterface: new HeadlessPlatformRenderInterface())); } } } diff --git a/tests/Avalonia.Base.UnitTests/Rendering/CompositorHitTestingTests.cs b/tests/Avalonia.Base.UnitTests/Rendering/CompositorHitTestingTests.cs index 27bb0355e6..7cd02d2907 100644 --- a/tests/Avalonia.Base.UnitTests/Rendering/CompositorHitTestingTests.cs +++ b/tests/Avalonia.Base.UnitTests/Rendering/CompositorHitTestingTests.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using Avalonia.Base.UnitTests.VisualTree; using Avalonia.Controls; using Avalonia.Controls.Presenters; using Avalonia.Controls.Shapes; diff --git a/tests/Avalonia.Base.UnitTests/VisualTree/MockRenderInterface.cs b/tests/Avalonia.Base.UnitTests/VisualTree/MockRenderInterface.cs deleted file mode 100644 index 37adb03628..0000000000 --- a/tests/Avalonia.Base.UnitTests/VisualTree/MockRenderInterface.cs +++ /dev/null @@ -1,285 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using Avalonia.Media; -using Avalonia.Platform; -using Avalonia.UnitTests; -using Avalonia.Media.Imaging; -using Avalonia.Media.TextFormatting; - -namespace Avalonia.Base.UnitTests.VisualTree -{ - class MockRenderInterface : IPlatformRenderInterface, IPlatformRenderInterfaceContext - { - public IRenderTarget CreateRenderTarget(IEnumerable surfaces) - { - throw new NotImplementedException(); - } - - public bool IsLost => false; - - public object TryGetFeature(Type featureType) => null; - - public IRenderTargetBitmapImpl CreateRenderTargetBitmap(PixelSize size, Vector dpi) - { - throw new NotImplementedException(); - } - - public IStreamGeometryImpl CreateStreamGeometry() - { - return new MockStreamGeometry(); - } - - public IGeometryImpl CreateGeometryGroup(FillRule fillRule, IReadOnlyList children) - { - throw new NotImplementedException(); - } - - public IGeometryImpl CreateCombinedGeometry(GeometryCombineMode combineMode, IGeometryImpl g1, IGeometryImpl g2) - { - throw new NotImplementedException(); - } - - public IBitmapImpl LoadBitmap(Stream stream) - { - throw new NotImplementedException(); - } - - public IWriteableBitmapImpl LoadWriteableBitmapToWidth(Stream stream, int width, - BitmapInterpolationMode interpolationMode = BitmapInterpolationMode.HighQuality) - { - throw new NotImplementedException(); - } - - public IWriteableBitmapImpl LoadWriteableBitmapToHeight(Stream stream, int height, - BitmapInterpolationMode interpolationMode = BitmapInterpolationMode.HighQuality) - { - throw new NotImplementedException(); - } - - public IWriteableBitmapImpl LoadWriteableBitmap(string fileName) - { - throw new NotImplementedException(); - } - - public IWriteableBitmapImpl LoadWriteableBitmap(Stream stream) - { - throw new NotImplementedException(); - } - - public IBitmapImpl LoadBitmap(string fileName) - { - throw new NotImplementedException(); - } - - public IBitmapImpl LoadBitmap(PixelFormat format, AlphaFormat alphaFormat, IntPtr data, PixelSize size, Vector dpi, int stride) - { - throw new NotImplementedException(); - } - - public IGlyphRunImpl CreateGlyphRun(IGlyphTypeface glyphTypeface, double fontRenderingEmSize, - IReadOnlyList glyphInfos, Point baselineOrigin, Rect bounds) - { - throw new NotImplementedException(); - } - - public IPlatformRenderInterfaceContext CreateBackendContext(IPlatformGraphicsContext graphicsContext) - { - return this; - } - - public bool SupportsIndividualRoundRects { get; set; } - public AlphaFormat DefaultAlphaFormat { get; } - public PixelFormat DefaultPixelFormat { get; } - public bool IsSupportedBitmapPixelFormat(PixelFormat format) => true; - - public IFontManagerImpl CreateFontManager() - { - return new MockFontManagerImpl(); - } - - public IWriteableBitmapImpl CreateWriteableBitmap(PixelSize size, Vector dpi, PixelFormat fmt, AlphaFormat alphaFormat) - { - throw new NotImplementedException(); - } - - public IGeometryImpl CreateEllipseGeometry(Rect rect) - { - throw new NotImplementedException(); - } - - public IGeometryImpl CreateLineGeometry(Point p1, Point p2) - { - throw new NotImplementedException(); - } - - public IGeometryImpl CreateRectangleGeometry(Rect rect) - { - throw new NotImplementedException(); - } - - public IBitmapImpl LoadBitmapToWidth(Stream stream, int width, BitmapInterpolationMode interpolationMode = BitmapInterpolationMode.HighQuality) - { - throw new NotImplementedException(); - } - - public IBitmapImpl LoadBitmapToHeight(Stream stream, int height, BitmapInterpolationMode interpolationMode = BitmapInterpolationMode.HighQuality) - { - throw new NotImplementedException(); - } - - public IBitmapImpl ResizeBitmap(IBitmapImpl bitmapImpl, PixelSize destinationSize, BitmapInterpolationMode interpolationMode = BitmapInterpolationMode.HighQuality) - { - throw new NotImplementedException(); - } - - public IGeometryImpl BuildGlyphRunGeometry(GlyphRun glyphRun) - { - throw new NotImplementedException(); - } - - class MockStreamGeometry : IStreamGeometryImpl - { - private MockStreamGeometryContext _impl = new MockStreamGeometryContext(); - public Rect Bounds - { - get - { - throw new NotImplementedException(); - } - } - - public double ContourLength { get; } - - public IStreamGeometryImpl Clone() - { - return this; - } - - public void Dispose() - { - } - - public bool FillContains(Point point) - { - return _impl.FillContains(point); - } - - public Rect GetRenderBounds(IPen pen) - { - throw new NotImplementedException(); - } - - public IGeometryImpl Intersect(IGeometryImpl geometry) - { - throw new NotImplementedException(); - } - - public IStreamGeometryContextImpl Open() - { - return _impl; - } - - public bool StrokeContains(IPen pen, Point point) - { - throw new NotImplementedException(); - } - - public ITransformedGeometryImpl WithTransform(Matrix transform) - { - throw new NotImplementedException(); - } - - public bool TryGetPointAtDistance(double distance, out Point point) - { - throw new NotImplementedException(); - } - - public bool TryGetPointAndTangentAtDistance(double distance, out Point point, out Point tangent) - { - throw new NotImplementedException(); - } - - public bool TryGetSegment(double startDistance, double stopDistance, bool startOnBeginFigure, out IGeometryImpl segmentGeometry) - { - throw new NotImplementedException(); - } - - class MockStreamGeometryContext : IStreamGeometryContextImpl - { - private List points = new List(); - public void ArcTo(Point point, Size size, double rotationAngle, bool isLargeArc, SweepDirection sweepDirection) - { - throw new NotImplementedException(); - } - - public void BeginFigure(Point startPoint, bool isFilled) - { - points.Add(startPoint); - } - - public void CubicBezierTo(Point point1, Point point2, Point point3) - { - throw new NotImplementedException(); - } - - public void Dispose() - { - } - - public void EndFigure(bool isClosed) - { - } - - public void LineTo(Point point) - { - points.Add(point); - } - - public void QuadraticBezierTo(Point control, Point endPoint) - { - throw new NotImplementedException(); - } - - public void SetFillRule(FillRule fillRule) - { - } - - public bool FillContains(Point point) - { - // Use the algorithm from https://www.blackpawn.com/texts/pointinpoly/default.html - // to determine if the point is in the geometry (since it will always be convex in this situation) - for (int i = 0; i < points.Count; i++) - { - var a = points[i]; - var b = points[(i + 1) % points.Count]; - var c = points[(i + 2) % points.Count]; - - Vector v0 = c - a; - Vector v1 = b - a; - Vector v2 = point - a; - - var dot00 = v0 * v0; - var dot01 = v0 * v1; - var dot02 = v0 * v2; - var dot11 = v1 * v1; - var dot12 = v1 * v2; - - - var invDenom = 1 / (dot00 * dot11 - dot01 * dot01); - var u = (dot11 * dot02 - dot01 * dot12) * invDenom; - var v = (dot00 * dot12 - dot01 * dot02) * invDenom; - if ((u >= 0) && (v >= 0) && (u + v < 1)) return true; - } - return false; - } - } - } - - public void Dispose() - { - - } - } - -} diff --git a/tests/Avalonia.Benchmarks/Layout/ControlsBenchmark.cs b/tests/Avalonia.Benchmarks/Layout/ControlsBenchmark.cs index 5df1dd1679..4202e60fd6 100644 --- a/tests/Avalonia.Benchmarks/Layout/ControlsBenchmark.cs +++ b/tests/Avalonia.Benchmarks/Layout/ControlsBenchmark.cs @@ -1,6 +1,7 @@ using System; using System.Runtime.CompilerServices; using Avalonia.Controls; +using Avalonia.Headless; using Avalonia.Threading; using Avalonia.UnitTests; using BenchmarkDotNet.Attributes; @@ -15,11 +16,7 @@ namespace Avalonia.Benchmarks.Layout public ControlsBenchmark() { - _app = UnitTestApplication.Start( - TestServices.StyledWindow.With( - renderInterface: new NullRenderingPlatform(), - dispatcherImpl: new NullThreadingPlatform(), - standardCursorFactory: new NullCursorFactory())); + _app = UnitTestApplication.Start(TestServices.StyledWindow); _root = new TestRoot(true, null) { diff --git a/tests/Avalonia.Benchmarks/NullCursorFactory.cs b/tests/Avalonia.Benchmarks/NullCursorFactory.cs deleted file mode 100644 index 9aeb353151..0000000000 --- a/tests/Avalonia.Benchmarks/NullCursorFactory.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using Avalonia.Input; -using Avalonia.Platform; - -namespace Avalonia.Benchmarks -{ - internal class NullCursorFactory : ICursorFactory - { - public ICursorImpl CreateCursor(IBitmapImpl cursor, PixelPoint hotSpot) => new NullCursorImpl(); - ICursorImpl ICursorFactory.GetCursor(StandardCursorType cursorType) => new NullCursorImpl(); - - private class NullCursorImpl : ICursorImpl - { - public void Dispose() { } - } - } -} diff --git a/tests/Avalonia.Benchmarks/NullDrawingContextImpl.cs b/tests/Avalonia.Benchmarks/NullDrawingContextImpl.cs deleted file mode 100644 index 3513843367..0000000000 --- a/tests/Avalonia.Benchmarks/NullDrawingContextImpl.cs +++ /dev/null @@ -1,107 +0,0 @@ -using System; -using Avalonia.Media; -using Avalonia.Platform; -using Avalonia.Rendering.SceneGraph; -using Avalonia.Utilities; -using Avalonia.Media.Imaging; - -namespace Avalonia.Benchmarks -{ - internal class NullDrawingContextImpl : IDrawingContextImpl - { - public void Dispose() - { - } - - public Matrix Transform { get; set; } - - public RenderOptions RenderOptions { get; set; } - - public void Clear(Color color) - { - } - - public void DrawBitmap(IRef source, double opacity, Rect sourceRect, Rect destRect) - { - } - - public void DrawBitmap(IRef source, IBrush opacityMask, Rect opacityMaskRect, Rect destRect) - { - } - - public void DrawLine(IPen pen, Point p1, Point p2) - { - } - - public void DrawGeometry(IBrush brush, IPen pen, IGeometryImpl geometry) - { - } - - public void DrawRectangle(IBrush brush, IPen pen, RoundedRect rect, BoxShadows boxShadows = default) - { - } - - public void DrawEllipse(IBrush brush, IPen pen, Rect rect) - { - } - - public void DrawGlyphRun(IBrush foreground, IRef glyphRun) - { - } - - public IDrawingContextLayerImpl CreateLayer(Size size) - { - return null; - } - - public void PushClip(Rect clip) - { - } - - public void PushClip(RoundedRect clip) - { - } - - public void PopClip() - { - } - - public void PushOpacity(double opacity, Rect bounds) - { - } - - public void PopOpacity() - { - } - - public void PushOpacityMask(IBrush mask, Rect bounds) - { - } - - public void PopOpacityMask() - { - } - - public void PushGeometryClip(IGeometryImpl clip) - { - } - - public void PopGeometryClip() - { - } - - public void PushBitmapBlendMode(BitmapBlendingMode blendingMode) - { - } - - public void PopBitmapBlendMode() - { - } - - public void Custom(ICustomDrawOperation custom) - { - } - - public object GetFeature(Type t) => null; - } -} diff --git a/tests/Avalonia.Benchmarks/NullRenderingPlatform.cs b/tests/Avalonia.Benchmarks/NullRenderingPlatform.cs deleted file mode 100644 index 55cd9e8d4b..0000000000 --- a/tests/Avalonia.Benchmarks/NullRenderingPlatform.cs +++ /dev/null @@ -1,149 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using Avalonia.Media; -using Avalonia.Platform; -using Avalonia.UnitTests; -using Avalonia.Media.Imaging; -using Avalonia.Media.TextFormatting; -using Microsoft.Diagnostics.Runtime; - -namespace Avalonia.Benchmarks -{ - internal class NullRenderingPlatform : IPlatformRenderInterface, IPlatformRenderInterfaceContext - { - public IGeometryImpl CreateEllipseGeometry(Rect rect) - { - return new MockStreamGeometryImpl(); - } - - public IGeometryImpl CreateLineGeometry(Point p1, Point p2) - { - return new MockStreamGeometryImpl(); - } - - public IGeometryImpl CreateRectangleGeometry(Rect rect) - { - return new MockStreamGeometryImpl(); - } - - public IStreamGeometryImpl CreateStreamGeometry() - { - return new MockStreamGeometryImpl(); - } - - public IGeometryImpl CreateGeometryGroup(FillRule fillRule, IReadOnlyList children) - { - throw new NotImplementedException(); - } - - public IGeometryImpl CreateCombinedGeometry(GeometryCombineMode combineMode, IGeometryImpl g1, IGeometryImpl g2) - { - throw new NotImplementedException(); - } - - public IRenderTarget CreateRenderTarget(IEnumerable surfaces) - { - throw new NotImplementedException(); - } - - public bool IsLost => false; - - public object TryGetFeature(Type featureType) => null; - - public IRenderTargetBitmapImpl CreateRenderTargetBitmap(PixelSize size, Vector dpi) - { - throw new NotImplementedException(); - } - - public IWriteableBitmapImpl CreateWriteableBitmap(PixelSize size, Vector dpi, PixelFormat format, AlphaFormat alphaFormat) - { - throw new NotImplementedException(); - } - - public IBitmapImpl LoadBitmap(string fileName) - { - throw new NotImplementedException(); - } - - public IBitmapImpl LoadBitmap(Stream stream) - { - throw new NotImplementedException(); - } - - public IWriteableBitmapImpl LoadWriteableBitmapToWidth(Stream stream, int width, - BitmapInterpolationMode interpolationMode = BitmapInterpolationMode.HighQuality) - { - throw new NotImplementedException(); - } - - public IWriteableBitmapImpl LoadWriteableBitmapToHeight(Stream stream, int height, - BitmapInterpolationMode interpolationMode = BitmapInterpolationMode.HighQuality) - { - throw new NotImplementedException(); - } - - public IWriteableBitmapImpl LoadWriteableBitmap(string fileName) - { - throw new NotImplementedException(); - } - - public IWriteableBitmapImpl LoadWriteableBitmap(Stream stream) - { - throw new NotImplementedException(); - } - - public IBitmapImpl LoadBitmap(PixelFormat format, AlphaFormat alphaFormat, IntPtr data, PixelSize size, Vector dpi, int stride) - { - throw new NotImplementedException(); - } - - public IBitmapImpl LoadBitmapToWidth(Stream stream, int width, BitmapInterpolationMode interpolationMode = BitmapInterpolationMode.HighQuality) - { - throw new NotImplementedException(); - } - - public IBitmapImpl LoadBitmapToHeight(Stream stream, int height, BitmapInterpolationMode interpolationMode = BitmapInterpolationMode.HighQuality) - { - throw new NotImplementedException(); - } - - public IBitmapImpl ResizeBitmap(IBitmapImpl bitmapImpl, PixelSize destinationSize, BitmapInterpolationMode interpolationMode = BitmapInterpolationMode.HighQuality) - { - throw new NotImplementedException(); - } - - public IFontManagerImpl CreateFontManager() - { - return new MockFontManagerImpl(); - } - - public IGeometryImpl BuildGlyphRunGeometry(GlyphRun glyphRun) - { - return new MockStreamGeometryImpl(); - } - - public IGlyphRunImpl CreateGlyphRun(IGlyphTypeface glyphTypeface, double fontRenderingEmSize, - IReadOnlyList glyphInfos, Point baselineOrigin, Rect bounds) - { - return new MockGlyphRun(glyphTypeface, fontRenderingEmSize, baselineOrigin, bounds); - } - - public IPlatformRenderInterfaceContext CreateBackendContext(IPlatformGraphicsContext graphicsContext) - { - return this; - } - - public bool SupportsIndividualRoundRects => true; - - public AlphaFormat DefaultAlphaFormat => AlphaFormat.Premul; - - public PixelFormat DefaultPixelFormat => PixelFormat.Rgba8888; - public bool IsSupportedBitmapPixelFormat(PixelFormat format) => true; - - public void Dispose() - { - - } - } -} diff --git a/tests/Avalonia.Benchmarks/NullThreadingPlatform.cs b/tests/Avalonia.Benchmarks/NullThreadingPlatform.cs deleted file mode 100644 index 1b5b60031c..0000000000 --- a/tests/Avalonia.Benchmarks/NullThreadingPlatform.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using System.Reactive.Disposables; -using System.Threading; -using Avalonia.Platform; -using Avalonia.Threading; - -namespace Avalonia.Benchmarks -{ - internal class NullThreadingPlatform : IDispatcherImpl - { - public void Signal() - { - } - - public void UpdateTimer(long? dueTimeInMs) - { - } - - public bool CurrentThreadIsLoopThread => true; - -#pragma warning disable CS0067 - public event Action Signaled; - public event Action Timer; - public long Now => 0; -#pragma warning restore CS0067 - } -} diff --git a/tests/Avalonia.Benchmarks/Rendering/ShapeRendering.cs b/tests/Avalonia.Benchmarks/Rendering/ShapeRendering.cs index 2905b1e464..ba217017d1 100644 --- a/tests/Avalonia.Benchmarks/Rendering/ShapeRendering.cs +++ b/tests/Avalonia.Benchmarks/Rendering/ShapeRendering.cs @@ -1,4 +1,5 @@ using Avalonia.Controls.Shapes; +using Avalonia.Headless; using Avalonia.Media; using Avalonia.Platform; using BenchmarkDotNet.Attributes; @@ -21,9 +22,9 @@ namespace Avalonia.Benchmarks.Rendering _lineFill = new Line { Fill = new SolidColorBrush() }; _lineFillAndStroke = new Line { Stroke = new SolidColorBrush(), Fill = new SolidColorBrush() }; - _drawingContext = new PlatformDrawingContext(new NullDrawingContextImpl(), true); + _drawingContext = new PlatformDrawingContext(new HeadlessPlatformRenderInterface.HeadlessDrawingContextStub(), true); - AvaloniaLocator.CurrentMutable.Bind().ToConstant(new NullRenderingPlatform()); + AvaloniaLocator.CurrentMutable.Bind().ToConstant(new HeadlessPlatformRenderInterface()); } [Benchmark] diff --git a/tests/Avalonia.Benchmarks/Styling/ControlTheme_Change.cs b/tests/Avalonia.Benchmarks/Styling/ControlTheme_Change.cs index 00080e3b82..9e79b25488 100644 --- a/tests/Avalonia.Benchmarks/Styling/ControlTheme_Change.cs +++ b/tests/Avalonia.Benchmarks/Styling/ControlTheme_Change.cs @@ -20,10 +20,7 @@ namespace Avalonia.Benchmarks.Styling public ControlTheme_Change() { - _app = UnitTestApplication.Start( - TestServices.StyledWindow.With( - renderInterface: new NullRenderingPlatform(), - dispatcherImpl: new NullThreadingPlatform())); + _app = UnitTestApplication.Start(TestServices.StyledWindow); // Simulate an application with a lot of styles by creating a tree of nested panels, // each with a bunch of styles applied. diff --git a/tests/Avalonia.Benchmarks/Styling/ResourceBenchmarks.cs b/tests/Avalonia.Benchmarks/Styling/ResourceBenchmarks.cs index a32f98e462..ebd8a6474a 100644 --- a/tests/Avalonia.Benchmarks/Styling/ResourceBenchmarks.cs +++ b/tests/Avalonia.Benchmarks/Styling/ResourceBenchmarks.cs @@ -1,5 +1,6 @@ using System; using Avalonia.Controls; +using Avalonia.Headless; using Avalonia.Platform; using Avalonia.Styling; using Avalonia.UnitTests; @@ -20,12 +21,8 @@ namespace Avalonia.Benchmarks.Styling assetLoader: new StandardAssetLoader(), globalClock: new MockGlobalClock(), platform: new AppBuilder().RuntimePlatform, - renderInterface: new MockPlatformRenderInterface(), standardCursorFactory: Mock.Of(), theme: () => CreateTheme(), - dispatcherImpl: new NullThreadingPlatform(), - fontManagerImpl: new MockFontManagerImpl(), - textShaperImpl: new MockTextShaperImpl(), windowingPlatform: new MockWindowingPlatform()); return UnitTestApplication.Start(services); diff --git a/tests/Avalonia.Benchmarks/Styling/Style_Apply_Detach_Complex.cs b/tests/Avalonia.Benchmarks/Styling/Style_Apply_Detach_Complex.cs index 307f15a6c0..03f3f47276 100644 --- a/tests/Avalonia.Benchmarks/Styling/Style_Apply_Detach_Complex.cs +++ b/tests/Avalonia.Benchmarks/Styling/Style_Apply_Detach_Complex.cs @@ -17,10 +17,7 @@ namespace Avalonia.Benchmarks.Styling public Style_Apply_Detach_Complex() { - _app = UnitTestApplication.Start( - TestServices.StyledWindow.With( - renderInterface: new NullRenderingPlatform(), - dispatcherImpl: new NullThreadingPlatform())); + _app = UnitTestApplication.Start(TestServices.StyledWindow); // Simulate an application with a lot of styles by creating a tree of nested panels, // each with a bunch of styles applied. diff --git a/tests/Avalonia.Benchmarks/Text/HugeTextLayout.cs b/tests/Avalonia.Benchmarks/Text/HugeTextLayout.cs index 22ca9d8c6d..bc90abad7e 100644 --- a/tests/Avalonia.Benchmarks/Text/HugeTextLayout.cs +++ b/tests/Avalonia.Benchmarks/Text/HugeTextLayout.cs @@ -30,10 +30,7 @@ public class HugeTextLayout : IDisposable { _manySmallStrings = Enumerable.Range(0, 1000).Select(_ => RandomString(s_rand.Next(2, 15))).ToArray(); - var testServices = TestServices.StyledWindow.With( - renderInterface: new NullRenderingPlatform(), - dispatcherImpl: new NullThreadingPlatform(), - standardCursorFactory: new NullCursorFactory()); + var testServices = TestServices.StyledWindow; if (s_useSkia) { diff --git a/tests/Avalonia.Benchmarks/Themes/FluentBenchmark.cs b/tests/Avalonia.Benchmarks/Themes/FluentBenchmark.cs index 8eadb3a3f0..9ec3cb9b9a 100644 --- a/tests/Avalonia.Benchmarks/Themes/FluentBenchmark.cs +++ b/tests/Avalonia.Benchmarks/Themes/FluentBenchmark.cs @@ -45,9 +45,6 @@ namespace Avalonia.Benchmarks.Themes private static IDisposable CreateApp() { var services = new TestServices( - renderInterface: new NullRenderingPlatform(), - dispatcherImpl: new NullThreadingPlatform(), - standardCursorFactory: new NullCursorFactory(), theme: () => LoadFluentTheme()); return UnitTestApplication.Start(services); diff --git a/tests/Avalonia.Controls.UnitTests/DatePickerTests.cs b/tests/Avalonia.Controls.UnitTests/DatePickerTests.cs index 3b2ca51976..6c9aefc5a7 100644 --- a/tests/Avalonia.Controls.UnitTests/DatePickerTests.cs +++ b/tests/Avalonia.Controls.UnitTests/DatePickerTests.cs @@ -2,6 +2,7 @@ using System.Linq; using Avalonia.Controls.Shapes; using Avalonia.Controls.Templates; +using Avalonia.Headless; using Avalonia.Platform; using Avalonia.UnitTests; using Avalonia.VisualTree; @@ -203,10 +204,10 @@ namespace Avalonia.Controls.UnitTests } private static TestServices Services => TestServices.MockThreadingInterface.With( - fontManagerImpl: new MockFontManagerImpl(), + fontManagerImpl: new HeadlessFontManagerStub(), standardCursorFactory: Mock.Of(), - textShaperImpl: new MockTextShaperImpl(), - renderInterface: new MockPlatformRenderInterface()); + textShaperImpl: new HeadlessTextShaperStub(), + renderInterface: new HeadlessPlatformRenderInterface()); private static IControlTemplate CreateTemplate() { diff --git a/tests/Avalonia.Controls.UnitTests/ItemsControlTests.cs b/tests/Avalonia.Controls.UnitTests/ItemsControlTests.cs index dec295169f..3d4852c4ff 100644 --- a/tests/Avalonia.Controls.UnitTests/ItemsControlTests.cs +++ b/tests/Avalonia.Controls.UnitTests/ItemsControlTests.cs @@ -9,6 +9,7 @@ using Avalonia.Controls.Presenters; using Avalonia.Controls.Primitives; using Avalonia.Controls.Templates; using Avalonia.Data; +using Avalonia.Headless; using Avalonia.Input; using Avalonia.Layout; using Avalonia.LogicalTree; @@ -1022,12 +1023,12 @@ namespace Avalonia.Controls.UnitTests return UnitTestApplication.Start( TestServices.MockThreadingInterface.With( focusManager: new FocusManager(), - fontManagerImpl: new MockFontManagerImpl(), + fontManagerImpl: new HeadlessFontManagerStub(), keyboardDevice: () => new KeyboardDevice(), keyboardNavigation: new KeyboardNavigationHandler(), inputManager: new InputManager(), - renderInterface: new MockPlatformRenderInterface(), - textShaperImpl: new MockTextShaperImpl())); + renderInterface: new HeadlessPlatformRenderInterface(), + textShaperImpl: new HeadlessTextShaperStub())); } private class ItemsControlWithContainer : ItemsControl, IStyleable diff --git a/tests/Avalonia.Controls.UnitTests/MaskedTextBoxTests.cs b/tests/Avalonia.Controls.UnitTests/MaskedTextBoxTests.cs index 1d1065501f..04acd1c36d 100644 --- a/tests/Avalonia.Controls.UnitTests/MaskedTextBoxTests.cs +++ b/tests/Avalonia.Controls.UnitTests/MaskedTextBoxTests.cs @@ -7,6 +7,7 @@ using Avalonia.Controls.Presenters; using Avalonia.Controls.Primitives; using Avalonia.Controls.Templates; using Avalonia.Data; +using Avalonia.Headless; using Avalonia.Input; using Avalonia.Input.Platform; using Avalonia.Layout; @@ -891,16 +892,16 @@ namespace Avalonia.Controls.UnitTests keyboardDevice: () => new KeyboardDevice(), keyboardNavigation: new KeyboardNavigationHandler(), inputManager: new InputManager(), - renderInterface: new MockPlatformRenderInterface(), - fontManagerImpl: new MockFontManagerImpl(), - textShaperImpl: new MockTextShaperImpl(), + renderInterface: new HeadlessPlatformRenderInterface(), + fontManagerImpl: new HeadlessFontManagerStub(), + textShaperImpl: new HeadlessTextShaperStub(), standardCursorFactory: Mock.Of()); private static TestServices Services => TestServices.MockThreadingInterface.With( - renderInterface: new MockPlatformRenderInterface(), + renderInterface: new HeadlessPlatformRenderInterface(), standardCursorFactory: Mock.Of(), - textShaperImpl: new MockTextShaperImpl(), - fontManagerImpl: new MockFontManagerImpl()); + textShaperImpl: new HeadlessTextShaperStub(), + fontManagerImpl: new HeadlessFontManagerStub()); private static IControlTemplate CreateTemplate() { diff --git a/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests_Multiple.cs b/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests_Multiple.cs index 4f135d94ee..78ac6bb3e2 100644 --- a/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests_Multiple.cs +++ b/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests_Multiple.cs @@ -10,6 +10,7 @@ using Avalonia.Controls.Primitives; using Avalonia.Controls.Selection; using Avalonia.Controls.Templates; using Avalonia.Data; +using Avalonia.Headless; using Avalonia.Input; using Avalonia.Layout; using Avalonia.Styling; @@ -1347,12 +1348,12 @@ namespace Avalonia.Controls.UnitTests.Primitives return UnitTestApplication.Start( TestServices.MockThreadingInterface.With( focusManager: new FocusManager(), - fontManagerImpl: new MockFontManagerImpl(), + fontManagerImpl: new HeadlessFontManagerStub(), keyboardDevice: () => new KeyboardDevice(), keyboardNavigation: new KeyboardNavigationHandler(), inputManager: new InputManager(), - renderInterface: new MockPlatformRenderInterface(), - textShaperImpl: new MockTextShaperImpl())); + renderInterface: new HeadlessPlatformRenderInterface(), + textShaperImpl: new HeadlessTextShaperStub())); } private class TestSelector : SelectingItemsControl diff --git a/tests/Avalonia.Controls.UnitTests/TextBoxTests.cs b/tests/Avalonia.Controls.UnitTests/TextBoxTests.cs index 9c858a20e1..ca1986d293 100644 --- a/tests/Avalonia.Controls.UnitTests/TextBoxTests.cs +++ b/tests/Avalonia.Controls.UnitTests/TextBoxTests.cs @@ -6,6 +6,7 @@ using Avalonia.Controls.Presenters; using Avalonia.Controls.Primitives; using Avalonia.Controls.Templates; using Avalonia.Data; +using Avalonia.Headless; using Avalonia.Input; using Avalonia.Input.Platform; using Avalonia.Layout; @@ -1103,14 +1104,14 @@ namespace Avalonia.Controls.UnitTests keyboardNavigation: new KeyboardNavigationHandler(), inputManager: new InputManager(), standardCursorFactory: Mock.Of(), - textShaperImpl: new MockTextShaperImpl(), - fontManagerImpl: new MockFontManagerImpl()); + textShaperImpl: new HeadlessTextShaperStub(), + fontManagerImpl: new HeadlessFontManagerStub()); private static TestServices Services => TestServices.MockThreadingInterface.With( standardCursorFactory: Mock.Of(), - renderInterface: new MockPlatformRenderInterface(), - textShaperImpl: new MockTextShaperImpl(), - fontManagerImpl: new MockFontManagerImpl()); + renderInterface: new HeadlessPlatformRenderInterface(), + textShaperImpl: new HeadlessTextShaperStub(), + fontManagerImpl: new HeadlessFontManagerStub()); private IControlTemplate CreateTemplate() { diff --git a/tests/Avalonia.Controls.UnitTests/TextBoxTests_DataValidation.cs b/tests/Avalonia.Controls.UnitTests/TextBoxTests_DataValidation.cs index bb952ca7e0..9a9c4d352e 100644 --- a/tests/Avalonia.Controls.UnitTests/TextBoxTests_DataValidation.cs +++ b/tests/Avalonia.Controls.UnitTests/TextBoxTests_DataValidation.cs @@ -6,6 +6,7 @@ using System.Linq; using Avalonia.Controls.Presenters; using Avalonia.Controls.Templates; using Avalonia.Data; +using Avalonia.Headless; using Avalonia.Markup.Data; using Avalonia.Platform; using Avalonia.UnitTests; @@ -87,8 +88,8 @@ namespace Avalonia.Controls.UnitTests private static TestServices Services => TestServices.MockThreadingInterface.With( standardCursorFactory: Mock.Of(), - textShaperImpl: new MockTextShaperImpl(), - fontManagerImpl: new MockFontManagerImpl()); + textShaperImpl: new HeadlessTextShaperStub(), + fontManagerImpl: new HeadlessFontManagerStub()); private static IControlTemplate CreateTemplate() { diff --git a/tests/Avalonia.Controls.UnitTests/TimePickerTests.cs b/tests/Avalonia.Controls.UnitTests/TimePickerTests.cs index e0bf230d99..1449f3f759 100644 --- a/tests/Avalonia.Controls.UnitTests/TimePickerTests.cs +++ b/tests/Avalonia.Controls.UnitTests/TimePickerTests.cs @@ -2,6 +2,7 @@ using System.Linq; using Avalonia.Controls.Shapes; using Avalonia.Controls.Templates; +using Avalonia.Headless; using Avalonia.Platform; using Avalonia.UnitTests; using Avalonia.VisualTree; @@ -99,10 +100,10 @@ namespace Avalonia.Controls.UnitTests } private static TestServices Services => TestServices.MockThreadingInterface.With( - fontManagerImpl: new MockFontManagerImpl(), + fontManagerImpl: new HeadlessFontManagerStub(), standardCursorFactory: Mock.Of(), - textShaperImpl: new MockTextShaperImpl(), - renderInterface: new MockPlatformRenderInterface()); + textShaperImpl: new HeadlessTextShaperStub(), + renderInterface: new HeadlessPlatformRenderInterface()); private static IControlTemplate CreateTemplate() { diff --git a/tests/Avalonia.Controls.UnitTests/TreeViewTests.cs b/tests/Avalonia.Controls.UnitTests/TreeViewTests.cs index 12792305e2..7d290b1ec0 100644 --- a/tests/Avalonia.Controls.UnitTests/TreeViewTests.cs +++ b/tests/Avalonia.Controls.UnitTests/TreeViewTests.cs @@ -9,6 +9,7 @@ using Avalonia.Controls.Primitives; using Avalonia.Controls.Templates; using Avalonia.Data; using Avalonia.Data.Core; +using Avalonia.Headless; using Avalonia.Input; using Avalonia.Input.Platform; using Avalonia.Layout; @@ -1694,12 +1695,12 @@ namespace Avalonia.Controls.UnitTests return UnitTestApplication.Start( TestServices.MockThreadingInterface.With( focusManager: new FocusManager(), - fontManagerImpl: new MockFontManagerImpl(), + fontManagerImpl: new HeadlessFontManagerStub(), keyboardDevice: () => new KeyboardDevice(), keyboardNavigation: new KeyboardNavigationHandler(), inputManager: new InputManager(), - renderInterface: new MockPlatformRenderInterface(), - textShaperImpl: new MockTextShaperImpl())); + renderInterface: new HeadlessPlatformRenderInterface(), + textShaperImpl: new HeadlessTextShaperStub())); } private class Node : NotifyingBase diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/StyleTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/StyleTests.cs index 062195b003..06589beddf 100644 --- a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/StyleTests.cs +++ b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/StyleTests.cs @@ -402,6 +402,8 @@ namespace Avalonia.Markup.Xaml.UnitTests.Xaml [Fact] public void Style_Can_Use_NthChild_Selector_With_ItemsRepeater() { + GC.KeepAlive(typeof(ItemsRepeater)); + using (UnitTestApplication.Start(TestServices.StyledWindow)) { var xaml = @" diff --git a/tests/Avalonia.Skia.UnitTests/Media/FontManagerTests.cs b/tests/Avalonia.Skia.UnitTests/Media/FontManagerTests.cs index 8ca16bd873..62f1cd2032 100644 --- a/tests/Avalonia.Skia.UnitTests/Media/FontManagerTests.cs +++ b/tests/Avalonia.Skia.UnitTests/Media/FontManagerTests.cs @@ -1,4 +1,5 @@ using System; +using Avalonia.Headless; using Avalonia.Media; using Avalonia.UnitTests; using SkiaSharp; @@ -90,7 +91,7 @@ namespace Avalonia.Skia.UnitTests.Media [Fact] public void Should_Only_Try_To_Create_GlyphTypeface_Once() { - var fontManagerImpl = new MockFontManagerImpl(); + var fontManagerImpl = new HeadlessFontManagerStub(); using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface.With(fontManagerImpl: fontManagerImpl))) { diff --git a/tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextLayoutTests.cs b/tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextLayoutTests.cs index c84fcaaa9a..543dd0805e 100644 --- a/tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextLayoutTests.cs +++ b/tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextLayoutTests.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Runtime.InteropServices; +using Avalonia.Headless; using Avalonia.Media; using Avalonia.Media.TextFormatting; using Avalonia.Media.TextFormatting.Unicode; diff --git a/tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextLineTests.cs b/tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextLineTests.cs index 1a39dd5223..1feaefbcc1 100644 --- a/tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextLineTests.cs +++ b/tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextLineTests.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Runtime.InteropServices; +using Avalonia.Headless; using Avalonia.Media; using Avalonia.Media.TextFormatting; using Avalonia.UnitTests; diff --git a/tests/Avalonia.UnitTests/Avalonia.UnitTests.csproj b/tests/Avalonia.UnitTests/Avalonia.UnitTests.csproj index aec6647226..0d49f78dd9 100644 --- a/tests/Avalonia.UnitTests/Avalonia.UnitTests.csproj +++ b/tests/Avalonia.UnitTests/Avalonia.UnitTests.csproj @@ -10,6 +10,7 @@ + diff --git a/tests/Avalonia.UnitTests/ImmediateDispatcher.cs b/tests/Avalonia.UnitTests/ImmediateDispatcher.cs deleted file mode 100644 index f6f3de3bc6..0000000000 --- a/tests/Avalonia.UnitTests/ImmediateDispatcher.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System; -using System.Threading; -using System.Threading.Tasks; -using Avalonia.Threading; - -namespace Avalonia.UnitTests -{ - /// - /// Immediately invokes dispatched jobs on the current thread. - /// - public class ImmediateDispatcher : IDispatcher - { - /// - public bool CheckAccess() - { - return true; - } - - /// - public void Post(Action action, DispatcherPriority priority) - { - action(); - } - - /// - public void Post(SendOrPostCallback action, object arg, DispatcherPriority priority) - { - action(arg); - } - - /// - public Task InvokeAsync(Action action, DispatcherPriority priority) - { - action(); - return Task.CompletedTask; - } - - /// - public Task InvokeAsync(Func function, DispatcherPriority priority) - { - var result = function(); - return Task.FromResult(result); - } - - /// - public Task InvokeAsync(Func function, DispatcherPriority priority) - { - return function(); - } - - /// - public Task InvokeAsync(Func> function, DispatcherPriority priority) - { - return function(); - } - - /// - public void VerifyAccess() - { - } - } -} diff --git a/tests/Avalonia.UnitTests/MockFontManagerImpl.cs b/tests/Avalonia.UnitTests/MockFontManagerImpl.cs deleted file mode 100644 index 16423884b3..0000000000 --- a/tests/Avalonia.UnitTests/MockFontManagerImpl.cs +++ /dev/null @@ -1,63 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.IO; -using Avalonia.Media; -using Avalonia.Platform; - -namespace Avalonia.UnitTests -{ - public class MockFontManagerImpl : IFontManagerImpl - { - private readonly string _defaultFamilyName; - - public MockFontManagerImpl(string defaultFamilyName = "Default") - { - _defaultFamilyName = defaultFamilyName; - } - - public int TryCreateGlyphTypefaceCount { get; private set; } - - public string GetDefaultFontFamilyName() - { - return _defaultFamilyName; - } - - string[] IFontManagerImpl.GetInstalledFontFamilyNames(bool checkForUpdates) - { - return new[] { _defaultFamilyName }; - } - - public bool TryMatchCharacter(int codepoint, FontStyle fontStyle, FontWeight fontWeight, - FontStretch fontStretch, - CultureInfo culture, out Typeface fontKey) - { - fontKey = new Typeface(_defaultFamilyName); - - return false; - } - - public virtual bool TryCreateGlyphTypeface(string familyName, FontStyle style, FontWeight weight, - FontStretch stretch, [NotNullWhen(true)] out IGlyphTypeface glyphTypeface) - { - glyphTypeface = null; - - TryCreateGlyphTypefaceCount++; - - if (familyName == "Unknown") - { - return false; - } - - glyphTypeface = new MockGlyphTypeface(); - - return true; - } - - public virtual bool TryCreateGlyphTypeface(Stream stream, out IGlyphTypeface glyphTypeface) - { - glyphTypeface = new MockGlyphTypeface(); - - return true; - } - } -} diff --git a/tests/Avalonia.UnitTests/MockGlyphRun.cs b/tests/Avalonia.UnitTests/MockGlyphRun.cs deleted file mode 100644 index 805c0b6a8a..0000000000 --- a/tests/Avalonia.UnitTests/MockGlyphRun.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using System.Collections.Generic; -using Avalonia.Media; -using Avalonia.Platform; - -namespace Avalonia.UnitTests -{ - public class MockGlyphRun : IGlyphRunImpl - { - public MockGlyphRun(IGlyphTypeface glyphTypeface, double fontRenderingEmSize, Point baselineOrigin, Rect bounds) - { - GlyphTypeface = glyphTypeface; - FontRenderingEmSize = fontRenderingEmSize; - BaselineOrigin = baselineOrigin; - Bounds =bounds; - } - - public IGlyphTypeface GlyphTypeface { get; } - - public double FontRenderingEmSize { get; } - - public Point BaselineOrigin { get; } - - public Rect Bounds { get; } - - public void Dispose() - { - - } - - public IReadOnlyList GetIntersections(float lowerLimit, float upperLimit) - => Array.Empty(); - } -} diff --git a/tests/Avalonia.UnitTests/MockGlyphTypeface.cs b/tests/Avalonia.UnitTests/MockGlyphTypeface.cs deleted file mode 100644 index 5fcee7f515..0000000000 --- a/tests/Avalonia.UnitTests/MockGlyphTypeface.cs +++ /dev/null @@ -1,81 +0,0 @@ -using System; -using Avalonia.Media; - -namespace Avalonia.UnitTests -{ - public class MockGlyphTypeface : IGlyphTypeface - { - public FontMetrics Metrics => new FontMetrics - { - DesignEmHeight = 10, - Ascent = 2, - Descent = 10, - IsFixedPitch = true - }; - - public int GlyphCount => 1337; - - public FontSimulations FontSimulations => throw new NotImplementedException(); - - public string FamilyName => "$Default"; - - public FontWeight Weight { get; } - - public FontStyle Style { get; } - - public FontStretch Stretch { get; } - - public ushort GetGlyph(uint codepoint) - { - return (ushort)codepoint; - } - - public ushort[] GetGlyphs(ReadOnlySpan codepoints) - { - return new ushort[codepoints.Length]; - } - - public int GetGlyphAdvance(ushort glyph) - { - return 8; - } - - public bool TryGetGlyph(uint codepoint, out ushort glyph) - { - glyph = 8; - - return true; - } - - public int[] GetGlyphAdvances(ReadOnlySpan glyphs) - { - var advances = new int[glyphs.Length]; - - for (var i = 0; i < advances.Length; i++) - { - advances[i] = 8; - } - - return advances; - } - - public void Dispose() { } - - public bool TryGetTable(uint tag, out byte[] table) - { - table = null; - return false; - } - - public bool TryGetGlyphMetrics(ushort glyph, out GlyphMetrics metrics) - { - metrics = new GlyphMetrics - { - Width = 10, - Height = 10 - }; - - return true; - } - } -} diff --git a/tests/Avalonia.UnitTests/MockPlatformRenderInterface.cs b/tests/Avalonia.UnitTests/MockPlatformRenderInterface.cs deleted file mode 100644 index 8647461c0e..0000000000 --- a/tests/Avalonia.UnitTests/MockPlatformRenderInterface.cs +++ /dev/null @@ -1,174 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using Avalonia.Media; -using Avalonia.Platform; -using Avalonia.Media.Imaging; -using Avalonia.Media.TextFormatting; -using Moq; - -namespace Avalonia.UnitTests -{ - public class MockPlatformRenderInterface : IPlatformRenderInterface, IPlatformRenderInterfaceContext - { - public IGeometryImpl CreateEllipseGeometry(Rect rect) - { - return Mock.Of(); - } - - public IGeometryImpl CreateLineGeometry(Point p1, Point p2) - { - return Mock.Of(); - } - - public IGeometryImpl CreateRectangleGeometry(Rect rect) - { - return Mock.Of(x => x.Bounds == rect); - } - - class MockRenderTarget : IRenderTarget - { - public void Dispose() - { - - } - - public IDrawingContextImpl CreateDrawingContext() - { - var m = new Mock(); - m.Setup(c => c.CreateLayer(It.IsAny())) - .Returns(() => - { - var r = new Mock(); - r.Setup(r => r.CreateDrawingContext()) - .Returns(CreateDrawingContext()); - return r.Object; - } - ); - return m.Object; - - } - - public bool IsCorrupted => false; - } - - public IRenderTarget CreateRenderTarget(IEnumerable surfaces) - { - return new MockRenderTarget(); - } - - public bool IsLost => false; - - public object TryGetFeature(Type featureType) => null; - - public IRenderTargetBitmapImpl CreateRenderTargetBitmap(PixelSize size, Vector dpi) - { - return Mock.Of(); - } - - public IStreamGeometryImpl CreateStreamGeometry() - { - return new MockStreamGeometryImpl(); - } - - public IGeometryImpl CreateGeometryGroup(FillRule fillRule, IReadOnlyList children) - { - return Mock.Of(); - } - - public IGeometryImpl CreateCombinedGeometry(GeometryCombineMode combineMode, IGeometryImpl g1, IGeometryImpl g2) - { - return Mock.Of(); - } - - public IWriteableBitmapImpl CreateWriteableBitmap( - PixelSize size, - Vector dpi, - PixelFormat format, - AlphaFormat alphaFormat) - { - throw new NotImplementedException(); - } - - public IBitmapImpl LoadBitmap(Stream stream) - { - return Mock.Of(); - } - - public IWriteableBitmapImpl LoadWriteableBitmapToWidth(Stream stream, int width, - BitmapInterpolationMode interpolationMode = BitmapInterpolationMode.HighQuality) - { - throw new NotImplementedException(); - } - - public IWriteableBitmapImpl LoadWriteableBitmapToHeight(Stream stream, int height, - BitmapInterpolationMode interpolationMode = BitmapInterpolationMode.HighQuality) - { - throw new NotImplementedException(); - } - - public IWriteableBitmapImpl LoadWriteableBitmap(string fileName) - { - throw new NotImplementedException(); - } - - public IWriteableBitmapImpl LoadWriteableBitmap(Stream stream) - { - throw new NotImplementedException(); - } - - public IBitmapImpl LoadBitmap(string fileName) - { - return Mock.Of(); - } - - public IBitmapImpl LoadBitmapToWidth(Stream stream, int width, BitmapInterpolationMode interpolationMode = BitmapInterpolationMode.HighQuality) - { - return Mock.Of(); - } - - public IBitmapImpl LoadBitmapToHeight(Stream stream, int height, BitmapInterpolationMode interpolationMode = BitmapInterpolationMode.HighQuality) - { - return Mock.Of(); - } - - public IBitmapImpl ResizeBitmap(IBitmapImpl bitmapImpl, PixelSize destinationSize, BitmapInterpolationMode interpolationMode = BitmapInterpolationMode.HighQuality) - { - return Mock.Of(); - } - - public IBitmapImpl LoadBitmap( - PixelFormat format, - AlphaFormat alphaFormat, - IntPtr data, - PixelSize size, - Vector dpi, - int stride) - { - throw new NotImplementedException(); - } - - public IGlyphRunImpl CreateGlyphRun(IGlyphTypeface glyphTypeface, double fontRenderingEmSize, IReadOnlyList glyphInfos, Point baselineOrigin, Rect bounds) - { - return new MockGlyphRun(glyphTypeface, fontRenderingEmSize, baselineOrigin, bounds); - } - - public IPlatformRenderInterfaceContext CreateBackendContext(IPlatformGraphicsContext graphicsContext) => this; - - public IGeometryImpl BuildGlyphRunGeometry(GlyphRun glyphRun) - { - return Mock.Of(); - } - - public bool SupportsIndividualRoundRects { get; set; } - - public AlphaFormat DefaultAlphaFormat => AlphaFormat.Premul; - - public PixelFormat DefaultPixelFormat => PixelFormat.Rgba8888; - public bool IsSupportedBitmapPixelFormat(PixelFormat format) => true; - - public void Dispose() - { - } - } -} diff --git a/tests/Avalonia.UnitTests/MockStreamGeometryImpl.cs b/tests/Avalonia.UnitTests/MockStreamGeometryImpl.cs deleted file mode 100644 index 9d039a386e..0000000000 --- a/tests/Avalonia.UnitTests/MockStreamGeometryImpl.cs +++ /dev/null @@ -1,179 +0,0 @@ -using System; -using System.Collections.Generic; -using Avalonia.Media; -using Avalonia.Platform; - -namespace Avalonia.UnitTests -{ - public class MockStreamGeometryImpl : IStreamGeometryImpl, ITransformedGeometryImpl - { - private MockStreamGeometryContext _context; - - public MockStreamGeometryImpl() - { - Transform = Matrix.Identity; - _context = new MockStreamGeometryContext(); - } - - public MockStreamGeometryImpl(Matrix transform) - { - Transform = transform; - _context = new MockStreamGeometryContext(); - } - - private MockStreamGeometryImpl(Matrix transform, MockStreamGeometryContext context) - { - Transform = transform; - _context = context; - } - - public IGeometryImpl SourceGeometry { get; } - - public Rect Bounds => _context.CalculateBounds(); - - public double ContourLength { get; } - - public Matrix Transform { get; } - - public IStreamGeometryImpl Clone() - { - return this; - } - - public void Dispose() - { - } - - public bool FillContains(Point point) - { - return _context.FillContains(point); - } - - public bool StrokeContains(IPen pen, Point point) - { - return false; - } - - public Rect GetRenderBounds(IPen pen) => Bounds; - - public IGeometryImpl Intersect(IGeometryImpl geometry) - { - return new MockStreamGeometryImpl(Transform); - } - - public IStreamGeometryContextImpl Open() - { - return _context; - } - - public ITransformedGeometryImpl WithTransform(Matrix transform) - { - return new MockStreamGeometryImpl(transform, _context); - } - - public bool TryGetPointAtDistance(double distance, out Point point) - { - point = new Point(); - return false; - } - - public bool TryGetPointAndTangentAtDistance(double distance, out Point point, out Point tangent) - { - point = new Point(); - tangent = new Point(); - return false; - } - - public bool TryGetSegment(double startDistance, double stopDistance, bool startOnBeginFigure, out IGeometryImpl segmentGeometry) - { - segmentGeometry = null; - return false; - } - - class MockStreamGeometryContext : IStreamGeometryContextImpl - { - private List points = new List(); - public void ArcTo(Point point, Size size, double rotationAngle, bool isLargeArc, SweepDirection sweepDirection) - { - } - - public void BeginFigure(Point startPoint, bool isFilled) - { - points.Add(startPoint); - } - - public Rect CalculateBounds() - { - var left = double.MaxValue; - var right = double.MinValue; - var top = double.MaxValue; - var bottom = double.MinValue; - - foreach (var p in points) - { - left = Math.Min(p.X, left); - right = Math.Max(p.X, right); - top = Math.Min(p.Y, top); - bottom = Math.Max(p.Y, bottom); - } - - return new Rect(new Point(left, top), new Point(right, bottom)); - } - - public void CubicBezierTo(Point point1, Point point2, Point point3) - { - } - - public void Dispose() - { - } - - public void EndFigure(bool isClosed) - { - } - - public void LineTo(Point point) - { - points.Add(point); - } - - public void QuadraticBezierTo(Point control, Point endPoint) - { - throw new NotImplementedException(); - } - - public void SetFillRule(FillRule fillRule) - { - } - - public bool FillContains(Point point) - { - // Use the algorithm from https://www.blackpawn.com/texts/pointinpoly/default.html - // to determine if the point is in the geometry (since it will always be convex in this situation) - for (int i = 0; i < points.Count; i++) - { - var a = points[i]; - var b = points[(i + 1) % points.Count]; - var c = points[(i + 2) % points.Count]; - - Vector v0 = c - a; - Vector v1 = b - a; - Vector v2 = point - a; - - var dot00 = v0 * v0; - var dot01 = v0 * v1; - var dot02 = v0 * v2; - var dot11 = v1 * v1; - var dot12 = v1 * v2; - - - var invDenom = 1 / (dot00 * dot11 - dot01 * dot01); - var u = (dot11 * dot02 - dot01 * dot12) * invDenom; - var v = (dot00 * dot12 - dot01 * dot02) * invDenom; - if ((u >= 0) && (v >= 0) && (u + v < 1)) return true; - } - return false; - } - } - } -} diff --git a/tests/Avalonia.UnitTests/MockTextShaperImpl.cs b/tests/Avalonia.UnitTests/MockTextShaperImpl.cs deleted file mode 100644 index b5f4777192..0000000000 --- a/tests/Avalonia.UnitTests/MockTextShaperImpl.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System; -using Avalonia.Media.TextFormatting; -using Avalonia.Media.TextFormatting.Unicode; -using Avalonia.Platform; - -namespace Avalonia.UnitTests -{ - public class MockTextShaperImpl : ITextShaperImpl - { - public ShapedBuffer ShapeText(ReadOnlyMemory text, TextShaperOptions options) - { - var typeface = options.Typeface; - var fontRenderingEmSize = options.FontRenderingEmSize; - var bidiLevel = options.BidiLevel; - var shapedBuffer = new ShapedBuffer(text, text.Length, typeface, fontRenderingEmSize, bidiLevel); - var textSpan = text.Span; - var textStartIndex = TextTestHelper.GetStartCharIndex(text); - - for (var i = 0; i < shapedBuffer.Length;) - { - var glyphCluster = i + textStartIndex; - - var codepoint = Codepoint.ReadAt(textSpan, i, out var count); - - var glyphIndex = typeface.GetGlyph(codepoint); - - for (var j = 0; j < count; ++j) - { - shapedBuffer[i + j] = new GlyphInfo(glyphIndex, glyphCluster, 10); - } - - i += count; - } - - return shapedBuffer; - } - } -} diff --git a/tests/Avalonia.UnitTests/TestServices.cs b/tests/Avalonia.UnitTests/TestServices.cs index 9b95e71d8c..f226a7ef55 100644 --- a/tests/Avalonia.UnitTests/TestServices.cs +++ b/tests/Avalonia.UnitTests/TestServices.cs @@ -13,6 +13,7 @@ using System.Collections.Generic; using Avalonia.Controls; using System.Reflection; using Avalonia.Animation; +using Avalonia.Headless; using Avalonia.Threading; namespace Avalonia.UnitTests @@ -22,25 +23,25 @@ namespace Avalonia.UnitTests public static readonly TestServices StyledWindow = new TestServices( assetLoader: new StandardAssetLoader(), platform: new StandardRuntimePlatform(), - renderInterface: new MockPlatformRenderInterface(), - standardCursorFactory: Mock.Of(), + renderInterface: new HeadlessPlatformRenderInterface(), + standardCursorFactory: new HeadlessCursorFactoryStub(), theme: () => CreateSimpleTheme(), - dispatcherImpl: Mock.Of(x => x.CurrentThreadIsLoopThread == true), - fontManagerImpl: new MockFontManagerImpl(), - textShaperImpl: new MockTextShaperImpl(), + dispatcherImpl: new NullDispatcherImpl(), + fontManagerImpl: new HeadlessFontManagerStub(), + textShaperImpl: new HeadlessTextShaperStub(), windowingPlatform: new MockWindowingPlatform()); public static readonly TestServices MockPlatformRenderInterface = new TestServices( assetLoader: new StandardAssetLoader(), - renderInterface: new MockPlatformRenderInterface(), - fontManagerImpl: new MockFontManagerImpl(), - textShaperImpl: new MockTextShaperImpl()); + renderInterface: new HeadlessPlatformRenderInterface(), + fontManagerImpl: new HeadlessFontManagerStub(), + textShaperImpl: new HeadlessTextShaperStub()); public static readonly TestServices MockPlatformWrapper = new TestServices( platform: Mock.Of()); public static readonly TestServices MockThreadingInterface = new TestServices( - dispatcherImpl: Mock.Of(x => x.CurrentThreadIsLoopThread == true)); + dispatcherImpl: new NullDispatcherImpl()); public static readonly TestServices MockWindowingPlatform = new TestServices( windowingPlatform: new MockWindowingPlatform()); @@ -51,13 +52,13 @@ namespace Avalonia.UnitTests keyboardNavigation: new KeyboardNavigationHandler(), inputManager: new InputManager(), assetLoader: new StandardAssetLoader(), - renderInterface: new MockPlatformRenderInterface(), - fontManagerImpl: new MockFontManagerImpl(), - textShaperImpl: new MockTextShaperImpl()); + renderInterface: new HeadlessPlatformRenderInterface(), + fontManagerImpl: new HeadlessFontManagerStub(), + textShaperImpl: new HeadlessTextShaperStub()); public static readonly TestServices TextServices = new TestServices( assetLoader: new StandardAssetLoader(), - renderInterface: new MockPlatformRenderInterface(), + renderInterface: new HeadlessPlatformRenderInterface(), fontManagerImpl: new HarfBuzzFontManagerImpl(), textShaperImpl: new HarfBuzzTextShaperImpl()); @@ -158,12 +159,5 @@ namespace Avalonia.UnitTests { return new SimpleTheme(); } - - private static IPlatformRenderInterface CreateRenderInterfaceMock() - { - return Mock.Of(x => - x.CreateStreamGeometry() == Mock.Of( - y => y.Open() == Mock.Of())); - } } } diff --git a/tests/Avalonia.UnitTests/TextTestHelper.cs b/tests/Avalonia.UnitTests/TextTestHelper.cs deleted file mode 100644 index b572333027..0000000000 --- a/tests/Avalonia.UnitTests/TextTestHelper.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using System.Runtime.InteropServices; - -namespace Avalonia.UnitTests -{ - public static class TextTestHelper - { - public static int GetStartCharIndex(ReadOnlyMemory text) - { - if (!MemoryMarshal.TryGetString(text, out _, out var start, out _)) - throw new InvalidOperationException("text memory should have been a string"); - return start; - } - } -}