blob: 013d7ca8eb6a4ddeae9dc9929dc0303a318044d3 [file] [log] [blame]
//
// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// FloatLex_test.cpp:
// Tests for parsing floats in GLSL source.
//
#include <sstream>
#include <string>
#include "common/debug.h"
#include "common/mathutil.h"
#include "compiler/translator/util.h"
#include "gtest/gtest.h"
namespace
{
class StrtofClampParser
{
public:
static float Parse(std::string str)
{
float value;
sh::strtof_clamp(str, &value);
return value;
}
};
// NumericLexFloat32OutOfRangeToInfinity usually only comes to play in corner cases of parsing, but
// it's useful to test that it works as expected across the whole range of floats.
class NumericLexFloatParser
{
public:
static float Parse(std::string str) { return sh::NumericLexFloat32OutOfRangeToInfinity(str); }
};
} // anonymous namespace
template <typename T>
class FloatLexTest : public ::testing::Test
{
public:
FloatLexTest() {}
protected:
void SetUp() override {}
void TearDown() override {}
static bool ParsedMatches(std::string str, float expected)
{
return (T::Parse(str) == expected);
}
static bool IsInfinity(std::string str)
{
float f = T::Parse(str);
return gl::isInf(f);
}
static std::string Zeros(size_t count) { return std::string(count, '0'); }
};
typedef ::testing::Types<StrtofClampParser, NumericLexFloatParser> FloatParserTypes;
TYPED_TEST_CASE(FloatLexTest, FloatParserTypes);
TYPED_TEST(FloatLexTest, One)
{
ASSERT_TRUE(TestFixture::ParsedMatches("1.0", 1.0f));
}
TYPED_TEST(FloatLexTest, Ten)
{
ASSERT_TRUE(TestFixture::ParsedMatches("10.0", 10.0f));
}
TYPED_TEST(FloatLexTest, TenScientific)
{
ASSERT_TRUE(TestFixture::ParsedMatches("1.0e1", 10.0f));
}
TYPED_TEST(FloatLexTest, ScientificWithSmallMantissa)
{
std::stringstream ss;
ss << "0." << TestFixture::Zeros(100) << "125e102";
ASSERT_TRUE(TestFixture::ParsedMatches(ss.str(), 12.5f));
}
TYPED_TEST(FloatLexTest, ScientificWithLargeMantissa)
{
std::stringstream ss;
ss << "9" << TestFixture::Zeros(100) << ".0e-100";
ASSERT_TRUE(TestFixture::ParsedMatches(ss.str(), 9.0f));
}
TYPED_TEST(FloatLexTest, ScientificWithVerySmallMantissa)
{
std::stringstream ss;
ss << "0." << TestFixture::Zeros(5000) << "125e5002";
ASSERT_TRUE(TestFixture::ParsedMatches(ss.str(), 12.5f));
}
TYPED_TEST(FloatLexTest, ScientificWithVeryLargeMantissa)
{
std::stringstream ss;
ss << "9" << TestFixture::Zeros(5000) << ".0e-5000";
ASSERT_TRUE(TestFixture::ParsedMatches(ss.str(), 9.0f));
}
TYPED_TEST(FloatLexTest, StartWithDecimalDot)
{
ASSERT_TRUE(TestFixture::ParsedMatches(".125", 0.125f));
}
TYPED_TEST(FloatLexTest, EndWithDecimalDot)
{
ASSERT_TRUE(TestFixture::ParsedMatches("123.", 123.0f));
}
TYPED_TEST(FloatLexTest, NoDecimalDot)
{
ASSERT_TRUE(TestFixture::ParsedMatches("125e-2", 1.25f));
}
TYPED_TEST(FloatLexTest, EndStartWithDecimalDotScientific)
{
ASSERT_TRUE(TestFixture::ParsedMatches(".625e-1", 0.0625f));
}
TYPED_TEST(FloatLexTest, EndWithDecimalDotScientific)
{
ASSERT_TRUE(TestFixture::ParsedMatches("102400.e-2", 1024.0f));
}
TYPED_TEST(FloatLexTest, UppercaseE)
{
ASSERT_TRUE(TestFixture::ParsedMatches("125E-2", 1.25f));
}
TYPED_TEST(FloatLexTest, PlusInExponent)
{
ASSERT_TRUE(TestFixture::ParsedMatches("1E+2", 100.0f));
}
TYPED_TEST(FloatLexTest, SlightlyAboveMaxFloat)
{
ASSERT_TRUE(TestFixture::IsInfinity("3.4029e38"));
}
TYPED_TEST(FloatLexTest, SlightlyBelowMaxFloat)
{
ASSERT_FALSE(TestFixture::IsInfinity("3.4028e38"));
}
TYPED_TEST(FloatLexTest, SlightlyBelowMinSubnormalFloat)
{
ASSERT_TRUE(TestFixture::ParsedMatches("1.0e-48", 0.0f));
}
TYPED_TEST(FloatLexTest, SlightlyAboveMinNormalFloat)
{
ASSERT_FALSE(TestFixture::ParsedMatches("1.0e-37", 0.0f));
}
TYPED_TEST(FloatLexTest, ManySignificantDigits)
{
ASSERT_TRUE(TestFixture::ParsedMatches("1.23456789", 1.23456789f));
}
TYPED_TEST(FloatLexTest, MantissaBitAboveMaxUint)
{
ASSERT_TRUE(TestFixture::ParsedMatches("4294967299.", 4294967299.0f));
}
TYPED_TEST(FloatLexTest, ExponentBitAboveMaxInt)
{
ASSERT_TRUE(TestFixture::IsInfinity("1.0e2147483649"));
}
TYPED_TEST(FloatLexTest, ExponentBitBelowMaxIntAndLargeMantissa)
{
std::stringstream ss;
ss << "1" << TestFixture::Zeros(32) << ".0e2147483640";
ASSERT_TRUE(TestFixture::IsInfinity(ss.str()));
}
TYPED_TEST(FloatLexTest, ExponentBitAboveMinIntAndSmallMantissa)
{
std::stringstream ss;
ss << "0." << TestFixture::Zeros(32) << "1e-2147483640";
ASSERT_TRUE(TestFixture::ParsedMatches(ss.str(), 0.0f));
}