using System.Collections.Generic; using System.Linq; using System.Reflection; using Azimuth; using Glass.UnitTests.Materials; using UnitTestSharp; namespace Glass.UnitTests { public class TextStyleTests : TestFixture { /// /// Lines 4 high. /// public static TextStyle WithFont() => new TextStyle { Font = TextMaterialTests.SharedMonospaceFont }; public class MultilineTests : TestFixture { public void DefaultsToUnlimited() { var style = new TextStyle(); CheckTrue(style.Multiline); CheckNull(style.MaxLines); } public void False_SetsMaxLinesToOne() { CheckEqual(1, new TextStyle { Multiline = false }.MaxLines); } public void True_ClearsMaxLines() { CheckNull(new TextStyle { MaxLines = 5, Multiline = true }.MaxLines); } public void MaxLinesOfOne_ReadsAsNotMultiline() { CheckFalse(new TextStyle { MaxLines = 1 }.Multiline); } public void MaxLinesGreaterThanOne_ReadsAsMultiline() { CheckTrue(new TextStyle { MaxLines = 3 }.Multiline); } public void SettingBoth_TheOneWrittenLastWins() { var multilineThenMaxLines = new TextStyle { Multiline = false, MaxLines = 5 }; CheckEqual(5, multilineThenMaxLines.MaxLines); CheckTrue(multilineThenMaxLines.Multiline); var maxLinesThenMultiline = new TextStyle { MaxLines = 5, Multiline = false }; CheckEqual(1, maxLinesThenMultiline.MaxLines); CheckFalse(maxLinesThenMultiline.Multiline); } } public class VerticalMarginTests : TestFixture { public void Unset_IsAQuarterOfTheFontsLineHeight() { CheckEqual((Scalar)1, WithFont().VerticalMargin); } public void UnsetWithoutAFont_IsZero() { CheckEqual((Scalar)0, new TextStyle().VerticalMargin); } public void Set_IsWhatWasSet() { CheckEqual((Scalar)7, (WithFont() with { VerticalMargin = 7 }).VerticalMargin); } } public class HorizontalMarginTests : TestFixture { public void Unset_IsHalfTheFontsLineHeight() { CheckEqual((Scalar)2, WithFont().HorizontalMargin); } public void UnsetWithoutAFont_IsZero() { CheckEqual((Scalar)0, new TextStyle().HorizontalMargin); } public void Set_IsWhatWasSet() { CheckEqual((Scalar)7, (WithFont() with { HorizontalMargin = 7 }).HorizontalMargin); } } public class ScaleTests : TestFixture { public void DefaultsToOne() { CheckEqual((Scalar)1, new TextStyle().Scale); } } public class SingleLineHeightTests : TestFixture { public void WithAFont_IsTheLineHeightPlusBothVerticalMargins() { CheckEqual((Scalar)6, WithFont().SingleLineHeight); } public void ASetMargin_ReplacesTheDefaultOne() { CheckEqual((Scalar)18, (WithFont() with { VerticalMargin = 7 }).SingleLineHeight); } public void Scaled_ScalesTheMarginsToo() { CheckEqual((Scalar)12, (WithFont() with { Scale = 2 }).SingleLineHeight); } public void WithoutAFont_IsJustTheMargins() { CheckEqual((Scalar)10, new TextStyle { VerticalMargin = 5 }.SingleLineHeight); } public void WithoutAFontOrMargin_IsZero() { CheckEqual((Scalar)0, new TextStyle().SingleLineHeight); } } public class VerticalAlignmentTests : TestFixture { public void DefaultsToTop() { CheckEqual(Alignment.Vertical.Top, new TextStyle().VerticalAlignment); } } public class HorizontalAlignmentTests : TestFixture { public void DefaultsToLeft() { CheckEqual(Alignment.Horizontal.Left, new TextStyle().HorizontalAlignment); } } public class OverflowBehaviorTests : TestFixture { public void DefaultsToClip() { CheckEqual(TextOverflow.Clip, new TextStyle().OverflowBehavior); } } public class TrailingSpacesTests : TestFixture { public void DefaultsToHang() { CheckEqual(Glass.Typesetting.TrailingSpaceMode.Hang, new TextStyle().TrailingSpaces); } } public class EqualityTests : TestFixture { public void SeparatelyBuiltWithTheSameSettings_AreEqual() { SpriteFontDefinition font = TextMaterialTests.SharedMonospaceFont; CheckEqual(new TextStyle { Font = font, Scale = 2 }, new TextStyle { Font = font, Scale = 2 }); } public void DifferingInAnySetting_AreNotEqual() { SpriteFontDefinition font = TextMaterialTests.SharedMonospaceFont; CheckNotEqual(new TextStyle { Font = font, Scale = 2 }, new TextStyle { Font = font, Scale = 3 }); } } public class LaysOutLikeTests : TestFixture { public void DifferingOnlyInColorTextureAndGamma_IsTrue() { TextStyle style = WithFont(); TextStyle recolored = style with { TintColor = System.Drawing.Color.Red, TintTexture = new FakeTexture(), CoverageGamma = 2, }; CheckTrue(recolored.LaysOutLike(style)); } public void DifferingInAnyLayoutSetting_IsFalse() { TextStyle style = WithFont(); var variants = new Dictionary { [nameof(TextStyle.Font)] = style with { Font = TextMaterialTests.CreateMonospaceTestFont(3, 4) }, [nameof(TextStyle.VerticalAlignment)] = style with { VerticalAlignment = Alignment.Vertical.Center }, [nameof(TextStyle.HorizontalAlignment)] = style with { HorizontalAlignment = Alignment.Horizontal.Right }, [nameof(TextStyle.VerticalMargin)] = style with { VerticalMargin = 7 }, [nameof(TextStyle.HorizontalMargin)] = style with { HorizontalMargin = 7 }, [nameof(TextStyle.MaxLines)] = style with { MaxLines = 2 }, [nameof(TextStyle.OverflowBehavior)] = style with { OverflowBehavior = TextOverflow.Ellipsis }, [nameof(TextStyle.TrailingSpaces)] = style with { TrailingSpaces = Glass.Typesetting.TrailingSpaceMode.Wrap }, [nameof(TextStyle.Scale)] = style with { Scale = 2 }, }; CheckEqual(new string[0], variants.Where(variant => variant.Value.LaysOutLike(style)).Select(variant => variant.Key)); } public void AMarginSetToTheFontsDefault_IsTrue() { TextStyle style = WithFont(); CheckTrue((style with { VerticalMargin = style.VerticalMargin }).LaysOutLike(style)); } /// /// LaysOutLike lists its fields by hand, so a property added to TextStyle has to be sorted into one /// list or the other here before this passes. /// public void EveryProperty_IsEitherLayoutOrAppearance() { string[] layout = { "Font", "VerticalAlignment", "HorizontalAlignment", "VerticalMargin", "HorizontalMargin", "MaxLines", "OverflowBehavior", "TrailingSpaces", "Scale", }; string[] appearanceOrDerived = { "TintColor", "TintTexture", "CoverageGamma", "Multiline", "SingleLineHeight", }; IEnumerable properties = typeof(TextStyle) .GetProperties(BindingFlags.Public | BindingFlags.Instance).Select(property => property.Name); CheckEqual(layout.Concat(appearanceOrDerived).OrderBy(name => name), properties.OrderBy(name => name)); } public static readonly TextStyle AllocationStyle = WithFont(); public static readonly TextStyle AllocationRecolored = AllocationStyle with { TintColor = System.Drawing.Color.Red }; [AllocationTest] public void AllocatesNothing() { bool laysOutLike = AllocationRecolored.LaysOutLike(AllocationStyle); CheckNoAllocations(); CheckTrue(laysOutLike); } } public class FakeTexture : ITexture { } public class MaxLayoutHeightTests : TestFixture { public void MultilineClipping_ClampsToWhatWasOffered() { CheckEqual((Scalar)100, WithFont().MaxLayoutHeight(100)); } public void MultilineEllipsis_ClampsToTheSameHeightAsClipping() { TextStyle style = WithFont() with { OverflowBehavior = TextOverflow.Ellipsis }; CheckEqual((Scalar)100, style.MaxLayoutHeight(100)); } public void SingleLine_ClampsToOneLineOfTheFontEvenWhenClipping() { CheckEqual((Scalar)4, (WithFont() with { Multiline = false }).MaxLayoutHeight(100)); } public void SingleLineWithoutAFont_FallsBackToWhatWasOffered() { CheckEqual((Scalar)100, new TextStyle { Multiline = false }.MaxLayoutHeight(100)); } } } }