Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Cascading User + Default Settings #2515

Merged
merged 54 commits into from
Sep 16, 2019
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
858341f
Create profiles by layering them
zadjii-msft Aug 20, 2019
2074ac2
Update test to layer multiple times on the same profile
zadjii-msft Aug 20, 2019
deb135f
Add support for layering an array of profiles, but break a couple tests
zadjii-msft Aug 20, 2019
e524ea7
Add a defaults.json to the package
zadjii-msft Aug 20, 2019
8157fd6
Layer colorschemes
zadjii-msft Aug 20, 2019
16336bb
Layer an array of color schemes
zadjii-msft Aug 20, 2019
870fed3
Merge remote-tracking branch 'origin/master' into dev/migrie/f/754-la…
zadjii-msft Aug 21, 2019
22e375d
oh no, this was missed with #2481
zadjii-msft Aug 21, 2019
4e3c3c3
Layer keybindings
zadjii-msft Aug 21, 2019
2c2fa14
Read settings from defaults.json + profiles.json, layer appropriately
zadjii-msft Aug 21, 2019
9bcf0c5
Add tests for keybindings
zadjii-msft Aug 21, 2019
c6b80b9
Layer or clear optional properties
zadjii-msft Aug 21, 2019
c040356
Add a helper to get an optional variable for a bunch of different types
zadjii-msft Aug 21, 2019
51bcf11
Do this with the stretch mode too
zadjii-msft Aug 21, 2019
8b938ff
Add back in the GUID check for profiles
zadjii-msft Aug 22, 2019
aec4c51
Add some tests for global settings layering
zadjii-msft Aug 22, 2019
1d662ca
M A D W I T H P O W E R
zadjii-msft Aug 22, 2019
9a14dab
When the user's profile.json doesn't exist, create it from a template
zadjii-msft Aug 22, 2019
82b57f8
Re-order profiles to match the order set in the user's profiles.json
zadjii-msft Aug 22, 2019
2084f89
Add tests for re-ordering profiles to match user ordering
zadjii-msft Aug 22, 2019
e07c1ba
Add support for hiding profiles using `"hidden": true`
zadjii-msft Aug 22, 2019
3ab0f25
Use the hardcoded defaults.json for the exception->"use defaults" case
zadjii-msft Aug 22, 2019
39b7fe1
Merge remote-tracking branch 'origin/master' into dev/migrie/f/754-la…
zadjii-msft Aug 22, 2019
9b6a2ee
Somehow I messed up the git submodules?
zadjii-msft Aug 22, 2019
be8e858
woo documentation
zadjii-msft Aug 22, 2019
7dcb179
Fix a Terminal.App.Unit.Tests failure
zadjii-msft Aug 23, 2019
7953e8c
signed/unsigned is hard
zadjii-msft Aug 23, 2019
2032b96
Use Alt+Settings button to open the default settings
zadjii-msft Aug 23, 2019
bf792e8
Missed a signed/unsigned
zadjii-msft Aug 23, 2019
215af70
Merge branch 'master' into dev/migrie/f/754-layer-settings
zadjii-msft Aug 26, 2019
48d3e76
Some very preliminary PR feedback
zadjii-msft Aug 26, 2019
679bf2e
More PR feedback
zadjii-msft Aug 26, 2019
2c978f7
Add templates to these bois
zadjii-msft Aug 26, 2019
9320304
remove some code for generating defaults, reorder defaults.json a tad
zadjii-msft Aug 26, 2019
083ac42
Merge branch 'master' into dev/migrie/f/754-layer-settings
zadjii-msft Aug 26, 2019
2278f22
Make guid a std::optional
zadjii-msft Aug 26, 2019
0873210
Large block of PR feedback
zadjii-msft Aug 27, 2019
e3171ea
stl is love, stl is life
zadjii-msft Aug 27, 2019
966ddeb
add `-noprofile`
zadjii-msft Aug 29, 2019
db6a734
Fix the crash that dustin found
zadjii-msft Aug 29, 2019
eea22cc
-Encoding ASCII
zadjii-msft Aug 29, 2019
a685bd8
Set a profile's default scheme to Campbell
zadjii-msft Aug 29, 2019
5e98b81
Fix the tests I regressed
zadjii-msft Aug 29, 2019
4eec81b
Update UsingJsonSetting.md to reflect that changes from these PRs
zadjii-msft Aug 29, 2019
ff1ad96
Change how GenerateGuidForProfile works
zadjii-msft Sep 3, 2019
54eb9c7
Merge branch 'master' into dev/migrie/f/754-layer-settings
zadjii-msft Sep 5, 2019
a659db1
Make AppKeyBindings do its own serialization
zadjii-msft Sep 5, 2019
a757b07
Remove leftover dead code from the previous commit
zadjii-msft Sep 5, 2019
46adadf
Fix up an enormous number of PR nits
zadjii-msft Sep 6, 2019
86aabba
Merge remote-tracking branch 'origin/master' into dev/migrie/f/754-la…
zadjii-msft Sep 11, 2019
edb1ead
Fix a typo; Update the defaults to match #2378
zadjii-msft Sep 11, 2019
fed6492
Tiny nits
zadjii-msft Sep 11, 2019
d1e98b6
Some typos, PR nits
zadjii-msft Sep 13, 2019
e454753
Fix this broken defaults case
zadjii-msft Sep 16, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/cascadia/CascadiaPackage/CascadiaPackage.wapproj
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@
<Content Include="$(OpenConsoleDir)res\terminal\Wide310x150Logo.scale-400.png">
<Link>Images\Wide310x150Logo.scale-400.png</Link>
</Content>
<!-- Profile Icons -->
<Content Include="ProfileIcons\{0caa0dad-35be-5f56-a8ff-afceeeaa6101}.scale-100.png" />
<Content Include="ProfileIcons\{0caa0dad-35be-5f56-a8ff-afceeeaa6101}.scale-200.png" />
<Content Include="ProfileIcons\{574e775e-4f2a-5b96-ac1e-a2962a402336}.scale-100.png" />
Expand All @@ -259,9 +260,16 @@
<Content Include="ProfileIcons\{9acb9455-ca41-5af7-950f-6bca1bc9722f}.scale-200.png" />
<Content Include="ProfileIcons\{b453ae62-4e3d-5e58-b989-0a998ec441b8}.scale-100.png" />
<Content Include="ProfileIcons\{b453ae62-4e3d-5e58-b989-0a998ec441b8}.scale-200.png" />
<!-- Default Settings -->
<Content Include="$(OpenConsoleDir)src\cascadia\TerminalApp\defaults.json">
<Link>defaults.json</Link>
</Content>
<!-- Resources -->
<PRIResource Include="Resources\en-US\Resources.resw" />
</ItemGroup>

