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 #ifndef ECMASCRIPT_TOOLING_TEST_UTILS_TESTCASES_JS_STEP_OUT_TEST_H
17 #define ECMASCRIPT_TOOLING_TEST_UTILS_TESTCASES_JS_STEP_OUT_TEST_H
18
19 #include "test/utils/test_util.h"
20
21 namespace panda::ecmascript::tooling::test {
22 class JsStepOutTest : public TestEvents {
23 public:
JsStepOutTest()24 JsStepOutTest()
25 {
26 vmDeath = [this]() {
27 ASSERT_EQ(breakpointCounter_, pointerLocations_.size()); // size: break point counter
28 ASSERT_EQ(stepCompleteCounter_, stepLocations_.size()); // size: step complete counter
29 return true;
30 };
31
32 loadModule = [this](std::string_view moduleName) {
33 // 74、36: line number for breakpoint array
34 size_t breakpoint[5][2] = {{74, 0}, {36, 0}, {50, 0}, {61, 0}, {96, 0}};
35 // 28: line number for stepinto array
36 size_t stepOut[4][2] = {{28, 0}, {43, 0}, {57, 0}, {88, 5}};
37 SetJSPtLocation(breakpoint[0], POINTER_SIZE, pointerLocations_);
38 SetJSPtLocation(stepOut[0], STEP_SIZE, stepLocations_);
39 TestUtil::SuspendUntilContinue(DebugEvent::LOAD_MODULE);
40 ASSERT_EQ(moduleName, pandaFile_);
41 debugger_->NotifyScriptParsed(0, moduleName.data());
42 auto condFuncRef = FunctionRef::Undefined(vm_);
43 for (auto &iter : pointerLocations_) {
44 auto ret = debugInterface_->SetBreakpoint(iter, condFuncRef);
45 ASSERT_TRUE(ret);
46 }
47 return true;
48 };
49
50 breakpoint = [this](const JSPtLocation &location) {
51 ASSERT_TRUE(location.GetMethodId().IsValid());
52 ASSERT_LOCATION_EQ(location, pointerLocations_.at(breakpointCounter_));
53 ++breakpointCounter_;
54 TestUtil::SuspendUntilContinue(DebugEvent::BREAKPOINT, location);
55 debugger_->StepOut();
56 return true;
57 };
58
59 singleStep = [this](const JSPtLocation &location) {
60 if (debugger_->NotifySingleStep(location)) {
61 ASSERT_TRUE(location.GetMethodId().IsValid());
62 ASSERT_LOCATION_EQ(location, stepLocations_.at(stepCompleteCounter_));
63 stepCompleteCounter_++;
64 TestUtil::SuspendUntilContinue(DebugEvent::STEP_COMPLETE, location);
65 return true;
66 }
67 return false;
68 };
69
70 scenario = [this]() {
71 TestUtil::WaitForLoadModule();
72 TestUtil::Continue();
73 size_t index = 0;
74 while (index < pointerLocations_.size()) {
75 TestUtil::WaitForBreakpoint(pointerLocations_.at(index));
76 TestUtil::Continue();
77 if (index < STEP_SIZE) {
78 TestUtil::WaitForStepComplete(stepLocations_.at(index));
79 TestUtil::Continue();
80 }
81 ++index;
82 }
83 ASSERT_EXITED();
84 return true;
85 };
86 }
87
GetEntryPoint()88 std::pair<std::string, std::string> GetEntryPoint() override
89 {
90 return {pandaFile_, entryPoint_};
91 }
92
93 private:
94 static constexpr size_t LINE_COLUMN = 2;
95 static constexpr size_t POINTER_SIZE = 5;
96 static constexpr size_t STEP_SIZE = 4;
97
98 std::string pandaFile_ = DEBUGGER_ABC_DIR "step.abc";
99 std::string entryPoint_ = "_GLOBAL::func_main_0";
100 JSPtLocation location1_ {nullptr, JSPtLocation::EntityId(0), 0};
101 JSPtLocation location2_ {nullptr, JSPtLocation::EntityId(0), 0};
102 size_t breakpointCounter_ = 0;
103 size_t stepCompleteCounter_ = 0;
104 std::vector<JSPtLocation> pointerLocations_;
105 std::vector<JSPtLocation> stepLocations_;
106
SetJSPtLocation(size_t * arr,size_t number,std::vector<JSPtLocation> & locations)107 void SetJSPtLocation(size_t *arr, size_t number, std::vector<JSPtLocation> &locations)
108 {
109 for (size_t i = 0; i < number; i++) {
110 JSPtLocation location_ =
111 TestUtil::GetLocation(arr[i * LINE_COLUMN], arr[i * LINE_COLUMN + 1], pandaFile_.c_str());
112 locations.push_back(location_);
113 }
114 };
115 };
116
GetJsStepOutTest()117 std::unique_ptr<TestEvents> GetJsStepOutTest()
118 {
119 return std::make_unique<JsStepOutTest>();
120 }
121 } // namespace panda::ecmascript::tooling::test
122
123 #endif // ECMASCRIPT_TOOLING_TEST_UTILS_TESTCASES_JS_STEP_OUT_TEST_H
124