mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-07-02 16:39:14 +02:00
Compare commits
2 Commits
powerscrip
...
copilot/ad
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d1e07080e8 | ||
|
|
e918714f22 |
@@ -0,0 +1,138 @@
|
||||
// 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.CmdPal.Ext.TimeDate.Pages;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
namespace Microsoft.CmdPal.Ext.TimeDate.UnitTests
|
||||
{
|
||||
[TestClass]
|
||||
public class CalendarPageTests
|
||||
{
|
||||
private CultureInfo originalCulture;
|
||||
private CultureInfo originalUiCulture;
|
||||
|
||||
[TestInitialize]
|
||||
public void Setup()
|
||||
{
|
||||
originalCulture = CultureInfo.CurrentCulture;
|
||||
CultureInfo.CurrentCulture = new CultureInfo("en-us", false);
|
||||
originalUiCulture = CultureInfo.CurrentUICulture;
|
||||
CultureInfo.CurrentUICulture = new CultureInfo("en-us", false);
|
||||
}
|
||||
|
||||
[TestCleanup]
|
||||
public void Cleanup()
|
||||
{
|
||||
CultureInfo.CurrentCulture = originalCulture;
|
||||
CultureInfo.CurrentUICulture = originalUiCulture;
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void CalendarPage_HasExpectedId()
|
||||
{
|
||||
var page = new CalendarPage();
|
||||
|
||||
Assert.AreEqual("com.microsoft.cmdpal.timedate.calendarPage", page.Id);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void CalendarPage_HasNonEmptyName()
|
||||
{
|
||||
var page = new CalendarPage();
|
||||
|
||||
Assert.IsFalse(string.IsNullOrEmpty(page.Name));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void GetContent_ReturnsOneMarkdownContent()
|
||||
{
|
||||
var page = new CalendarPage();
|
||||
|
||||
var content = page.GetContent();
|
||||
|
||||
Assert.IsNotNull(content);
|
||||
Assert.AreEqual(1, content.Length);
|
||||
Assert.IsInstanceOfType(content[0], typeof(MarkdownContent));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void GetContent_TitleIsCurrentMonthAndYear()
|
||||
{
|
||||
var page = new CalendarPage();
|
||||
page.GetContent();
|
||||
|
||||
var expected = DateTime.Now.ToString("MMMM yyyy", CultureInfo.CurrentCulture);
|
||||
|
||||
Assert.AreEqual(expected, page.Title);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void GetContent_BodyContainsTodayBold()
|
||||
{
|
||||
var page = new CalendarPage();
|
||||
var content = page.GetContent();
|
||||
|
||||
var markdown = content[0] as MarkdownContent;
|
||||
var today = DateTime.Now.Day.ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
Assert.IsTrue(markdown!.Body.Contains($"**{today}**"), "Today's day number should be bold in the calendar markdown.");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void GetContent_BodyContainsDayHeaders()
|
||||
{
|
||||
var page = new CalendarPage();
|
||||
var content = page.GetContent();
|
||||
|
||||
var markdown = content[0] as MarkdownContent;
|
||||
|
||||
// The body should contain abbreviated day names as column headers
|
||||
var dayNames = CultureInfo.CurrentCulture.DateTimeFormat.AbbreviatedDayNames;
|
||||
foreach (var dayName in dayNames)
|
||||
{
|
||||
Assert.IsTrue(markdown!.Body.Contains(dayName), $"Calendar should contain day header '{dayName}'.");
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void GetContent_BodyContainsAllDaysOfCurrentMonth()
|
||||
{
|
||||
var page = new CalendarPage();
|
||||
var content = page.GetContent();
|
||||
|
||||
var markdown = content[0] as MarkdownContent;
|
||||
var daysInMonth = DateTime.DaysInMonth(DateTime.Now.Year, DateTime.Now.Month);
|
||||
|
||||
for (var day = 1; day <= daysInMonth; day++)
|
||||
{
|
||||
Assert.IsTrue(markdown!.Body.Contains(day.ToString(CultureInfo.InvariantCulture)), $"Calendar should contain day {day}.");
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void GetDockBands_CommandIsCalendarPage()
|
||||
{
|
||||
var provider = new TimeDateCommandsProvider();
|
||||
|
||||
var bands = provider.GetDockBands();
|
||||
|
||||
Assert.IsNotNull(bands);
|
||||
Assert.AreEqual(1, bands.Length);
|
||||
|
||||
// The band wraps a list; dig into its items to find the NowDockBand command.
|
||||
var wrappedBand = bands[0] as WrappedDockItem;
|
||||
Assert.IsNotNull(wrappedBand, "Dock band should be a WrappedDockItem.");
|
||||
|
||||
var items = wrappedBand.Items;
|
||||
Assert.IsTrue(items.Length > 0, "Dock band should have at least one item.");
|
||||
|
||||
var command = items[0].Command;
|
||||
Assert.IsInstanceOfType(command, typeof(CalendarPage), "The clock dock item's command should be a CalendarPage.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
// 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 System.Text;
|
||||
using Microsoft.CommandPalette.Extensions.Toolkit;
|
||||
|
||||
namespace Microsoft.CmdPal.Ext.TimeDate.Pages;
|
||||
|
||||
internal sealed partial class CalendarPage : ContentPage
|
||||
{
|
||||
public CalendarPage()
|
||||
{
|
||||
Id = "com.microsoft.cmdpal.timedate.calendarPage";
|
||||
Name = Resources.timedate_calendar_page_name;
|
||||
Icon = Icons.TimeDateExtIcon;
|
||||
}
|
||||
|
||||
public override IContent[] GetContent()
|
||||
{
|
||||
var now = DateTime.Now;
|
||||
Title = now.ToString("MMMM yyyy", CultureInfo.CurrentCulture);
|
||||
return [new MarkdownContent(GenerateCalendarMarkdown(now))];
|
||||
}
|
||||
|
||||
private static string GenerateCalendarMarkdown(DateTime now)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
var culture = CultureInfo.CurrentCulture;
|
||||
var firstDayOfMonth = new DateTime(now.Year, now.Month, 1);
|
||||
var daysInMonth = DateTime.DaysInMonth(now.Year, now.Month);
|
||||
var firstDayOfWeek = culture.DateTimeFormat.FirstDayOfWeek;
|
||||
var abbreviatedDayNames = culture.DateTimeFormat.AbbreviatedDayNames;
|
||||
|
||||
// Header row: abbreviated day names starting from the culture's first day of week
|
||||
sb.Append('|');
|
||||
for (var i = 0; i < 7; i++)
|
||||
{
|
||||
var dayIndex = ((int)firstDayOfWeek + i) % 7;
|
||||
sb.Append($" {abbreviatedDayNames[dayIndex]} |");
|
||||
}
|
||||
|
||||
sb.AppendLine();
|
||||
|
||||
// Separator
|
||||
sb.Append('|');
|
||||
for (var i = 0; i < 7; i++)
|
||||
{
|
||||
sb.Append(":-:|");
|
||||
}
|
||||
|
||||
sb.AppendLine();
|
||||
|
||||
// Calculate how many blank cells appear before day 1
|
||||
var firstDayDow = (int)firstDayOfMonth.DayOfWeek;
|
||||
var offset = ((firstDayDow - (int)firstDayOfWeek) + 7) % 7;
|
||||
|
||||
sb.Append('|');
|
||||
for (var i = 0; i < offset; i++)
|
||||
{
|
||||
sb.Append(" |");
|
||||
}
|
||||
|
||||
var col = offset;
|
||||
for (var day = 1; day <= daysInMonth; day++)
|
||||
{
|
||||
if (day == now.Day)
|
||||
{
|
||||
sb.Append($" **{day}** |");
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append($" {day} |");
|
||||
}
|
||||
|
||||
col++;
|
||||
|
||||
if (col == 7 && day < daysInMonth)
|
||||
{
|
||||
sb.AppendLine();
|
||||
sb.Append('|');
|
||||
col = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Pad the last row with empty cells
|
||||
while (col > 0 && col < 7)
|
||||
{
|
||||
sb.Append(" |");
|
||||
col++;
|
||||
}
|
||||
|
||||
sb.AppendLine();
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
@@ -959,5 +959,14 @@ namespace Microsoft.CmdPal.Ext.TimeDate {
|
||||
return ResourceManager.GetString("timedate_copy_time_command_name", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Calendar.
|
||||
/// </summary>
|
||||
public static string timedate_calendar_page_name {
|
||||
get {
|
||||
return ResourceManager.GetString("timedate_calendar_page_name", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -444,4 +444,8 @@
|
||||
<value>Copy date</value>
|
||||
<comment>Name of a command to copy the current date to the clipboard</comment>
|
||||
</data>
|
||||
<data name="timedate_calendar_page_name" xml:space="preserve">
|
||||
<value>Calendar</value>
|
||||
<comment>Name of the calendar page shown when clicking the clock in the dock</comment>
|
||||
</data>
|
||||
</root>
|
||||
@@ -75,7 +75,7 @@ internal sealed partial class NowDockBand : ListItem
|
||||
|
||||
public NowDockBand()
|
||||
{
|
||||
Command = new NoOpCommand() { Id = "com.microsoft.cmdpal.timedate.dockBand" };
|
||||
Command = new CalendarPage();
|
||||
_copyTimeCommand = new CopyTextCommand(string.Empty) { Name = Resources.timedate_copy_time_command_name };
|
||||
_copyDateCommand = new CopyTextCommand(string.Empty) { Name = Resources.timedate_copy_date_command_name };
|
||||
MoreCommands = [
|
||||
|
||||
Reference in New Issue
Block a user