!43971 新增navigation栈备份恢复的TDD

Merge pull request !43971 from MaYaoHW/recovery_tdd
This commit is contained in:
openharmony_ci 2024-09-26 09:26:59 +00:00 committed by Gitee
commit 75c6454966
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
5 changed files with 293 additions and 0 deletions

View File

@ -2989,6 +2989,7 @@ test/unittest/core/image_provider/ @arkui_image
test/unittest/core/layout/ @arkuilayout
test/unittest/core/layout/safe_area/ @arkuilayout
test/unittest/core/manager/ @arkuievent
test/unittest/core/manager/navigation_manager_test_ng.cpp @arkui_superman
test/unittest/core/pattern/animator/ @arkuiframework
test/unittest/core/pattern/app_bar/ @arkuievent
test/unittest/core/pattern/badge/ @arkui_image

View File

@ -110,6 +110,15 @@ ace_unittest("safe_area_manager_test_ng") {
sources = [ "safe_area_manager_test_ng.cpp" ]
}
ace_unittest("navigation_manager_test_ng") {
type = "new"
module_output = "manager"
sources = [
"$ace_root/test/unittest/core/pattern/navigation/mock_navigation_stack.cpp",
"navigation_manager_test_ng.cpp",
]
}
group("core_manager_unittest") {
testonly = true
deps = [
@ -123,6 +132,7 @@ group("core_manager_unittest") {
":focus_view_test_ng",
":frame_rate_manager_test_ng",
":full_screen_manager_test_ng",
":navigation_manager_test_ng",
":post_event_manager_test_ng",
":safe_area_manager_test_ng",
":select_overlay_manager_test_ng",

View File

@ -0,0 +1,241 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <optional>
#include "gtest/gtest.h"
#include "test/unittest/core/pattern/navigation/mock_navigation_route.h"
#include "test/unittest/core/pattern/navigation/mock_navigation_stack.h"
#include "core/components_ng/pattern/navigation/navigation_model_ng.h"
#include "core/components_ng/pattern/navigation/navigation_pattern.h"
#include "test/mock/core/pipeline/mock_pipeline_context.h"
#include "test/mock/core/common/mock_container.h"
#include "test/mock/core/common/mock_theme_manager.h"
using namespace testing;
using namespace testing::ext;
namespace OHOS::Ace::NG {
namespace {
constexpr char DEST_NAME_BASE[] = "dest";
RefPtr<NavigationManager> GetNavigationManager()
{
auto pipeline = MockPipelineContext::GetCurrent();
return pipeline ? pipeline->GetNavigationManager() : nullptr;
}
void RunNavigationStackSync(const RefPtr<NavigationPattern>& navigationPattern)
{
navigationPattern->OnModifyDone();
navigationPattern->MarkNeedSyncWithJsStack();
navigationPattern->SyncWithJsStackIfNeeded();
}
RefPtr<NavigationGroupNode> InitAndCreateNavigation(const RefPtr<MockNavigationStack>& stack)
{
NavigationModelNG navigationModel;
navigationModel.Create();
navigationModel.SetNavigationStack(stack);
return AceType::DynamicCast<NavigationGroupNode>(ViewStackProcessor::GetInstance()->Finish());
}
} // namespace
class NavigationManagerTestNg : public testing::Test {
public:
static void SetUpTestSuite();
static void TearDownTestSuite();
};
void NavigationManagerTestNg::SetUpTestSuite()
{
MockPipelineContext::SetUp();
MockContainer::SetUp();
auto themeManager = AceType::MakeRefPtr<MockThemeManager>();
MockPipelineContext::GetCurrent()->SetThemeManager(themeManager);
EXPECT_CALL(*themeManager, GetTheme(_)).WillRepeatedly(Return(AceType::MakeRefPtr<NavigationBarTheme>()));
MockContainer::Current()->SetNavigationRoute(AceType::MakeRefPtr<MockNavigationRoute>(""));
}
void NavigationManagerTestNg::TearDownTestSuite()
{
MockPipelineContext::TearDown();
MockContainer::TearDown();
}
/**
* @tc.name: NavigationManagerTest001
* @tc.desc: Test basic ability of get navigationJsonInfo
* @tc.type: FUNC
* @tc.author:
*/
HWTEST_F(NavigationManagerTestNg, NavigationManagerTest001, TestSize.Level1)
{
/**
* @tc.steps: step1. test whether can get navigation manager
*/
auto navigationManager = GetNavigationManager();
ASSERT_NE(navigationManager, nullptr);
/**
* @tc.steps: step2. test whether recoverable can be set
*/
auto mockNavPathStack = AceType::MakeRefPtr<MockNavigationStack>();
auto navigationNode = InitAndCreateNavigation(mockNavPathStack);
ASSERT_NE(navigationNode, nullptr);
ASSERT_EQ(navigationNode->CanRecovery(), false);
navigationNode->OnInspectorIdUpdate("testTag");
ASSERT_EQ(navigationNode->CanRecovery(), false);
navigationNode->SetRecoverable(true);
ASSERT_EQ(navigationNode->CanRecovery(), true);
/**
* @tc.steps: step3. test whether can get navigation recovery info
*/
auto navigationPattern = AceType::DynamicCast<NavigationPattern>(navigationNode->GetPattern());
ASSERT_NE(navigationPattern, nullptr);
navigationPattern->OnModifyDone();
auto json = navigationManager->GetNavigationJsonInfo();
ASSERT_NE(json, nullptr);
}
/**
* @tc.name: NavigationManagerTest002
* @tc.desc: Test getting complex navigationJsonInfo
* @tc.type: FUNC
* @tc.author:
*/
HWTEST_F(NavigationManagerTestNg, NavigationManagerTest002, TestSize.Level1)
{
/**
* @tc.steps: step1. get navigation manager
*/
auto navigationManager = GetNavigationManager();
ASSERT_NE(navigationManager, nullptr);
/**
* @tc.steps: step2. build navigation
*/
auto mockNavPathStack = AceType::MakeRefPtr<MockNavigationStack>();
auto navigationNode = InitAndCreateNavigation(mockNavPathStack);
ASSERT_NE(navigationNode, nullptr);
const std::string navigationId = "navigationId";
navigationNode->OnInspectorIdUpdate(navigationId);
navigationNode->SetRecoverable(true);
/**
* @tc.steps: step3. mock stack operation and sync stack
*/
const int32_t testNumber = 10;
for (int32_t index = 0; index < testNumber; ++ index) {
mockNavPathStack->MockPushPath(MockNavPathInfo(DEST_NAME_BASE + std::to_string(index)));
}
auto navigationPattern = AceType::DynamicCast<NavigationPattern>(navigationNode->GetPattern());
ASSERT_NE(navigationNode, navigationPattern);
RunNavigationStackSync(navigationPattern);
auto navigationContent = navigationNode->GetContentNode();
ASSERT_NE(navigationContent, nullptr);
ASSERT_EQ(static_cast<int32_t>(navigationContent->GetChildren().size()), testNumber);
/**
* @tc.steps: step4. mock set recovery property and check
*/
const int32_t recoveryDestNum = 5;
for (int32_t index = recoveryDestNum; index < testNumber; ++ index) {
auto navDestination = AceType::DynamicCast<NavDestinationGroupNode>(navigationContent->GetChildAtIndex(index));
ASSERT_NE(navDestination, nullptr);
navDestination->SetRecoverable(false);
}
for (int32_t index = 0; index < recoveryDestNum; ++ index) {
auto navDestination = AceType::DynamicCast<NavDestinationGroupNode>(navigationContent->GetChildAtIndex(index));
ASSERT_NE(navDestination, nullptr);
// the default value of navdestination->CanRecovery() should be true
ASSERT_EQ(navDestination->CanRecovery(), index < recoveryDestNum ? true : false);
}
/**
* @tc.steps: step5. get json info and do verify
*/
auto json = navigationManager->GetNavigationJsonInfo();
std::cout << "Got Json: " << json->ToString() << std::endl;
ASSERT_NE(json, nullptr);
ASSERT_EQ(json->IsArray(), true);
auto navigationInfo = json->GetArrayItem(0);
ASSERT_NE(navigationInfo, nullptr);
auto stackInfo = navigationInfo->GetValue("stack");
ASSERT_NE(stackInfo, nullptr);
ASSERT_EQ(stackInfo->IsArray(), true);
ASSERT_EQ(stackInfo->GetArraySize(), recoveryDestNum);
for (int32_t index = 0; index < recoveryDestNum; ++ index) {
auto destInfo = stackInfo->GetArrayItem(index);
ASSERT_NE(destInfo, nullptr);
auto nameInfo = destInfo->GetValue("name");
ASSERT_NE(nameInfo, nullptr);
ASSERT_EQ(nameInfo->IsString(), true);
ASSERT_EQ(nameInfo->GetString(), DEST_NAME_BASE + std::to_string(index));
}
}
/**
* @tc.name: NavigationManagerTest003
* @tc.desc: Test storage navigationJsonInfo
* @tc.type: FUNC
* @tc.author:
*/
HWTEST_F(NavigationManagerTestNg, NavigationManagerTest003, TestSize.Level1)
{
/**
* @tc.steps: step1. get navigation manager
*/
auto navigationManager = GetNavigationManager();
ASSERT_NE(navigationManager, nullptr);
/**
* @tc.steps: step2. build navigation
*/
auto mockNavPathStack = AceType::MakeRefPtr<MockNavigationStack>();
auto navigationNode = InitAndCreateNavigation(mockNavPathStack);
ASSERT_NE(navigationNode, nullptr);
const std::string navigationId = "navigationId";
navigationNode->OnInspectorIdUpdate(navigationId);
navigationNode->SetRecoverable(true);
/**
* @tc.steps: step3. mock stack operation and sync stack
*/
const int32_t testNumber = 10;
for (int32_t index = 0; index < testNumber; ++ index) {
mockNavPathStack->MockPushPath(MockNavPathInfo(DEST_NAME_BASE + std::to_string(index)));
}
auto navigationPattern = AceType::DynamicCast<NavigationPattern>(navigationNode->GetPattern());
ASSERT_NE(navigationNode, navigationPattern);
RunNavigationStackSync(navigationPattern);
auto navigationContent = navigationNode->GetContentNode();
ASSERT_NE(navigationContent, nullptr);
ASSERT_EQ(static_cast<int32_t>(navigationContent->GetChildren().size()), testNumber);
/**
* @tc.steps: step4. mock set recovery property and check
*/
const int32_t recoveryDestNum = 5;
for (int32_t index = recoveryDestNum; index < testNumber; ++ index) {
auto navDestination = AceType::DynamicCast<NavDestinationGroupNode>(navigationContent->GetChildAtIndex(index));
ASSERT_NE(navDestination, nullptr);
navDestination->SetRecoverable(false);
}
/**
* @tc.steps: step5. get json info and do storage
*/
auto json = navigationManager->GetNavigationJsonInfo();
navigationManager->StorageNavigationRecoveryInfo(std::move(json));
auto recoveryDests = navigationManager->GetNavigationRecoveryInfo(navigationId);
ASSERT_EQ(static_cast<int32_t>(recoveryDests.size()), recoveryDestNum);
for (int32_t index = 0; index < recoveryDestNum; ++ index) {
auto name = recoveryDests[index].name;
ASSERT_EQ(name, DEST_NAME_BASE + std::to_string(index));
}
}
} // namespace OHOS::Ace::NG

View File

@ -176,4 +176,32 @@ void MockNavigationStack::SetNeedBuildNewInstance(int32_t index, bool need)
}
mockPathArray_[index].needBuildNewInstance = need;
}
void MockNavigationStack::SetPathArray(const std::vector<NavdestinationRecoveryInfo>& navdestinationsInfo)
{
std::vector<MockNavPathInfo> newPathArray;
for (auto recoveryInfo : navdestinationsInfo) {
MockNavPathInfo navPathInfo(recoveryInfo.name);
navPathInfo.mode = recoveryInfo.mode;
navPathInfo.fromRecovery = true;
newPathArray.push_back(navPathInfo);
}
mockPathArray_ = newPathArray;
}
void MockNavigationStack::SetFromRecovery(int32_t index, bool fromRecovery)
{
if (!CheckIndexValid(index, mockPathArray_.size())) {
return;
}
mockPathArray_[index].fromRecovery = fromRecovery;
}
bool MockNavigationStack::IsFromRecovery(int32_t index)
{
if (!CheckIndexValid(index, mockPathArray_.size())) {
return false;
}
return mockPathArray_[index].fromRecovery;
}
} // namespace OHOS::Ace::NG

View File

@ -36,6 +36,8 @@ struct MockNavPathInfo {
std::string name = "";
std::string navDestinationId = UNDEFINED_ID;
bool needBuildNewInstance = false;
bool fromRecovery = false;
int32_t mode = 0; // 0 for standard and 1 for dialog
explicit MockNavPathInfo(std::string name) : name(std::move(name)) {}
};
@ -139,6 +141,12 @@ public:
void SetNeedBuildNewInstance(int32_t index, bool need) override;
void SetPathArray(const std::vector<NavdestinationRecoveryInfo>& navdestinationsInfo);
void SetFromRecovery(int32_t index, bool fromRecovery);
bool IsFromRecovery(int32_t index);
// ============================ operation below is for mock NavPathStack in arkTS ============================
/**
* @brief simply mock push operation of NavPathStack(@arkTS)
@ -158,6 +166,11 @@ public:
void PopToIndex(int32_t index);
std::pair<int32_t, std::string> FindInPopArray(const std::string& name);
int32_t Size() const
{
return static_cast<int32_t>(mockPathArray_.size());
}
// ============================ operation above is for mock NavPathStack in arkTS ============================
private:
int8_t lifecycleIndex_ = 0;