<Import Project="$(OpenConsoleDir)src\wap-common.build.post.props" />

<ItemGroup>
<ProjectReference Include="..\WindowsTerminal\WindowsTerminal.vcxproj" />
<ProjectReference Include="..\..\host\exe\Host.EXE.vcxproj" />
Expand Down
234 changes: 234 additions & 0 deletions src/cascadia/LocalTests_TerminalApp/ColorSchemeTests.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

#include "precomp.h"

#include "../TerminalApp/ColorScheme.h"
#include "../TerminalApp/CascadiaSettings.h"
#include "JsonTestClass.h"

using namespace Microsoft::Console;
using namespace TerminalApp;
using namespace WEX::Logging;
using namespace WEX::TestExecution;
using namespace WEX::Common;

namespace TerminalAppLocalTests
{
// Unfortunately, these tests _WILL NOT_ work in our CI, until we have a lab
zadjii-msft marked this conversation as resolved.
Show resolved Hide resolved
// machine available that can run Windows version 18362.

class ColorSchemeTests : public JsonTestClass
{
// Use a custom manifest to ensure that we can activate winrt types from
// our test. This property will tell taef to manually use this as the
// sxs manifest during this test class. It includes all the cppwinrt
// types we've defined, so if your test is crashing for an unknown
// reason, make sure it's included in that file.
// If you want to do anything XAML-y, you'll need to run yor test in a
zadjii-msft marked this conversation as resolved.
Show resolved Hide resolved
// packaged context. See TabTests.cpp for more details on that.
BEGIN_TEST_CLASS(ColorSchemeTests)
TEST_CLASS_PROPERTY(L"ActivationContext", L"TerminalApp.LocalTests.manifest")
END_TEST_CLASS()

TEST_METHOD(CanLayerColorScheme);
TEST_METHOD(LayerColorSchemeProperties);
TEST_METHOD(LayerColorSchemesOnArray);

TEST_CLASS_SETUP(ClassSetup)
{
InitializeJsonReader();
return true;
}
};

void ColorSchemeTests::CanLayerColorScheme()
{
const std::string scheme0String{ R"({
"name": "scheme0",
"foreground": "#000000",
"background": "#010101"
})" };
const std::string scheme1String{ R"({
"name": "scheme1",
"foreground": "#020202",
"background": "#030303"
})" };
const std::string scheme2String{ R"({
"name": "scheme0",
"foreground": "#040404",
"background": "#050505"
})" };
const std::string scheme3String{ R"({
// "name": "scheme3",
"foreground": "#060606",
"background": "#070707"
})" };

