Skip to content

Commit e98839f

Browse files
authored
Merge pull request #1738 from tier4/fix/double-INF
2 parents 6531997 + 61af83e commit e98839f

3 files changed

Lines changed: 130 additions & 2 deletions

File tree

openscenario/openscenario_interpreter/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,10 @@ if(BUILD_TESTING)
104104
ament_lint_auto_find_test_dependencies()
105105
ament_add_gtest(test_syntax test/test_syntax.cpp)
106106
ament_add_gtest(test_parsed_traffic_signal_id test/test_parsed_traffic_signal_id.cpp)
107+
ament_add_gtest(test_double test/test_double.cpp)
107108
target_link_libraries(test_syntax ${PROJECT_NAME})
108109
target_link_libraries(test_parsed_traffic_signal_id ${PROJECT_NAME})
110+
target_link_libraries(test_double ${PROJECT_NAME})
109111
endif()
110112

111113
ament_auto_package()

openscenario/openscenario_interpreter/src/syntax/double.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,12 +82,13 @@ auto operator>>(std::istream & is, Double & datum) -> std::istream &
8282

8383
is >> token;
8484

85-
static const std::regex infinity{R"([+-]?INF)"};
85+
static const std::regex infinity{R"(([+-])?INF)"};
8686

8787
std::smatch result;
8888

8989
if (std::regex_match(token, result, infinity)) {
90-
datum.data = (result.str(1) == "-" ? -1 : 1) * std::numeric_limits<Double::value_type>::max();
90+
datum.data =
91+
(result.str(1) == "-" ? -1 : 1) * std::numeric_limits<Double::value_type>::infinity();
9192
} else {
9293
datum.data = boost::lexical_cast<Double::value_type>(token);
9394
}
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
// Copyright 2015 TIER IV, Inc. All rights reserved.
2+
//
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+
#include <gtest/gtest.h>
16+
17+
#include <cmath>
18+
#include <limits>
19+
#include <sstream>
20+
21+
#include "openscenario_interpreter/syntax/double.hpp"
22+
23+
namespace
24+
{
25+
openscenario_interpreter::Double parseDouble(const std::string & string)
26+
{
27+
std::stringstream stream(string);
28+
openscenario_interpreter::Double value;
29+
stream >> value;
30+
return value;
31+
}
32+
} // namespace
33+
34+
class DoubleInfTest : public ::testing::TestWithParam<std::pair<std::string, double>>
35+
{
36+
};
37+
38+
TEST_P(DoubleInfTest, ParseInfinity)
39+
{
40+
auto [input, expected] = GetParam();
41+
auto value = parseDouble(input);
42+
EXPECT_TRUE(std::isinf(value.data));
43+
EXPECT_DOUBLE_EQ(value.data, expected);
44+
}
45+
46+
INSTANTIATE_TEST_SUITE_P(
47+
InfValues, DoubleInfTest,
48+
::testing::Values(
49+
std::make_pair("INF", std::numeric_limits<double>::infinity()),
50+
std::make_pair("+INF", std::numeric_limits<double>::infinity()),
51+
std::make_pair("-INF", -std::numeric_limits<double>::infinity())));
52+
53+
class DoubleNumericParseTest : public ::testing::TestWithParam<std::pair<std::string, double>>
54+
{
55+
};
56+
57+
TEST_P(DoubleNumericParseTest, ParseNumber)
58+
{
59+
auto [input, expected] = GetParam();
60+
auto value = parseDouble(input);
61+
EXPECT_DOUBLE_EQ(value.data, expected);
62+
}
63+
64+
INSTANTIATE_TEST_SUITE_P(
65+
NumericValues, DoubleNumericParseTest,
66+
::testing::Values(
67+
// clang-format off
68+
std::make_pair("123.45", 123.45),
69+
std::make_pair("-67.89", -67.89),
70+
std::make_pair("0", 0.0),
71+
std::make_pair("-0", -0.0),
72+
std::make_pair("1.23e10", 1.23e10),
73+
std::make_pair("-4.56e-5", -4.56e-5),
74+
std::make_pair("1.7976931348623157e+308", 1.7976931348623157e+308),
75+
std::make_pair("2.2250738585072014e-308", 2.2250738585072014e-308)));
76+
// clang-format on
77+
78+
TEST(DoubleStaticMethods, StaticMethods)
79+
{
80+
EXPECT_TRUE(std::isinf(openscenario_interpreter::Double::infinity().data));
81+
EXPECT_TRUE(std::isnan(openscenario_interpreter::Double::nan().data));
82+
EXPECT_DOUBLE_EQ(
83+
openscenario_interpreter::Double::max().data, std::numeric_limits<double>::max());
84+
EXPECT_DOUBLE_EQ(
85+
openscenario_interpreter::Double::lowest().data, std::numeric_limits<double>::lowest());
86+
}
87+
88+
TEST(DoubleOperators, AssignmentAndArithmetic)
89+
{
90+
openscenario_interpreter::Double value;
91+
value = 10.0;
92+
EXPECT_DOUBLE_EQ(value.data, 10.0);
93+
value += 5.5;
94+
EXPECT_DOUBLE_EQ(value.data, 15.5);
95+
value *= 2.0;
96+
EXPECT_DOUBLE_EQ(value.data, 31.0);
97+
}
98+
99+
TEST(DoubleOperators, OStream)
100+
{
101+
std::stringstream value;
102+
value << openscenario_interpreter::Double(123.456);
103+
EXPECT_TRUE(value.str().find("123.456") == 0);
104+
105+
std::stringstream inf;
106+
inf << openscenario_interpreter::Double::infinity();
107+
EXPECT_EQ(inf.str(), "inf");
108+
109+
std::stringstream negative_inf;
110+
negative_inf << parseDouble("-INF");
111+
EXPECT_EQ(negative_inf.str(), "-inf");
112+
}
113+
114+
TEST(DoubleSpecialCases, InvalidString)
115+
{
116+
std::stringstream not_a_number("not_a_number");
117+
openscenario_interpreter::Double value;
118+
EXPECT_THROW(not_a_number >> value, std::exception);
119+
}
120+
121+
int main(int argc, char ** argv)
122+
{
123+
testing::InitGoogleTest(&argc, argv);
124+
return RUN_ALL_TESTS();
125+
}

0 commit comments

Comments
 (0)