From eb8ce86245eb2b94601b542f4ba05fcb65161590 Mon Sep 17 00:00:00 2001 From: Jan Date: Mon, 25 Dec 2023 17:48:32 +0100 Subject: [PATCH 1/7] Add assertions to dvarStrList test to make sure the state is correct --- .../Menu/Sequence/ItemScopeSequencesTests.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/test/ObjLoadingTests/Parsing/Menu/Sequence/ItemScopeSequencesTests.cpp b/test/ObjLoadingTests/Parsing/Menu/Sequence/ItemScopeSequencesTests.cpp index 7109a818b..d3fd9c410 100644 --- a/test/ObjLoadingTests/Parsing/Menu/Sequence/ItemScopeSequencesTests.cpp +++ b/test/ObjLoadingTests/Parsing/Menu/Sequence/ItemScopeSequencesTests.cpp @@ -88,5 +88,23 @@ namespace test::parsing::menu::sequence::item REQUIRE(result); REQUIRE(helper.m_consumed_token_count == 11); + + const auto* item = helper.m_state->m_current_item; + REQUIRE(item); + const auto* multiValueFeatures = item->m_multi_value_features.get(); + REQUIRE(multiValueFeatures); + + REQUIRE(multiValueFeatures->m_step_names.size() == 4); + REQUIRE(multiValueFeatures->m_string_values.size() == 4); + + REQUIRE(multiValueFeatures->m_step_names[0] == "@MENU_AUTO"); + REQUIRE(multiValueFeatures->m_step_names[1] == "@MENU_STANDARD_4_3"); + REQUIRE(multiValueFeatures->m_step_names[2] == "@MENU_WIDE_16_10"); + REQUIRE(multiValueFeatures->m_step_names[3] == "@MENU_WIDE_16_9"); + + REQUIRE(multiValueFeatures->m_string_values[0] == "auto"); + REQUIRE(multiValueFeatures->m_string_values[1] == "standard"); + REQUIRE(multiValueFeatures->m_string_values[2] == "wide 16:10"); + REQUIRE(multiValueFeatures->m_string_values[3] == "wide 16:9"); } } // namespace test::parsing::menu::sequence::item From f5c987ce59966de068ed8d66797568f596e46e9e Mon Sep 17 00:00:00 2001 From: Jan Date: Mon, 25 Dec 2023 19:35:03 +0100 Subject: [PATCH 2/7] Add unit tests for menu item rect --- .../Menu/Sequence/ItemScopeSequences.cpp | 23 ++-- .../Menu/Sequence/ItemScopeSequencesTests.cpp | 128 ++++++++++++++++++ 2 files changed, 138 insertions(+), 13 deletions(-) diff --git a/src/ObjLoading/Parsing/Menu/Sequence/ItemScopeSequences.cpp b/src/ObjLoading/Parsing/Menu/Sequence/ItemScopeSequences.cpp index 032caeb36..0ba34791f 100644 --- a/src/ObjLoading/Parsing/Menu/Sequence/ItemScopeSequences.cpp +++ b/src/ObjLoading/Parsing/Menu/Sequence/ItemScopeSequences.cpp @@ -189,8 +189,7 @@ namespace menu::item_scope_sequences class SequenceRect final : public MenuFileParser::sequence_t { - static constexpr auto CAPTURE_ALIGN_HORIZONTAL = 1; - static constexpr auto CAPTURE_ALIGN_VERTICAL = 2; + static constexpr auto TAG_ALIGN = 1; public: SequenceRect() @@ -204,10 +203,12 @@ namespace menu::item_scope_sequences create.NumericExpression(), // y create.NumericExpression(), // w create.NumericExpression(), // h - create.Optional(create.And({ - create.Integer().Capture(CAPTURE_ALIGN_HORIZONTAL), - create.Integer().Capture(CAPTURE_ALIGN_VERTICAL), - })), + create.Optional(create + .And({ + create.IntExpression(), // Align horizontal + create.IntExpression(), // Align vertical + }) + .Tag(TAG_ALIGN)), }); } @@ -222,10 +223,10 @@ namespace menu::item_scope_sequences const auto h = MenuMatcherFactory::TokenNumericExpressionValue(state, result); CommonRect rect{x, y, w, h, 0, 0}; - if (result.HasNextCapture(CAPTURE_ALIGN_HORIZONTAL) && result.HasNextCapture(CAPTURE_ALIGN_VERTICAL)) + if (result.PeekAndRemoveIfTag(TAG_ALIGN) == TAG_ALIGN) { - rect.horizontalAlign = result.NextCapture(CAPTURE_ALIGN_HORIZONTAL).IntegerValue(); - rect.verticalAlign = result.NextCapture(CAPTURE_ALIGN_VERTICAL).IntegerValue(); + rect.horizontalAlign = MenuMatcherFactory::TokenIntExpressionValue(state, result); + rect.verticalAlign = MenuMatcherFactory::TokenIntExpressionValue(state, result); } state->m_current_item->m_rect = rect; @@ -259,10 +260,6 @@ namespace menu::item_scope_sequences class SequenceDecodeEffect final : public MenuFileParser::sequence_t { - static constexpr auto CAPTURE_LETTER_TIME = 1; - static constexpr auto CAPTURE_DECAY_START_TIME = 2; - static constexpr auto CAPTURE_DECAY_DURATION = 3; - public: SequenceDecodeEffect() { diff --git a/test/ObjLoadingTests/Parsing/Menu/Sequence/ItemScopeSequencesTests.cpp b/test/ObjLoadingTests/Parsing/Menu/Sequence/ItemScopeSequencesTests.cpp index d3fd9c410..4be3355d4 100644 --- a/test/ObjLoadingTests/Parsing/Menu/Sequence/ItemScopeSequencesTests.cpp +++ b/test/ObjLoadingTests/Parsing/Menu/Sequence/ItemScopeSequencesTests.cpp @@ -4,8 +4,10 @@ #include #include +#include using namespace menu; +using namespace Catch::Matchers; namespace test::parsing::menu::sequence::item { @@ -62,6 +64,132 @@ namespace test::parsing::menu::sequence::item } }; + TEST_CASE("ItemScopeSequences: Rect works with only x,y,w,h as ints", "[parsing][sequence][menu]") + { + ItemSequenceTestsHelper helper(FeatureLevel::IW4, false); + const TokenPos pos; + helper.Tokens({ + SimpleParserValue::Identifier(pos, new std::string("rect")), + SimpleParserValue::Integer(pos, 20), + SimpleParserValue::Integer(pos, 40), + SimpleParserValue::Integer(pos, 100), + SimpleParserValue::Integer(pos, 520), + SimpleParserValue::EndOfFile(pos), + }); + + const auto result = helper.PerformTest(); + + REQUIRE(result); + REQUIRE(helper.m_consumed_token_count == 5); + + const auto* item = helper.m_state->m_current_item; + REQUIRE(item); + + REQUIRE_THAT(item->m_rect.x, WithinRel(20.0)); + REQUIRE_THAT(item->m_rect.y, WithinRel(40.0)); + REQUIRE_THAT(item->m_rect.w, WithinRel(100.0)); + REQUIRE_THAT(item->m_rect.h, WithinRel(520.0)); + REQUIRE(item->m_rect.horizontalAlign == 0); + REQUIRE(item->m_rect.verticalAlign == 0); + } + + TEST_CASE("ItemScopeSequences: Rect works with only x,y,w,h as floats", "[parsing][sequence][menu]") + { + ItemSequenceTestsHelper helper(FeatureLevel::IW4, false); + const TokenPos pos; + helper.Tokens({ + SimpleParserValue::Identifier(pos, new std::string("rect")), + SimpleParserValue::FloatingPoint(pos, 20.2), + SimpleParserValue::FloatingPoint(pos, 40.4), + SimpleParserValue::FloatingPoint(pos, 100.6), + SimpleParserValue::FloatingPoint(pos, 520.8), + SimpleParserValue::EndOfFile(pos), + }); + + const auto result = helper.PerformTest(); + + REQUIRE(result); + REQUIRE(helper.m_consumed_token_count == 5); + + const auto* item = helper.m_state->m_current_item; + REQUIRE(item); + + REQUIRE_THAT(item->m_rect.x, WithinRel(20.2)); + REQUIRE_THAT(item->m_rect.y, WithinRel(40.4)); + REQUIRE_THAT(item->m_rect.w, WithinRel(100.6)); + REQUIRE_THAT(item->m_rect.h, WithinRel(520.8)); + } + + TEST_CASE("ItemScopeSequences: Rect supports expressions", "[parsing][sequence][menu]") + { + ItemSequenceTestsHelper helper(FeatureLevel::IW4, false); + const TokenPos pos; + helper.Tokens({ + SimpleParserValue::Identifier(pos, new std::string("rect")), + SimpleParserValue::Character(pos, '('), + SimpleParserValue::FloatingPoint(pos, 20.2), + SimpleParserValue::Character(pos, '+'), + SimpleParserValue::Integer(pos, 40), + SimpleParserValue::Character(pos, ')'), + SimpleParserValue::Character(pos, '('), + SimpleParserValue::FloatingPoint(pos, 40.2), + SimpleParserValue::Character(pos, '-'), + SimpleParserValue::FloatingPoint(pos, 1.4), + SimpleParserValue::Character(pos, ')'), + SimpleParserValue::Character(pos, '('), + SimpleParserValue::FloatingPoint(pos, 100.6), + SimpleParserValue::Character(pos, '+'), + SimpleParserValue::FloatingPoint(pos, 2.0), + SimpleParserValue::Character(pos, ')'), + SimpleParserValue::Character(pos, '('), + SimpleParserValue::FloatingPoint(pos, 5.0), + SimpleParserValue::Character(pos, '*'), + SimpleParserValue::FloatingPoint(pos, 1.5), + SimpleParserValue::Character(pos, ')'), + SimpleParserValue::EndOfFile(pos), + }); + + const auto result = helper.PerformTest(); + + REQUIRE(result); + REQUIRE(helper.m_consumed_token_count == 21); + + const auto* item = helper.m_state->m_current_item; + REQUIRE(item); + + REQUIRE_THAT(item->m_rect.x, WithinRel(60.2)); + REQUIRE_THAT(item->m_rect.y, WithinRel(38.8)); + REQUIRE_THAT(item->m_rect.w, WithinRel(102.6)); + REQUIRE_THAT(item->m_rect.h, WithinRel(7.5)); + } + + TEST_CASE("ItemScopeSequences: Rect can specify align", "[parsing][sequence][menu]") + { + ItemSequenceTestsHelper helper(FeatureLevel::IW4, false); + const TokenPos pos; + helper.Tokens({ + SimpleParserValue::Identifier(pos, new std::string("rect")), + SimpleParserValue::FloatingPoint(pos, 20.2), + SimpleParserValue::FloatingPoint(pos, 40.4), + SimpleParserValue::FloatingPoint(pos, 100.6), + SimpleParserValue::FloatingPoint(pos, 520.8), + SimpleParserValue::Integer(pos, 1), + SimpleParserValue::Integer(pos, 2), + SimpleParserValue::EndOfFile(pos), + }); + + const auto result = helper.PerformTest(); + + REQUIRE(result); + REQUIRE(helper.m_consumed_token_count == 7); + + const auto* item = helper.m_state->m_current_item; + REQUIRE(item); + + REQUIRE(item->m_rect.horizontalAlign == 1); + REQUIRE(item->m_rect.verticalAlign == 2); + } + TEST_CASE("ItemScopeSequences: Simple dvarStrList works", "[parsing][sequence][menu]") { ItemSequenceTestsHelper helper(FeatureLevel::IW4, false); From 1b5d6f7439e865eea554a66d44690153f9744e06 Mon Sep 17 00:00:00 2001 From: Jan Date: Mon, 25 Dec 2023 19:52:20 +0100 Subject: [PATCH 3/7] Add unit test for menu item origin --- .../Menu/Sequence/ItemScopeSequencesTests.cpp | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/test/ObjLoadingTests/Parsing/Menu/Sequence/ItemScopeSequencesTests.cpp b/test/ObjLoadingTests/Parsing/Menu/Sequence/ItemScopeSequencesTests.cpp index 4be3355d4..adf31fc36 100644 --- a/test/ObjLoadingTests/Parsing/Menu/Sequence/ItemScopeSequencesTests.cpp +++ b/test/ObjLoadingTests/Parsing/Menu/Sequence/ItemScopeSequencesTests.cpp @@ -190,6 +190,37 @@ namespace test::parsing::menu::sequence::item REQUIRE(item->m_rect.verticalAlign == 2); } + TEST_CASE("ItemScopeSequences: Can specify origin", "[parsing][sequence][menu]") + { + ItemSequenceTestsHelper helper(FeatureLevel::IW4, false); + const TokenPos pos; + helper.Tokens({ + SimpleParserValue::Identifier(pos, new std::string("origin")), + SimpleParserValue::FloatingPoint(pos, 4.20), + SimpleParserValue::Character(pos, '('), + SimpleParserValue::FloatingPoint(pos, 11.37), + SimpleParserValue::Character(pos, '+'), + SimpleParserValue::FloatingPoint(pos, 2.0), + SimpleParserValue::Character(pos, ')'), + SimpleParserValue::EndOfFile(pos), + }); + + const auto result = helper.PerformTest(); + + REQUIRE(result); + REQUIRE(helper.m_consumed_token_count == 7); + + const auto* item = helper.m_state->m_current_item; + REQUIRE(item); + + REQUIRE_THAT(item->m_rect.x, WithinRel(4.20)); + REQUIRE_THAT(item->m_rect.y, WithinRel(13.37)); + REQUIRE_THAT(item->m_rect.w, WithinRel(0.0)); + REQUIRE_THAT(item->m_rect.h, WithinRel(0.0)); + REQUIRE(item->m_rect.horizontalAlign == 0); + REQUIRE(item->m_rect.verticalAlign == 0); + } + TEST_CASE("ItemScopeSequences: Simple dvarStrList works", "[parsing][sequence][menu]") { ItemSequenceTestsHelper helper(FeatureLevel::IW4, false); From 7820390dd89ae5a9bcec667faa0ebb62a34d2170 Mon Sep 17 00:00:00 2001 From: Jan Date: Mon, 25 Dec 2023 22:59:56 +0100 Subject: [PATCH 4/7] Support static expressions for menu simple string properties --- .../Menu/Matcher/MenuMatcherFactory.cpp | 50 +++++++++++++++++++ .../Parsing/Menu/Matcher/MenuMatcherFactory.h | 16 ++++-- .../Generic/GenericStringPropertySequence.cpp | 6 ++- .../Generic/GenericStringPropertySequence.h | 1 - .../Menu/Sequence/ItemScopeSequencesTests.cpp | 27 ++++++++++ 5 files changed, 92 insertions(+), 8 deletions(-) diff --git a/src/ObjLoading/Parsing/Menu/Matcher/MenuMatcherFactory.cpp b/src/ObjLoading/Parsing/Menu/Matcher/MenuMatcherFactory.cpp index 3adb50438..e8686b47f 100644 --- a/src/ObjLoading/Parsing/Menu/Matcher/MenuMatcherFactory.cpp +++ b/src/ObjLoading/Parsing/Menu/Matcher/MenuMatcherFactory.cpp @@ -58,6 +58,20 @@ MatcherFactoryWrapper MenuMatcherFactory::Numeric() const })); } +MatcherFactoryWrapper MenuMatcherFactory::TextExpression() const +{ + return MatcherFactoryWrapper(Or({ + StringChain().Tag(TAG_STRING_CHAIN).Capture(CAPTURE_STRING_CHAIN), + Identifier().Tag(TAG_IDENTIFIER).Capture(CAPTURE_IDENTIFIER), + And({ + Char('(').Capture(CAPTURE_FIRST_TOKEN), + Label(MenuExpressionMatchers::LABEL_EXPRESSION), + Char(')'), + }) + .Tag(TAG_EXPRESSION), + })); +} + MatcherFactoryWrapper MenuMatcherFactory::IntExpression() const { return MatcherFactoryWrapper(Or({ @@ -144,6 +158,42 @@ int MenuMatcherFactory::TokenIntExpressionValue(MenuFileParserState* state, Sequ throw ParsingException(TokenPos(), "TokenIntExpressionValue must be expression or int"); } +std::string MenuMatcherFactory::TokenTextExpressionValue(MenuFileParserState* state, SequenceResult& result) +{ + const auto nextTag = result.PeekTag(); + + assert(nextTag == TAG_STRING_CHAIN || nextTag == TAG_IDENTIFIER || nextTag == TAG_EXPRESSION); + if (nextTag == TAG_STRING_CHAIN) + { + result.NextTag(); + return result.NextCapture(CAPTURE_STRING_CHAIN).StringValue(); + } + + if (nextTag == TAG_IDENTIFIER) + { + result.NextTag(); + return result.NextCapture(CAPTURE_IDENTIFIER).IdentifierValue(); + } + + if (nextTag == TAG_EXPRESSION) + { + result.NextTag(); + const auto expression = MenuExpressionMatchers(state).ProcessExpression(result); + + if (!expression || !expression->IsStatic()) + throw ParsingException(result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos(), "Not a valid static expression"); + + const auto value = expression->EvaluateStatic(); + + if (value.m_type != SimpleExpressionValue::Type::STRING) + throw ParsingException(result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos(), "Expression MUST be string type"); + + return std::move(*value.m_string_value); + } + + throw ParsingException(TokenPos(), "TokenIntExpressionValue must be expression or int"); +} + double MenuMatcherFactory::TokenNumericExpressionValue(MenuFileParserState* state, SequenceResult& result) { const auto nextTag = result.PeekTag(); diff --git a/src/ObjLoading/Parsing/Menu/Matcher/MenuMatcherFactory.h b/src/ObjLoading/Parsing/Menu/Matcher/MenuMatcherFactory.h index c0c8ccf43..562deeedf 100644 --- a/src/ObjLoading/Parsing/Menu/Matcher/MenuMatcherFactory.h +++ b/src/ObjLoading/Parsing/Menu/Matcher/MenuMatcherFactory.h @@ -8,13 +8,17 @@ namespace menu { class MenuMatcherFactory : public SimpleMatcherFactory { - static constexpr auto TAG_INT = 1420; - static constexpr auto TAG_NUMERIC = 1421; - static constexpr auto TAG_EXPRESSION = 1422; + static constexpr auto TAG_STRING_CHAIN = 1420; + static constexpr auto TAG_IDENTIFIER = 1421; + static constexpr auto TAG_INT = 1422; + static constexpr auto TAG_NUMERIC = 1423; + static constexpr auto TAG_EXPRESSION = 1424; static constexpr auto CAPTURE_FIRST_TOKEN = 1420; - static constexpr auto CAPTURE_INT = 1421; - static constexpr auto CAPTURE_NUMERIC = 1422; + static constexpr auto CAPTURE_STRING_CHAIN = 1421; + static constexpr auto CAPTURE_IDENTIFIER = 1422; + static constexpr auto CAPTURE_INT = 1423; + static constexpr auto CAPTURE_NUMERIC = 1424; public: explicit MenuMatcherFactory(const IMatcherForLabelSupplier* labelSupplier); @@ -24,6 +28,7 @@ namespace menu _NODISCARD MatcherFactoryWrapper TextNoChain() const; _NODISCARD MatcherFactoryWrapper Numeric() const; + _NODISCARD MatcherFactoryWrapper TextExpression() const; _NODISCARD MatcherFactoryWrapper IntExpression() const; _NODISCARD MatcherFactoryWrapper NumericExpression() const; @@ -31,6 +36,7 @@ namespace menu _NODISCARD static double TokenNumericFloatingPointValue(const SimpleParserValue& value); _NODISCARD static std::string& TokenTextValue(const SimpleParserValue& value); + _NODISCARD static std::string TokenTextExpressionValue(MenuFileParserState* state, SequenceResult& result); _NODISCARD static int TokenIntExpressionValue(MenuFileParserState* state, SequenceResult& result); _NODISCARD static double TokenNumericExpressionValue(MenuFileParserState* state, SequenceResult& result); }; diff --git a/src/ObjLoading/Parsing/Menu/Sequence/Generic/GenericStringPropertySequence.cpp b/src/ObjLoading/Parsing/Menu/Sequence/Generic/GenericStringPropertySequence.cpp index c0faa0744..7340db90c 100644 --- a/src/ObjLoading/Parsing/Menu/Sequence/Generic/GenericStringPropertySequence.cpp +++ b/src/ObjLoading/Parsing/Menu/Sequence/Generic/GenericStringPropertySequence.cpp @@ -1,5 +1,6 @@ #include "GenericStringPropertySequence.h" +#include "Parsing/Menu/Matcher/MenuExpressionMatchers.h" #include "Parsing/Menu/Matcher/MenuMatcherFactory.h" #include @@ -10,10 +11,11 @@ GenericStringPropertySequence::GenericStringPropertySequence(std::string keyword : m_set_callback(std::move(setCallback)) { const MenuMatcherFactory create(this); + AddLabeledMatchers(MenuExpressionMatchers().Expression(this), MenuExpressionMatchers::LABEL_EXPRESSION); AddMatchers({ create.KeywordIgnoreCase(std::move(keywordName)).Capture(CAPTURE_FIRST_TOKEN), - create.Text().Capture(CAPTURE_VALUE), + create.TextExpression(), }); } @@ -21,7 +23,7 @@ void GenericStringPropertySequence::ProcessMatch(MenuFileParserState* state, Seq { if (m_set_callback) { - const auto& value = MenuMatcherFactory::TokenTextValue(result.NextCapture(CAPTURE_VALUE)); + const auto value = MenuMatcherFactory::TokenTextExpressionValue(state, result); m_set_callback(state, result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos(), value); } } diff --git a/src/ObjLoading/Parsing/Menu/Sequence/Generic/GenericStringPropertySequence.h b/src/ObjLoading/Parsing/Menu/Sequence/Generic/GenericStringPropertySequence.h index c199c295a..60a846ba7 100644 --- a/src/ObjLoading/Parsing/Menu/Sequence/Generic/GenericStringPropertySequence.h +++ b/src/ObjLoading/Parsing/Menu/Sequence/Generic/GenericStringPropertySequence.h @@ -14,7 +14,6 @@ namespace menu private: static constexpr auto CAPTURE_FIRST_TOKEN = 1; - static constexpr auto CAPTURE_VALUE = 2; const callback_t m_set_callback; diff --git a/test/ObjLoadingTests/Parsing/Menu/Sequence/ItemScopeSequencesTests.cpp b/test/ObjLoadingTests/Parsing/Menu/Sequence/ItemScopeSequencesTests.cpp index adf31fc36..71edcd3ca 100644 --- a/test/ObjLoadingTests/Parsing/Menu/Sequence/ItemScopeSequencesTests.cpp +++ b/test/ObjLoadingTests/Parsing/Menu/Sequence/ItemScopeSequencesTests.cpp @@ -64,6 +64,33 @@ namespace test::parsing::menu::sequence::item } }; + TEST_CASE("ItemScopeSequences: Can use static expressions for simple text properties", "[parsing][sequence][menu]") + { + ItemSequenceTestsHelper helper(FeatureLevel::IW4, false); + const TokenPos pos; + helper.Tokens({ + SimpleParserValue::Identifier(pos, new std::string("name")), + SimpleParserValue::Character(pos, '('), + SimpleParserValue::String(pos, new std::string("Hello")), + SimpleParserValue::Character(pos, '+'), + SimpleParserValue::String(pos, new std::string(" ")), + SimpleParserValue::Character(pos, '+'), + SimpleParserValue::String(pos, new std::string("World")), + SimpleParserValue::Character(pos, ')'), + SimpleParserValue::EndOfFile(pos), + }); + + const auto result = helper.PerformTest(); + + REQUIRE(result); + REQUIRE(helper.m_consumed_token_count == 8); + + const auto* item = helper.m_state->m_current_item; + REQUIRE(item); + + REQUIRE(item->m_name == "Hello World"); + } + TEST_CASE("ItemScopeSequences: Rect works with only x,y,w,h as ints", "[parsing][sequence][menu]") { ItemSequenceTestsHelper helper(FeatureLevel::IW4, false); From 749f44b2c4e852fdf8ebe532f77a9ff5390ac3ad Mon Sep 17 00:00:00 2001 From: Jan Date: Tue, 26 Dec 2023 13:06:48 +0100 Subject: [PATCH 5/7] Add tests to ensure menu simple int properties can be static expressions --- .../Menu/Sequence/ItemScopeSequencesTests.cpp | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/test/ObjLoadingTests/Parsing/Menu/Sequence/ItemScopeSequencesTests.cpp b/test/ObjLoadingTests/Parsing/Menu/Sequence/ItemScopeSequencesTests.cpp index 71edcd3ca..ad76a38ad 100644 --- a/test/ObjLoadingTests/Parsing/Menu/Sequence/ItemScopeSequencesTests.cpp +++ b/test/ObjLoadingTests/Parsing/Menu/Sequence/ItemScopeSequencesTests.cpp @@ -91,6 +91,33 @@ namespace test::parsing::menu::sequence::item REQUIRE(item->m_name == "Hello World"); } + TEST_CASE("ItemScopeSequences: Can use static expressions for simple int properties", "[parsing][sequence][menu]") + { + ItemSequenceTestsHelper helper(FeatureLevel::IW4, false); + const TokenPos pos; + helper.Tokens({ + SimpleParserValue::Identifier(pos, new std::string("style")), + SimpleParserValue::Character(pos, '('), + SimpleParserValue::Integer(pos, 1), + SimpleParserValue::Character(pos, '+'), + SimpleParserValue::Integer(pos, 2), + SimpleParserValue::Character(pos, '+'), + SimpleParserValue::Integer(pos, 6), + SimpleParserValue::Character(pos, ')'), + SimpleParserValue::EndOfFile(pos), + }); + + const auto result = helper.PerformTest(); + + REQUIRE(result); + REQUIRE(helper.m_consumed_token_count == 8); + + const auto* item = helper.m_state->m_current_item; + REQUIRE(item); + + REQUIRE(item->m_style == 9); + } + TEST_CASE("ItemScopeSequences: Rect works with only x,y,w,h as ints", "[parsing][sequence][menu]") { ItemSequenceTestsHelper helper(FeatureLevel::IW4, false); From 851baa5931ea8f899ee73b4786c24103faaf51a9 Mon Sep 17 00:00:00 2001 From: Jan Date: Tue, 26 Dec 2023 13:09:20 +0100 Subject: [PATCH 6/7] Add test to ensure menu simple floating point properties can be static expressions --- .../Menu/Sequence/ItemScopeSequencesTests.cpp | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/test/ObjLoadingTests/Parsing/Menu/Sequence/ItemScopeSequencesTests.cpp b/test/ObjLoadingTests/Parsing/Menu/Sequence/ItemScopeSequencesTests.cpp index ad76a38ad..7fe9817cd 100644 --- a/test/ObjLoadingTests/Parsing/Menu/Sequence/ItemScopeSequencesTests.cpp +++ b/test/ObjLoadingTests/Parsing/Menu/Sequence/ItemScopeSequencesTests.cpp @@ -118,6 +118,33 @@ namespace test::parsing::menu::sequence::item REQUIRE(item->m_style == 9); } + TEST_CASE("ItemScopeSequences: Can use static expressions for simple float properties", "[parsing][sequence][menu]") + { + ItemSequenceTestsHelper helper(FeatureLevel::IW4, false); + const TokenPos pos; + helper.Tokens({ + SimpleParserValue::Identifier(pos, new std::string("borderSize")), + SimpleParserValue::Character(pos, '('), + SimpleParserValue::FloatingPoint(pos, 4.2), + SimpleParserValue::Character(pos, '+'), + SimpleParserValue::FloatingPoint(pos, 5), + SimpleParserValue::Character(pos, '+'), + SimpleParserValue::FloatingPoint(pos, 0.2), + SimpleParserValue::Character(pos, ')'), + SimpleParserValue::EndOfFile(pos), + }); + + const auto result = helper.PerformTest(); + + REQUIRE(result); + REQUIRE(helper.m_consumed_token_count == 8); + + const auto* item = helper.m_state->m_current_item; + REQUIRE(item); + + REQUIRE_THAT(item->m_border_size, WithinRel(9.4)); + } + TEST_CASE("ItemScopeSequences: Rect works with only x,y,w,h as ints", "[parsing][sequence][menu]") { ItemSequenceTestsHelper helper(FeatureLevel::IW4, false); From 0bcadc1abe4ee7ac645b486cb9b3573d409573f7 Mon Sep 17 00:00:00 2001 From: Jan Date: Tue, 26 Dec 2023 13:11:59 +0100 Subject: [PATCH 7/7] Add test to ensure menu simple color properties can be static expressions --- .../Menu/Sequence/ItemScopeSequencesTests.cpp | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/test/ObjLoadingTests/Parsing/Menu/Sequence/ItemScopeSequencesTests.cpp b/test/ObjLoadingTests/Parsing/Menu/Sequence/ItemScopeSequencesTests.cpp index 7fe9817cd..da457fe12 100644 --- a/test/ObjLoadingTests/Parsing/Menu/Sequence/ItemScopeSequencesTests.cpp +++ b/test/ObjLoadingTests/Parsing/Menu/Sequence/ItemScopeSequencesTests.cpp @@ -145,6 +145,39 @@ namespace test::parsing::menu::sequence::item REQUIRE_THAT(item->m_border_size, WithinRel(9.4)); } + TEST_CASE("ItemScopeSequences: Can use static expressions for simple color properties", "[parsing][sequence][menu]") + { + ItemSequenceTestsHelper helper(FeatureLevel::IW4, false); + const TokenPos pos; + helper.Tokens({ + SimpleParserValue::Identifier(pos, new std::string("backColor")), + SimpleParserValue::Character(pos, '('), + SimpleParserValue::FloatingPoint(pos, 0.2), + SimpleParserValue::Character(pos, '+'), + SimpleParserValue::FloatingPoint(pos, 0.5), + SimpleParserValue::Character(pos, '+'), + SimpleParserValue::FloatingPoint(pos, 0.2), + SimpleParserValue::Character(pos, ')'), + SimpleParserValue::FloatingPoint(pos, 0.5), + SimpleParserValue::FloatingPoint(pos, 0.6), + SimpleParserValue::FloatingPoint(pos, 1.0), + SimpleParserValue::EndOfFile(pos), + }); + + const auto result = helper.PerformTest(); + + REQUIRE(result); + REQUIRE(helper.m_consumed_token_count == 11); + + const auto* item = helper.m_state->m_current_item; + REQUIRE(item); + + REQUIRE_THAT(item->m_back_color.r, WithinRel(0.9)); + REQUIRE_THAT(item->m_back_color.g, WithinRel(0.5)); + REQUIRE_THAT(item->m_back_color.b, WithinRel(0.6)); + REQUIRE_THAT(item->m_back_color.a, WithinRel(1.0)); + } + TEST_CASE("ItemScopeSequences: Rect works with only x,y,w,h as ints", "[parsing][sequence][menu]") { ItemSequenceTestsHelper helper(FeatureLevel::IW4, false);