//
// 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));
}
