2020-11-17 01:37:19 +01:00
|
|
|
// Copyright (c) Microsoft Corporation.
|
|
|
|
// Licensed under the MIT license.
|
|
|
|
|
|
|
|
#include "pch.h"
|
|
|
|
|
|
|
|
#include "../TerminalSettingsModel/ColorScheme.h"
|
|
|
|
#include "../TerminalSettingsModel/CascadiaSettings.h"
|
|
|
|
#include "JsonTestClass.h"
|
|
|
|
#include "TestUtils.h"
|
|
|
|
#include <defaults.h>
|
|
|
|
|
|
|
|
using namespace Microsoft::Console;
|
|
|
|
using namespace WEX::Logging;
|
|
|
|
using namespace WEX::TestExecution;
|
|
|
|
using namespace WEX::Common;
|
|
|
|
using namespace winrt::Microsoft::Terminal::Settings::Model;
|
2021-03-17 21:47:24 +01:00
|
|
|
using namespace winrt::Microsoft::Terminal::Control;
|
2020-11-17 01:37:19 +01:00
|
|
|
|
|
|
|
namespace SettingsModelLocalTests
|
|
|
|
{
|
|
|
|
// TODO:microsoft/terminal#3838:
|
|
|
|
// Unfortunately, these tests _WILL NOT_ work in our CI. We're waiting for
|
|
|
|
// an updated TAEF that will let us install framework packages when the test
|
|
|
|
// package is deployed. Until then, these tests won't deploy in CI.
|
|
|
|
|
|
|
|
class SerializationTests : public JsonTestClass
|
|
|
|
{
|
|
|
|
// Use a custom AppxManifest to ensure that we can activate winrt types
|
|
|
|
// from our test. This property will tell taef to manually use this as
|
|
|
|
// the AppxManifest for this test class.
|
|
|
|
// This does not yet work for anything XAML-y. See TabTests.cpp for more
|
|
|
|
// details on that.
|
|
|
|
BEGIN_TEST_CLASS(SerializationTests)
|
|
|
|
TEST_CLASS_PROPERTY(L"RunAs", L"UAP")
|
|
|
|
TEST_CLASS_PROPERTY(L"UAP:AppXManifest", L"TestHostAppXManifest.xml")
|
|
|
|
END_TEST_CLASS()
|
|
|
|
|
|
|
|
TEST_METHOD(GlobalSettings);
|
|
|
|
TEST_METHOD(Profile);
|
|
|
|
TEST_METHOD(ColorScheme);
|
2021-05-20 20:44:04 +02:00
|
|
|
TEST_METHOD(Actions);
|
2020-11-17 01:37:19 +01:00
|
|
|
TEST_METHOD(CascadiaSettings);
|
2021-07-01 19:08:46 +02:00
|
|
|
TEST_METHOD(LegacyFontSettings);
|
2020-11-17 01:37:19 +01:00
|
|
|
|
|
|
|
private:
|
|
|
|
// Method Description:
|
|
|
|
// - deserializes and reserializes a json string representing a settings object model of type T
|
|
|
|
// - verifies that the generated json string matches the provided one
|
|
|
|
// Template Types:
|
|
|
|
// - <T>: The type of Settings Model object to generate (must be impl type)
|
|
|
|
// Arguments:
|
|
|
|
// - jsonString - JSON string we're performing the test on
|
|
|
|
// Return Value:
|
|
|
|
// - the JsonObject representing this instance
|
|
|
|
template<typename T>
|
2021-10-05 20:21:03 +02:00
|
|
|
void RoundtripTest(const std::string_view& jsonString)
|
2020-11-17 01:37:19 +01:00
|
|
|
{
|
|
|
|
const auto json{ VerifyParseSucceeded(jsonString) };
|
|
|
|
const auto settings{ T::FromJson(json) };
|
|
|
|
const auto result{ settings->ToJson() };
|
|
|
|
|
|
|
|
// Compare toString(json) instead of jsonString here.
|
|
|
|
// The toString writes the json out alphabetically.
|
|
|
|
// This trick allows jsonString to _not_ have to be
|
|
|
|
// written alphabetically.
|
|
|
|
VERIFY_ARE_EQUAL(toString(json), toString(result));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
void SerializationTests::GlobalSettings()
|
|
|
|
{
|
2021-10-05 20:21:03 +02:00
|
|
|
static constexpr std::string_view globalsString{ R"(
|
2020-11-17 01:37:19 +01:00
|
|
|
{
|
|
|
|
"defaultProfile": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}",
|
|
|
|
|
|
|
|
"initialRows": 30,
|
|
|
|
"initialCols": 120,
|
|
|
|
"initialPosition": ",",
|
|
|
|
"launchMode": "default",
|
|
|
|
"alwaysOnTop": false,
|
2021-02-22 21:08:49 +01:00
|
|
|
"inputServiceWarning": true,
|
2020-11-17 01:37:19 +01:00
|
|
|
"copyOnSelect": false,
|
|
|
|
"copyFormatting": "all",
|
|
|
|
"wordDelimiters": " /\\()\"'-.,:;<>~!@#$%^&*|+=[]{}~?\u2502",
|
|
|
|
|
|
|
|
"alwaysShowTabs": true,
|
|
|
|
"showTabsInTitlebar": true,
|
|
|
|
"showTerminalTitleInTitlebar": true,
|
|
|
|
"tabWidthMode": "equal",
|
|
|
|
"tabSwitcherMode": "mru",
|
|
|
|
|
|
|
|
"startOnUserLogin": false,
|
|
|
|
"theme": "system",
|
|
|
|
"snapToGridOnResize": true,
|
|
|
|
"disableAnimations": false,
|
|
|
|
|
|
|
|
"confirmCloseAllTabs": true,
|
|
|
|
"largePasteWarning": true,
|
|
|
|
"multiLinePasteWarning": true,
|
2021-10-28 17:38:23 +02:00
|
|
|
"trimPaste": true,
|
2020-11-17 01:37:19 +01:00
|
|
|
|
|
|
|
"experimental.input.forceVT": false,
|
|
|
|
"experimental.rendering.forceFullRepaint": false,
|
2021-05-20 20:44:04 +02:00
|
|
|
"experimental.rendering.software": false,
|
|
|
|
|
|
|
|
"actions": []
|
2020-11-17 01:37:19 +01:00
|
|
|
})" };
|
|
|
|
|
2021-10-05 20:21:03 +02:00
|
|
|
static constexpr std::string_view smallGlobalsString{ R"(
|
2020-11-17 01:37:19 +01:00
|
|
|
{
|
2021-05-20 20:44:04 +02:00
|
|
|
"defaultProfile": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}",
|
|
|
|
"actions": []
|
2020-11-17 01:37:19 +01:00
|
|
|
})" };
|
|
|
|
|
|
|
|
RoundtripTest<implementation::GlobalAppSettings>(globalsString);
|
|
|
|
RoundtripTest<implementation::GlobalAppSettings>(smallGlobalsString);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SerializationTests::Profile()
|
|
|
|
{
|
2021-10-05 20:21:03 +02:00
|
|
|
static constexpr std::string_view profileString{ R"(
|
2020-11-17 01:37:19 +01:00
|
|
|
{
|
|
|
|
"name": "Windows PowerShell",
|
|
|
|
"guid": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}",
|
|
|
|
|
|
|
|
"commandline": "%SystemRoot%\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
|
|
|
|
"startingDirectory": "%USERPROFILE%",
|
|
|
|
|
|
|
|
"icon": "ms-appx:///ProfileIcons/{61c54bbd-c2c6-5271-96e7-009a87ff44bf}.png",
|
|
|
|
"hidden": false,
|
|
|
|
|
|
|
|
"tabTitle": "Cool Tab",
|
|
|
|
"suppressApplicationTitle": false,
|
|
|
|
|
2021-07-01 19:08:46 +02:00
|
|
|
"font": {
|
|
|
|
"face": "Cascadia Mono",
|
|
|
|
"size": 12,
|
|
|
|
"weight": "normal"
|
|
|
|
},
|
2020-11-17 01:37:19 +01:00
|
|
|
"padding": "8, 8, 8, 8",
|
|
|
|
"antialiasingMode": "grayscale",
|
|
|
|
|
|
|
|
"cursorShape": "bar",
|
|
|
|
"cursorColor": "#CCBBAA",
|
|
|
|
"cursorHeight": 10,
|
|
|
|
|
|
|
|
"altGrAliasing": true,
|
|
|
|
|
|
|
|
"colorScheme": "Campbell",
|
|
|
|
"tabColor": "#0C0C0C",
|
|
|
|
"foreground": "#AABBCC",
|
|
|
|
"background": "#BBCCAA",
|
|
|
|
"selectionBackground": "#CCAABB",
|
|
|
|
|
|
|
|
"useAcrylic": false,
|
2021-10-05 20:21:03 +02:00
|
|
|
"opacity": 50,
|
2020-11-17 01:37:19 +01:00
|
|
|
|
|
|
|
"backgroundImage": "made_you_look.jpeg",
|
|
|
|
"backgroundImageStretchMode": "uniformToFill",
|
|
|
|
"backgroundImageAlignment": "center",
|
|
|
|
"backgroundImageOpacity": 1.0,
|
|
|
|
|
|
|
|
"scrollbarState": "visible",
|
|
|
|
"snapOnInput": true,
|
|
|
|
"historySize": 9001,
|
|
|
|
|
|
|
|
"closeOnExit": "graceful",
|
|
|
|
"experimental.retroTerminalEffect": false
|
|
|
|
})" };
|
|
|
|
|
2021-10-05 20:21:03 +02:00
|
|
|
static constexpr std::string_view smallProfileString{ R"(
|
2020-11-17 01:37:19 +01:00
|
|
|
{
|
|
|
|
"name": "Custom Profile"
|
|
|
|
})" };
|
|
|
|
|
|
|
|
// Setting "tabColor" to null tests two things:
|
|
|
|
// - null should count as an explicit user-set value, not falling back to the parent's value
|
|
|
|
// - null should be acceptable even though we're working with colors
|
2021-10-05 20:21:03 +02:00
|
|
|
static constexpr std::string_view weirdProfileString{ R"(
|
2020-11-17 01:37:19 +01:00
|
|
|
{
|
2021-05-20 20:44:04 +02:00
|
|
|
"guid" : "{8b039d4d-77ca-5a83-88e1-dfc8e895a127}",
|
2020-11-17 01:37:19 +01:00
|
|
|
"name": "Weird Profile",
|
2021-05-20 20:44:04 +02:00
|
|
|
"hidden": false,
|
2020-11-17 01:37:19 +01:00
|
|
|
"tabColor": null,
|
|
|
|
"foreground": null,
|
|
|
|
"source": "local"
|
|
|
|
})" };
|
|
|
|
|
|
|
|
RoundtripTest<implementation::Profile>(profileString);
|
|
|
|
RoundtripTest<implementation::Profile>(smallProfileString);
|
|
|
|
RoundtripTest<implementation::Profile>(weirdProfileString);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SerializationTests::ColorScheme()
|
|
|
|
{
|
2021-10-05 20:21:03 +02:00
|
|
|
static constexpr std::string_view schemeString{ R"({
|
2020-11-17 01:37:19 +01:00
|
|
|
"name": "Campbell",
|
|
|
|
|
|
|
|
"cursorColor": "#FFFFFF",
|
|
|
|
"selectionBackground": "#131313",
|
|
|
|
|
|
|
|
"background": "#0C0C0C",
|
|
|
|
"foreground": "#F2F2F2",
|
|
|
|
|
|
|
|
"black": "#0C0C0C",
|
|
|
|
"blue": "#0037DA",
|
|
|
|
"cyan": "#3A96DD",
|
|
|
|
"green": "#13A10E",
|
|
|
|
"purple": "#881798",
|
|
|
|
"red": "#C50F1F",
|
|
|
|
"white": "#CCCCCC",
|
|
|
|
"yellow": "#C19C00",
|
|
|
|
"brightBlack": "#767676",
|
|
|
|
"brightBlue": "#3B78FF",
|
|
|
|
"brightCyan": "#61D6D6",
|
|
|
|
"brightGreen": "#16C60C",
|
|
|
|
"brightPurple": "#B4009E",
|
|
|
|
"brightRed": "#E74856",
|
|
|
|
"brightWhite": "#F2F2F2",
|
|
|
|
"brightYellow": "#F9F1A5"
|
|
|
|
})" };
|
|
|
|
|
|
|
|
RoundtripTest<implementation::ColorScheme>(schemeString);
|
|
|
|
}
|
|
|
|
|
2021-05-20 20:44:04 +02:00
|
|
|
void SerializationTests::Actions()
|
|
|
|
{
|
2021-06-10 20:25:27 +02:00
|
|
|
// simple command
|
2021-10-05 20:21:03 +02:00
|
|
|
static constexpr std::string_view actionsString1{ R"([
|
2021-05-20 20:44:04 +02:00
|
|
|
{ "command": "paste" }
|
|
|
|
])" };
|
|
|
|
|
2021-06-10 20:25:27 +02:00
|
|
|
// complex command
|
2021-10-05 20:21:03 +02:00
|
|
|
static constexpr std::string_view actionsString2A{ R"([
|
2021-05-20 20:44:04 +02:00
|
|
|
{ "command": { "action": "setTabColor" } }
|
|
|
|
])" };
|
2021-10-05 20:21:03 +02:00
|
|
|
static constexpr std::string_view actionsString2B{ R"([
|
2021-05-20 20:44:04 +02:00
|
|
|
{ "command": { "action": "setTabColor", "color": "#112233" } }
|
|
|
|
])" };
|
2021-10-05 20:21:03 +02:00
|
|
|
static constexpr std::string_view actionsString2C{ R"([
|
2021-05-20 20:44:04 +02:00
|
|
|
{ "command": { "action": "copy" } },
|
|
|
|
{ "command": { "action": "copy", "singleLine": true, "copyFormatting": "html" } }
|
|
|
|
])" };
|
|
|
|
|
2021-06-10 20:25:27 +02:00
|
|
|
// simple command with key chords
|
2021-10-05 20:21:03 +02:00
|
|
|
static constexpr std::string_view actionsString3{ R"([
|
2021-05-20 20:44:04 +02:00
|
|
|
{ "command": "toggleAlwaysOnTop", "keys": "ctrl+a" },
|
|
|
|
{ "command": "toggleAlwaysOnTop", "keys": "ctrl+b" }
|
|
|
|
])" };
|
|
|
|
|
2021-06-10 20:25:27 +02:00
|
|
|
// complex command with key chords
|
2021-10-05 20:21:03 +02:00
|
|
|
static constexpr std::string_view actionsString4A{ R"([
|
2021-05-20 20:44:04 +02:00
|
|
|
{ "command": { "action": "adjustFontSize", "delta": 1 }, "keys": "ctrl+c" },
|
|
|
|
{ "command": { "action": "adjustFontSize", "delta": 1 }, "keys": "ctrl+d" }
|
|
|
|
])" };
|
2021-10-05 20:21:03 +02:00
|
|
|
static constexpr std::string_view actionsString4B{ R"([
|
2021-09-15 20:00:33 +02:00
|
|
|
{ "command": { "action": "findMatch", "direction": "next" }, "keys": "ctrl+shift+s" },
|
|
|
|
{ "command": { "action": "findMatch", "direction": "prev" }, "keys": "ctrl+shift+r" }
|
|
|
|
])" };
|
2021-05-20 20:44:04 +02:00
|
|
|
|
2021-06-10 20:25:27 +02:00
|
|
|
// command with name and icon and multiple key chords
|
2021-10-05 20:21:03 +02:00
|
|
|
static constexpr std::string_view actionsString5{ R"([
|
2021-05-20 20:44:04 +02:00
|
|
|
{ "icon": "image.png", "name": "Scroll To Top Name", "command": "scrollToTop", "keys": "ctrl+e" },
|
|
|
|
{ "command": "scrollToTop", "keys": "ctrl+f" }
|
|
|
|
])" };
|
|
|
|
|
2021-06-10 20:25:27 +02:00
|
|
|
// complex command with new terminal args
|
2021-10-05 20:21:03 +02:00
|
|
|
static constexpr std::string_view actionsString6{ R"([
|
2021-05-20 20:44:04 +02:00
|
|
|
{ "command": { "action": "newTab", "index": 0 }, "keys": "ctrl+g" },
|
|
|
|
])" };
|
|
|
|
|
2021-06-10 20:25:27 +02:00
|
|
|
// complex command with meaningful null arg
|
2021-10-05 20:21:03 +02:00
|
|
|
static constexpr std::string_view actionsString7{ R"([
|
2021-05-20 20:44:04 +02:00
|
|
|
{ "command": { "action": "renameWindow", "name": null }, "keys": "ctrl+h" }
|
|
|
|
])" };
|
|
|
|
|
2021-06-10 20:25:27 +02:00
|
|
|
// nested command
|
2021-10-05 20:21:03 +02:00
|
|
|
static constexpr std::string_view actionsString8{ R"([
|
2021-05-20 20:44:04 +02:00
|
|
|
{
|
|
|
|
"name": "Change font size...",
|
|
|
|
"commands": [
|
|
|
|
{ "command": { "action": "adjustFontSize", "delta": 1 } },
|
|
|
|
{ "command": { "action": "adjustFontSize", "delta": -1 } },
|
|
|
|
{ "command": "resetFontSize" },
|
|
|
|
]
|
|
|
|
}
|
|
|
|
])" };
|
|
|
|
|
2021-06-10 20:25:27 +02:00
|
|
|
// iterable command
|
2021-10-05 20:21:03 +02:00
|
|
|
static constexpr std::string_view actionsString9A{ R"([
|
2021-05-20 20:44:04 +02:00
|
|
|
{
|
|
|
|
"name": "New tab",
|
|
|
|
"commands": [
|
|
|
|
{
|
|
|
|
"iterateOn": "profiles",
|
|
|
|
"icon": "${profile.icon}",
|
|
|
|
"name": "${profile.name}",
|
|
|
|
"command": { "action": "newTab", "profile": "${profile.name}" }
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
])" };
|
2021-10-05 20:21:03 +02:00
|
|
|
static constexpr std::string_view actionsString9B{ R"([
|
2021-05-20 20:44:04 +02:00
|
|
|
{
|
Reduce usage of Json::Value throughout Terminal.Settings.Model (#11184)
This commit reduces the code surface that interacts with raw JSON data,
reducing code complexity and improving maintainability.
Files that needed to be changed drastically were additionally
cleaned up to remove any code cruft that has accrued over time.
In order to facility this the following changes were made:
* Move JSON handling from `CascadiaSettings` into `SettingsLoader`
This allows us to use STL containers for data model instances.
For instance profiles are now added to a hashmap for O(1) lookup.
* JSON parsing within `SettingsLoader` doesn't differentiate between user,
inbox and fragment JSON data, reducing code complexity and size.
It also centralizes common concerns, like profile deduplication and
ensuring that all profiles are assigned a GUID.
* Direct JSON modification, like the insertion of dynamic profiles into
settings.json were removed. This vastly reduces code complexity,
but unfortunately removes support for comments in JSON on first start.
* `ColorScheme`s cannot be layered. As such its `LayerJson` API was replaced
with `FromJson`, allowing us to remove JSON-based color scheme validation.
* `Profile`s used to test their wish to layer using `ShouldBeLayered`, which
was replaced with a GUID-based hashmap lookup on previously parsed profiles.
Further changes were made as improvements upon the previous changes:
* Compact the JSON files embedded binary, saving 28kB
* Prevent double-initialization of the color table in `ColorScheme`
* Making `til::color` getters `constexpr`, allow better optimizations
The result is a reduction of:
* 48kB binary size for the Settings.Model.dll
* 5-10% startup duration
* 26% code for the `CascadiaSettings` class
* 1% overall code in this project
Furthermore this results in the following breaking changes:
* The long deprecated "globals" settings object will not be detected and no
warning will be created during load.
* The initial creation of a new settings.json will not produce helpful comments.
Both cases are caused by the removal of manual JSON handling and the
move to representing the settings file with model objects instead
## PR Checklist
* [x] Closes #5276
* [x] Closes #7421
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
* Out-of-box-experience is identical to before ✔️
(Except for the settings.json file lacking comments.)
* Existing user settings load correctly ✔️
* New WSL instances are added to user settings ✔️
* New fragments are added to user settings ✔️
* All profiles are assigned GUIDs ✔️
2021-09-22 18:27:31 +02:00
|
|
|
"commands":
|
2021-05-20 20:44:04 +02:00
|
|
|
[
|
|
|
|
{
|
Reduce usage of Json::Value throughout Terminal.Settings.Model (#11184)
This commit reduces the code surface that interacts with raw JSON data,
reducing code complexity and improving maintainability.
Files that needed to be changed drastically were additionally
cleaned up to remove any code cruft that has accrued over time.
In order to facility this the following changes were made:
* Move JSON handling from `CascadiaSettings` into `SettingsLoader`
This allows us to use STL containers for data model instances.
For instance profiles are now added to a hashmap for O(1) lookup.
* JSON parsing within `SettingsLoader` doesn't differentiate between user,
inbox and fragment JSON data, reducing code complexity and size.
It also centralizes common concerns, like profile deduplication and
ensuring that all profiles are assigned a GUID.
* Direct JSON modification, like the insertion of dynamic profiles into
settings.json were removed. This vastly reduces code complexity,
but unfortunately removes support for comments in JSON on first start.
* `ColorScheme`s cannot be layered. As such its `LayerJson` API was replaced
with `FromJson`, allowing us to remove JSON-based color scheme validation.
* `Profile`s used to test their wish to layer using `ShouldBeLayered`, which
was replaced with a GUID-based hashmap lookup on previously parsed profiles.
Further changes were made as improvements upon the previous changes:
* Compact the JSON files embedded binary, saving 28kB
* Prevent double-initialization of the color table in `ColorScheme`
* Making `til::color` getters `constexpr`, allow better optimizations
The result is a reduction of:
* 48kB binary size for the Settings.Model.dll
* 5-10% startup duration
* 26% code for the `CascadiaSettings` class
* 1% overall code in this project
Furthermore this results in the following breaking changes:
* The long deprecated "globals" settings object will not be detected and no
warning will be created during load.
* The initial creation of a new settings.json will not produce helpful comments.
Both cases are caused by the removal of manual JSON handling and the
move to representing the settings file with model objects instead
## PR Checklist
* [x] Closes #5276
* [x] Closes #7421
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
* Out-of-box-experience is identical to before ✔️
(Except for the settings.json file lacking comments.)
* Existing user settings load correctly ✔️
* New WSL instances are added to user settings ✔️
* New fragments are added to user settings ✔️
* All profiles are assigned GUIDs ✔️
2021-09-22 18:27:31 +02:00
|
|
|
"command":
|
2021-05-20 20:44:04 +02:00
|
|
|
{
|
|
|
|
"action": "sendInput",
|
|
|
|
"input": "${profile.name}"
|
|
|
|
},
|
|
|
|
"iterateOn": "profiles"
|
|
|
|
}
|
|
|
|
],
|
|
|
|
"name": "Send Input ..."
|
|
|
|
}
|
|
|
|
])" };
|
2021-10-05 20:21:03 +02:00
|
|
|
static constexpr std::string_view actionsString9C{ R""([
|
2021-05-20 20:44:04 +02:00
|
|
|
{
|
Reduce usage of Json::Value throughout Terminal.Settings.Model (#11184)
This commit reduces the code surface that interacts with raw JSON data,
reducing code complexity and improving maintainability.
Files that needed to be changed drastically were additionally
cleaned up to remove any code cruft that has accrued over time.
In order to facility this the following changes were made:
* Move JSON handling from `CascadiaSettings` into `SettingsLoader`
This allows us to use STL containers for data model instances.
For instance profiles are now added to a hashmap for O(1) lookup.
* JSON parsing within `SettingsLoader` doesn't differentiate between user,
inbox and fragment JSON data, reducing code complexity and size.
It also centralizes common concerns, like profile deduplication and
ensuring that all profiles are assigned a GUID.
* Direct JSON modification, like the insertion of dynamic profiles into
settings.json were removed. This vastly reduces code complexity,
but unfortunately removes support for comments in JSON on first start.
* `ColorScheme`s cannot be layered. As such its `LayerJson` API was replaced
with `FromJson`, allowing us to remove JSON-based color scheme validation.
* `Profile`s used to test their wish to layer using `ShouldBeLayered`, which
was replaced with a GUID-based hashmap lookup on previously parsed profiles.
Further changes were made as improvements upon the previous changes:
* Compact the JSON files embedded binary, saving 28kB
* Prevent double-initialization of the color table in `ColorScheme`
* Making `til::color` getters `constexpr`, allow better optimizations
The result is a reduction of:
* 48kB binary size for the Settings.Model.dll
* 5-10% startup duration
* 26% code for the `CascadiaSettings` class
* 1% overall code in this project
Furthermore this results in the following breaking changes:
* The long deprecated "globals" settings object will not be detected and no
warning will be created during load.
* The initial creation of a new settings.json will not produce helpful comments.
Both cases are caused by the removal of manual JSON handling and the
move to representing the settings file with model objects instead
## PR Checklist
* [x] Closes #5276
* [x] Closes #7421
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
* Out-of-box-experience is identical to before ✔️
(Except for the settings.json file lacking comments.)
* Existing user settings load correctly ✔️
* New WSL instances are added to user settings ✔️
* New fragments are added to user settings ✔️
* All profiles are assigned GUIDs ✔️
2021-09-22 18:27:31 +02:00
|
|
|
"commands":
|
2021-05-20 20:44:04 +02:00
|
|
|
[
|
|
|
|
{
|
Reduce usage of Json::Value throughout Terminal.Settings.Model (#11184)
This commit reduces the code surface that interacts with raw JSON data,
reducing code complexity and improving maintainability.
Files that needed to be changed drastically were additionally
cleaned up to remove any code cruft that has accrued over time.
In order to facility this the following changes were made:
* Move JSON handling from `CascadiaSettings` into `SettingsLoader`
This allows us to use STL containers for data model instances.
For instance profiles are now added to a hashmap for O(1) lookup.
* JSON parsing within `SettingsLoader` doesn't differentiate between user,
inbox and fragment JSON data, reducing code complexity and size.
It also centralizes common concerns, like profile deduplication and
ensuring that all profiles are assigned a GUID.
* Direct JSON modification, like the insertion of dynamic profiles into
settings.json were removed. This vastly reduces code complexity,
but unfortunately removes support for comments in JSON on first start.
* `ColorScheme`s cannot be layered. As such its `LayerJson` API was replaced
with `FromJson`, allowing us to remove JSON-based color scheme validation.
* `Profile`s used to test their wish to layer using `ShouldBeLayered`, which
was replaced with a GUID-based hashmap lookup on previously parsed profiles.
Further changes were made as improvements upon the previous changes:
* Compact the JSON files embedded binary, saving 28kB
* Prevent double-initialization of the color table in `ColorScheme`
* Making `til::color` getters `constexpr`, allow better optimizations
The result is a reduction of:
* 48kB binary size for the Settings.Model.dll
* 5-10% startup duration
* 26% code for the `CascadiaSettings` class
* 1% overall code in this project
Furthermore this results in the following breaking changes:
* The long deprecated "globals" settings object will not be detected and no
warning will be created during load.
* The initial creation of a new settings.json will not produce helpful comments.
Both cases are caused by the removal of manual JSON handling and the
move to representing the settings file with model objects instead
## PR Checklist
* [x] Closes #5276
* [x] Closes #7421
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
* Out-of-box-experience is identical to before ✔️
(Except for the settings.json file lacking comments.)
* Existing user settings load correctly ✔️
* New WSL instances are added to user settings ✔️
* New fragments are added to user settings ✔️
* All profiles are assigned GUIDs ✔️
2021-09-22 18:27:31 +02:00
|
|
|
"commands":
|
2021-05-20 20:44:04 +02:00
|
|
|
[
|
|
|
|
{
|
Reduce usage of Json::Value throughout Terminal.Settings.Model (#11184)
This commit reduces the code surface that interacts with raw JSON data,
reducing code complexity and improving maintainability.
Files that needed to be changed drastically were additionally
cleaned up to remove any code cruft that has accrued over time.
In order to facility this the following changes were made:
* Move JSON handling from `CascadiaSettings` into `SettingsLoader`
This allows us to use STL containers for data model instances.
For instance profiles are now added to a hashmap for O(1) lookup.
* JSON parsing within `SettingsLoader` doesn't differentiate between user,
inbox and fragment JSON data, reducing code complexity and size.
It also centralizes common concerns, like profile deduplication and
ensuring that all profiles are assigned a GUID.
* Direct JSON modification, like the insertion of dynamic profiles into
settings.json were removed. This vastly reduces code complexity,
but unfortunately removes support for comments in JSON on first start.
* `ColorScheme`s cannot be layered. As such its `LayerJson` API was replaced
with `FromJson`, allowing us to remove JSON-based color scheme validation.
* `Profile`s used to test their wish to layer using `ShouldBeLayered`, which
was replaced with a GUID-based hashmap lookup on previously parsed profiles.
Further changes were made as improvements upon the previous changes:
* Compact the JSON files embedded binary, saving 28kB
* Prevent double-initialization of the color table in `ColorScheme`
* Making `til::color` getters `constexpr`, allow better optimizations
The result is a reduction of:
* 48kB binary size for the Settings.Model.dll
* 5-10% startup duration
* 26% code for the `CascadiaSettings` class
* 1% overall code in this project
Furthermore this results in the following breaking changes:
* The long deprecated "globals" settings object will not be detected and no
warning will be created during load.
* The initial creation of a new settings.json will not produce helpful comments.
Both cases are caused by the removal of manual JSON handling and the
move to representing the settings file with model objects instead
## PR Checklist
* [x] Closes #5276
* [x] Closes #7421
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
* Out-of-box-experience is identical to before ✔️
(Except for the settings.json file lacking comments.)
* Existing user settings load correctly ✔️
* New WSL instances are added to user settings ✔️
* New fragments are added to user settings ✔️
* All profiles are assigned GUIDs ✔️
2021-09-22 18:27:31 +02:00
|
|
|
"command":
|
2021-05-20 20:44:04 +02:00
|
|
|
{
|
|
|
|
"action": "sendInput",
|
|
|
|
"input": "${profile.name} ${scheme.name}"
|
|
|
|
},
|
|
|
|
"iterateOn": "schemes"
|
|
|
|
}
|
|
|
|
],
|
|
|
|
"iterateOn": "profiles",
|
|
|
|
"name": "nest level (${profile.name})"
|
|
|
|
}
|
|
|
|
],
|
|
|
|
"name": "Send Input (Evil) ..."
|
|
|
|
}
|
|
|
|
])"" };
|
2021-10-05 20:21:03 +02:00
|
|
|
static constexpr std::string_view actionsString9D{ R""([
|
2021-06-10 20:25:27 +02:00
|
|
|
{
|
Reduce usage of Json::Value throughout Terminal.Settings.Model (#11184)
This commit reduces the code surface that interacts with raw JSON data,
reducing code complexity and improving maintainability.
Files that needed to be changed drastically were additionally
cleaned up to remove any code cruft that has accrued over time.
In order to facility this the following changes were made:
* Move JSON handling from `CascadiaSettings` into `SettingsLoader`
This allows us to use STL containers for data model instances.
For instance profiles are now added to a hashmap for O(1) lookup.
* JSON parsing within `SettingsLoader` doesn't differentiate between user,
inbox and fragment JSON data, reducing code complexity and size.
It also centralizes common concerns, like profile deduplication and
ensuring that all profiles are assigned a GUID.
* Direct JSON modification, like the insertion of dynamic profiles into
settings.json were removed. This vastly reduces code complexity,
but unfortunately removes support for comments in JSON on first start.
* `ColorScheme`s cannot be layered. As such its `LayerJson` API was replaced
with `FromJson`, allowing us to remove JSON-based color scheme validation.
* `Profile`s used to test their wish to layer using `ShouldBeLayered`, which
was replaced with a GUID-based hashmap lookup on previously parsed profiles.
Further changes were made as improvements upon the previous changes:
* Compact the JSON files embedded binary, saving 28kB
* Prevent double-initialization of the color table in `ColorScheme`
* Making `til::color` getters `constexpr`, allow better optimizations
The result is a reduction of:
* 48kB binary size for the Settings.Model.dll
* 5-10% startup duration
* 26% code for the `CascadiaSettings` class
* 1% overall code in this project
Furthermore this results in the following breaking changes:
* The long deprecated "globals" settings object will not be detected and no
warning will be created during load.
* The initial creation of a new settings.json will not produce helpful comments.
Both cases are caused by the removal of manual JSON handling and the
move to representing the settings file with model objects instead
## PR Checklist
* [x] Closes #5276
* [x] Closes #7421
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
* Out-of-box-experience is identical to before ✔️
(Except for the settings.json file lacking comments.)
* Existing user settings load correctly ✔️
* New WSL instances are added to user settings ✔️
* New fragments are added to user settings ✔️
* All profiles are assigned GUIDs ✔️
2021-09-22 18:27:31 +02:00
|
|
|
"command":
|
2021-06-10 20:25:27 +02:00
|
|
|
{
|
|
|
|
"action": "newTab",
|
|
|
|
"profile": "${profile.name}"
|
|
|
|
},
|
|
|
|
"icon": "${profile.icon}",
|
|
|
|
"iterateOn": "profiles",
|
|
|
|
"name": "${profile.name}: New tab"
|
|
|
|
}
|
|
|
|
])"" };
|
2021-05-20 20:44:04 +02:00
|
|
|
|
2021-06-10 20:25:27 +02:00
|
|
|
// unbound command
|
2021-10-05 20:21:03 +02:00
|
|
|
static constexpr std::string_view actionsString10{ R"([
|
2021-05-20 20:44:04 +02:00
|
|
|
{ "command": "unbound", "keys": "ctrl+c" }
|
|
|
|
])" };
|
|
|
|
|
|
|
|
Log::Comment(L"simple command");
|
|
|
|
RoundtripTest<implementation::ActionMap>(actionsString1);
|
|
|
|
|
|
|
|
Log::Comment(L"complex commands");
|
|
|
|
RoundtripTest<implementation::ActionMap>(actionsString2A);
|
|
|
|
RoundtripTest<implementation::ActionMap>(actionsString2B);
|
|
|
|
RoundtripTest<implementation::ActionMap>(actionsString2C);
|
|
|
|
|
|
|
|
Log::Comment(L"simple command with key chords");
|
|
|
|
RoundtripTest<implementation::ActionMap>(actionsString3);
|
|
|
|
|
|
|
|
Log::Comment(L"complex commands with key chords");
|
2021-09-15 20:00:33 +02:00
|
|
|
RoundtripTest<implementation::ActionMap>(actionsString4A);
|
|
|
|
RoundtripTest<implementation::ActionMap>(actionsString4B);
|
2021-05-20 20:44:04 +02:00
|
|
|
|
|
|
|
Log::Comment(L"command with name and icon and multiple key chords");
|
|
|
|
RoundtripTest<implementation::ActionMap>(actionsString5);
|
|
|
|
|
|
|
|
Log::Comment(L"complex command with new terminal args");
|
|
|
|
RoundtripTest<implementation::ActionMap>(actionsString6);
|
|
|
|
|
|
|
|
Log::Comment(L"complex command with meaningful null arg");
|
|
|
|
RoundtripTest<implementation::ActionMap>(actionsString7);
|
|
|
|
|
|
|
|
Log::Comment(L"nested command");
|
|
|
|
RoundtripTest<implementation::ActionMap>(actionsString8);
|
|
|
|
|
|
|
|
Log::Comment(L"iterable command");
|
|
|
|
RoundtripTest<implementation::ActionMap>(actionsString9A);
|
|
|
|
RoundtripTest<implementation::ActionMap>(actionsString9B);
|
|
|
|
RoundtripTest<implementation::ActionMap>(actionsString9C);
|
2021-06-10 20:25:27 +02:00
|
|
|
RoundtripTest<implementation::ActionMap>(actionsString9D);
|
2021-05-20 20:44:04 +02:00
|
|
|
|
|
|
|
Log::Comment(L"unbound command");
|
|
|
|
RoundtripTest<implementation::ActionMap>(actionsString10);
|
|
|
|
}
|
|
|
|
|
2020-11-17 01:37:19 +01:00
|
|
|
void SerializationTests::CascadiaSettings()
|
|
|
|
{
|
2021-10-05 20:21:03 +02:00
|
|
|
static constexpr std::string_view settingsString{ R"({
|
Reduce usage of Json::Value throughout Terminal.Settings.Model (#11184)
This commit reduces the code surface that interacts with raw JSON data,
reducing code complexity and improving maintainability.
Files that needed to be changed drastically were additionally
cleaned up to remove any code cruft that has accrued over time.
In order to facility this the following changes were made:
* Move JSON handling from `CascadiaSettings` into `SettingsLoader`
This allows us to use STL containers for data model instances.
For instance profiles are now added to a hashmap for O(1) lookup.
* JSON parsing within `SettingsLoader` doesn't differentiate between user,
inbox and fragment JSON data, reducing code complexity and size.
It also centralizes common concerns, like profile deduplication and
ensuring that all profiles are assigned a GUID.
* Direct JSON modification, like the insertion of dynamic profiles into
settings.json were removed. This vastly reduces code complexity,
but unfortunately removes support for comments in JSON on first start.
* `ColorScheme`s cannot be layered. As such its `LayerJson` API was replaced
with `FromJson`, allowing us to remove JSON-based color scheme validation.
* `Profile`s used to test their wish to layer using `ShouldBeLayered`, which
was replaced with a GUID-based hashmap lookup on previously parsed profiles.
Further changes were made as improvements upon the previous changes:
* Compact the JSON files embedded binary, saving 28kB
* Prevent double-initialization of the color table in `ColorScheme`
* Making `til::color` getters `constexpr`, allow better optimizations
The result is a reduction of:
* 48kB binary size for the Settings.Model.dll
* 5-10% startup duration
* 26% code for the `CascadiaSettings` class
* 1% overall code in this project
Furthermore this results in the following breaking changes:
* The long deprecated "globals" settings object will not be detected and no
warning will be created during load.
* The initial creation of a new settings.json will not produce helpful comments.
Both cases are caused by the removal of manual JSON handling and the
move to representing the settings file with model objects instead
## PR Checklist
* [x] Closes #5276
* [x] Closes #7421
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
* Out-of-box-experience is identical to before ✔️
(Except for the settings.json file lacking comments.)
* Existing user settings load correctly ✔️
* New WSL instances are added to user settings ✔️
* New fragments are added to user settings ✔️
* All profiles are assigned GUIDs ✔️
2021-09-22 18:27:31 +02:00
|
|
|
"$help" : "https://aka.ms/terminal-documentation",
|
|
|
|
"$schema" : "https://aka.ms/terminal-profiles-schema",
|
|
|
|
"defaultProfile": "{61c54bbd-1111-5271-96e7-009a87ff44bf}",
|
|
|
|
"disabledProfileSources": [ "Windows.Terminal.Wsl" ],
|
|
|
|
"profiles": {
|
|
|
|
"defaults": {
|
|
|
|
"font": {
|
|
|
|
"face": "Zamora Code"
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"list": [
|
|
|
|
{
|
|
|
|
"font": { "face": "Cascadia Code" },
|
|
|
|
"guid": "{61c54bbd-1111-5271-96e7-009a87ff44bf}",
|
|
|
|
"name": "HowettShell"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"hidden": true,
|
|
|
|
"guid": "{c08b0496-e71c-5503-b84e-3af7a7a6d2a7}",
|
|
|
|
"name": "BhojwaniShell"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"antialiasingMode": "aliased",
|
|
|
|
"guid": "{fe9df758-ac22-5c20-922d-c7766cdd13af}",
|
|
|
|
"name": "NiksaShell"
|
|
|
|
}
|
|
|
|
]
|
|
|
|
},
|
|
|
|
"schemes": [
|
|
|
|
{
|
|
|
|
"name": "Cinnamon Roll",
|
|
|
|
|
|
|
|
"cursorColor": "#FFFFFD",
|
|
|
|
"selectionBackground": "#FFFFFF",
|
|
|
|
|
|
|
|
"background": "#3C0315",
|
|
|
|
"foreground": "#FFFFFD",
|
|
|
|
|
|
|
|
"black": "#282A2E",
|
|
|
|
"blue": "#0170C5",
|
|
|
|
"cyan": "#3F8D83",
|
|
|
|
"green": "#76AB23",
|
|
|
|
"purple": "#7D498F",
|
|
|
|
"red": "#BD0940",
|
|
|
|
"white": "#FFFFFD",
|
|
|
|
"yellow": "#E0DE48",
|
|
|
|
"brightBlack": "#676E7A",
|
|
|
|
"brightBlue": "#5C98C5",
|
|
|
|
"brightCyan": "#8ABEB7",
|
|
|
|
"brightGreen": "#B5D680",
|
|
|
|
"brightPurple": "#AC79BB",
|
|
|
|
"brightRed": "#BD6D85",
|
|
|
|
"brightWhite": "#FFFFFD",
|
|
|
|
"brightYellow": "#FFFD76"
|
|
|
|
}
|
|
|
|
],
|
|
|
|
"actions": [
|
|
|
|
{ "command": { "action": "sendInput", "input": "VT Griese Mode" }, "keys": "ctrl+k" }
|
|
|
|
]
|
|
|
|
})" };
|
|
|
|
|
|
|
|
const auto settings{ winrt::make_self<implementation::CascadiaSettings>(settingsString) };
|
2020-11-17 01:37:19 +01:00
|
|
|
|
|
|
|
const auto result{ settings->ToJson() };
|
Reduce usage of Json::Value throughout Terminal.Settings.Model (#11184)
This commit reduces the code surface that interacts with raw JSON data,
reducing code complexity and improving maintainability.
Files that needed to be changed drastically were additionally
cleaned up to remove any code cruft that has accrued over time.
In order to facility this the following changes were made:
* Move JSON handling from `CascadiaSettings` into `SettingsLoader`
This allows us to use STL containers for data model instances.
For instance profiles are now added to a hashmap for O(1) lookup.
* JSON parsing within `SettingsLoader` doesn't differentiate between user,
inbox and fragment JSON data, reducing code complexity and size.
It also centralizes common concerns, like profile deduplication and
ensuring that all profiles are assigned a GUID.
* Direct JSON modification, like the insertion of dynamic profiles into
settings.json were removed. This vastly reduces code complexity,
but unfortunately removes support for comments in JSON on first start.
* `ColorScheme`s cannot be layered. As such its `LayerJson` API was replaced
with `FromJson`, allowing us to remove JSON-based color scheme validation.
* `Profile`s used to test their wish to layer using `ShouldBeLayered`, which
was replaced with a GUID-based hashmap lookup on previously parsed profiles.
Further changes were made as improvements upon the previous changes:
* Compact the JSON files embedded binary, saving 28kB
* Prevent double-initialization of the color table in `ColorScheme`
* Making `til::color` getters `constexpr`, allow better optimizations
The result is a reduction of:
* 48kB binary size for the Settings.Model.dll
* 5-10% startup duration
* 26% code for the `CascadiaSettings` class
* 1% overall code in this project
Furthermore this results in the following breaking changes:
* The long deprecated "globals" settings object will not be detected and no
warning will be created during load.
* The initial creation of a new settings.json will not produce helpful comments.
Both cases are caused by the removal of manual JSON handling and the
move to representing the settings file with model objects instead
## PR Checklist
* [x] Closes #5276
* [x] Closes #7421
* [x] I work here
* [x] Tests added/passed
## Validation Steps Performed
* Out-of-box-experience is identical to before ✔️
(Except for the settings.json file lacking comments.)
* Existing user settings load correctly ✔️
* New WSL instances are added to user settings ✔️
* New fragments are added to user settings ✔️
* All profiles are assigned GUIDs ✔️
2021-09-22 18:27:31 +02:00
|
|
|
VERIFY_ARE_EQUAL(toString(VerifyParseSucceeded(settingsString)), toString(result));
|
2020-11-17 01:37:19 +01:00
|
|
|
}
|
2021-07-01 19:08:46 +02:00
|
|
|
|
|
|
|
void SerializationTests::LegacyFontSettings()
|
|
|
|
{
|
2021-10-05 20:21:03 +02:00
|
|
|
static constexpr std::string_view profileString{ R"(
|
2021-07-01 19:08:46 +02:00
|
|
|
{
|
|
|
|
"name": "Profile with legacy font settings",
|
|
|
|
|
|
|
|
"fontFace": "Cascadia Mono",
|
|
|
|
"fontSize": 12,
|
|
|
|
"fontWeight": "normal"
|
|
|
|
})" };
|
|
|
|
|
2021-10-05 20:21:03 +02:00
|
|
|
static constexpr std::string_view expectedOutput{ R"(
|
2021-07-01 19:08:46 +02:00
|
|
|
{
|
|
|
|
"name": "Profile with legacy font settings",
|
|
|
|
|
|
|
|
"font": {
|
|
|
|
"face": "Cascadia Mono",
|
|
|
|
"size": 12,
|
|
|
|
"weight": "normal"
|
|
|
|
}
|
|
|
|
})" };
|
|
|
|
|
|
|
|
const auto json{ VerifyParseSucceeded(profileString) };
|
|
|
|
const auto settings{ implementation::Profile::FromJson(json) };
|
|
|
|
const auto result{ settings->ToJson() };
|
|
|
|
|
|
|
|
const auto jsonOutput{ VerifyParseSucceeded(expectedOutput) };
|
|
|
|
|
|
|
|
VERIFY_ARE_EQUAL(toString(jsonOutput), toString(result));
|
|
|
|
}
|
2020-11-17 01:37:19 +01:00
|
|
|
}
|