Skip to content

Commit

Permalink
[PTRun][DateTime]Setting for First week of year and `First day of w…
Browse files Browse the repository at this point in the history
…eek` (microsoft#33406)

## Summary of the Pull Request

This PR implements two new plugin settings:
- **First week of year**

![image](https://github.com/microsoft/PowerToys/assets/61519853/c866ffc2-2a21-438c-9a1a-5f4c7f68a22e)

- **First day of week**

![image](https://github.com/microsoft/PowerToys/assets/61519853/b2ec125b-d87c-40c5-8793-743a1ffae237)

## Detailed Description of the Pull Request / Additional comments

For both settings the users can decide to be in sync with the system
settings (default) or to use their own setting. The order of days for
the `first day of week` setting is based on the current system culture.

PT Run respects these settings for the relevant results:
- calendar week
- week of month
- number of day in week
  • Loading branch information
htcfreek authored Jul 18, 2024
1 parent 98cfeb0 commit 7808033
Show file tree
Hide file tree
Showing 9 changed files with 483 additions and 43 deletions.
31 changes: 19 additions & 12 deletions doc/devdocs/modules/launcher/plugins/timedate.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,14 @@ The following formats are currently available:
- All available settings for the plugin are defined in the [`TimeDateSettings`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate/Components/TimeDateSettings.cs) class of the plugin. The settings can be accessed everywhere in the plugin code via the static class instance `TimeDateSettings.Instance`.
- We have the following settings that the user can configure to change the behavior of the plugin:

| Key | Default value | Name | Description |
|--------------|-----------|------------|------------|
| `OnlyDateTimeNowGlobal` | `true` | Show only 'Time', 'Date', and 'Now' result for system time on global queries | Regardless of this setting, for global queries the first word of the query has to be a complete match. |
| `TimeWithSeconds` | `false` | Show time with seconds | This setting applies to the 'Time' and 'Now' result. |
| `DateWithWeekday` | `false` | Show date with weekday and name of month | This setting applies to the 'Date' and 'Now' result. |
| `HideNumberMessageOnGlobalQuery` | `false` | Hide 'Invalid number input' error message on global queries | |
| Key | Type | Default value | Name | Description |
|--------------|--------------|-----------|------------|------------|
| `CalendarFirstWeekRule` | Combo box | `-1` (Use system settings) | First week of the year | Configure the calendar rule for the first week of the year. |
| `FirstDayOfWeek` | Combo box | `-1` (Use system settings) | First day of the week | |
| `OnlyDateTimeNowGlobal` | Checkbox | `true` | Show only 'Time', 'Date', and 'Now' result for system time on global queries | Regardless of this setting, for global queries the first word of the query has to be a complete match. |
| `TimeWithSeconds` | Checkbox | `false` | Show time with seconds | This setting applies to the 'Time' and 'Now' result. |
| `DateWithWeekday` | Checkbox | `false` | Show date with weekday and name of month | This setting applies to the 'Date' and 'Now' result. |
| `HideNumberMessageOnGlobalQuery` | Checkbox | `false` | Hide 'Invalid number input' error message on global queries | |


## Classes
Expand All @@ -97,6 +99,7 @@ The following formats are currently available:

### [`TimeAndDateHelper.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate/Components/TimeAndDateHelper.cs)
- The [`TimeAndDateHelper`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate/Components/TimeAndDateHelper.cs) class contains methods to format/convert date and time formats/strings.
- And it contains methods to return the `first week day` and `first week of the year rule` based on the current plugin settings.

### [`TimeDateSettings.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate/Components/TimeDateSettings.cs)
- The [`TimeDateSettings`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate/Components/TimeDateSettings.cs) class provides access to all optional plugin settings.
Expand Down Expand Up @@ -129,11 +132,6 @@ On global queries the high score returned by `FuzzySearch` has negative impacts
## [Unit Tests](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests)
We have a [Unit Test project](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests) that executes various test to ensure that the plugin works as expected.

### [`TimeDateResultTests.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests/TimeDateResultTests.cs)
- The [`TimeDateResultTests.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests/TimeDateResultTests.cs) class contains tests to validate that the time and date values are correctly formatted/calculated.
- That we can execute the tests at any time on any machine, we use a specified date/time value and set the thread culture always to `en-us` while executing the tests.
- Some tests contain checks that calculate the expected result at runtime instead of using an expected value written fix in the code. This is done to get valid results on every machine at any time.

### [`ImageTests.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests/ImageTests.cs)
- The [`ImageTests.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests/ImageTests.cs) class contains tests to validate that each result shows the expected and correct image.
- That we can execute the tests at any time on any machine, we set the thread culture always to `en-us` while executing the tests.
Expand All @@ -147,4 +145,13 @@ We have a [Unit Test project](/src/modules/launcher/Plugins/Microsoft.PowerToys.

### [`StringParserTests.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests/StringParserTests.cs)
- The [`StringParserTests.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests/StringParserTests.cs) class contains tests to validate that the typed string gets converted correctly into a `DateTime` object.
- That we can execute the tests at any time on any machine, we set the thread culture always to `en-us` while executing the tests.
- That we can execute the tests at any time on any machine, we set the thread culture always to `en-us` while executing the tests.

### [`TimeAndDateHelperTests.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests/TimeAndDateHelperTests.cs)
- The [`TimeAndDateHelperTests.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests/TimeAndDateHelperTests.cs) class contains tests to validate important methods form the `TimeAndDateHelper` class that are not used for string parsing.

### [`TimeDateResultTests.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests/TimeDateResultTests.cs)
- The [`TimeDateResultTests.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests/TimeDateResultTests.cs) class contains tests to validate that the time and date values are correctly formatted/calculated.
- That we can execute the tests at any time on any machine, we use a specified date/time value and set the thread culture always to `en-us` while executing the tests.
- Some tests use custom settings for the first day of week and the first week of year. (This is done in the tests for the affected results to validate them for different settings/cultures.)
- Some tests contain checks that calculate the expected result at runtime instead of using an expected value written fix in the code. This is done to get valid results on every machine at any time.
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@ public void SettingsCount()
var result = settings?.Length;

// Assert
Assert.AreEqual(4, result);
Assert.AreEqual(6, result);
}

[DataTestMethod]
[DataRow("CalendarFirstWeekRule")]
[DataRow("FirstDayOfWeek")]
[DataRow("OnlyDateTimeNowGlobal")]
[DataRow("TimeWithSeconds")]
[DataRow("DateWithWeekday")]
Expand Down Expand Up @@ -59,5 +61,21 @@ public void DefaultValues(string name, bool valueExpected)
// Assert
Assert.AreEqual(valueExpected, result);
}

[DataTestMethod]
[DataRow("CalendarFirstWeekRule", -1)]
[DataRow("FirstDayOfWeek", -1)]
public void DefaultEnumValues(string name, int valueExpected)
{
// Setup
TimeDateSettings setting = TimeDateSettings.Instance;

// Act
PropertyInfo propertyInfo = setting?.GetType()?.GetProperty(name, BindingFlags.NonPublic | BindingFlags.Instance);
var result = propertyInfo?.GetValue(setting);

// Assert
Assert.AreEqual(valueExpected, result);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Globalization;
using Microsoft.PowerToys.Run.Plugin.TimeDate.Components;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests
{
[TestClass]
public class TimeAndDateHelperTests
{
[DataTestMethod]
[DataRow(-1, null)] // default setting
[DataRow(0, CalendarWeekRule.FirstDay)]
[DataRow(1, CalendarWeekRule.FirstFullWeek)]
[DataRow(2, CalendarWeekRule.FirstFourDayWeek)]
[DataRow(30, null)] // wrong setting
public void GetCalendarWeekRuleBasedOnPluginSetting(int setting, CalendarWeekRule? valueExpected)
{
// Act
var result = TimeAndDateHelper.GetCalendarWeekRule(setting);

// Assert
if (valueExpected == null)
{
// falls back to system setting.
Assert.AreEqual(DateTimeFormatInfo.CurrentInfo.CalendarWeekRule, result);
}
else
{
Assert.AreEqual(valueExpected, result);
}
}

[DataTestMethod]
[DataRow(-1, null)] // default setting
[DataRow(1, DayOfWeek.Monday)]
[DataRow(2, DayOfWeek.Tuesday)]
[DataRow(3, DayOfWeek.Wednesday)]
[DataRow(4, DayOfWeek.Thursday)]
[DataRow(5, DayOfWeek.Friday)]
[DataRow(6, DayOfWeek.Saturday)]
[DataRow(0, DayOfWeek.Sunday)]
[DataRow(70, null)] // wrong setting
public void GetFirstDayOfWeekBasedOnPluginSetting(int setting, DayOfWeek? valueExpected)
{
// Act
var result = TimeAndDateHelper.GetFirstDayOfWeek(setting);

// Assert
if (valueExpected == null)
{
// falls back to system setting.
Assert.AreEqual(DateTimeFormatInfo.CurrentInfo.FirstDayOfWeek, result);
}
else
{
Assert.AreEqual(valueExpected, result);
}
}
}
}
Loading

0 comments on commit 7808033

Please sign in to comment.