Files
o3de/Gems/Atom/Asset/Shader/Code/Tests/SupervariantCmdArgumentTests.cpp
T
lumberyard-employee-dm b9824ed172 Updated all array_view uses with the C++20 span. (#7157)
* Updated all array_view uses with the C++20 span.

The updates were done in the following order
1. `AZStd::array_view<([^>].+)\* ?>`  -> `AZStd::span<\1 const>`
2. `AZStd::array_view<(?:const )(.+)>` -> `AZStd::span<const \1>`
3. `AZStd::array_view` -> `AZStd::span`

Removed the implementation of array_view.

Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com>

* Added missing whitespace between `const` and the typename for spans.

Updated the ShaderTest comparison of the ShaderResourceGroupLayout span
to compare the sizes as well

Updated comments on some of the methods that stated that they return "an
array" to mention they return "a span".

Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com>
2022-01-26 16:15:47 -06:00

520 lines
26 KiB
C++

/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AzTest/AzTest.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <AzCore/std/algorithm.h>
#include <Atom/RPI.Edit/Common/JsonUtils.h>
#include <Atom/RPI.Edit/Shader/ShaderSourceData.h>
#include <Atom/RHI.Edit/Utils.h>
#include <CommonFiles/GlobalBuildOptions.h>
#include "Common/ShaderBuilderTestFixture.h"
namespace UnitTest
{
using namespace AZ;
struct KeyValueView
{
AZStd::string_view m_key;
AZStd::string_view m_value;
};
class SupervariantCmdArgumentTests : public ShaderBuilderTestFixture
{
protected:
static constexpr char MCPP_MACRO1[] = "MACRO1";
static constexpr char MCPP_VALUE1[] = "VALUE1a";
static constexpr char MCPP_NEW_VALUE1[] = "VALUE1b"; // Missing A is not a typo
static constexpr char MCPP_MACRO2[] = "MACRO2";
static constexpr char MCPP_VALUE2[] = "VALUE2";
static constexpr char MCPP_MACRO3[] = "MACRO3";
static constexpr char MCPP_VALUE3[] = "VALUE3a";
static constexpr char MCPP_NEW_VALUE3[] = "VALUE3b";
static constexpr char MCPP_MACRO4[] = "MACRO4";
static constexpr char MCPP_MACRO5[] = "MACRO5";
static constexpr char MCPP_MACRO6[] = "MACRO6";
static constexpr char MCPP_VALUE6[] = "VALUE6";
static constexpr char AZSLC_ARG1[] = "--azsl1";
static constexpr char AZSLC_ARG2[] = "--azsl2";
static constexpr char AZSLC_VAL2[] = "open,source";
static constexpr char AZSLC_NEW_VAL2a[] = "closed,binary";
static constexpr char AZSLC_NEW_VAL2b[] = "closed,source";
static constexpr char AZSLC_ARG3[] = "--azsl3";
static constexpr char AZSLC_VAL3[] = "blue";
static constexpr char AZSLC_ARG4[] = "-azsl4";
static constexpr char AZSLC_ARG5[] = "--azsl5";
static constexpr char AZSLC_VAL5[] = "smith,wick,john,45,-1,-1";
static constexpr char AZSLC_NEW_VAL5[] = "apple,seed,crisp,-1,2,0";
static constexpr char AZSLC_ARG6[] = "--azsl6";
static constexpr char AZSLC_ARG7[] = "--azsl7";
//! Helper function.
//! Given an input list of {Key, Value} pairs returns a list of strings where each string is of the form: "Key=Value".
AZStd::vector<AZStd::string> CreateListOfStringsFromListOfKeyValues(AZStd::span<const KeyValueView> listOfKeyValues) const
{
AZStd::vector<AZStd::string> listOfStrings;
for (const auto& keyValue : listOfKeyValues)
{
if (keyValue.m_value.empty())
{
listOfStrings.push_back(keyValue.m_key);
}
else
{
listOfStrings.push_back(AZStd::string::format("%s=%s", keyValue.m_key.data(), keyValue.m_value.data()));
}
}
return listOfStrings;
}
//! Helper function.
//! Given an input list of {Key, Value} pairs returns a list of strings where each string is of the form: "Key1", "Value1", "Key2", "Value2".
AZStd::vector<AZStd::string> CreateListOfSingleStringsFromListOfKeyValues(AZStd::span<const KeyValueView> listOfKeyValues) const
{
AZStd::vector<AZStd::string> listOfStrings;
for (const auto& keyValue : listOfKeyValues)
{
listOfStrings.push_back(keyValue.m_key);
if (!keyValue.m_value.empty())
{
listOfStrings.push_back(keyValue.m_value);
}
}
return listOfStrings;
}
//! Helper function.
//! @param outputString: [out] The string " @argName" gets appended to it (The space is intentional).
//! Alternatively, if @argValue is NOT empty, then the string " @argName=@argValue" is
//! appended to it.
//! @param argName: A typical command line argument. "-p" or "--some".
//! @param argValue: A string representing the value that should be appended to @argName.
void AppendCmdLineArgument(AZStd::string& outputString, AZStd::string_view argName, AZStd::string_view argValue) const
{
if (argValue.empty())
{
outputString += AZStd::string::format(" %s", argName.data());
}
else
{
outputString += AZStd::string::format(" %s=%s", argName.data(), argValue.data());
}
}
//! Helper function.
//! Similar to above, but assumes that @argName refers to just the name of a macro definition so the appended string will always start
//! with "-D".
void AppendMacroDefinitionArgument(AZStd::string& outputString, AZStd::string_view argName, AZStd::string_view argValue) const
{
AppendCmdLineArgument(outputString, AZStd::string::format("-D%s", argName.data()), argValue);
}
//! A helper made of helpers.
//! Returns a command line string that results of concatenating the input list of {Key, Value} pairs (with '=').
//! Example of a returned string:
//! "key1=value1 key2 key3 key4=value"
AZStd::string CreateCmdLineStringFromListOfKeyValues(AZStd::span<const KeyValueView> listOfKeyValues) const
{
AZStd::string cmdLineString;
for (const auto& keyValueView : listOfKeyValues)
{
AppendCmdLineArgument(cmdLineString, keyValueView.m_key, keyValueView.m_value);
}
return cmdLineString;
}
//! A helper made of helpers.
//! Returns a command line string of macro definitions that results of concatenating the input list of {Key, Value} pairs.
//! Example of a returned string:
//! "-Dkey1=value1 -Dkey2 -Dkey3 -Dkey4=value"
AZStd::string CreateMacroDefinitionCmdLineStringFromListOfKeyValues(AZStd::span<const KeyValueView> listOfKeyValues) const
{
AZStd::string cmdLineString;
for (const auto& keyValueView : listOfKeyValues)
{
AppendMacroDefinitionArgument(cmdLineString, keyValueView.m_key, keyValueView.m_value);
}
return cmdLineString;
}
//! @param includePaths A List of folder paths
//! @param predefinedMacros A List of strings with format: "name[=value]"
ShaderBuilder::PreprocessorOptions CreatePreprocessorOptions(
AZStd::span<const AZStd::string> includePaths, AZStd::span<const AZStd::string> predefinedMacros) const
{
ShaderBuilder::PreprocessorOptions preprocessorOptions;
preprocessorOptions.m_projectIncludePaths.reserve(includePaths.size());
for (const auto& path : includePaths)
{
preprocessorOptions.m_projectIncludePaths.push_back(path);
}
preprocessorOptions.m_predefinedMacros.reserve(predefinedMacros.size());
for (const auto& macro : predefinedMacros)
{
preprocessorOptions.m_predefinedMacros.push_back(macro);
}
return preprocessorOptions;
}
//! @param azslcAdditionalFreeArguments: A string representing series of command line arguments for AZSLc.
//! @param dxcAdditionalFreeArguments: A string representing series of command line arguments for DXC.
RHI::ShaderCompilerArguments CreateShaderCompilerArguments(
AZStd::string_view azslcAdditionalFreeArguments, AZStd::string_view dxcAdditionalFreeArguments) const
{
RHI::ShaderCompilerArguments shaderCompilerArguments;
shaderCompilerArguments.m_azslcWarningLevel = 1;
shaderCompilerArguments.m_azslcAdditionalFreeArguments = azslcAdditionalFreeArguments;
shaderCompilerArguments.m_defaultMatrixOrder = RHI::MatrixOrder::Row;
shaderCompilerArguments.m_dxcAdditionalFreeArguments = dxcAdditionalFreeArguments;
return shaderCompilerArguments;
}
//! @param includePaths A List of folder paths
//! @param predefinedMacros A List of strings with format: "name[=value]"
//! @param azslcAdditionalFreeArguments A string representing series of command line arguments for AZSLc.
//! @param dxcAdditionalFreeArguments: A string representing series of command line arguments for DXC.
ShaderBuilder::GlobalBuildOptions CreateGlobalBuildOptions(
AZStd::span<const AZStd::string> includePaths,
AZStd::span<const AZStd::string> predefinedMacros,
AZStd::string_view azslcAdditionalFreeArguments,
AZStd::string_view dxcAdditionalFreeArguments) const
{
ShaderBuilder::GlobalBuildOptions globalBuildOptions;
globalBuildOptions.m_preprocessorSettings = CreatePreprocessorOptions(includePaths, predefinedMacros);
globalBuildOptions.m_compilerArguments =
CreateShaderCompilerArguments(azslcAdditionalFreeArguments, dxcAdditionalFreeArguments);
return globalBuildOptions;
}
//! @param name Name of the supervariant.
//! @param plusArguments A string with command line arguments that contains both C-preprocessor macro definitions
//! and other command line arguments for AZSLc.
//! @param minusArguments A string with command line arguments that should be removed from the finalized command line arguments.
//! it can contain both, C-preprocessor macro definitions and other command line arguments for AZSLc.
RPI::ShaderSourceData::SupervariantInfo CreateSupervariantInfo(
AZStd::string_view name, AZStd::string_view plusArguments, AZStd::string_view minusArguments) const
{
RPI::ShaderSourceData::SupervariantInfo supervariantInfo;
supervariantInfo.m_name = name;
supervariantInfo.m_plusArguments = plusArguments;
supervariantInfo.m_minusArguments = minusArguments;
return supervariantInfo;
}
bool StringContainsAllSubstrings(AZStd::string_view haystack, AZStd::span<const AZStd::string> substrings)
{
return AZStd::all_of(AZ_BEGIN_END(substrings),
[&](AZStd::string_view needle) -> bool
{
return (haystack.find(needle) != AZStd::string::npos);
}
);
}
bool StringDoesNotContainAnyOneOfTheSubstrings(AZStd::string_view haystack, AZStd::span<const AZStd::string> substrings)
{
return AZStd::all_of(AZ_BEGIN_END(substrings), [&](AZStd::string_view needle) -> bool {
return (haystack.find(needle) == AZStd::string::npos);
});
}
//! @returns: True if all strings in @substring appear in @vectorOfString.
//! @remark: Keep in mind that this is not the same as saying that all strings in @vectorOfStrings appear in @substrings.
bool VectorContainsAllSubstrings(
AZStd::span<const AZStd::string> vectorOfStrings, AZStd::span<const AZStd::string> substrings)
{
return AZStd::all_of(
AZ_BEGIN_END(substrings),
[&](AZStd::string_view needle) -> bool {
bool res = AZStd::any_of(AZ_BEGIN_END(vectorOfStrings),
[&](AZStd::string_view haystack) -> bool
{
return haystack.find(needle) != AZStd::string::npos;
}
);
return res;
}
);
}
//! @returns: True only if None of the strings in @vectorOfStrings contains any of the strings in @substrings.
bool VectorDoesNotContainAnyOneOfTheSubstrings(AZStd::span<const AZStd::string> vectorOfStrings, AZStd::span<const AZStd::string> substrings)
{
return AZStd::all_of(AZ_BEGIN_END(vectorOfStrings), [&](AZStd::string_view haystack) -> bool {
return StringDoesNotContainAnyOneOfTheSubstrings(haystack, substrings);
});
}
}; // class SupervariantCmdArgumentTests
TEST_F(SupervariantCmdArgumentTests, CommandLineArgumentUtils_ValidateHelperFunctions)
{
// In this test the idea is to validate the static helper functions in AZ::RHI::ShaderCompilerArguments class
// that are useful for command line argument manipulation, etc.
AZStd::vector<KeyValueView> argumentList = {
{AZSLC_ARG1, ""}, {AZSLC_ARG2, AZSLC_VAL2}, {AZSLC_ARG3, AZSLC_VAL3}, {AZSLC_ARG4, ""}, {AZSLC_ARG5, AZSLC_VAL5},
};
auto argumentsAsString = CreateCmdLineStringFromListOfKeyValues(argumentList);
auto listOfArgumentNames = AZ::RHI::CommandLineArgumentUtils::GetListOfArgumentNames(argumentsAsString);
EXPECT_TRUE(AZStd::all_of(AZ_BEGIN_END(argumentList), [&](const KeyValueView& needle) -> bool {
return (AZStd::find(AZ_BEGIN_END(listOfArgumentNames), needle.m_key) != listOfArgumentNames.end()) &&
// Make sure the values did not make into the expected list of keys.
(AZStd::find(AZ_BEGIN_END(listOfArgumentNames), needle.m_value) == listOfArgumentNames.end());
}));
AZStd::vector<AZStd::string> listOfArgumentsToRemove = { AZSLC_ARG4, AZSLC_ARG2 };
auto stringWithRemovedArguments =
AZ::RHI::CommandLineArgumentUtils::RemoveArgumentsFromCommandLineString(listOfArgumentsToRemove, argumentsAsString);
EXPECT_TRUE(AZStd::all_of(AZ_BEGIN_END(listOfArgumentsToRemove), [&](const AZStd::string& needle) -> bool {
return stringWithRemovedArguments.find(needle) == AZStd::string::npos;
}));
AZStd::vector<AZStd::string> listOfSurvivingArguments = {AZSLC_ARG1, AZSLC_ARG3, AZSLC_ARG5};
EXPECT_TRUE(AZStd::all_of(AZ_BEGIN_END(listOfSurvivingArguments), [&](const AZStd::string& needle) -> bool {
return stringWithRemovedArguments.find(needle) != AZStd::string::npos;
}));
auto stringWithoutExtraSpaces =
AZ::RHI::CommandLineArgumentUtils::RemoveExtraSpaces(" --arg1 -arg2 --arg3=foo --arg4=bar ");
EXPECT_EQ(stringWithoutExtraSpaces, AZStd::string("--arg1 -arg2 --arg3=foo --arg4=bar"));
auto stringAsMergedArguments =
AZ::RHI::CommandLineArgumentUtils::MergeCommandLineArguments("--arg1 -arg2 --arg3=foo", "--arg3=bar --arg4");
EXPECT_EQ(stringAsMergedArguments, AZStd::string("--arg1 -arg2 --arg3=bar --arg4"));
EXPECT_TRUE(AZ::RHI::CommandLineArgumentUtils::HasMacroDefinitions("-DMACRO"));
EXPECT_TRUE(AZ::RHI::CommandLineArgumentUtils::HasMacroDefinitions("-D MACRO"));
EXPECT_TRUE(AZ::RHI::CommandLineArgumentUtils::HasMacroDefinitions("--help -D MACRO"));
EXPECT_TRUE(AZ::RHI::CommandLineArgumentUtils::HasMacroDefinitions("--help -p -DMACRO --more"));
EXPECT_TRUE(AZ::RHI::CommandLineArgumentUtils::HasMacroDefinitions("--help -p -D MACRO=VALUE --more"));
EXPECT_FALSE(AZ::RHI::CommandLineArgumentUtils::HasMacroDefinitions("--help -p --more"));
EXPECT_FALSE(AZ::RHI::CommandLineArgumentUtils::HasMacroDefinitions("--help -p --more --DFAKE"));
EXPECT_FALSE(AZ::RHI::CommandLineArgumentUtils::HasMacroDefinitions("--DFAKE1 --help -p --more --D FAKE2"));
}
TEST_F(SupervariantCmdArgumentTests, ShaderCompilerArguments_ValidateCommandLineArgumentsMerge)
{
// In this test we validate that AZ::RHI::ShaderCompilerArguments::Merge() works as expected
// by merging AZSLC & DXC arguments giving higher priority to the arguments in the "right".
auto shaderCompilerArgumentsLeft = CreateShaderCompilerArguments(
"--azsl1 --azsl2=avalue2a -azsl3 --azsl4=avalue4a",
"--dxc1=dvalue1a -dxc2 --dxc3=dvalue3a --dxc4");
auto shaderCompilerArgumentsRight = CreateShaderCompilerArguments(
"--azsl1 --azsl2=avalue2b -azsl3 --azsl4=avalue4a --azsl5",
"--dxc1=dvalue1a -dxc2 --dxc3=dvalue3b --dxc4 --dxc5=dvalue5a");
shaderCompilerArgumentsLeft.Merge(shaderCompilerArgumentsRight);
EXPECT_EQ(shaderCompilerArgumentsLeft.m_azslcAdditionalFreeArguments, "--azsl1 --azsl2=avalue2b -azsl3 --azsl4=avalue4a --azsl5");
EXPECT_EQ(shaderCompilerArgumentsLeft.m_dxcAdditionalFreeArguments, "--dxc1=dvalue1a -dxc2 --dxc3=dvalue3b --dxc4 --dxc5=dvalue5a");
}
TEST_F(SupervariantCmdArgumentTests, SupervariantInfo_ValidateMemberFunctions)
{
// In this test all member functions of the ShaderSourceData::SupervariantInfo class
// are validated.
AZStd::vector<KeyValueView> mcppMacrosList = {
{MCPP_MACRO1, MCPP_VALUE1},
{MCPP_MACRO2, MCPP_VALUE2},
{MCPP_MACRO3, MCPP_VALUE3},
{MCPP_MACRO4, ""},
};
AZStd::string argumentsToAddOrReplace;
AppendMacroDefinitionArgument(argumentsToAddOrReplace, MCPP_MACRO3, MCPP_NEW_VALUE3);
AppendCmdLineArgument(argumentsToAddOrReplace, AZSLC_ARG2, AZSLC_NEW_VAL2a);
AppendMacroDefinitionArgument(argumentsToAddOrReplace, MCPP_MACRO1, MCPP_NEW_VALUE1);
AppendCmdLineArgument(argumentsToAddOrReplace, AZSLC_ARG5, AZSLC_NEW_VAL5);
AppendMacroDefinitionArgument(argumentsToAddOrReplace, MCPP_MACRO5, "");
AppendCmdLineArgument(argumentsToAddOrReplace, AZSLC_ARG6, "");
AZStd::string argumentsToRemove;
AppendCmdLineArgument(argumentsToRemove, AZSLC_ARG3, "");
AppendMacroDefinitionArgument(argumentsToRemove, MCPP_MACRO2, "");
AppendCmdLineArgument(argumentsToRemove, AZSLC_ARG4, "");
AppendMacroDefinitionArgument(argumentsToRemove, MCPP_MACRO4, "");
auto supervariantInfo = CreateSupervariantInfo("Dummy", argumentsToAddOrReplace, argumentsToRemove);
auto macroListToRemove = supervariantInfo.GetCombinedListOfMacroDefinitionNamesToRemove();
AZStd::vector<AZStd::string> macroNamesToRemoveThatMustBePresent = { MCPP_MACRO1, MCPP_MACRO2, MCPP_MACRO3, MCPP_MACRO4, MCPP_MACRO5 };
EXPECT_EQ(macroListToRemove.size(), macroNamesToRemoveThatMustBePresent.size());
EXPECT_TRUE(
VectorContainsAllSubstrings(macroListToRemove, macroNamesToRemoveThatMustBePresent)
);
auto macroListToAdd = supervariantInfo.GetMacroDefinitionsToAdd();
AZStd::vector<AZStd::string> macroNamesToAddThatMustBePresent = {MCPP_MACRO1, MCPP_MACRO3, MCPP_MACRO5};
EXPECT_EQ(macroListToAdd.size(), macroNamesToAddThatMustBePresent.size());
EXPECT_TRUE(VectorContainsAllSubstrings(macroListToAdd, macroNamesToAddThatMustBePresent));
// The result of GetCustomizedArgumentsForAzslc() is the most important value to test
AZStd::vector<KeyValueView> freeAzslcArgumentList = {
{AZSLC_ARG1, ""}, {AZSLC_ARG2, AZSLC_VAL2}, {AZSLC_ARG3, AZSLC_VAL3}, {AZSLC_ARG4, ""}, {AZSLC_ARG5, AZSLC_VAL5},
};
AZStd::string azslcArgs = CreateCmdLineStringFromListOfKeyValues(freeAzslcArgumentList);
AZStd::string customizedAzslcArgs = supervariantInfo.GetCustomizedArgumentsForAzslc(azslcArgs);
AZStd::vector<AZStd::string> stringsThatMustBePresent = {
AZSLC_ARG1, AZSLC_ARG2, AZSLC_NEW_VAL2a, AZSLC_ARG5, AZSLC_NEW_VAL5, AZSLC_ARG6};
EXPECT_TRUE(StringContainsAllSubstrings(customizedAzslcArgs, stringsThatMustBePresent));
AZStd::vector<AZStd::string> stringsThatCanNotBePresent = { AZSLC_ARG3, AZSLC_VAL3, AZSLC_ARG4,
// Because GetCustomizedArgumentsForAzslc() only returns arguments for AZSLc, none of the macro related
// arguments can be present
MCPP_MACRO1, MCPP_VALUE1, MCPP_NEW_VALUE1,
MCPP_MACRO2, MCPP_VALUE2,
MCPP_MACRO3, MCPP_VALUE3, MCPP_NEW_VALUE3,
MCPP_MACRO4,
MCPP_MACRO5
};
EXPECT_TRUE(
StringDoesNotContainAnyOneOfTheSubstrings(customizedAzslcArgs, stringsThatCanNotBePresent)
);
}
TEST_F(SupervariantCmdArgumentTests, ShaderAssetBuilder_ValidateInfluenceOfSupervariantInfoOnGlobalBuildOptions)
{
// In this test we validate how the ShaderAssetBuilder configure the commmand line arguments it passes
// to MCPP, AZSLc & DXC. It basically starts with a GlobalBuildOptions, that gets further customized by
// the ShaderCompilerArguments from ShaderSourceData(.shader file) and later further customized
// by each SupervariantInfo in ShaderSourceData.
// The first step is to define the initial values of the GlobalBuildOptions.
AZStd::vector<KeyValueView> globalMcppMacrosList = {
{MCPP_MACRO1, MCPP_VALUE1},
{MCPP_MACRO2, MCPP_VALUE2},
{MCPP_MACRO3, MCPP_VALUE3},
{MCPP_MACRO4, ""},
};
AZStd::vector<KeyValueView> globalAzslArguments = {
{AZSLC_ARG1, ""},
{AZSLC_ARG2, AZSLC_VAL2},
{AZSLC_ARG3, AZSLC_VAL3},
{AZSLC_ARG4, ""},
{AZSLC_ARG5, AZSLC_VAL5},
};
auto globalBuildOptions = CreateGlobalBuildOptions(
AZStd::vector<AZStd::string>(), CreateListOfStringsFromListOfKeyValues(globalMcppMacrosList),
CreateCmdLineStringFromListOfKeyValues(globalAzslArguments),
"" /* Don't care about DXC in this test */);
// The second step is to load the Shader Compiler Arguments from the .shader file.
// These arguments will be merged in @globalBuildOptions, but the .shader arguments have
// higher priority.
AZStd::vector<KeyValueView> shaderAzslArguments = {
{AZSLC_ARG2, AZSLC_NEW_VAL2a},
{AZSLC_ARG6, ""},
};
auto shaderCompilerArguments = CreateShaderCompilerArguments(
CreateCmdLineStringFromListOfKeyValues(shaderAzslArguments), "" /* Don't care about DXC in this test */);
globalBuildOptions.m_compilerArguments.Merge(shaderCompilerArguments);
// Let's create the dummy supervariant. It will have some MCPP & AZSLc arguments to be added/replaced AND other MCPP & AZSLc arguments to be removed.
AZStd::vector<KeyValueView> supervariantAzslArgumentsToAdd = {
{AZSLC_ARG2, AZSLC_NEW_VAL2b},
{AZSLC_ARG7, ""},
};
AZStd::vector<KeyValueView> supervariantMacroDefinitionsToAdd = {
{MCPP_MACRO1, MCPP_NEW_VALUE1},
{MCPP_MACRO3, MCPP_NEW_VALUE3},
{MCPP_MACRO5, ""},
};
auto supervariantArgumentsToAdd = CreateCmdLineStringFromListOfKeyValues(supervariantAzslArgumentsToAdd) +
CreateMacroDefinitionCmdLineStringFromListOfKeyValues(supervariantMacroDefinitionsToAdd);
AZStd::vector<KeyValueView> supervariantAzslArgumentsToRemove = {
{AZSLC_ARG4, ""},
{AZSLC_ARG1, ""},
};
AZStd::vector<KeyValueView> supervariantMacrosToRemove = {
{MCPP_MACRO2, ""},
{MCPP_MACRO4, ""},
};
auto supervariantArgumentsToRemove = CreateCmdLineStringFromListOfKeyValues(supervariantAzslArgumentsToRemove) +
CreateMacroDefinitionCmdLineStringFromListOfKeyValues(supervariantMacrosToRemove);
//CreateMacroDefinitionCmdLineStringFromListOfKeyValues
auto supervariantInfo = CreateSupervariantInfo("Dummy",
supervariantArgumentsToAdd, // These arguments will be added or replace existing ones.
supervariantArgumentsToRemove); // These arguments must be removed.
AZStd::vector<AZStd::string> macroDefinitionNamesToRemove = supervariantInfo.GetCombinedListOfMacroDefinitionNamesToRemove();
globalBuildOptions.m_preprocessorSettings.RemovePredefinedMacros(macroDefinitionNamesToRemove);
AZStd::vector<AZStd::string> macroDefinitionsToAdd = supervariantInfo.GetMacroDefinitionsToAdd();
globalBuildOptions.m_preprocessorSettings.m_predefinedMacros.insert(
globalBuildOptions.m_preprocessorSettings.m_predefinedMacros.end(), macroDefinitionsToAdd.begin(), macroDefinitionsToAdd.end());
// Validate macro definitions that must be present.
EXPECT_TRUE(
VectorContainsAllSubstrings(
globalBuildOptions.m_preprocessorSettings.m_predefinedMacros,
AZStd::vector<AZStd::string>({MCPP_MACRO1, MCPP_NEW_VALUE1, MCPP_MACRO3, MCPP_NEW_VALUE3, MCPP_MACRO5}))
);
// Validate macro definitions that can't be present.
EXPECT_TRUE(
VectorDoesNotContainAnyOneOfTheSubstrings(
globalBuildOptions.m_preprocessorSettings.m_predefinedMacros,
AZStd::vector<AZStd::string>({MCPP_MACRO2, MCPP_VALUE3, MCPP_MACRO4}))
);
AZStd::string azslcArgsFromGlobalBuildOptions = globalBuildOptions.m_compilerArguments.MakeAdditionalAzslcCommandLineString();
// The result of GetCustomizedArgumentsForAzslc() is the most important value to test
AZStd::string customizedAzslcArgs = supervariantInfo.GetCustomizedArgumentsForAzslc(azslcArgsFromGlobalBuildOptions);
EXPECT_TRUE(
StringContainsAllSubstrings(customizedAzslcArgs, CreateListOfSingleStringsFromListOfKeyValues(supervariantAzslArgumentsToAdd))
);
EXPECT_TRUE(
StringDoesNotContainAnyOneOfTheSubstrings(customizedAzslcArgs, CreateListOfSingleStringsFromListOfKeyValues(supervariantAzslArgumentsToRemove))
);
EXPECT_TRUE(
StringContainsAllSubstrings(customizedAzslcArgs, AZStd::vector<AZStd::string>({AZSLC_ARG3, AZSLC_VAL3, AZSLC_ARG5, AZSLC_VAL5}))
);
}
} //namespace UnitTest
AZ_UNIT_TEST_HOOK(DEFAULT_UNIT_TEST_ENV);