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_TEST_HOOKS_H
17e509ee18Sopenharmony_ci#define ECMASCRIPT_TOOLING_TEST_UTILS_TEST_HOOKS_H
18e509ee18Sopenharmony_ci
19e509ee18Sopenharmony_ci#include "agent/debugger_impl.h"
20e509ee18Sopenharmony_ci#include "backend/js_pt_hooks.h"
21e509ee18Sopenharmony_ci#include "test/utils/test_util.h"
22e509ee18Sopenharmony_ci
23e509ee18Sopenharmony_cinamespace panda::ecmascript::tooling::test {
24e509ee18Sopenharmony_ciclass TestHooks : public PtHooks {
25e509ee18Sopenharmony_cipublic:
26e509ee18Sopenharmony_ci    TestHooks(const std::string &testName, const EcmaVM *vm) : vm_(vm)
27e509ee18Sopenharmony_ci    {
28e509ee18Sopenharmony_ci        testName_ = testName;
29e509ee18Sopenharmony_ci        test_ = TestUtil::GetTest(testName);
30e509ee18Sopenharmony_ci        runtime_ = std::make_unique<RuntimeImpl>(vm, test_->channel_);
31e509ee18Sopenharmony_ci        debugger_ = std::make_unique<DebuggerImpl>(vm, test_->channel_, runtime_.get());
32e509ee18Sopenharmony_ci        test_->vm_ = vm;
33e509ee18Sopenharmony_ci        test_->debugger_ = debugger_.get();
34e509ee18Sopenharmony_ci        test_->runtime_ = runtime_.get();
35e509ee18Sopenharmony_ci        test_->debugInterface_ = debugger_->jsDebugger_;
36e509ee18Sopenharmony_ci        debugInterface_ = debugger_->jsDebugger_;
37e509ee18Sopenharmony_ci        TestUtil::Reset();
38e509ee18Sopenharmony_ci        debugInterface_->RegisterHooks(this);
39e509ee18Sopenharmony_ci    }
40e509ee18Sopenharmony_ci
41e509ee18Sopenharmony_ci    void Run()
42e509ee18Sopenharmony_ci    {
43e509ee18Sopenharmony_ci        if (test_->scenario) {
44e509ee18Sopenharmony_ci            test_->scenario();
45e509ee18Sopenharmony_ci        }
46e509ee18Sopenharmony_ci    }
47e509ee18Sopenharmony_ci
48e509ee18Sopenharmony_ci    void DebuggerStmt(const JSPtLocation &location) override
49e509ee18Sopenharmony_ci    {
50e509ee18Sopenharmony_ci        if (test_->debugger_) {
51e509ee18Sopenharmony_ci            test_->debuggerStmt(location);
52e509ee18Sopenharmony_ci        }
53e509ee18Sopenharmony_ci    }
54e509ee18Sopenharmony_ci
55e509ee18Sopenharmony_ci    void Breakpoint(const JSPtLocation &location) override
56e509ee18Sopenharmony_ci    {
57e509ee18Sopenharmony_ci        if (test_->breakpoint) {
58e509ee18Sopenharmony_ci            test_->breakpoint(location);
59e509ee18Sopenharmony_ci        }
60e509ee18Sopenharmony_ci    }
61e509ee18Sopenharmony_ci
62e509ee18Sopenharmony_ci    void LoadModule(std::string_view panda_file_name, [[maybe_unused]] std::string_view entryPoint) override
63e509ee18Sopenharmony_ci    {
64e509ee18Sopenharmony_ci        if (test_->loadModule) {
65e509ee18Sopenharmony_ci            test_->loadModule(panda_file_name);
66e509ee18Sopenharmony_ci        }
67e509ee18Sopenharmony_ci    }
68e509ee18Sopenharmony_ci
69e509ee18Sopenharmony_ci    void Exception(const JSPtLocation &location) override
70e509ee18Sopenharmony_ci    {
71e509ee18Sopenharmony_ci        if (test_->exception) {
72e509ee18Sopenharmony_ci            Local<JSValueRef> exception = DebuggerApi::GetAndClearException(vm_);
73e509ee18Sopenharmony_ci
74e509ee18Sopenharmony_ci            test_->exception(location);
75e509ee18Sopenharmony_ci
76e509ee18Sopenharmony_ci            if (!exception->IsHole()) {
77e509ee18Sopenharmony_ci                DebuggerApi::SetException(vm_, exception);
78e509ee18Sopenharmony_ci            }
79e509ee18Sopenharmony_ci        }
80e509ee18Sopenharmony_ci    }
81e509ee18Sopenharmony_ci
82e509ee18Sopenharmony_ci    bool SingleStep(const JSPtLocation &location) override
83e509ee18Sopenharmony_ci    {
84e509ee18Sopenharmony_ci        if (test_->singleStep) {
85e509ee18Sopenharmony_ci            return test_->singleStep(location);
86e509ee18Sopenharmony_ci        }
87e509ee18Sopenharmony_ci        return false;
88e509ee18Sopenharmony_ci    }
89e509ee18Sopenharmony_ci
90e509ee18Sopenharmony_ci    bool NativeOut() override
91e509ee18Sopenharmony_ci    {
92e509ee18Sopenharmony_ci        if (test_->nativeOut) {
93e509ee18Sopenharmony_ci            return test_->nativeOut();
94e509ee18Sopenharmony_ci        }
95e509ee18Sopenharmony_ci
96e509ee18Sopenharmony_ci        return false;
97e509ee18Sopenharmony_ci    }
98e509ee18Sopenharmony_ci
99e509ee18Sopenharmony_ci    void VmDeath() override
100e509ee18Sopenharmony_ci    {
101e509ee18Sopenharmony_ci        if (test_->vmDeath) {
102e509ee18Sopenharmony_ci            test_->vmDeath();
103e509ee18Sopenharmony_ci        }
104e509ee18Sopenharmony_ci        TestUtil::Event(DebugEvent::VM_DEATH);
105e509ee18Sopenharmony_ci    }
106e509ee18Sopenharmony_ci
107e509ee18Sopenharmony_ci    void VmStart() override
108e509ee18Sopenharmony_ci    {
109e509ee18Sopenharmony_ci        if (test_->vmStart) {
110e509ee18Sopenharmony_ci            test_->vmStart();
111e509ee18Sopenharmony_ci        }
112e509ee18Sopenharmony_ci        TestUtil::Event(DebugEvent::VM_START);
113e509ee18Sopenharmony_ci    }
114e509ee18Sopenharmony_ci
115e509ee18Sopenharmony_ci    void NativeCalling([[maybe_unused]] const void *nativeAddress) override {}
116e509ee18Sopenharmony_ci
117e509ee18Sopenharmony_ci    void NativeReturn([[maybe_unused]] const void *nativeAddress) override {}
118e509ee18Sopenharmony_ci
119e509ee18Sopenharmony_ci    void SendableMethodEntry([[maybe_unused]] JSHandle<Method> method) override {}
120e509ee18Sopenharmony_ci
121e509ee18Sopenharmony_ci    void TerminateTest()
122e509ee18Sopenharmony_ci    {
123e509ee18Sopenharmony_ci        debugInterface_->UnregisterHooks();
124e509ee18Sopenharmony_ci        if (TestUtil::IsTestFinished()) {
125e509ee18Sopenharmony_ci            return;
126e509ee18Sopenharmony_ci        }
127e509ee18Sopenharmony_ci        LOG_DEBUGGER(FATAL) << "Test " << testName_ << " failed";
128e509ee18Sopenharmony_ci    }
129e509ee18Sopenharmony_ci
130e509ee18Sopenharmony_ci    ~TestHooks() = default;
131e509ee18Sopenharmony_ci
132e509ee18Sopenharmony_ciprivate:
133e509ee18Sopenharmony_ci    const EcmaVM *vm_ {nullptr};
134e509ee18Sopenharmony_ci    std::unique_ptr<RuntimeImpl> runtime_ {nullptr};
135e509ee18Sopenharmony_ci    std::unique_ptr<DebuggerImpl> debugger_ {nullptr};
136e509ee18Sopenharmony_ci    JSDebugger *debugInterface_;
137e509ee18Sopenharmony_ci    std::string testName_;
138e509ee18Sopenharmony_ci    TestEvents *test_;
139e509ee18Sopenharmony_ci};
140e509ee18Sopenharmony_ci}  // namespace panda::ecmascript::tooling::test
141e509ee18Sopenharmony_ci
142e509ee18Sopenharmony_ci#endif  // ECMASCRIPT_TOOLING_TEST_UTILS_TEST_HOOKS_H
143