• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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