1/* 2 * Copyright (c) 2021 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_SINGLE_STEP_TEST_H 17#define ECMASCRIPT_TOOLING_TEST_UTILS_TESTCASES_JS_SINGLE_STEP_TEST_H 18 19#include "test/utils/test_util.h" 20 21namespace panda::ecmascript::tooling::test { 22class JsSingleStepTest : public TestEvents { 23public: 24 JsSingleStepTest() 25 { 26 vmDeath = [this]() { 27 ASSERT_NE(stepCounter_, 0); // 0: step counter 28 ASSERT_EQ(breakpointCounter_, 2); // 2: break point counter 29 return true; 30 }; 31 32 loadModule = [this](std::string_view moduleName) { 33 runtime_->Enable(); 34 // 19: line number 35 locationStart_ = TestUtil::GetLocation(sourceFile_.c_str(), 19, 0, pandaFile_.c_str()); 36 // 22: line number 37 locationEnd_ = TestUtil::GetLocation(sourceFile_.c_str(), 22, 0, pandaFile_.c_str()); 38 TestUtil::SuspendUntilContinue(DebugEvent::LOAD_MODULE); 39 ASSERT_EQ(moduleName, pandaFile_); 40 auto condFuncRef = FunctionRef::Undefined(vm_); 41 auto ret = debugInterface_->SetBreakpoint(locationEnd_, condFuncRef); 42 ASSERT_TRUE(ret); 43 return true; 44 }; 45 46 breakpoint = [this](const JSPtLocation &location) { 47 ASSERT_TRUE(location.GetMethodId().IsValid()); 48 ASSERT_LOCATION_EQ(location, locationEnd_); 49 // Check what step signalled before breakpoint 50 ASSERT_LOCATION_EQ(location, locationStep_); 51 ASSERT_TRUE(collectSteps_); 52 breakpointCounter_++; 53 // Disable collect steps 54 collectSteps_ = false; 55 return true; 56 }; 57 58 singleStep = [this](const JSPtLocation &location) { 59 ASSERT_TRUE(location.GetMethodId().IsValid()); 60 if (!collectSteps_) { 61 if (locationStart_ == location) { 62 collectSteps_ = true; 63 } 64 return false; 65 } 66 67 ASSERT_NE(bytecodeOffset_, location.GetBytecodeOffset()); 68 locationStep_ = location; 69 stepCounter_++; 70 bytecodeOffset_ = location.GetBytecodeOffset(); 71 return false; 72 }; 73 74 scenario = []() { 75 TestUtil::WaitForLoadModule(); 76 TestUtil::Continue(); 77 return true; 78 }; 79 } 80 81 std::pair<std::string, std::string> GetEntryPoint() override 82 { 83 return {pandaFile_, entryPoint_}; 84 } 85 86private: 87 std::string pandaFile_ = DEBUGGER_ABC_DIR "sample.abc"; 88 std::string sourceFile_ = DEBUGGER_JS_DIR "sample.js"; 89 std::string entryPoint_ = "_GLOBAL::func_main_0"; 90 JSPtLocation locationStart_ {nullptr, JSPtLocation::EntityId(0), 0}; 91 JSPtLocation locationEnd_ {nullptr, JSPtLocation::EntityId(0), 0}; 92 JSPtLocation locationStep_ {nullptr, JSPtLocation::EntityId(0), 0}; 93 int32_t stepCounter_ = 0; 94 int32_t breakpointCounter_ = 0; 95 bool collectSteps_ = false; 96 uint32_t bytecodeOffset_ = std::numeric_limits<uint32_t>::max(); 97}; 98 99std::unique_ptr<TestEvents> GetJsSingleStepTest() 100{ 101 return std::make_unique<JsSingleStepTest>(); 102} 103} // namespace panda::ecmascript::tooling::test 104 105#endif // ECMASCRIPT_TOOLING_TEST_UTILS_TESTCASES_JS_SINGLE_STEP_TEST_H 106