1e509ee18Sopenharmony_ci/*
2e509ee18Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd.
3e509ee18Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4e509ee18Sopenharmony_ci * you may not use this file except in compliance with the License.
5e509ee18Sopenharmony_ci * You may obtain a copy of the License at
6e509ee18Sopenharmony_ci *
7e509ee18Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8e509ee18Sopenharmony_ci *
9e509ee18Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10e509ee18Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11e509ee18Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12e509ee18Sopenharmony_ci * See the License for the specific language governing permissions and
13e509ee18Sopenharmony_ci * limitations under the License.
14e509ee18Sopenharmony_ci */
15e509ee18Sopenharmony_ci
16e509ee18Sopenharmony_ci#ifndef ECMASCRIPT_TOOLING_TEST_UTILS_TESTCASES_JS_SINGLE_STEP_TEST_H
17e509ee18Sopenharmony_ci#define ECMASCRIPT_TOOLING_TEST_UTILS_TESTCASES_JS_SINGLE_STEP_TEST_H
18e509ee18Sopenharmony_ci
19e509ee18Sopenharmony_ci#include "test/utils/test_util.h"
20e509ee18Sopenharmony_ci
21e509ee18Sopenharmony_cinamespace panda::ecmascript::tooling::test {
22e509ee18Sopenharmony_ciclass JsSingleStepTest : public TestEvents {
23e509ee18Sopenharmony_cipublic:
24e509ee18Sopenharmony_ci    JsSingleStepTest()
25e509ee18Sopenharmony_ci    {
26e509ee18Sopenharmony_ci        vmDeath = [this]() {
27e509ee18Sopenharmony_ci            ASSERT_NE(stepCounter_, 0);  // 0: step counter
28e509ee18Sopenharmony_ci            ASSERT_EQ(breakpointCounter_, 2);  // 2: break point counter
29e509ee18Sopenharmony_ci            return true;
30e509ee18Sopenharmony_ci        };
31e509ee18Sopenharmony_ci
32e509ee18Sopenharmony_ci        loadModule = [this](std::string_view moduleName) {
33e509ee18Sopenharmony_ci            runtime_->Enable();
34e509ee18Sopenharmony_ci            // 19: line number
35e509ee18Sopenharmony_ci            locationStart_ = TestUtil::GetLocation(sourceFile_.c_str(), 19, 0, pandaFile_.c_str());
36e509ee18Sopenharmony_ci            // 22: line number
37e509ee18Sopenharmony_ci            locationEnd_ = TestUtil::GetLocation(sourceFile_.c_str(), 22, 0, pandaFile_.c_str());
38e509ee18Sopenharmony_ci            TestUtil::SuspendUntilContinue(DebugEvent::LOAD_MODULE);
39e509ee18Sopenharmony_ci            ASSERT_EQ(moduleName, pandaFile_);
40e509ee18Sopenharmony_ci            auto condFuncRef = FunctionRef::Undefined(vm_);
41e509ee18Sopenharmony_ci            auto ret = debugInterface_->SetBreakpoint(locationEnd_, condFuncRef);
42e509ee18Sopenharmony_ci            ASSERT_TRUE(ret);
43e509ee18Sopenharmony_ci            return true;
44e509ee18Sopenharmony_ci        };
45e509ee18Sopenharmony_ci
46e509ee18Sopenharmony_ci        breakpoint = [this](const JSPtLocation &location) {
47e509ee18Sopenharmony_ci            ASSERT_TRUE(location.GetMethodId().IsValid());
48e509ee18Sopenharmony_ci            ASSERT_LOCATION_EQ(location, locationEnd_);
49e509ee18Sopenharmony_ci            // Check what step signalled before breakpoint
50e509ee18Sopenharmony_ci            ASSERT_LOCATION_EQ(location, locationStep_);
51e509ee18Sopenharmony_ci            ASSERT_TRUE(collectSteps_);
52e509ee18Sopenharmony_ci            breakpointCounter_++;
53e509ee18Sopenharmony_ci            // Disable collect steps
54e509ee18Sopenharmony_ci            collectSteps_ = false;
55e509ee18Sopenharmony_ci            return true;
56e509ee18Sopenharmony_ci        };
57e509ee18Sopenharmony_ci
58e509ee18Sopenharmony_ci        singleStep = [this](const JSPtLocation &location) {
59e509ee18Sopenharmony_ci            ASSERT_TRUE(location.GetMethodId().IsValid());
60e509ee18Sopenharmony_ci            if (!collectSteps_) {
61e509ee18Sopenharmony_ci                if (locationStart_ == location) {
62e509ee18Sopenharmony_ci                    collectSteps_ = true;
63e509ee18Sopenharmony_ci                }
64e509ee18Sopenharmony_ci                return false;
65e509ee18Sopenharmony_ci            }
66e509ee18Sopenharmony_ci
67e509ee18Sopenharmony_ci            ASSERT_NE(bytecodeOffset_, location.GetBytecodeOffset());
68e509ee18Sopenharmony_ci            locationStep_ = location;
69e509ee18Sopenharmony_ci            stepCounter_++;
70e509ee18Sopenharmony_ci            bytecodeOffset_ = location.GetBytecodeOffset();
71e509ee18Sopenharmony_ci            return false;
72e509ee18Sopenharmony_ci        };
73e509ee18Sopenharmony_ci
74e509ee18Sopenharmony_ci        scenario = []() {
75e509ee18Sopenharmony_ci            TestUtil::WaitForLoadModule();
76e509ee18Sopenharmony_ci            TestUtil::Continue();
77e509ee18Sopenharmony_ci            return true;
78e509ee18Sopenharmony_ci        };
79e509ee18Sopenharmony_ci    }
80e509ee18Sopenharmony_ci
81e509ee18Sopenharmony_ci    std::pair<std::string, std::string> GetEntryPoint() override
82e509ee18Sopenharmony_ci    {
83e509ee18Sopenharmony_ci        return {pandaFile_, entryPoint_};
84e509ee18Sopenharmony_ci    }
85e509ee18Sopenharmony_ci
86e509ee18Sopenharmony_ciprivate:
87e509ee18Sopenharmony_ci    std::string pandaFile_ = DEBUGGER_ABC_DIR "sample.abc";
88e509ee18Sopenharmony_ci    std::string sourceFile_ = DEBUGGER_JS_DIR "sample.js";
89e509ee18Sopenharmony_ci    std::string entryPoint_ = "_GLOBAL::func_main_0";
90e509ee18Sopenharmony_ci    JSPtLocation locationStart_ {nullptr, JSPtLocation::EntityId(0), 0};
91e509ee18Sopenharmony_ci    JSPtLocation locationEnd_ {nullptr, JSPtLocation::EntityId(0), 0};
92e509ee18Sopenharmony_ci    JSPtLocation locationStep_ {nullptr, JSPtLocation::EntityId(0), 0};
93e509ee18Sopenharmony_ci    int32_t stepCounter_ = 0;
94e509ee18Sopenharmony_ci    int32_t breakpointCounter_ = 0;
95e509ee18Sopenharmony_ci    bool collectSteps_ = false;
96e509ee18Sopenharmony_ci    uint32_t bytecodeOffset_ = std::numeric_limits<uint32_t>::max();
97e509ee18Sopenharmony_ci};
98e509ee18Sopenharmony_ci
99e509ee18Sopenharmony_cistd::unique_ptr<TestEvents> GetJsSingleStepTest()
100e509ee18Sopenharmony_ci{
101e509ee18Sopenharmony_ci    return std::make_unique<JsSingleStepTest>();
102e509ee18Sopenharmony_ci}
103e509ee18Sopenharmony_ci}  // namespace panda::ecmascript::tooling::test
104e509ee18Sopenharmony_ci
105e509ee18Sopenharmony_ci#endif  // ECMASCRIPT_TOOLING_TEST_UTILS_TESTCASES_JS_SINGLE_STEP_TEST_H
106