const auto scheme0Json = VerifyParseSucceeded(scheme0String);
const auto scheme1Json = VerifyParseSucceeded(scheme1String);
const auto scheme2Json = VerifyParseSucceeded(scheme2String);
const auto scheme3Json = VerifyParseSucceeded(scheme3String);

auto scheme0 = ColorScheme::FromJson(scheme0Json);
zadjii-msft marked this conversation as resolved.
Show resolved Hide resolved

VERIFY_IS_TRUE(scheme0.ShouldBeLayered(scheme0Json));
VERIFY_IS_FALSE(scheme0.ShouldBeLayered(scheme1Json));
VERIFY_IS_TRUE(scheme0.ShouldBeLayered(scheme2Json));
VERIFY_IS_FALSE(scheme0.ShouldBeLayered(scheme3Json));

auto scheme1 = ColorScheme::FromJson(scheme1Json);

VERIFY_IS_FALSE(scheme1.ShouldBeLayered(scheme0Json));
VERIFY_IS_TRUE(scheme1.ShouldBeLayered(scheme1Json));
VERIFY_IS_FALSE(scheme1.ShouldBeLayered(scheme2Json));
VERIFY_IS_FALSE(scheme1.ShouldBeLayered(scheme3Json));

auto scheme3 = ColorScheme::FromJson(scheme3Json);

VERIFY_IS_FALSE(scheme3.ShouldBeLayered(scheme0Json));
VERIFY_IS_FALSE(scheme3.ShouldBeLayered(scheme1Json));
VERIFY_IS_FALSE(scheme3.ShouldBeLayered(scheme2Json));
VERIFY_IS_FALSE(scheme3.ShouldBeLayered(scheme3Json));
}

void ColorSchemeTests::LayerColorSchemeProperties()
{
const std::string scheme0String{ R"({
"name": "scheme0",
"foreground": "#000000",
"background": "#010101",
"red": "#010000",
"green": "#000100",
"blue": "#000001"
})" };
const std::string scheme1String{ R"({
"name": "scheme1",
"foreground": "#020202",
"background": "#030303",
"red": "#020000",

"blue": "#000002"
})" };
const std::string scheme2String{ R"({
"name": "scheme0",
"foreground": "#040404",
"background": "#050505",
"red": "#030000",
"green": "#000300"
})" };

const auto scheme0Json = VerifyParseSucceeded(scheme0String);
const auto scheme1Json = VerifyParseSucceeded(scheme1String);
const auto scheme2Json = VerifyParseSucceeded(scheme2String);

auto scheme0 = ColorScheme::FromJson(scheme0Json);
VERIFY_ARE_EQUAL(L"scheme0", scheme0._schemeName);
VERIFY_ARE_EQUAL(ARGB(0, 0, 0, 0), scheme0._defaultForeground);
VERIFY_ARE_EQUAL(ARGB(0, 1, 1, 1), scheme0._defaultBackground);
VERIFY_ARE_EQUAL(ARGB(0, 1, 0, 0), scheme0._table[XTERM_RED_ATTR]);
VERIFY_ARE_EQUAL(ARGB(0, 0, 1, 0), scheme0._table[XTERM_GREEN_ATTR]);
VERIFY_ARE_EQUAL(ARGB(0, 0, 0, 1), scheme0._table[XTERM_BLUE_ATTR]);

Log::Comment(NoThrowString().Format(
L"Layering scheme1 on top of scheme0"));
scheme0.LayerJson(scheme1Json);

