123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255 |
- using System;
- using System.ComponentModel;
- using System.Security.Cryptography.X509Certificates;
- using Avalonia.Controls.Primitives;
- using Avalonia.Controls.Templates;
- using Avalonia.Data;
- using Avalonia.Layout;
- using Avalonia.Markup.Data;
- using Avalonia.Styling;
- using Avalonia.UnitTests;
- using Xunit;
- namespace Avalonia.Controls.UnitTests.Primitives
- {
- public class RangeBaseTests : ScopedTestBase
- {
- [Fact]
- public void Maximum_Should_Be_Coerced_To_Minimum()
- {
- var target = new TestRange
- {
- Minimum = 100,
- Maximum = 50,
- };
- var root = new TestRoot(target);
- Assert.Equal(100, target.Minimum);
- Assert.Equal(100, target.Maximum);
- }
- [Fact]
- public void ChangingDataContextShouldNotChangeOldDataContext()
- {
- var viewModel = new RangeTestViewModel()
- {
- Minimum = -5000,
- Maximum = 5000,
- Value = 4000
- };
-
- var target = new TestRange
- {
- [!RangeBase.MinimumProperty] = new Binding(nameof(viewModel.Minimum)),
- [!RangeBase.MaximumProperty] = new Binding(nameof(viewModel.Maximum)),
- [!RangeBase.ValueProperty] = new Binding(nameof(viewModel.Value)),
- };
-
- var root = new TestRoot(target);
- target.DataContext = viewModel;
- target.DataContext = null;
-
- Assert.Equal(4000, viewModel.Value);
- Assert.Equal(-5000, viewModel.Minimum);
- Assert.Equal(5000, viewModel.Maximum);
- }
-
- [Fact]
- public void Value_Should_Be_Coerced_To_Range()
- {
- var target = new TestRange
- {
- Minimum = 0,
- Maximum = 50,
- Value = 100,
- };
- var root = new TestRoot(target);
- Assert.Equal(0, target.Minimum);
- Assert.Equal(50, target.Maximum);
- Assert.Equal(50, target.Value);
- }
- [Fact]
- public void Changing_Minimum_Should_Coerce_Value_And_Maximum()
- {
- var target = new TestRange
- {
- Minimum = 0,
- Maximum = 100,
- Value = 50,
- };
- var root = new TestRoot(target);
- target.Minimum = 200;
- Assert.Equal(200, target.Minimum);
- Assert.Equal(200, target.Maximum);
- Assert.Equal(200, target.Value);
- }
- [Fact]
- public void Changing_Maximum_Should_Coerce_Value()
- {
- var target = new TestRange
- {
- Minimum = 0,
- Maximum = 100,
- Value = 100,
- };
- var root = new TestRoot(target);
- target.Maximum = 50;
- Assert.Equal(0, target.Minimum);
- Assert.Equal(50, target.Maximum);
- Assert.Equal(50, target.Value);
- }
- [Theory]
- [InlineData(true)]
- [InlineData(false)]
- public void SetValue_Should_Not_Cause_StackOverflow(bool useXamlBinding)
- {
- var viewModel = new TestStackOverflowViewModel()
- {
- Value = 50
- };
- Track track = null;
- var target = new TestRange()
- {
- Template = new FuncControlTemplate<RangeBase>((c, scope) =>
- {
- track = new Track()
- {
- Width = 100,
- Orientation = Orientation.Horizontal,
- [~~Track.MinimumProperty] = c[~~RangeBase.MinimumProperty],
- [~~Track.MaximumProperty] = c[~~RangeBase.MaximumProperty],
- Name = "PART_Track",
- Thumb = new Thumb()
- }.RegisterInNameScope(scope);
- if (useXamlBinding)
- {
- track.Bind(Track.ValueProperty, new Binding("Value")
- {
- Mode = BindingMode.TwoWay,
- Source = c,
- Priority = BindingPriority.Style
- });
- }
- else
- {
- track[~~Track.ValueProperty] = c[~~RangeBase.ValueProperty];
- }
- return track;
- }),
- Minimum = 0,
- Maximum = 100,
- DataContext = viewModel
- };
- target.Bind(TestRange.ValueProperty, new Binding("Value") { Mode = BindingMode.TwoWay });
- target.ApplyTemplate();
- track.Measure(new Size(100, 0));
- track.Arrange(new Rect(0, 0, 100, 0));
- Assert.Equal(1, viewModel.SetterInvokedCount);
- // Issues #855 and #824 were causing a StackOverflowException at this point.
- target.Value = 51.001;
- Assert.Equal(2, viewModel.SetterInvokedCount);
- double expected = 51;
- Assert.Equal(expected, viewModel.Value);
- Assert.Equal(expected, target.Value);
- Assert.Equal(expected, track.Value);
- }
- [Fact]
- public void Coercion_Should_Not_Be_Done_During_Initialization()
- {
- var target = new TestRange();
- target.BeginInit();
- var root = new TestRoot(target);
- target.Minimum = 1;
- Assert.Equal(0, target.Value);
- target.Value = 50;
- target.EndInit();
- Assert.Equal(50, target.Value);
- }
- [Fact]
- public void Coercion_Should_Be_Done_After_Initialization()
- {
- var target = new TestRange();
- target.BeginInit();
- var root = new TestRoot(target);
- target.Minimum = 1;
- target.EndInit();
- Assert.Equal(1, target.Value);
- }
- private class TestRange : RangeBase
- {
- }
- private class TestStackOverflowViewModel : INotifyPropertyChanged
- {
- public int SetterInvokedCount { get; private set; }
- public const int MaxInvokedCount = 1000;
- private double _value;
- public event PropertyChangedEventHandler PropertyChanged;
- public double Value
- {
- get { return _value; }
- set
- {
- if (_value != value)
- {
- SetterInvokedCount++;
- if (SetterInvokedCount < MaxInvokedCount)
- {
- _value = (int)value;
- if (_value > 75) _value = 75;
- if (_value < 25) _value = 25;
- }
- else
- {
- _value = value;
- }
- PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Value)));
- }
- }
- }
- }
- private class RangeTestViewModel
- {
- public double Minimum { get; set; }
- public double Maximum { get; set; }
- public double Value { get; set; }
- }
- }
- }
|