1/*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "ecmascript/tests/test_helper.h"
17
18#include "ecmascript/debugger/hot_reload_manager.h"
19#include "ecmascript/debugger/js_debugger_manager.h"
20#include "ecmascript/jspandafile/js_pandafile_manager.h"
21#include "ecmascript/napi/include/jsnapi.h"
22
23namespace panda::ecmascript::tooling {
24// dummy class for test only
25class ProtocolHandler {};
26}
27
28namespace panda::test {
29using namespace panda::ecmascript;
30using PatchErrorCode = panda::JSNApi::PatchErrorCode;
31using ProtocolHandler = tooling::ProtocolHandler;
32
33class HotReloadManagerTest : public testing::Test {
34public:
35    static void SetUpTestCase()
36    {
37        GTEST_LOG_(INFO) << "SetUpTestCase";
38    }
39
40    static void TearDownTestCase()
41    {
42        GTEST_LOG_(INFO) << "TearDownCase";
43    }
44
45    void SetUp() override
46    {
47        TestHelper::CreateEcmaVMWithScope(ecmaVm, thread, scope);
48        JSNApi::SetBundle(ecmaVm, false);
49        ecmaVm->GetJsDebuggerManager()->SetDebuggerHandler(new ProtocolHandler());
50    }
51
52    void TearDown() override
53    {
54        ecmaVm->GetJsDebuggerManager()->SetDebuggerHandler(nullptr);
55        TestHelper::DestroyEcmaVMWithScope(ecmaVm, scope);
56    }
57
58    EcmaVM *ecmaVm {nullptr};
59    EcmaHandleScope *scope {nullptr};
60    JSThread *thread {nullptr};
61};
62
63HWTEST_F_L0(HotReloadManagerTest, LoadAndUnload)
64{
65    std::string baseFileName = DEBUGGER_ABC_DIR "single_file/base/index.abc";
66    std::string patchFileName = DEBUGGER_ABC_DIR "single_file/patch/index.abc";
67    std::string sourceFile = DEBUGGER_JS_DIR "patch/index.js";
68
69    const auto *hotReloadManager = ecmaVm->GetJsDebuggerManager()->GetHotReloadManager();
70    JSNApi::EnableUserUncaughtErrorHandler(ecmaVm);
71
72    bool result = JSNApi::Execute(ecmaVm, baseFileName, "index");
73    EXPECT_TRUE(result);
74
75    auto baseFile = JSPandaFileManager::GetInstance()->FindJSPandaFile(baseFileName.c_str());
76    EXPECT_TRUE(baseFile != nullptr);
77    EXPECT_TRUE(hotReloadManager->GetBaseJSPandaFile(baseFile.get()) == baseFile.get());
78
79    auto res = JSNApi::LoadPatch(ecmaVm, patchFileName, baseFileName);
80    EXPECT_TRUE(res == PatchErrorCode::SUCCESS);
81    auto patchFile = JSPandaFileManager::GetInstance()->FindJSPandaFile(patchFileName.c_str());
82    EXPECT_TRUE(patchFile != nullptr);
83    EXPECT_TRUE(hotReloadManager->GetBaseJSPandaFile(patchFile.get()) == baseFile.get());
84
85    [[maybe_unused]] auto patchExtractors = hotReloadManager->GetPatchExtractors(sourceFile);
86    EXPECT_TRUE(!patchExtractors.empty());
87
88    Local<ObjectRef> exception = JSNApi::GetAndClearUncaughtException(ecmaVm);
89    result = JSNApi::IsQuickFixCausedException(ecmaVm, exception, patchFileName);
90    EXPECT_FALSE(result);
91
92    res = JSNApi::UnloadPatch(ecmaVm, patchFileName);
93    EXPECT_TRUE(res == PatchErrorCode::SUCCESS);
94    EXPECT_TRUE(hotReloadManager->GetBaseJSPandaFile(patchFile.get()) != baseFile.get());
95    EXPECT_TRUE(hotReloadManager->GetPatchExtractors(sourceFile).empty());
96}
97}  // namespace panda::test
98