1/*
2 * Copyright (c) 2024 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#include "ecmascript/debugger/js_debugger.h"
18#include "ecmascript/jspandafile/js_pandafile_manager.h"
19#include "assembler/assembly-parser.h"
20
21using namespace panda::ecmascript;
22using namespace panda::ecmascript::tooling;
23using namespace panda::panda_file;
24using namespace panda::pandasm;
25
26namespace panda::ecmascript::tooling {
27class JsDebuggerFriendTest {
28public:
29    explicit JsDebuggerFriendTest(const EcmaVM* vm) : jsDebugger_(vm) {}
30
31    bool HandleStepTest(JSHandle<Method> method, uint32_t bcOffset)
32    {
33        return jsDebugger_.HandleStep(method, bcOffset);
34    }
35
36    bool HandleNativeOutTest()
37    {
38        return jsDebugger_.HandleNativeOut();
39    }
40
41    bool HandleBreakpointTest(JSHandle<Method> method, uint32_t bcOffset)
42    {
43        return jsDebugger_.HandleBreakpoint(method, bcOffset);
44    }
45
46    bool IsBreakpointCondSatisfiedTest(std::optional<JSBreakpoint> breakpoint) const
47    {
48        return jsDebugger_.IsBreakpointCondSatisfied(breakpoint);
49    }
50
51private:
52    JSDebugger jsDebugger_;
53};
54}
55
56namespace panda::test {
57class JsDebuggerTest : public testing::Test {
58public:
59    static void SetUpTestCase()
60    {
61        GTEST_LOG_(INFO) << "SetUpTestCase";
62    }
63
64    static void TearDownTestCase()
65    {
66        GTEST_LOG_(INFO) << "TearDownCase";
67    }
68
69    void SetUp() override
70    {
71        TestHelper::CreateEcmaVMWithScope(ecmaVm, thread, scope);
72    }
73
74    void TearDown() override
75    {
76        TestHelper::DestroyEcmaVMWithScope(ecmaVm, scope);
77    }
78
79    EcmaVM *ecmaVm {nullptr};
80    EcmaHandleScope *scope {nullptr};
81    JSThread *thread {nullptr};
82};
83
84HWTEST_F_L0(JsDebuggerTest, SetSmartBreakpointTest)
85{
86    JSDebugger debugger(ecmaVm);
87    Parser parser;
88    const char *filename = "__PandaFileTranslatorTest2.pa";
89    const char *data = R"(
90        .function any func_main_0(any a0, any a1, any a2) {
91            ldai 1
92            return
93        }
94    )";
95    auto res = parser.Parse(data);
96    JSPandaFileManager *pfManager = JSPandaFileManager::GetInstance();
97    std::unique_ptr<const File> pfPtr = pandasm::AsmEmitter::Emit(res.Value());
98    std::shared_ptr<JSPandaFile> pf = pfManager->NewJSPandaFile(pfPtr.release(), CString(filename));
99    const panda_file::File *testpf = pf.get()->GetPandaFile();
100    CString descriptor = "example_descriptor";
101    std::shared_ptr<JSPandaFile> jspandaFilePtr = std::make_shared<JSPandaFile>(testpf, descriptor);
102    pfManager->AddJSPandaFile(jspandaFilePtr);
103    JSPandaFile* jspandaFilePtrTest = new JSPandaFile(testpf, descriptor);
104    panda_file::File::EntityId entityId(42);
105
106    JSPtLocation location(jspandaFilePtrTest, entityId, 60, "sourceFile.js");
107    bool result = debugger.RemoveBreakpoint(location);
108    EXPECT_EQ(result, false);
109    result = debugger.SetSmartBreakpoint(location);
110    EXPECT_EQ(result, false);
111}
112
113HWTEST_F_L0(JsDebuggerTest, JsDebuggerHooksNullTest)
114{
115    JSHandle<Method> methodHandle;
116    uint32_t bcOffsetTest = 42;
117    JSHandle<JSTaggedValue> envHandle;
118    JSDebugger debugger(ecmaVm);
119    debugger.MethodEntry(methodHandle, envHandle);
120
121    bool result = debugger.HandleDebuggerStmt(methodHandle, bcOffsetTest);
122    EXPECT_EQ(result, false);
123
124    JsDebuggerFriendTest debuggerFriend(ecmaVm);
125    result = debuggerFriend.HandleNativeOutTest();
126    EXPECT_EQ(result, false);
127
128    result = debuggerFriend.HandleBreakpointTest(methodHandle, bcOffsetTest);
129    EXPECT_EQ(result, false);
130
131    result = debuggerFriend.HandleStepTest(methodHandle, bcOffsetTest);
132    EXPECT_EQ(result, false);
133}
134
135HWTEST_F_L0(JsDebuggerTest, JsDebuggerBreakpointNullTest)
136{
137    JsDebuggerFriendTest debuggerFriend(ecmaVm);
138    std::optional<ecmascript::tooling::JSBreakpoint> breakpoint;
139    bool result = debuggerFriend.IsBreakpointCondSatisfiedTest(breakpoint);
140    EXPECT_EQ(result, false);
141}
142}  // namespace panda::test