330 lines
14 KiB
C++
330 lines
14 KiB
C++
// Copyright (c) Microsoft Corporation.
|
|
// Licensed under the MIT license.
|
|
|
|
#include "pch.h"
|
|
|
|
#include "../TerminalSettingsModel/ColorScheme.h"
|
|
#include "../TerminalSettingsModel/CascadiaSettings.h"
|
|
#include "JsonTestClass.h"
|
|
|
|
#include <defaults.h>
|
|
|
|
using namespace Microsoft::Console;
|
|
using namespace winrt::Microsoft::Terminal::Settings::Model;
|
|
using namespace WEX::Logging;
|
|
using namespace WEX::TestExecution;
|
|
using namespace WEX::Common;
|
|
|
|
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 ProfileTests : 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(ProfileTests)
|
|
TEST_CLASS_PROPERTY(L"RunAs", L"UAP")
|
|
TEST_CLASS_PROPERTY(L"UAP:AppXManifest", L"TestHostAppXManifest.xml")
|
|
END_TEST_CLASS()
|
|
|
|
TEST_METHOD(ProfileGeneratesGuid);
|
|
TEST_METHOD(LayerProfileProperties);
|
|
TEST_METHOD(LayerProfileIcon);
|
|
TEST_METHOD(LayerProfilesOnArray);
|
|
TEST_METHOD(DuplicateProfileTest);
|
|
TEST_METHOD(TestGenGuidsForProfiles);
|
|
};
|
|
|
|
void ProfileTests::ProfileGeneratesGuid()
|
|
{
|
|
// Parse some profiles without guids. We should NOT generate new guids
|
|
// for them. If a profile doesn't have a GUID, we'll leave its _guid
|
|
// set to nullopt. The Profile::Guid() getter will
|
|
// ensure all profiles have a GUID that's actually set.
|
|
// The null guid _is_ a valid guid, so we won't re-generate that
|
|
// guid. null is _not_ a valid guid, so we'll leave that nullopt
|
|
|
|
// See SettingsTests::ValidateProfilesGenerateGuids for a version of
|
|
// this test that includes synthesizing GUIDS for profiles without GUIDs
|
|
// set
|
|
|
|
const std::string profileWithoutGuid{ R"({
|
|
"name" : "profile0"
|
|
})" };
|
|
const std::string secondProfileWithoutGuid{ R"({
|
|
"name" : "profile1"
|
|
})" };
|
|
const std::string profileWithNullForGuid{ R"({
|
|
"name" : "profile2",
|
|
"guid" : null
|
|
})" };
|
|
const std::string profileWithNullGuid{ R"({
|
|
"name" : "profile3",
|
|
"guid" : "{00000000-0000-0000-0000-000000000000}"
|
|
})" };
|
|
const std::string profileWithGuid{ R"({
|
|
"name" : "profile4",
|
|
"guid" : "{6239a42c-1de4-49a3-80bd-e8fdd045185c}"
|
|
})" };
|
|
|
|
const auto profile0Json = VerifyParseSucceeded(profileWithoutGuid);
|
|
const auto profile1Json = VerifyParseSucceeded(secondProfileWithoutGuid);
|
|
const auto profile2Json = VerifyParseSucceeded(profileWithNullForGuid);
|
|
const auto profile3Json = VerifyParseSucceeded(profileWithNullGuid);
|
|
const auto profile4Json = VerifyParseSucceeded(profileWithGuid);
|
|
|
|
const auto profile0 = implementation::Profile::FromJson(profile0Json);
|
|
const auto profile1 = implementation::Profile::FromJson(profile1Json);
|
|
const auto profile2 = implementation::Profile::FromJson(profile2Json);
|
|
const auto profile3 = implementation::Profile::FromJson(profile3Json);
|
|
const auto profile4 = implementation::Profile::FromJson(profile4Json);
|
|
const winrt::guid cmdGuid = Utils::GuidFromString(L"{6239a42c-1de4-49a3-80bd-e8fdd045185c}");
|
|
const winrt::guid nullGuid{};
|
|
|
|
VERIFY_IS_FALSE(profile0->HasGuid());
|
|
VERIFY_IS_FALSE(profile1->HasGuid());
|
|
VERIFY_IS_FALSE(profile2->HasGuid());
|
|
VERIFY_IS_TRUE(profile3->HasGuid());
|
|
VERIFY_IS_TRUE(profile4->HasGuid());
|
|
|
|
VERIFY_ARE_EQUAL(profile3->Guid(), nullGuid);
|
|
VERIFY_ARE_EQUAL(profile4->Guid(), cmdGuid);
|
|
}
|
|
|
|
void ProfileTests::LayerProfileProperties()
|
|
{
|
|
static constexpr std::string_view profile0String{ R"({
|
|
"name": "profile0",
|
|
"guid": "{6239a42c-1111-49a3-80bd-e8fdd045185c}",
|
|
"foreground": "#000000",
|
|
"background": "#010101",
|
|
"selectionBackground": "#010101"
|
|
})" };
|
|
static constexpr std::string_view profile1String{ R"({
|
|
"name": "profile1",
|
|
"guid": "{6239a42c-1111-49a3-80bd-e8fdd045185c}",
|
|
"foreground": "#020202",
|
|
"startingDirectory": "C:/"
|
|
})" };
|
|
static constexpr std::string_view profile2String{ R"({
|
|
"name": "profile2",
|
|
"guid": "{6239a42c-1111-49a3-80bd-e8fdd045185c}",
|
|
"foreground": "#030303",
|
|
"selectionBackground": "#020202"
|
|
})" };
|
|
|
|
const auto profile0Json = VerifyParseSucceeded(profile0String);
|
|
const auto profile1Json = VerifyParseSucceeded(profile1String);
|
|
const auto profile2Json = VerifyParseSucceeded(profile2String);
|
|
|
|
auto profile0 = implementation::Profile::FromJson(profile0Json);
|
|
VERIFY_IS_NOT_NULL(profile0->DefaultAppearance().Foreground());
|
|
VERIFY_ARE_EQUAL(til::color(0, 0, 0), til::color{ profile0->DefaultAppearance().Foreground().Value() });
|
|
|
|
VERIFY_IS_NOT_NULL(profile0->DefaultAppearance().Background());
|
|
VERIFY_ARE_EQUAL(til::color(1, 1, 1), til::color{ profile0->DefaultAppearance().Background().Value() });
|
|
|
|
VERIFY_IS_NOT_NULL(profile0->DefaultAppearance().SelectionBackground());
|
|
VERIFY_ARE_EQUAL(til::color(1, 1, 1), til::color{ profile0->DefaultAppearance().SelectionBackground().Value() });
|
|
|
|
VERIFY_ARE_EQUAL(L"profile0", profile0->Name());
|
|
|
|
VERIFY_IS_TRUE(profile0->StartingDirectory().empty());
|
|
|
|
Log::Comment(NoThrowString().Format(
|
|
L"Layering profile1 on top of profile0"));
|
|
auto profile1{ profile0->CreateChild() };
|
|
profile1->LayerJson(profile1Json);
|
|
|
|
VERIFY_IS_NOT_NULL(profile1->DefaultAppearance().Foreground());
|
|
VERIFY_ARE_EQUAL(til::color(2, 2, 2), til::color{ profile1->DefaultAppearance().Foreground().Value() });
|
|
|
|
VERIFY_IS_NOT_NULL(profile1->DefaultAppearance().Background());
|
|
VERIFY_ARE_EQUAL(til::color(1, 1, 1), til::color{ profile1->DefaultAppearance().Background().Value() });
|
|
|
|
VERIFY_IS_NOT_NULL(profile1->DefaultAppearance().Background());
|
|
VERIFY_ARE_EQUAL(til::color(1, 1, 1), til::color{ profile1->DefaultAppearance().Background().Value() });
|
|
|
|
VERIFY_ARE_EQUAL(L"profile1", profile1->Name());
|
|
|
|
VERIFY_IS_FALSE(profile1->StartingDirectory().empty());
|
|
VERIFY_ARE_EQUAL(L"C:/", profile1->StartingDirectory());
|
|
|
|
Log::Comment(NoThrowString().Format(
|
|
L"Layering profile2 on top of (profile0+profile1)"));
|
|
auto profile2{ profile1->CreateChild() };
|
|
profile2->LayerJson(profile2Json);
|
|
|
|
VERIFY_IS_NOT_NULL(profile2->DefaultAppearance().Foreground());
|
|
VERIFY_ARE_EQUAL(til::color(3, 3, 3), til::color{ profile2->DefaultAppearance().Foreground().Value() });
|
|
|
|
VERIFY_IS_NOT_NULL(profile2->DefaultAppearance().Background());
|
|
VERIFY_ARE_EQUAL(til::color(1, 1, 1), til::color{ profile2->DefaultAppearance().Background().Value() });
|
|
|
|
VERIFY_IS_NOT_NULL(profile2->DefaultAppearance().SelectionBackground());
|
|
VERIFY_ARE_EQUAL(til::color(2, 2, 2), til::color{ profile2->DefaultAppearance().SelectionBackground().Value() });
|
|
|
|
VERIFY_ARE_EQUAL(L"profile2", profile2->Name());
|
|
|
|
VERIFY_IS_FALSE(profile2->StartingDirectory().empty());
|
|
VERIFY_ARE_EQUAL(L"C:/", profile2->StartingDirectory());
|
|
}
|
|
|
|
void ProfileTests::LayerProfileIcon()
|
|
{
|
|
static constexpr std::string_view profile0String{ R"({
|
|
"name": "profile0",
|
|
"guid": "{6239a42c-1111-49a3-80bd-e8fdd045185c}",
|
|
"icon": "not-null.png"
|
|
})" };
|
|
static constexpr std::string_view profile1String{ R"({
|
|
"name": "profile1",
|
|
"guid": "{6239a42c-1111-49a3-80bd-e8fdd045185c}",
|
|
"icon": null
|
|
})" };
|
|
static constexpr std::string_view profile2String{ R"({
|
|
"name": "profile2",
|
|
"guid": "{6239a42c-1111-49a3-80bd-e8fdd045185c}"
|
|
})" };
|
|
static constexpr std::string_view profile3String{ R"({
|
|
"name": "profile3",
|
|
"guid": "{6239a42c-1111-49a3-80bd-e8fdd045185c}",
|
|
"icon": "another-real.png"
|
|
})" };
|
|
|
|
const auto profile0Json = VerifyParseSucceeded(profile0String);
|
|
const auto profile1Json = VerifyParseSucceeded(profile1String);
|
|
const auto profile2Json = VerifyParseSucceeded(profile2String);
|
|
const auto profile3Json = VerifyParseSucceeded(profile3String);
|
|
|
|
auto profile0 = implementation::Profile::FromJson(profile0Json);
|
|
VERIFY_IS_FALSE(profile0->Icon().empty());
|
|
VERIFY_ARE_EQUAL(L"not-null.png", profile0->Icon());
|
|
|
|
Log::Comment(NoThrowString().Format(
|
|
L"Verify that layering an object the key set to null will clear the key"));
|
|
profile0->LayerJson(profile1Json);
|
|
VERIFY_IS_TRUE(profile0->Icon().empty());
|
|
|
|
profile0->LayerJson(profile2Json);
|
|
VERIFY_IS_TRUE(profile0->Icon().empty());
|
|
|
|
profile0->LayerJson(profile3Json);
|
|
VERIFY_IS_FALSE(profile0->Icon().empty());
|
|
VERIFY_ARE_EQUAL(L"another-real.png", profile0->Icon());
|
|
|
|
Log::Comment(NoThrowString().Format(
|
|
L"Verify that layering an object _without_ the key will not clear the key"));
|
|
profile0->LayerJson(profile2Json);
|
|
VERIFY_IS_FALSE(profile0->Icon().empty());
|
|
VERIFY_ARE_EQUAL(L"another-real.png", profile0->Icon());
|
|
|
|
auto profile1 = implementation::Profile::FromJson(profile1Json);
|
|
VERIFY_IS_TRUE(profile1->Icon().empty());
|
|
profile1->LayerJson(profile3Json);
|
|
VERIFY_IS_FALSE(profile1->Icon().empty());
|
|
VERIFY_ARE_EQUAL(L"another-real.png", profile1->Icon());
|
|
}
|
|
|
|
void ProfileTests::LayerProfilesOnArray()
|
|
{
|
|
static constexpr std::string_view inboxProfiles{ R"({
|
|
"profiles": [
|
|
{
|
|
"name" : "profile0",
|
|
"guid" : "{6239a42c-0000-49a3-80bd-e8fdd045185c}"
|
|
}, {
|
|
"name" : "profile1",
|
|
"guid" : "{6239a42c-1111-49a3-80bd-e8fdd045185c}"
|
|
}, {
|
|
"name" : "profile2",
|
|
"guid" : "{6239a42c-2222-49a3-80bd-e8fdd045185c}"
|
|
}
|
|
]
|
|
})" };
|
|
static constexpr std::string_view userProfiles{ R"({
|
|
"profiles": [
|
|
{
|
|
"name" : "profile3",
|
|
"guid" : "{6239a42c-0000-49a3-80bd-e8fdd045185c}"
|
|
}, {
|
|
"name" : "profile4",
|
|
"guid" : "{6239a42c-1111-49a3-80bd-e8fdd045185c}"
|
|
}
|
|
]
|
|
})" };
|
|
|
|
const auto settings = winrt::make_self<implementation::CascadiaSettings>(userProfiles, inboxProfiles);
|
|
const auto allProfiles = settings->AllProfiles();
|
|
VERIFY_ARE_EQUAL(3u, allProfiles.Size());
|
|
VERIFY_ARE_EQUAL(L"profile3", allProfiles.GetAt(0).Name());
|
|
VERIFY_ARE_EQUAL(L"profile4", allProfiles.GetAt(1).Name());
|
|
VERIFY_ARE_EQUAL(L"profile2", allProfiles.GetAt(2).Name());
|
|
}
|
|
|
|
void ProfileTests::DuplicateProfileTest()
|
|
{
|
|
static constexpr std::string_view userProfiles{ R"({
|
|
"profiles": [
|
|
{
|
|
"name": "profile0",
|
|
"guid": "{6239a42c-0000-49a3-80bd-e8fdd045185c}",
|
|
"backgroundImage": "file:///some/path",
|
|
"hidden": false,
|
|
}
|
|
]
|
|
})" };
|
|
|
|
const auto settings = winrt::make_self<implementation::CascadiaSettings>(userProfiles);
|
|
const auto profile = settings->AllProfiles().GetAt(0);
|
|
const auto duplicatedProfile = settings->DuplicateProfile(profile);
|
|
|
|
duplicatedProfile.Guid(profile.Guid());
|
|
duplicatedProfile.Name(profile.Name());
|
|
|
|
const auto json = winrt::get_self<implementation::Profile>(profile)->ToJson();
|
|
const auto duplicatedJson = winrt::get_self<implementation::Profile>(duplicatedProfile)->ToJson();
|
|
VERIFY_ARE_EQUAL(json, duplicatedJson, til::u8u16(toString(duplicatedJson)).c_str());
|
|
}
|
|
|
|
void ProfileTests::TestGenGuidsForProfiles()
|
|
{
|
|
// We'll generate GUIDs in the Profile::Guid getter. We should make sure that
|
|
// the GUID generated for a dynamic profile (with a source) is different
|
|
// than that of a profile without a source.
|
|
|
|
static constexpr std::string_view userSettings{ R"({
|
|
"profiles": [
|
|
{
|
|
"name": "profile0",
|
|
"source": "Terminal.App.UnitTest.0",
|
|
},
|
|
{
|
|
"name": "profile0"
|
|
}
|
|
]
|
|
})" };
|
|
|
|
const auto settings = winrt::make_self<implementation::CascadiaSettings>(userSettings, DefaultJson);
|
|
|
|
VERIFY_ARE_EQUAL(4u, settings->AllProfiles().Size());
|
|
|
|
VERIFY_ARE_EQUAL(L"profile0", settings->AllProfiles().GetAt(0).Name());
|
|
VERIFY_IS_TRUE(settings->AllProfiles().GetAt(0).HasGuid());
|
|
VERIFY_IS_FALSE(settings->AllProfiles().GetAt(0).Source().empty());
|
|
|
|
VERIFY_ARE_EQUAL(L"profile0", settings->AllProfiles().GetAt(1).Name());
|
|
VERIFY_IS_TRUE(settings->AllProfiles().GetAt(1).HasGuid());
|
|
VERIFY_IS_TRUE(settings->AllProfiles().GetAt(1).Source().empty());
|
|
|
|
VERIFY_ARE_NOT_EQUAL(settings->AllProfiles().GetAt(0).Guid(), settings->AllProfiles().GetAt(1).Guid());
|
|
}
|
|
}
|