1 /**
2 * Copyright (c) 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 "ast_verifier_test.h"
17 #include "ir/astNode.h"
18 #include "public/es2panda_lib.h"
19
20 #include <gtest/gtest.h>
21
22 using ark::es2panda::compiler::ast_verifier::ASTVerifier;
23 using ark::es2panda::compiler::ast_verifier::InvariantNameSet;
24 using ark::es2panda::ir::AstNode;
25
26 namespace {
27 struct TestData {
28 char const *program;
29 };
30
31 // NOLINTNEXTLINE(fuchsia-multiple-inheritance)
32 class InfiniteLoopTests : public ASTVerifierTest, public testing::WithParamInterface<TestData> {};
33
34 // NOLINTNEXTLINE(fuchsia-multiple-inheritance)
35 class NormalLoopTests : public ASTVerifierTest, public testing::WithParamInterface<TestData> {};
36
37 // clang-format off
38 INSTANTIATE_TEST_SUITE_P(,
39 InfiniteLoopTests,
40 testing::Values(
41 TestData {
42 R"(
43 function main () {
44 while (true) {}
45 }
46 )",
47 },
48 TestData {
49 R"(
50 function main () {
51 while (2 > 1) {}
52 }
53 )",
54 },
55 TestData {
56 R"(
57 function main () {
58 do {
59 } while (true)
60 }
61 )",
62 },
63 TestData {
64 R"(
65 function main () {
66 do {
67 } while (2 > 1)
68 }
69 )",
70 },
71 TestData {
72 R"(
73 function main () {
74 for (;;) {}
75 }
76 )",
77 },
78 TestData {
79 R"(
80 function main () {
81 for (; 2 > 1;) {}
82 }
83 )",
84 }));
85 // clang-format on
86
TEST_P(InfiniteLoopTests,InfiniteLoop)87 TEST_P(InfiniteLoopTests, InfiniteLoop)
88 {
89 ASTVerifier verifier {Allocator()};
90 TestData data = GetParam();
91
92 char const *text = data.program;
93
94 es2panda_Context *ctx = impl_->CreateContextFromString(cfg_, text, "dummy.ets");
95 impl_->ProceedToState(ctx, ES2PANDA_STATE_CHECKED);
96 ASSERT_EQ(impl_->ContextState(ctx), ES2PANDA_STATE_CHECKED);
97
98 auto *ast = reinterpret_cast<AstNode *>(impl_->ProgramAst(impl_->ContextProgram(ctx)));
99
100 InvariantNameSet checks;
101 checks.insert("CheckInfiniteLoopForAll");
102 const auto &messages = verifier.Verify(ast, checks);
103
104 // Expecting warning
105 ASSERT_EQ(messages.size(), 1);
106 ASSERT_EQ(messages[0].Cause(), "INFINITE LOOP");
107
108 impl_->DestroyContext(ctx);
109 }
110
111 // clang-format off
112 INSTANTIATE_TEST_SUITE_P(,
113 NormalLoopTests,
114 testing::Values(
115 TestData {
116 R"(
117 function main() {
118 let counter = 0;
119 while (counter < 10) {
120 counter = counter + 1;
121 }
122 }
123 )",
124 },
125 TestData {
126 R"(
127 function main() {
128 let counter = 0;
129 do {
130 counter = counter + 1
131 } while (counter < 10)
132 }
133 )",
134 },
135 TestData {
136 R"(
137 function main() {
138 for (let i = 0; i < 10; ++i) {}
139 }
140 )",
141 }));
142 // clang-format on
143
TEST_P(NormalLoopTests,NormalLoop)144 TEST_P(NormalLoopTests, NormalLoop)
145 {
146 ASTVerifier verifier {Allocator()};
147
148 TestData data = GetParam();
149 char const *text = data.program;
150
151 es2panda_Context *ctx = impl_->CreateContextFromString(cfg_, text, "dummy.ets");
152 impl_->ProceedToState(ctx, ES2PANDA_STATE_CHECKED);
153 ASSERT_EQ(impl_->ContextState(ctx), ES2PANDA_STATE_CHECKED);
154
155 auto *ast = reinterpret_cast<AstNode *>(impl_->ProgramAst(impl_->ContextProgram(ctx)));
156
157 InvariantNameSet checks;
158 checks.insert("CheckInfiniteLoopForAll");
159 const auto &messages = verifier.Verify(ast, checks);
160
161 // Expecting no warnings
162 ASSERT_EQ(messages.size(), 0);
163
164 impl_->DestroyContext(ctx);
165 }
166 } // namespace
167