1/* 2 * Copyright (c) 2021-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 <gtest/gtest.h> 17#include "macros.h" 18#include "public/es2panda_lib.h" 19#include "test/utils/panda_executable_path_getter.h" 20 21class Es2PandaLibTest : public testing::Test { 22public: 23 Es2PandaLibTest() 24 { 25 impl_ = es2panda_GetImpl(ES2PANDA_LIB_VERSION); 26 auto es2pandaPath = test::utils::PandaExecutablePathGetter {}.Get(); 27 // NOLINTNEXTLINE(modernize-avoid-c-arrays) 28 char const *argv[] = {es2pandaPath.c_str()}; 29 cfg_ = impl_->CreateConfig(1, argv); 30 } 31 32 ~Es2PandaLibTest() override 33 { 34 impl_->DestroyConfig(cfg_); 35 } 36 37 NO_COPY_SEMANTIC(Es2PandaLibTest); 38 NO_MOVE_SEMANTIC(Es2PandaLibTest); 39 40protected: 41 // NOLINTBEGIN(misc-non-private-member-variables-in-classes) 42 es2panda_Impl const *impl_; 43 es2panda_Config *cfg_; 44 // NOLINTEND(misc-non-private-member-variables-in-classes) 45}; 46 47TEST_F(Es2PandaLibTest, NoError) 48{ 49 es2panda_Context *ctx = impl_->CreateContextFromString(cfg_, "function main() {}", "no-error.sts"); 50 impl_->ProceedToState(ctx, ES2PANDA_STATE_ASM_GENERATED); // don't produce any object files 51 ASSERT_EQ(impl_->ContextState(ctx), ES2PANDA_STATE_ASM_GENERATED); 52 impl_->DestroyContext(ctx); 53} 54 55TEST_F(Es2PandaLibTest, TypeError) 56{ 57 es2panda_Context *ctx = 58 impl_->CreateContextFromString(cfg_, "function main() { let x: int = \"\" }", "type-error.sts"); 59 impl_->ProceedToState(ctx, ES2PANDA_STATE_ASM_GENERATED); 60 ASSERT_EQ(impl_->ContextState(ctx), ES2PANDA_STATE_ERROR); 61 ASSERT_EQ(std::string(impl_->ContextErrorMessage(ctx)), 62 "TypeError: Type '\"\"' cannot be assigned to type 'int'[type-error.sts:1,32]"); 63 impl_->DestroyContext(ctx); 64} 65 66TEST_F(Es2PandaLibTest, ListIdentifiers) 67{ 68 char const *text = R"XXX( 69class C { 70 n: string = "oh" 71} 72 73function main() { 74 let c = new C 75 console.log(c.n + 1) // type error, but not syntax error 76} 77)XXX"; 78 es2panda_Context *ctx = impl_->CreateContextFromString(cfg_, text, "list-ids.sts"); 79 ctx = impl_->ProceedToState(ctx, ES2PANDA_STATE_PARSED); 80 ASSERT_EQ(impl_->ContextState(ctx), ES2PANDA_STATE_PARSED); 81 82 struct Arg { 83 es2panda_Impl const *impl = nullptr; 84 es2panda_Context *ctx = nullptr; 85 std::vector<std::string> ids; 86 } arg; 87 arg.impl = impl_; 88 arg.ctx = ctx; 89 90 auto func = [](es2panda_AstNode *ast, void *argp) { 91 auto *a = reinterpret_cast<Arg *>(argp); 92 if (a->impl->IsIdentifier(ast)) { 93 a->ids.emplace_back(a->impl->IdentifierName(a->ctx, ast)); 94 } 95 }; 96 97 impl_->AstNodeForEach(impl_->ProgramAst(impl_->ContextProgram(ctx)), func, &arg); 98 99 std::vector<std::string> expected {"C", "n", "string", "constructor", "constructor", "main", 100 "c", "C", "console", "log", "c", "n"}; 101 ASSERT_EQ(arg.ids, expected); 102 103 impl_->DestroyContext(ctx); 104} 105