VERIFY_ARE_EQUAL(ARGB(0, 2, 2, 2), scheme0._defaultForeground);
VERIFY_ARE_EQUAL(ARGB(0, 3, 3, 3), scheme0._defaultBackground);
VERIFY_ARE_EQUAL(ARGB(0, 2, 0, 0), scheme0._table[XTERM_RED_ATTR]);
VERIFY_ARE_EQUAL(ARGB(0, 0, 1, 0), scheme0._table[XTERM_GREEN_ATTR]);
VERIFY_ARE_EQUAL(ARGB(0, 0, 0, 2), scheme0._table[XTERM_BLUE_ATTR]);

Log::Comment(NoThrowString().Format(
L"Layering scheme2Json on top of (scheme0+scheme1)"));
scheme0.LayerJson(scheme2Json);

VERIFY_ARE_EQUAL(ARGB(0, 4, 4, 4), scheme0._defaultForeground);
VERIFY_ARE_EQUAL(ARGB(0, 5, 5, 5), scheme0._defaultBackground);
VERIFY_ARE_EQUAL(ARGB(0, 3, 0, 0), scheme0._table[XTERM_RED_ATTR]);
VERIFY_ARE_EQUAL(ARGB(0, 0, 3, 0), scheme0._table[XTERM_GREEN_ATTR]);
VERIFY_ARE_EQUAL(ARGB(0, 0, 0, 2), scheme0._table[XTERM_BLUE_ATTR]);
}

void ColorSchemeTests::LayerColorSchemesOnArray()
{
const std::string scheme0String{ R"({
"name": "scheme0",
"foreground": "#000000",
"background": "#010101"
})" };
const std::string scheme1String{ R"({
"name": "scheme1",
"foreground": "#020202",
"background": "#030303"
})" };
const std::string scheme2String{ R"({
"name": "scheme0",
"foreground": "#040404",
"background": "#050505"
})" };
const std::string scheme3String{ R"({
// "name": "scheme3",
"foreground": "#060606",
"background": "#070707"
})" };

const auto scheme0Json = VerifyParseSucceeded(scheme0String);
const auto scheme1Json = VerifyParseSucceeded(scheme1String);
const auto scheme2Json = VerifyParseSucceeded(scheme2String);
const auto scheme3Json = VerifyParseSucceeded(scheme3String);

CascadiaSettings settings{};
zadjii-msft marked this conversation as resolved.
Show resolved Hide resolved

VERIFY_ARE_EQUAL(0u, settings._globals.GetColorSchemes().size());
VERIFY_IS_NULL(settings._FindMatchingColorScheme(scheme0Json));
VERIFY_IS_NULL(settings._FindMatchingColorScheme(scheme1Json));
VERIFY_IS_NULL(settings._FindMatchingColorScheme(scheme2Json));
VERIFY_IS_NULL(settings._FindMatchingColorScheme(scheme3Json));

settings._LayerOrCreateColorScheme(scheme0Json);
VERIFY_ARE_EQUAL(1u, settings._globals.GetColorSchemes().size());
VERIFY_IS_NOT_NULL(settings._FindMatchingColorScheme(scheme0Json));
VERIFY_IS_NULL(settings._FindMatchingColorScheme(scheme1Json));
VERIFY_IS_NOT_NULL(settings._FindMatchingColorScheme(scheme2Json));
VERIFY_IS_NULL(settings._FindMatchingColorScheme(scheme3Json));
VERIFY_ARE_EQUAL(ARGB(0, 0, 0, 0), settings._globals.GetColorSchemes().at(0)._defaultForeground);
VERIFY_ARE_EQUAL(ARGB(0, 1, 1, 1), settings._globals.GetColorSchemes().at(0)._defaultBackground);

settings._LayerOrCreateColorScheme(scheme1Json);
VERIFY_ARE_EQUAL(2u, settings._globals.GetColorSchemes().size());
VERIFY_IS_NOT_NULL(settings._FindMatchingColorScheme(scheme0Json));
VERIFY_IS_NOT_NULL(settings._FindMatchingColorScheme(scheme1Json));
VERIFY_IS_NOT_NULL(settings._FindMatchingColorScheme(scheme2Json));
VERIFY_IS_NULL(settings._FindMatchingColorScheme(scheme3Json));
VERIFY_ARE_EQUAL(ARGB(0, 0, 0, 0), settings._globals.GetColorSchemes().at(0)._defaultForeground);
VERIFY_ARE_EQUAL(ARGB(0, 1, 1, 1), settings._globals.GetColorSchemes().at(0)._defaultBackground);
VERIFY_ARE_EQUAL(ARGB(0, 2, 2, 2), settings._globals.GetColorSchemes().at(1)._defaultForeground);
VERIFY_ARE_EQUAL(ARGB(0, 3, 3, 3), settings._globals.GetColorSchemes().at(1)._defaultBackground);

