Browse Source

Merge remote-tracking branch 'origin/nunit-headless-intergration' into unify-test-mocks

pull/11169/head
Max Katz 3 years ago
parent
commit
4a1daed251
  1. 12
      src/Avalonia.Base/Animation/Animation.cs
  2. 8
      src/Avalonia.Base/Layout/LayoutManager.cs
  3. 9
      src/Avalonia.Controls/Presenters/ContentPresenter.cs
  4. 33
      tests/Avalonia.Base.UnitTests/Layout/LayoutManagerTests.cs
  5. 32
      tests/Avalonia.Base.UnitTests/Layout/LayoutTestControl.cs
  6. 5
      tests/Avalonia.Controls.UnitTests/ContentControlTests.cs

12
src/Avalonia.Base/Animation/Animation.cs

@ -200,7 +200,7 @@ namespace Avalonia.Animation
/// </summary>
/// <param name="setter">The animation setter.</param>
/// <param name="value">The property animator value.</param>
public static void SetAnimator(IAnimationSetter setter,
public static void SetAnimator(IAnimationSetter setter,
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor | DynamicallyAccessedMemberTypes.PublicMethods)]
Type value)
{
@ -319,7 +319,7 @@ namespace Avalonia.Animation
if (animators.Count == 1)
{
var subscription = animators[0].Apply(this, control, clock, match, onComplete);
if (subscription is not null)
{
subscriptions.Add(subscription);
@ -348,9 +348,11 @@ namespace Avalonia.Animation
if (onComplete != null)
{
Task.WhenAll(completionTasks!).ContinueWith(
(_, state) => ((Action)state!).Invoke(),
onComplete);
Task.WhenAll(completionTasks!)
.ContinueWith((_, state) => ((Action)state!).Invoke()
, onComplete
, TaskScheduler.FromCurrentSynchronizationContext()
);
}
}
return new CompositeDisposable(subscriptions);

8
src/Avalonia.Base/Layout/LayoutManager.cs

@ -249,10 +249,12 @@ namespace Avalonia.Layout
{
var control = _toMeasure.Dequeue();
if (!control.IsMeasureValid && control.IsAttachedToVisualTree)
if (!control.IsMeasureValid)
{
Measure(control);
}
_toArrange.Enqueue(control);
}
}
@ -262,7 +264,7 @@ namespace Avalonia.Layout
{
var control = _toArrange.Dequeue();
if (!control.IsArrangeValid && control.IsAttachedToVisualTree)
if (!control.IsArrangeValid)
{
Arrange(control);
}
@ -297,8 +299,6 @@ namespace Avalonia.Layout
{
control.Measure(control.PreviousMeasure.Value);
}
_toArrange.Enqueue(control);
}
return true;

9
src/Avalonia.Controls/Presenters/ContentPresenter.cs

@ -1,5 +1,5 @@
using System;
using Avalonia.Collections;
using Avalonia.Controls.Documents;
using Avalonia.Controls.Metadata;
using Avalonia.Controls.Primitives;
@ -442,7 +442,7 @@ namespace Avalonia.Controls.Presenters
var contentTemplate = ContentTemplate;
var oldChild = Child;
var newChild = CreateChild(content, oldChild, contentTemplate);
var logicalChildren = Host?.LogicalChildren ?? LogicalChildren;
var logicalChildren = GetEffectiveLogicalChildren();
// Remove the old child if we're not recycling it.
if (newChild != oldChild)
@ -488,6 +488,9 @@ namespace Avalonia.Controls.Presenters
}
private IAvaloniaList<ILogical> GetEffectiveLogicalChildren()
=> Host?.LogicalChildren ?? LogicalChildren;
/// <inheritdoc/>
protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e)
{
@ -692,7 +695,7 @@ namespace Avalonia.Controls.Presenters
else if (Child != null)
{
VisualChildren.Remove(Child);
LogicalChildren.Remove(Child);
GetEffectiveLogicalChildren().Remove(Child);
((ISetInheritanceParent)Child).SetParent(Child.Parent);
Child = null;
_recyclingDataTemplate = null;

33
tests/Avalonia.Base.UnitTests/Layout/LayoutManagerTests.cs

@ -514,5 +514,38 @@ namespace Avalonia.Base.UnitTests.Layout
Assert.True(parent.IsMeasureValid);
Assert.True(parent.IsArrangeValid);
}
[Fact]
public void Grandparent_Can_Invalidate_Root_Measure_During_Arrange()
{
// Issue #11161.
var child = new LayoutTestControl();
var parent = new LayoutTestControl { Child = child };
var grandparent = new LayoutTestControl { Child = parent };
var root = new LayoutTestRoot { Child = grandparent };
root.LayoutManager.ExecuteInitialLayoutPass();
grandparent.DoArrangeOverride = (_, s) =>
{
root.InvalidateMeasure();
return s;
};
grandparent.CallBaseArrange = true;
child.InvalidateMeasure();
grandparent.InvalidateMeasure();
root.LayoutManager.ExecuteLayoutPass();
Assert.True(child.IsMeasureValid);
Assert.True(child.IsArrangeValid);
Assert.True(parent.IsMeasureValid);
Assert.True(parent.IsArrangeValid);
Assert.True(grandparent.IsMeasureValid);
Assert.True(grandparent.IsArrangeValid);
Assert.True(root.IsMeasureValid);
Assert.True(root.IsArrangeValid);
}
}
}

32
tests/Avalonia.Base.UnitTests/Layout/LayoutTestControl.cs

@ -10,21 +10,41 @@ namespace Avalonia.Base.UnitTests.Layout
public bool Arranged { get; set; }
public Func<Layoutable, Size, Size> DoMeasureOverride { get; set; }
public Func<Layoutable, Size, Size> DoArrangeOverride { get; set; }
public bool CallBaseMeasure { get; set; }
public bool CallBaseArrange { get; set; }
protected override Size MeasureOverride(Size availableSize)
{
Measured = true;
return DoMeasureOverride != null ?
DoMeasureOverride(this, availableSize) :
base.MeasureOverride(availableSize);
if (DoMeasureOverride is not null)
{
var overrideResult = DoMeasureOverride(this, availableSize);
return CallBaseMeasure ?
base.MeasureOverride(overrideResult) :
overrideResult;
}
else
{
return base.MeasureOverride(availableSize);
}
}
protected override Size ArrangeOverride(Size finalSize)
{
Arranged = true;
return DoArrangeOverride != null ?
DoArrangeOverride(this, finalSize) :
base.ArrangeOverride(finalSize);
if (DoArrangeOverride is not null)
{
var overrideResult = DoArrangeOverride(this, finalSize);
return CallBaseArrange ?
base.ArrangeOverride(overrideResult) :
overrideResult;
}
else
{
return base.ArrangeOverride(finalSize);
}
}
}
}

5
tests/Avalonia.Controls.UnitTests/ContentControlTests.cs

@ -359,16 +359,21 @@ namespace Avalonia.Controls.UnitTests
target.Presenter.ApplyTemplate();
Assert.Equal(target, target.Presenter.Child.GetLogicalParent());
Assert.Equal(new[] { target.Presenter.Child }, target.LogicalChildren);
root.Child = null;
Assert.Null(target.Template);
target.Content = null;
Assert.Empty(target.LogicalChildren);
root.Child = target;
target.Content = "Bar";
Assert.Equal(target, target.Presenter.Child.GetLogicalParent());
Assert.Equal(new[] { target.Presenter.Child }, target.LogicalChildren);
}
private static FuncControlTemplate GetTemplate()

Loading…
Cancel
Save