1 //
2 // Copyright 2016 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // FloatLex_test.cpp:
7 // Tests for parsing floats in GLSL source.
8 //
9
10 #include <sstream>
11 #include <string>
12
13 #include "common/debug.h"
14 #include "common/mathutil.h"
15 #include "compiler/translator/util.h"
16 #include "gtest/gtest.h"
17
18 namespace
19 {
20
21 class StrtofClampParser
22 {
23 public:
Parse(std::string str)24 static float Parse(std::string str)
25 {
26 float value;
27 sh::strtof_clamp(str, &value);
28 return value;
29 }
30 };
31
32 class NumericLexFloatParser
33 {
34 public:
Parse(std::string str)35 static float Parse(std::string str) { return sh::NumericLexFloat32OutOfRangeToInfinity(str); }
36 };
37
38 } // anonymous namespace
39
40 template <typename T>
41 class FloatLexTest : public ::testing::Test
42 {
43 public:
FloatLexTest()44 FloatLexTest() {}
45
46 protected:
SetUp()47 void SetUp() override {}
48
TearDown()49 void TearDown() override {}
50
ParsedMatches(std::string str,float expected)51 static bool ParsedMatches(std::string str, float expected)
52 {
53 return (T::Parse(str) == expected);
54 }
55
IsInfinity(std::string str)56 static bool IsInfinity(std::string str)
57 {
58 float f = T::Parse(str);
59 return gl::isInf(f);
60 }
61
Zeros(size_t count)62 static std::string Zeros(size_t count) { return std::string(count, '0'); }
63 };
64
65 typedef ::testing::Types<StrtofClampParser, NumericLexFloatParser> FloatParserTypes;
66 TYPED_TEST_SUITE(FloatLexTest, FloatParserTypes);
67
TYPED_TEST(FloatLexTest,One)68 TYPED_TEST(FloatLexTest, One)
69 {
70 ASSERT_TRUE(TestFixture::ParsedMatches("1.0", 1.0f));
71 }
72
TYPED_TEST(FloatLexTest,Ten)73 TYPED_TEST(FloatLexTest, Ten)
74 {
75 ASSERT_TRUE(TestFixture::ParsedMatches("10.0", 10.0f));
76 }
77
TYPED_TEST(FloatLexTest,TenScientific)78 TYPED_TEST(FloatLexTest, TenScientific)
79 {
80 ASSERT_TRUE(TestFixture::ParsedMatches("1.0e1", 10.0f));
81 }
82
TYPED_TEST(FloatLexTest,ScientificWithSmallMantissa)83 TYPED_TEST(FloatLexTest, ScientificWithSmallMantissa)
84 {
85 std::stringstream ss;
86 ss << "0." << TestFixture::Zeros(100) << "125e102";
87 ASSERT_TRUE(TestFixture::ParsedMatches(ss.str(), 12.5f));
88 }
89
TYPED_TEST(FloatLexTest,ScientificWithLargeMantissa)90 TYPED_TEST(FloatLexTest, ScientificWithLargeMantissa)
91 {
92 std::stringstream ss;
93 ss << "9" << TestFixture::Zeros(100) << ".0e-100";
94 ASSERT_TRUE(TestFixture::ParsedMatches(ss.str(), 9.0f));
95 }
96
TYPED_TEST(FloatLexTest,ScientificWithVerySmallMantissa)97 TYPED_TEST(FloatLexTest, ScientificWithVerySmallMantissa)
98 {
99 std::stringstream ss;
100 ss << "0." << TestFixture::Zeros(5000) << "125e5002";
101 ASSERT_TRUE(TestFixture::ParsedMatches(ss.str(), 12.5f));
102 }
103
TYPED_TEST(FloatLexTest,ScientificWithVeryLargeMantissa)104 TYPED_TEST(FloatLexTest, ScientificWithVeryLargeMantissa)
105 {
106 std::stringstream ss;
107 ss << "9" << TestFixture::Zeros(5000) << ".0e-5000";
108 ASSERT_TRUE(TestFixture::ParsedMatches(ss.str(), 9.0f));
109 }
110
TYPED_TEST(FloatLexTest,StartWithDecimalDot)111 TYPED_TEST(FloatLexTest, StartWithDecimalDot)
112 {
113 ASSERT_TRUE(TestFixture::ParsedMatches(".125", 0.125f));
114 }
115
TYPED_TEST(FloatLexTest,EndWithDecimalDot)116 TYPED_TEST(FloatLexTest, EndWithDecimalDot)
117 {
118 ASSERT_TRUE(TestFixture::ParsedMatches("123.", 123.0f));
119 }
120
TYPED_TEST(FloatLexTest,NoDecimalDot)121 TYPED_TEST(FloatLexTest, NoDecimalDot)
122 {
123 ASSERT_TRUE(TestFixture::ParsedMatches("125e-2", 1.25f));
124 }
125
TYPED_TEST(FloatLexTest,EndStartWithDecimalDotScientific)126 TYPED_TEST(FloatLexTest, EndStartWithDecimalDotScientific)
127 {
128 ASSERT_TRUE(TestFixture::ParsedMatches(".625e-1", 0.0625f));
129 }
130
TYPED_TEST(FloatLexTest,EndWithDecimalDotScientific)131 TYPED_TEST(FloatLexTest, EndWithDecimalDotScientific)
132 {
133 ASSERT_TRUE(TestFixture::ParsedMatches("102400.e-2", 1024.0f));
134 }
135
TYPED_TEST(FloatLexTest,UppercaseE)136 TYPED_TEST(FloatLexTest, UppercaseE)
137 {
138 ASSERT_TRUE(TestFixture::ParsedMatches("125E-2", 1.25f));
139 }
140
TYPED_TEST(FloatLexTest,PlusInExponent)141 TYPED_TEST(FloatLexTest, PlusInExponent)
142 {
143 ASSERT_TRUE(TestFixture::ParsedMatches("1E+2", 100.0f));
144 }
145
TYPED_TEST(FloatLexTest,SlightlyAboveMaxFloat)146 TYPED_TEST(FloatLexTest, SlightlyAboveMaxFloat)
147 {
148 ASSERT_TRUE(TestFixture::IsInfinity("3.4029e38"));
149 }
150
TYPED_TEST(FloatLexTest,SlightlyBelowMaxFloat)151 TYPED_TEST(FloatLexTest, SlightlyBelowMaxFloat)
152 {
153 ASSERT_FALSE(TestFixture::IsInfinity("3.4028e38"));
154 ASSERT_TRUE(TestFixture::ParsedMatches("3.4028e38", 3.4028e38f));
155 }
156
TYPED_TEST(FloatLexTest,SlightlyAboveMaxFloatLargerMantissa)157 TYPED_TEST(FloatLexTest, SlightlyAboveMaxFloatLargerMantissa)
158 {
159 ASSERT_TRUE(TestFixture::IsInfinity("34.029e37"));
160 }
161
TYPED_TEST(FloatLexTest,SlightlyBelowMaxFloatLargerMantissa)162 TYPED_TEST(FloatLexTest, SlightlyBelowMaxFloatLargerMantissa)
163 {
164 ASSERT_FALSE(TestFixture::IsInfinity("34.028e37"));
165 ASSERT_TRUE(TestFixture::ParsedMatches("34.028e37", 3.4028e38f));
166 }
167
TYPED_TEST(FloatLexTest,SlightlyAboveMaxFloatSmallerMantissa)168 TYPED_TEST(FloatLexTest, SlightlyAboveMaxFloatSmallerMantissa)
169 {
170 ASSERT_TRUE(TestFixture::IsInfinity("0.34029e39"));
171 }
172
TYPED_TEST(FloatLexTest,SlightlyBelowMaxFloatSmallerMantissa)173 TYPED_TEST(FloatLexTest, SlightlyBelowMaxFloatSmallerMantissa)
174 {
175 ASSERT_FALSE(TestFixture::IsInfinity("0.34028e39"));
176 ASSERT_TRUE(TestFixture::ParsedMatches("0.34028e39", 3.4028e38f));
177 }
178
TYPED_TEST(FloatLexTest,SlightlyBelowMinSubnormalFloat)179 TYPED_TEST(FloatLexTest, SlightlyBelowMinSubnormalFloat)
180 {
181 ASSERT_TRUE(TestFixture::ParsedMatches("1.0e-48", 0.0f));
182 }
183
TYPED_TEST(FloatLexTest,SlightlyAboveMinNormalFloat)184 TYPED_TEST(FloatLexTest, SlightlyAboveMinNormalFloat)
185 {
186 ASSERT_FALSE(TestFixture::ParsedMatches("1.0e-37", 0.0f));
187 }
188
TYPED_TEST(FloatLexTest,ManySignificantDigits)189 TYPED_TEST(FloatLexTest, ManySignificantDigits)
190 {
191 ASSERT_TRUE(TestFixture::ParsedMatches("1.23456789", 1.23456789f));
192 }
193
TYPED_TEST(FloatLexTest,MantissaBitAboveMaxUint)194 TYPED_TEST(FloatLexTest, MantissaBitAboveMaxUint)
195 {
196 ASSERT_TRUE(TestFixture::ParsedMatches("4294967299.", 4294967299.0f));
197 }
198
TYPED_TEST(FloatLexTest,ExponentBitAboveMaxInt)199 TYPED_TEST(FloatLexTest, ExponentBitAboveMaxInt)
200 {
201 ASSERT_TRUE(TestFixture::IsInfinity("1.0e2147483649"));
202 }
203
TYPED_TEST(FloatLexTest,ExponentBitBelowMaxIntAndLargeMantissa)204 TYPED_TEST(FloatLexTest, ExponentBitBelowMaxIntAndLargeMantissa)
205 {
206 std::stringstream ss;
207 ss << "1" << TestFixture::Zeros(32) << ".0e2147483640";
208 ASSERT_TRUE(TestFixture::IsInfinity(ss.str()));
209 }
210
TYPED_TEST(FloatLexTest,ExponentBitAboveMinIntAndSmallMantissa)211 TYPED_TEST(FloatLexTest, ExponentBitAboveMinIntAndSmallMantissa)
212 {
213 std::stringstream ss;
214 ss << "0." << TestFixture::Zeros(32) << "1e-2147483640";
215 ASSERT_TRUE(TestFixture::ParsedMatches(ss.str(), 0.0f));
216 }
217