GCC Code Coverage Report


Directory: ./
File: openvdb_ax/openvdb_ax/test/frontend/TestValueNode.cc
Date: 2022-07-25 17:40:05
Exec Total Coverage
Lines: 28 34 82.4%
Functions: 8 8 100.0%
Branches: 80 182 44.0%

Line Branch Exec Source
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3
4 #include <openvdb_ax/ast/AST.h>
5 #include <openvdb_ax/ast/Scanners.h>
6 #include <openvdb_ax/ast/PrintTree.h>
7 #include <openvdb_ax/Exceptions.h>
8
9 #include "../util.h"
10
11 #include <cppunit/extensions/HelperMacros.h>
12
13 #include <string>
14 #include <cstdlib>
15
16 using namespace openvdb::ax::ast;
17 using namespace openvdb::ax::ast::tokens;
18
19 namespace {
20
21 using CodeTestMap = std::map<Node::NodeType, unittest_util::CodeTests>;
22
23 8 auto converti(const char* c) -> uint64_t { return std::strtoull(c, /*end*/nullptr, /*base*/10); }
24 13 auto convertf(const char* c) -> float { return std::strtof(c, /*end*/nullptr); }
25 13 auto convertd(const char* c) -> double { return std::strtod(c, /*end*/nullptr); }
26
27 template <typename T>
28 2 std::string fullDecimalValue(const T t) {
29 // 767 is max number of digits necessary to accurately represent base 2 doubles
30 4 std::ostringstream os;
31 os << std::setprecision(767) << t;
32 2 return os.str();
33 }
34
35
36 static const CodeTestMap value_tests =
37 {
38 // No limits::lowest, negative values are a unary operator
39
40 {
41 Node::NodeType::ValueBoolNode,
42 {
43 { "false;", Node::Ptr(new Value<bool>(false)) },
44 { "true;", Node::Ptr(new Value<bool>(true)) },
45 }
46 },
47
48 {
49 Node::NodeType::ValueInt32Node,
50 {
51 { "00;", Node::Ptr(new Value<int32_t>(converti("0"))) },
52 { "1000000000000000;", Node::Ptr(new Value<int32_t>(converti("1000000000000000"))) }, // signed int wrap
53 { "0;", Node::Ptr(new Value<int32_t>(converti("0"))) },
54 { "1234567890;", Node::Ptr(new Value<int32_t>(converti("1234567890"))) },
55 { "1;", Node::Ptr(new Value<int32_t>(converti("1"))) },
56 // signed int wrap
57 { std::to_string(std::numeric_limits<int64_t>::max()) + ";",
58 Node::Ptr(new Value<int32_t>(std::numeric_limits<int64_t>::max()))
59 },
60 // signed int wrap
61 { std::to_string(std::numeric_limits<uint64_t>::max()) + ";",
62 Node::Ptr(new Value<int32_t>(std::numeric_limits<uint64_t>::max()))
63 },
64 // signed int wrap
65 { std::to_string(std::numeric_limits<int32_t>::max()) + "0;",
66 Node::Ptr(new Value<int32_t>(uint64_t(std::numeric_limits<int32_t>::max()) * 10ul))
67 }
68 }
69 },
70
71 {
72 Node::NodeType::ValueInt64Node,
73 {
74 { "01l;", Node::Ptr(new Value<int64_t>(converti("1"))) },
75 { "0l;", Node::Ptr(new Value<int64_t>(converti("0"))) },
76 { "1234567890l;", Node::Ptr(new Value<int64_t>(converti("1234567890l"))) },
77 // signed int wrap
78 { std::to_string(uint64_t(std::numeric_limits<int64_t>::max()) + 1) + "l;",
79 Node::Ptr(new Value<int64_t>(uint64_t(std::numeric_limits<int64_t>::max()) + 1ul))
80 }
81 }
82 },
83
84 {
85 Node::NodeType::ValueFloatNode,
86 {
87 { ".123456789f;", Node::Ptr(new Value<float>(convertf(".123456789f"))) },
88 { "0.0f;", Node::Ptr(new Value<float>(convertf("0.0f"))) },
89 { "00.f;", Node::Ptr(new Value<float>(convertf("0.0f"))) },
90 { "0e+0f;", Node::Ptr(new Value<float>(convertf("0.0f"))) },
91 { "0e-0f;", Node::Ptr(new Value<float>(convertf("0.0f"))) },
92 { "0e0f;", Node::Ptr(new Value<float>(convertf("0.0f"))) },
93 { "1234567890.0987654321f;", Node::Ptr(new Value<float>(convertf("1234567890.0987654321f"))) },
94 { "1e+6f;", Node::Ptr(new Value<float>(convertf("1e+6f"))) },
95 { "1E+6f;", Node::Ptr(new Value<float>(convertf("1E+6f"))) },
96 { "1e-6f;", Node::Ptr(new Value<float>(convertf("1e-6f"))) },
97 { "1E-6f;", Node::Ptr(new Value<float>(convertf("1E-6f"))) },
98 { "1e6f;", Node::Ptr(new Value<float>(convertf("1e6f"))) },
99 { "1E6f;", Node::Ptr(new Value<float>(convertf("1E6f"))) }
100 }
101 },
102
103 {
104 Node::NodeType::ValueDoubleNode,
105 {
106 { ".123456789;", Node::Ptr(new Value<double>(convertd(".123456789"))) },
107 { "0.0;", Node::Ptr(new Value<double>(convertd("0.0"))) },
108 { "0e0;", Node::Ptr(new Value<double>(convertd("0.0f"))) },
109 { "1.0;", Node::Ptr(new Value<double>(convertd("1.0"))) },
110 { "1234567890.00000000;", Node::Ptr(new Value<double>(convertd("1234567890.0"))) },
111 { "1234567890.0987654321;", Node::Ptr(new Value<double>(convertd("1234567890.0987654321"))) },
112 { "1234567890.10000000;", Node::Ptr(new Value<double>(convertd("1234567890.1"))) },
113 { "1234567890e-0;", Node::Ptr(new Value<double>(convertd("1234567890e-0"))) },
114 { "1e+6;", Node::Ptr(new Value<double>(convertd("1e+6"))) },
115 { "1e-6;", Node::Ptr(new Value<double>(convertd("1e-6"))) },
116 { "1e01;", Node::Ptr(new Value<double>(convertd("1e01"))) },
117 { "1e6;", Node::Ptr(new Value<double>(convertd("1e6"))) },
118 { "1E6;", Node::Ptr(new Value<double>(convertd("1E6"))) },
119 { std::to_string(std::numeric_limits<double>::max()) + ";",
120 Node::Ptr(new Value<double>(std::numeric_limits<double>::max()))
121 },
122 { fullDecimalValue(std::numeric_limits<double>::max()) + ".0;",
123 Node::Ptr(new Value<double>(std::numeric_limits<double>::max()))
124 },
125 { fullDecimalValue(std::numeric_limits<double>::min()) + ";",
126 Node::Ptr(new Value<double>(std::numeric_limits<double>::min()))
127 }
128 }
129 },
130
131 {
132 Node::NodeType::ValueStrNode,
133 {
134 { "\"0.0\";", Node::Ptr(new Value<std::string>("0.0")) },
135 { "\"0.0f\";", Node::Ptr(new Value<std::string>("0.0f")) },
136 { "\"0\";", Node::Ptr(new Value<std::string>("0")) },
137 { "\"1234567890.0987654321\";", Node::Ptr(new Value<std::string>("1234567890.0987654321")) },
138 { "\"1234567890\";", Node::Ptr(new Value<std::string>("1234567890")) },
139 { "\"a1b2c3d4.e5f6g7.0\";", Node::Ptr(new Value<std::string>("a1b2c3d4.e5f6g7.0")) },
140 { "\"literal\";", Node::Ptr(new Value<std::string>("literal")) },
141 { "\"\";", Node::Ptr(new Value<std::string>("")) },
142 { "\"" + std::to_string(std::numeric_limits<double>::lowest()) + "\";",
143 Node::Ptr(new Value<std::string>(std::to_string(std::numeric_limits<double>::lowest())))
144 },
145 { "\"" + std::to_string(std::numeric_limits<double>::max()) + "\";",
146 Node::Ptr(new Value<std::string>(std::to_string(std::numeric_limits<double>::max())))
147 },
148 { "\"" + std::to_string(std::numeric_limits<int64_t>::lowest()) + "\";",
149 Node::Ptr(new Value<std::string>(std::to_string(std::numeric_limits<int64_t>::lowest())))
150 },
151 { "\"" + std::to_string(std::numeric_limits<int64_t>::max()) + "\";",
152 Node::Ptr(new Value<std::string>(std::to_string(std::numeric_limits<int64_t>::max())))
153 }
154 }
155 }
156 };
157
158 }
159
160
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
2 class TestValueNode : public CppUnit::TestCase
161 {
162 public:
163
164
3/6
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
4 CPPUNIT_TEST_SUITE(TestValueNode);
165
5/10
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
6 CPPUNIT_TEST(testSyntax);
166
5/10
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
6 CPPUNIT_TEST(testASTNode);
167
4/8
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
4 CPPUNIT_TEST_SUITE_END();
168
169 1 void testSyntax() {
170
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 1 times.
7 for (const auto& tests : value_tests) {
171
20/40
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 55 times.
✓ Branch 8 taken 6 times.
✓ Branch 10 taken 55 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 55 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 55 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 55 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 55 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 55 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 55 times.
✗ Branch 29 not taken.
✓ Branch 31 taken 55 times.
✗ Branch 32 not taken.
✓ Branch 34 taken 55 times.
✗ Branch 35 not taken.
✓ Branch 37 taken 55 times.
✗ Branch 38 not taken.
✓ Branch 40 taken 55 times.
✗ Branch 41 not taken.
✓ Branch 43 taken 55 times.
✗ Branch 44 not taken.
✓ Branch 46 taken 55 times.
✗ Branch 47 not taken.
✓ Branch 48 taken 55 times.
✗ Branch 49 not taken.
✗ Branch 50 not taken.
✓ Branch 51 taken 55 times.
✓ Branch 53 taken 55 times.
✗ Branch 54 not taken.
✗ Branch 69 not taken.
✗ Branch 70 not taken.
183 TEST_SYNTAX_PASSES(tests.second);
172 }
173 1 }
174 void testASTNode();
175 };
176
177 CPPUNIT_TEST_SUITE_REGISTRATION(TestValueNode);
178
179 1 void TestValueNode::testASTNode()
180 {
181
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 1 times.
7 for (const auto& tests : value_tests) {
182 6 const Node::NodeType nodeType = tests.first;
183
2/2
✓ Branch 0 taken 55 times.
✓ Branch 1 taken 6 times.
61 for (const auto& test : tests.second) {
184
1/2
✓ Branch 1 taken 55 times.
✗ Branch 2 not taken.
55 const std::string& code = test.first;
185 const Node* expected = test.second.get();
186
1/2
✓ Branch 1 taken 55 times.
✗ Branch 2 not taken.
55 const Tree::ConstPtr tree = parse(code.c_str());
187
11/22
✓ Branch 1 taken 55 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 55 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 55 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 55 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 55 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 55 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 55 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 55 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 55 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 55 times.
✗ Branch 29 not taken.
✓ Branch 41 taken 55 times.
✗ Branch 42 not taken.
165 CPPUNIT_ASSERT_MESSAGE(ERROR_MSG("No AST returned", code), static_cast<bool>(tree));
188
189 // get the first statement
190 const Node* result = tree->child(0)->child(0);
191
6/12
✓ Branch 1 taken 55 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 55 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 55 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 55 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 55 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 55 times.
✗ Branch 17 not taken.
55 CPPUNIT_ASSERT(result);
192
12/24
✓ Branch 1 taken 55 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 55 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 55 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 55 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 55 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 55 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 55 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 55 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 55 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 55 times.
✗ Branch 29 not taken.
✓ Branch 31 taken 55 times.
✗ Branch 32 not taken.
✓ Branch 45 taken 55 times.
✗ Branch 46 not taken.
165 CPPUNIT_ASSERT_MESSAGE(ERROR_MSG("Invalid AST node", code),
193 nodeType == result->nodetype());
194
195 std::vector<const Node*> resultList, expectedList;
196
1/2
✓ Branch 1 taken 55 times.
✗ Branch 2 not taken.
55 linearize(*result, resultList);
197
1/2
✓ Branch 1 taken 55 times.
✗ Branch 2 not taken.
55 linearize(*expected, expectedList);
198
199
2/4
✓ Branch 1 taken 55 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 55 times.
55 if (!unittest_util::compareLinearTrees(expectedList, resultList)) {
200 std::ostringstream os;
201 os << "\nExpected:\n";
202 openvdb::ax::ast::print(*expected, true, os);
203 os << "Result:\n";
204 openvdb::ax::ast::print(*result, true, os);
205 CPPUNIT_FAIL(ERROR_MSG("Mismatching Trees for Value (literal) code", code) + os.str());
206 }
207 }
208 }
209 1 }
210
211