1*acea8879SAndroid Build Coastguard Worker /*
2*acea8879SAndroid Build Coastguard Worker * Copyright (C) 2009 The Android Open Source Project
3*acea8879SAndroid Build Coastguard Worker *
4*acea8879SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*acea8879SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*acea8879SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*acea8879SAndroid Build Coastguard Worker *
8*acea8879SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*acea8879SAndroid Build Coastguard Worker *
10*acea8879SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*acea8879SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*acea8879SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*acea8879SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*acea8879SAndroid Build Coastguard Worker * limitations under the License.
15*acea8879SAndroid Build Coastguard Worker */
16*acea8879SAndroid Build Coastguard Worker
17*acea8879SAndroid Build Coastguard Worker #include <memory>
18*acea8879SAndroid Build Coastguard Worker #include <string>
19*acea8879SAndroid Build Coastguard Worker
20*acea8879SAndroid Build Coastguard Worker #include <gtest/gtest.h>
21*acea8879SAndroid Build Coastguard Worker
22*acea8879SAndroid Build Coastguard Worker #include "edify/expr.h"
23*acea8879SAndroid Build Coastguard Worker
expect(const std::string & expr_str,const char * expected)24*acea8879SAndroid Build Coastguard Worker static void expect(const std::string& expr_str, const char* expected) {
25*acea8879SAndroid Build Coastguard Worker std::unique_ptr<Expr> e;
26*acea8879SAndroid Build Coastguard Worker int error_count = 0;
27*acea8879SAndroid Build Coastguard Worker EXPECT_EQ(0, ParseString(expr_str, &e, &error_count));
28*acea8879SAndroid Build Coastguard Worker EXPECT_EQ(0, error_count);
29*acea8879SAndroid Build Coastguard Worker
30*acea8879SAndroid Build Coastguard Worker State state(expr_str, nullptr);
31*acea8879SAndroid Build Coastguard Worker
32*acea8879SAndroid Build Coastguard Worker std::string result;
33*acea8879SAndroid Build Coastguard Worker bool status = Evaluate(&state, e, &result);
34*acea8879SAndroid Build Coastguard Worker
35*acea8879SAndroid Build Coastguard Worker if (expected == nullptr) {
36*acea8879SAndroid Build Coastguard Worker EXPECT_FALSE(status);
37*acea8879SAndroid Build Coastguard Worker } else {
38*acea8879SAndroid Build Coastguard Worker EXPECT_STREQ(expected, result.c_str());
39*acea8879SAndroid Build Coastguard Worker }
40*acea8879SAndroid Build Coastguard Worker }
41*acea8879SAndroid Build Coastguard Worker
42*acea8879SAndroid Build Coastguard Worker class EdifyTest : public ::testing::Test {
43*acea8879SAndroid Build Coastguard Worker protected:
SetUp()44*acea8879SAndroid Build Coastguard Worker void SetUp() {
45*acea8879SAndroid Build Coastguard Worker RegisterBuiltins();
46*acea8879SAndroid Build Coastguard Worker }
47*acea8879SAndroid Build Coastguard Worker };
48*acea8879SAndroid Build Coastguard Worker
TEST_F(EdifyTest,parsing)49*acea8879SAndroid Build Coastguard Worker TEST_F(EdifyTest, parsing) {
50*acea8879SAndroid Build Coastguard Worker expect("a", "a");
51*acea8879SAndroid Build Coastguard Worker expect("\"a\"", "a");
52*acea8879SAndroid Build Coastguard Worker expect("\"\\x61\"", "a");
53*acea8879SAndroid Build Coastguard Worker expect("# this is a comment\n"
54*acea8879SAndroid Build Coastguard Worker " a\n"
55*acea8879SAndroid Build Coastguard Worker " \n",
56*acea8879SAndroid Build Coastguard Worker "a");
57*acea8879SAndroid Build Coastguard Worker }
58*acea8879SAndroid Build Coastguard Worker
TEST_F(EdifyTest,sequence)59*acea8879SAndroid Build Coastguard Worker TEST_F(EdifyTest, sequence) {
60*acea8879SAndroid Build Coastguard Worker // sequence operator
61*acea8879SAndroid Build Coastguard Worker expect("a; b; c", "c");
62*acea8879SAndroid Build Coastguard Worker }
63*acea8879SAndroid Build Coastguard Worker
TEST_F(EdifyTest,concat)64*acea8879SAndroid Build Coastguard Worker TEST_F(EdifyTest, concat) {
65*acea8879SAndroid Build Coastguard Worker // string concat operator
66*acea8879SAndroid Build Coastguard Worker expect("a + b", "ab");
67*acea8879SAndroid Build Coastguard Worker expect("a + \n \"b\"", "ab");
68*acea8879SAndroid Build Coastguard Worker expect("a + b +\nc\n", "abc");
69*acea8879SAndroid Build Coastguard Worker
70*acea8879SAndroid Build Coastguard Worker // string concat function
71*acea8879SAndroid Build Coastguard Worker expect("concat(a, b)", "ab");
72*acea8879SAndroid Build Coastguard Worker expect("concat(a,\n \"b\")", "ab");
73*acea8879SAndroid Build Coastguard Worker expect("concat(a + b,\nc,\"d\")", "abcd");
74*acea8879SAndroid Build Coastguard Worker expect("\"concat\"(a + b,\nc,\"d\")", "abcd");
75*acea8879SAndroid Build Coastguard Worker }
76*acea8879SAndroid Build Coastguard Worker
TEST_F(EdifyTest,logical)77*acea8879SAndroid Build Coastguard Worker TEST_F(EdifyTest, logical) {
78*acea8879SAndroid Build Coastguard Worker // logical and
79*acea8879SAndroid Build Coastguard Worker expect("a && b", "b");
80*acea8879SAndroid Build Coastguard Worker expect("a && \"\"", "");
81*acea8879SAndroid Build Coastguard Worker expect("\"\" && b", "");
82*acea8879SAndroid Build Coastguard Worker expect("\"\" && \"\"", "");
83*acea8879SAndroid Build Coastguard Worker expect("\"\" && abort()", ""); // test short-circuiting
84*acea8879SAndroid Build Coastguard Worker expect("t && abort()", nullptr);
85*acea8879SAndroid Build Coastguard Worker
86*acea8879SAndroid Build Coastguard Worker // logical or
87*acea8879SAndroid Build Coastguard Worker expect("a || b", "a");
88*acea8879SAndroid Build Coastguard Worker expect("a || \"\"", "a");
89*acea8879SAndroid Build Coastguard Worker expect("\"\" || b", "b");
90*acea8879SAndroid Build Coastguard Worker expect("\"\" || \"\"", "");
91*acea8879SAndroid Build Coastguard Worker expect("a || abort()", "a"); // test short-circuiting
92*acea8879SAndroid Build Coastguard Worker expect("\"\" || abort()", NULL);
93*acea8879SAndroid Build Coastguard Worker
94*acea8879SAndroid Build Coastguard Worker // logical not
95*acea8879SAndroid Build Coastguard Worker expect("!a", "");
96*acea8879SAndroid Build Coastguard Worker expect("! \"\"", "t");
97*acea8879SAndroid Build Coastguard Worker expect("!!a", "t");
98*acea8879SAndroid Build Coastguard Worker }
99*acea8879SAndroid Build Coastguard Worker
TEST_F(EdifyTest,precedence)100*acea8879SAndroid Build Coastguard Worker TEST_F(EdifyTest, precedence) {
101*acea8879SAndroid Build Coastguard Worker // precedence
102*acea8879SAndroid Build Coastguard Worker expect("\"\" == \"\" && b", "b");
103*acea8879SAndroid Build Coastguard Worker expect("a + b == ab", "t");
104*acea8879SAndroid Build Coastguard Worker expect("ab == a + b", "t");
105*acea8879SAndroid Build Coastguard Worker expect("a + (b == ab)", "a");
106*acea8879SAndroid Build Coastguard Worker expect("(ab == a) + b", "b");
107*acea8879SAndroid Build Coastguard Worker }
108*acea8879SAndroid Build Coastguard Worker
TEST_F(EdifyTest,substring)109*acea8879SAndroid Build Coastguard Worker TEST_F(EdifyTest, substring) {
110*acea8879SAndroid Build Coastguard Worker // substring function
111*acea8879SAndroid Build Coastguard Worker expect("is_substring(cad, abracadabra)", "t");
112*acea8879SAndroid Build Coastguard Worker expect("is_substring(abrac, abracadabra)", "t");
113*acea8879SAndroid Build Coastguard Worker expect("is_substring(dabra, abracadabra)", "t");
114*acea8879SAndroid Build Coastguard Worker expect("is_substring(cad, abracxadabra)", "");
115*acea8879SAndroid Build Coastguard Worker expect("is_substring(abrac, axbracadabra)", "");
116*acea8879SAndroid Build Coastguard Worker expect("is_substring(dabra, abracadabrxa)", "");
117*acea8879SAndroid Build Coastguard Worker }
118*acea8879SAndroid Build Coastguard Worker
TEST_F(EdifyTest,ifelse)119*acea8879SAndroid Build Coastguard Worker TEST_F(EdifyTest, ifelse) {
120*acea8879SAndroid Build Coastguard Worker // ifelse function
121*acea8879SAndroid Build Coastguard Worker expect("ifelse(t, yes, no)", "yes");
122*acea8879SAndroid Build Coastguard Worker expect("ifelse(!t, yes, no)", "no");
123*acea8879SAndroid Build Coastguard Worker expect("ifelse(t, yes, abort())", "yes");
124*acea8879SAndroid Build Coastguard Worker expect("ifelse(!t, abort(), no)", "no");
125*acea8879SAndroid Build Coastguard Worker }
126*acea8879SAndroid Build Coastguard Worker
TEST_F(EdifyTest,if_statement)127*acea8879SAndroid Build Coastguard Worker TEST_F(EdifyTest, if_statement) {
128*acea8879SAndroid Build Coastguard Worker // if "statements"
129*acea8879SAndroid Build Coastguard Worker expect("if t then yes else no endif", "yes");
130*acea8879SAndroid Build Coastguard Worker expect("if \"\" then yes else no endif", "no");
131*acea8879SAndroid Build Coastguard Worker expect("if \"\" then yes endif", "");
132*acea8879SAndroid Build Coastguard Worker expect("if \"\"; t then yes endif", "yes");
133*acea8879SAndroid Build Coastguard Worker }
134*acea8879SAndroid Build Coastguard Worker
TEST_F(EdifyTest,comparison)135*acea8879SAndroid Build Coastguard Worker TEST_F(EdifyTest, comparison) {
136*acea8879SAndroid Build Coastguard Worker // numeric comparisons
137*acea8879SAndroid Build Coastguard Worker expect("less_than_int(3, 14)", "t");
138*acea8879SAndroid Build Coastguard Worker expect("less_than_int(14, 3)", "");
139*acea8879SAndroid Build Coastguard Worker expect("less_than_int(x, 3)", "");
140*acea8879SAndroid Build Coastguard Worker expect("less_than_int(3, x)", "");
141*acea8879SAndroid Build Coastguard Worker expect("greater_than_int(3, 14)", "");
142*acea8879SAndroid Build Coastguard Worker expect("greater_than_int(14, 3)", "t");
143*acea8879SAndroid Build Coastguard Worker expect("greater_than_int(x, 3)", "");
144*acea8879SAndroid Build Coastguard Worker expect("greater_than_int(3, x)", "");
145*acea8879SAndroid Build Coastguard Worker }
146*acea8879SAndroid Build Coastguard Worker
TEST_F(EdifyTest,big_string)147*acea8879SAndroid Build Coastguard Worker TEST_F(EdifyTest, big_string) {
148*acea8879SAndroid Build Coastguard Worker expect(std::string(8192, 's'), std::string(8192, 's').c_str());
149*acea8879SAndroid Build Coastguard Worker }
150*acea8879SAndroid Build Coastguard Worker
TEST_F(EdifyTest,unknown_function)151*acea8879SAndroid Build Coastguard Worker TEST_F(EdifyTest, unknown_function) {
152*acea8879SAndroid Build Coastguard Worker const char* script1 = "unknown_function()";
153*acea8879SAndroid Build Coastguard Worker std::unique_ptr<Expr> expr;
154*acea8879SAndroid Build Coastguard Worker int error_count = 0;
155*acea8879SAndroid Build Coastguard Worker EXPECT_EQ(1, ParseString(script1, &expr, &error_count));
156*acea8879SAndroid Build Coastguard Worker EXPECT_EQ(1, error_count);
157*acea8879SAndroid Build Coastguard Worker
158*acea8879SAndroid Build Coastguard Worker const char* script2 = "abc; unknown_function()";
159*acea8879SAndroid Build Coastguard Worker error_count = 0;
160*acea8879SAndroid Build Coastguard Worker EXPECT_EQ(1, ParseString(script2, &expr, &error_count));
161*acea8879SAndroid Build Coastguard Worker EXPECT_EQ(1, error_count);
162*acea8879SAndroid Build Coastguard Worker
163*acea8879SAndroid Build Coastguard Worker const char* script3 = "unknown_function1() || yes";
164*acea8879SAndroid Build Coastguard Worker error_count = 0;
165*acea8879SAndroid Build Coastguard Worker EXPECT_EQ(1, ParseString(script3, &expr, &error_count));
166*acea8879SAndroid Build Coastguard Worker EXPECT_EQ(1, error_count);
167*acea8879SAndroid Build Coastguard Worker }
168