123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367 |
- using Xunit;
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Linq;
- using Avalonia.UnitTests;
- namespace Avalonia.Controls.UnitTests
- {
- public class CalendarTests : ScopedTestBase
- {
- private static bool CompareDates(DateTime first, DateTime second)
- {
- return first.Year == second.Year &&
- first.Month == second.Month &&
- first.Day == second.Day;
- }
- [Fact]
- public void SelectedDatesChanged_Should_Fire_When_SelectedDate_Set()
- {
- bool handled = false;
- Calendar calendar = new Calendar();
- calendar.SelectionMode = CalendarSelectionMode.SingleDate;
- calendar.SelectedDatesChanged += new EventHandler<SelectionChangedEventArgs>(delegate
- {
- handled = true;
- });
- DateTime value = new DateTime(2000, 10, 10);
- calendar.SelectedDate = value;
- Assert.True(handled);
- }
- [Fact]
- public void DisplayDateChanged_Should_Fire_When_DisplayDate_Set()
- {
- bool handled = false;
- Calendar calendar = new Calendar();
- calendar.SelectionMode = CalendarSelectionMode.SingleDate;
- calendar.DisplayDateChanged += new EventHandler<CalendarDateChangedEventArgs>(delegate
- {
- handled = true;
- });
- DateTime value = new DateTime(2000, 10, 10);
- calendar.DisplayDate = value;
- Assert.True(handled);
- }
- [Fact]
- public void Setting_Selected_Date_To_Blackout_Date_Should_Throw()
- {
- Calendar calendar = new Calendar();
- calendar.BlackoutDates.AddDatesInPast();
- Assert.ThrowsAny<ArgumentOutOfRangeException>(
- () => calendar.SelectedDate = DateTime.Today.AddDays(-1));
- }
- [Fact]
- public void Setting_Selected_Date_To_Blackout_Date_Should_Throw_Range()
- {
- Calendar calendar = new Calendar();
- calendar.BlackoutDates.Add(new CalendarDateRange(DateTime.Today, DateTime.Today.AddDays(10)));
- calendar.SelectedDate = DateTime.Today.AddDays(-1);
- Assert.True(CompareDates(calendar.SelectedDate.Value, DateTime.Today.AddDays(-1)));
- Assert.True(CompareDates(calendar.SelectedDate.Value, calendar.SelectedDates[0]));
- calendar.SelectedDate = DateTime.Today.AddDays(11);
- Assert.True(CompareDates(calendar.SelectedDate.Value, DateTime.Today.AddDays(11)));
- Assert.True(CompareDates(calendar.SelectedDate.Value, calendar.SelectedDates[0]));
- Assert.ThrowsAny<ArgumentOutOfRangeException>(
- () => calendar.SelectedDate = DateTime.Today.AddDays(5));
- }
- [Fact]
- public void Adding_Blackout_Dates_Containing_Selected_Date_Should_Throw()
- {
- Calendar calendar = new Calendar();
- calendar.SelectedDate = DateTime.Today.AddDays(5);
- Assert.ThrowsAny<ArgumentOutOfRangeException>(
- () => calendar.BlackoutDates.Add(new CalendarDateRange(DateTime.Today, DateTime.Today.AddDays(10))));
- }
- [Fact]
- public void DisplayDateStartEnd_Should_Constrain_Display_Date()
- {
- Calendar calendar = new Calendar();
- calendar.SelectionMode = CalendarSelectionMode.SingleDate;
- calendar.DisplayDateStart = new DateTime(2005, 12, 30);
- DateTime value = new DateTime(2005, 12, 15);
- calendar.DisplayDate = value;
- Assert.True(CompareDates(calendar.DisplayDate, calendar.DisplayDateStart.Value));
- value = new DateTime(2005, 12, 30);
- calendar.DisplayDate = value;
- Assert.True(CompareDates(calendar.DisplayDate, value));
- value = DateTime.MaxValue;
- calendar.DisplayDate = value;
- Assert.True(CompareDates(calendar.DisplayDate, value));
- calendar.DisplayDateEnd = new DateTime(2010, 12, 30);
- Assert.True(CompareDates(calendar.DisplayDate, calendar.DisplayDateEnd.Value));
- }
- [Fact]
- public void Setting_DisplayDateEnd_Should_Alter_DispalyDate_And_DisplayDateStart()
- {
- Calendar calendar = new Calendar();
- DateTime value = new DateTime(2000, 1, 30);
- calendar.DisplayDate = value;
- calendar.DisplayDateEnd = value;
- calendar.DisplayDateStart = value;
- Assert.True(CompareDates(calendar.DisplayDateStart.Value, value));
- Assert.True(CompareDates(calendar.DisplayDateEnd.Value, value));
- value = value.AddMonths(2);
- calendar.DisplayDateStart = value;
- Assert.True(CompareDates(calendar.DisplayDateStart.Value, value));
- Assert.True(CompareDates(calendar.DisplayDateEnd.Value, value));
- Assert.True(CompareDates(calendar.DisplayDate, value));
- }
- [Fact]
- public void Display_Date_Range_End_Will_Contain_SelectedDate()
- {
- Calendar calendar = new Calendar();
- calendar.SelectionMode = CalendarSelectionMode.SingleDate;
- calendar.SelectedDate = DateTime.MaxValue;
- Assert.True(CompareDates((DateTime)calendar.SelectedDate, DateTime.MaxValue));
- calendar.DisplayDateEnd = DateTime.MaxValue.AddDays(-1);
- Assert.True(CompareDates((DateTime)calendar.DisplayDateEnd, DateTime.MaxValue));
- }
- /// <summary>
- /// The days added to the SelectedDates collection.
- /// </summary>
- private IList<object> _selectedDatesChangedAddedDays;
- /// <summary>
- /// The days removed from the SelectedDates collection.
- /// </summary>
- private IList<object> _selectedDateChangedRemovedDays;
- /// <summary>
- /// The number of times the SelectedDatesChanged event has been fired.
- /// </summary>
- private int _selectedDatesChangedCount;
- /// <summary>
- /// Handle the SelectedDatesChanged event.
- /// </summary>
- /// <param name="sender">The calendar.</param>
- /// <param name="e">Event arguments.</param>
- private void OnSelectedDatesChanged(object sender, SelectionChangedEventArgs e)
- {
- _selectedDatesChangedAddedDays =
- e.AddedItems
- .Cast<object>()
- .ToList();
- _selectedDateChangedRemovedDays =
- e.RemovedItems
- .Cast<object>()
- .ToList();
- _selectedDatesChangedCount++;
- }
- /// <summary>
- /// Clear the variables used to track the SelectedDatesChanged event.
- /// </summary>
- private void ResetSelectedDatesChanged()
- {
- if (_selectedDatesChangedAddedDays != null)
- {
- _selectedDatesChangedAddedDays.Clear();
- }
- if (_selectedDateChangedRemovedDays != null)
- {
- _selectedDateChangedRemovedDays.Clear();
- }
- _selectedDatesChangedCount = 0;
- }
- [Fact]
- public void SingleDate_Selection_Behavior()
- {
- ResetSelectedDatesChanged();
- Calendar calendar = new Calendar();
- calendar.SelectedDatesChanged += new EventHandler<SelectionChangedEventArgs>(OnSelectedDatesChanged);
- calendar.SelectionMode = CalendarSelectionMode.SingleDate;
- calendar.SelectedDate = DateTime.Today;
- Assert.True(CompareDates(calendar.SelectedDate.Value, DateTime.Today));
- Assert.True(calendar.SelectedDates.Count == 1);
- Assert.True(CompareDates(calendar.SelectedDates[0], DateTime.Today));
- Assert.True(_selectedDatesChangedCount == 1);
- Assert.True(_selectedDatesChangedAddedDays.Count == 1);
- Assert.True(_selectedDateChangedRemovedDays.Count == 0);
- ResetSelectedDatesChanged();
- calendar.SelectedDate = DateTime.Today;
- Assert.True(CompareDates(calendar.SelectedDate.Value, DateTime.Today));
- Assert.True(calendar.SelectedDates.Count == 1);
- Assert.True(CompareDates(calendar.SelectedDates[0], DateTime.Today));
- Assert.True(_selectedDatesChangedCount == 0);
- calendar.ClearValue(Calendar.SelectedDateProperty);
- calendar.SelectionMode = CalendarSelectionMode.None;
- Assert.True(calendar.SelectedDates.Count == 0);
- Assert.Null(calendar.SelectedDate);
- calendar.SelectionMode = CalendarSelectionMode.SingleDate;
- calendar.SelectedDates.Add(DateTime.Today.AddDays(1));
- Assert.True(CompareDates(calendar.SelectedDate.Value, DateTime.Today.AddDays(1)));
- Assert.True(calendar.SelectedDates.Count == 1);
- Assert.ThrowsAny<InvalidOperationException>(
- () => calendar.SelectedDates.Add(DateTime.Today.AddDays(2)));
- }
- [Fact]
- public void SingleRange_Selection_Behavior()
- {
- ResetSelectedDatesChanged();
- Calendar calendar = new Calendar();
- calendar.SelectedDatesChanged += new EventHandler<SelectionChangedEventArgs>(OnSelectedDatesChanged);
- calendar.SelectionMode = CalendarSelectionMode.SingleRange;
- calendar.SelectedDate = DateTime.Today;
- Assert.True(CompareDates(calendar.SelectedDate.Value, DateTime.Today));
- Assert.True(calendar.SelectedDates.Count == 1);
- Assert.True(CompareDates(calendar.SelectedDates[0], DateTime.Today));
- Assert.True(_selectedDatesChangedCount == 1);
- Assert.True(_selectedDatesChangedAddedDays.Count == 1);
- Assert.True(_selectedDateChangedRemovedDays.Count == 0);
- ResetSelectedDatesChanged();
- calendar.SelectedDates.Clear();
- Assert.Null(calendar.SelectedDate);
- ResetSelectedDatesChanged();
- calendar.SelectedDates.AddRange(DateTime.Today, DateTime.Today.AddDays(10));
- Assert.True(CompareDates(calendar.SelectedDate.Value, DateTime.Today));
- Assert.True(calendar.SelectedDates.Count == 11);
- ResetSelectedDatesChanged();
- calendar.SelectedDates.AddRange(DateTime.Today, DateTime.Today.AddDays(10));
- Assert.True(calendar.SelectedDates.Count == 11);
- Assert.True(_selectedDatesChangedCount == 0);
- ResetSelectedDatesChanged();
- calendar.SelectedDates.AddRange(DateTime.Today.AddDays(-20), DateTime.Today);
- Assert.True(CompareDates(calendar.SelectedDate.Value, DateTime.Today.AddDays(-20)));
- Assert.True(calendar.SelectedDates.Count == 21);
- Assert.True(_selectedDatesChangedCount == 1);
- Assert.True(_selectedDatesChangedAddedDays.Count == 21);
- Assert.True(_selectedDateChangedRemovedDays.Count == 11);
- ResetSelectedDatesChanged();
- calendar.SelectedDates.Add(DateTime.Today.AddDays(100));
- Assert.True(CompareDates(calendar.SelectedDate.Value, DateTime.Today.AddDays(100)));
- Assert.True(calendar.SelectedDates.Count == 1);
- }
- [Fact]
- public void AllowTapRangeSelection_Should_Disable_TapToSelectRange()
- {
- var calendar = new Calendar();
- Assert.True(calendar.AllowTapRangeSelection); // Default should be true
-
- calendar.AllowTapRangeSelection = false;
- Assert.False(calendar.AllowTapRangeSelection);
- }
- [Fact]
- public void TapRangeSelection_Should_Work_In_SingleRange_Mode()
- {
- var calendar = new Calendar();
- calendar.SelectionMode = CalendarSelectionMode.SingleRange;
- calendar.AllowTapRangeSelection = true;
-
- var startDate = new DateTime(2023, 10, 10);
- var endDate = new DateTime(2023, 10, 15);
-
- // First tap should select start date
- var firstTapResult = calendar.ProcessTapRangeSelection(startDate);
- Assert.True(firstTapResult);
- Assert.Equal(1, calendar.SelectedDates.Count);
- Assert.True(calendar.SelectedDates.Contains(startDate));
-
- // Second tap should complete the range
- var secondTapResult = calendar.ProcessTapRangeSelection(endDate);
- Assert.True(secondTapResult);
- Assert.Equal(6, calendar.SelectedDates.Count); // 5 days inclusive
- Assert.True(calendar.SelectedDates.Contains(startDate));
- Assert.True(calendar.SelectedDates.Contains(endDate));
- }
- [Fact]
- public void TapRangeSelection_Should_Not_Work_In_SingleDate_Mode()
- {
- var calendar = new Calendar();
- calendar.SelectionMode = CalendarSelectionMode.SingleDate;
- calendar.AllowTapRangeSelection = true;
-
- var date = new DateTime(2023, 10, 10);
- var result = calendar.ProcessTapRangeSelection(date);
- Assert.False(result); // Should not handle tap range selection
- }
- [Fact]
- public void TapRangeSelection_Should_Handle_Blackout_Dates()
- {
- var calendar = new Calendar();
- calendar.SelectionMode = CalendarSelectionMode.SingleRange;
- calendar.AllowTapRangeSelection = true;
-
- var startDate = new DateTime(2023, 10, 10);
- var blackoutDate = new DateTime(2023, 10, 12);
- var endDate = new DateTime(2023, 10, 15);
-
- // Add blackout date in the middle
- calendar.BlackoutDates.Add(new CalendarDateRange(blackoutDate, blackoutDate));
-
- // First tap
- calendar.ProcessTapRangeSelection(startDate);
- Assert.Equal(1, calendar.SelectedDates.Count);
-
- // Second tap should restart selection due to blackout date
- calendar.ProcessTapRangeSelection(endDate);
- Assert.Equal(1, calendar.SelectedDates.Count);
- Assert.True(calendar.SelectedDates.Contains(endDate));
- Assert.False(calendar.SelectedDates.Contains(startDate));
- }
- [Fact]
- public void TapRangeSelection_Should_Handle_Reverse_Order_Dates()
- {
- var calendar = new Calendar();
- calendar.SelectionMode = CalendarSelectionMode.SingleRange;
- calendar.AllowTapRangeSelection = true;
-
- var laterDate = new DateTime(2023, 10, 15);
- var earlierDate = new DateTime(2023, 10, 10);
-
- // First tap on later date
- calendar.ProcessTapRangeSelection(laterDate);
- Assert.Equal(1, calendar.SelectedDates.Count);
-
- // Second tap on earlier date should still create correct range
- calendar.ProcessTapRangeSelection(earlierDate);
- Assert.Equal(6, calendar.SelectedDates.Count);
- Assert.True(calendar.SelectedDates.Contains(earlierDate));
- Assert.True(calendar.SelectedDates.Contains(laterDate));
- }
- }
- }
|