settings._LayerOrCreateColorScheme(scheme2Json);
VERIFY_ARE_EQUAL(2u, settings._globals.GetColorSchemes().size());
VERIFY_IS_NOT_NULL(settings._FindMatchingColorScheme(scheme0Json));
VERIFY_IS_NOT_NULL(settings._FindMatchingColorScheme(scheme1Json));
VERIFY_IS_NOT_NULL(settings._FindMatchingColorScheme(scheme2Json));
VERIFY_IS_NULL(settings._FindMatchingColorScheme(scheme3Json));
VERIFY_ARE_EQUAL(ARGB(0, 4, 4, 4), settings._globals.GetColorSchemes().at(0)._defaultForeground);
VERIFY_ARE_EQUAL(ARGB(0, 5, 5, 5), settings._globals.GetColorSchemes().at(0)._defaultBackground);
VERIFY_ARE_EQUAL(ARGB(0, 2, 2, 2), settings._globals.GetColorSchemes().at(1)._defaultForeground);
VERIFY_ARE_EQUAL(ARGB(0, 3, 3, 3), settings._globals.GetColorSchemes().at(1)._defaultBackground);

settings._LayerOrCreateColorScheme(scheme3Json);
VERIFY_ARE_EQUAL(3u, settings._globals.GetColorSchemes().size());
VERIFY_IS_NOT_NULL(settings._FindMatchingColorScheme(scheme0Json));
VERIFY_IS_NOT_NULL(settings._FindMatchingColorScheme(scheme1Json));
VERIFY_IS_NOT_NULL(settings._FindMatchingColorScheme(scheme2Json));
VERIFY_IS_NULL(settings._FindMatchingColorScheme(scheme3Json));
VERIFY_ARE_EQUAL(ARGB(0, 4, 4, 4), settings._globals.GetColorSchemes().at(0)._defaultForeground);
VERIFY_ARE_EQUAL(ARGB(0, 5, 5, 5), settings._globals.GetColorSchemes().at(0)._defaultBackground);
VERIFY_ARE_EQUAL(ARGB(0, 2, 2, 2), settings._globals.GetColorSchemes().at(1)._defaultForeground);
VERIFY_ARE_EQUAL(ARGB(0, 3, 3, 3), settings._globals.GetColorSchemes().at(1)._defaultBackground);
VERIFY_ARE_EQUAL(ARGB(0, 6, 6, 6), settings._globals.GetColorSchemes().at(2)._defaultForeground);
VERIFY_ARE_EQUAL(ARGB(0, 7, 7, 7), settings._globals.GetColorSchemes().at(2)._defaultBackground);
}
}
36 changes: 36 additions & 0 deletions src/cascadia/LocalTests_TerminalApp/JsonTestClass.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*++
Copyright (c) Microsoft Corporation
Licensed under the MIT license.

Module Name:
- JsonTestClass.h

Abstract:
- This class is a helper that can be used to quickly create tests that need to
read & parse json data. Test classes that need to read JSON should make sure
to derive from this class, and also make sure to call InitializeJsonReader()
in the TEST_CLASS_SETUP().

Author(s):
Mike Griese (migrie) August-2019
--*/

class JsonTestClass
{
public:
void InitializeJsonReader()
{
reader = std::unique_ptr<Json::CharReader>(Json::CharReaderBuilder::CharReaderBuilder().newCharReader());
};
Json::Value VerifyParseSucceeded(std::string content)
{
Json::Value root;
std::string errs;
const bool parseResult = reader->parse(content.c_str(), content.c_str() + content.size(), &root, &errs);
VERIFY_IS_TRUE(parseResult, winrt::to_hstring(errs).c_str());
return root;
};

protected:
std::unique_ptr<Json::CharReader> reader;
zadjii-msft marked this conversation as resolved.
Show resolved Hide resolved
};
Loading