/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/




// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sal.hxx"
// autogenerated file with codegen.pl
// There exist some more test code in sal/qa/rtl_strings/rtl_OString.cxx
#include <rtl/string.hxx>

#include "gtest/gtest.h"
#include "valueequal.hxx"

namespace rtl_OString
{

class valueOf : public ::testing::Test
{
protected:
    void valueOf_float_test_impl(float _nValue)
        {
            rtl::OString sValue;
            sValue = rtl::OString::valueOf( _nValue );
            printf("nFloat := %.9f  sValue := %s\n", _nValue, sValue.getStr());

            float nValueATOF = static_cast<float>(atof( sValue.getStr() ));

            bool bEqualResult = is_float_equal(_nValue, nValueATOF);
            ASSERT_TRUE(bEqualResult == true) << "Values are not equal.";
        }

    void valueOf_float_test(float _nValue)
        {
            valueOf_float_test_impl(_nValue);

            // test also the negative part.
            float nNegativeValue = -_nValue;
            valueOf_float_test_impl(nNegativeValue);
        }

public:
    // initialise your test code values here.
    void SetUp()
    {
    }

    void TearDown()
    {
    }

protected:

    void valueOf_double_test_impl(double _nValue)
        {
            rtl::OString sValue;
            sValue = rtl::OString::valueOf( _nValue );
            printf("nDouble := %.20f  sValue := %s\n", _nValue, sValue.getStr());

            double nValueATOF = atof( sValue.getStr() );

            bool bEqualResult = is_double_equal(_nValue, nValueATOF);
            ASSERT_TRUE(bEqualResult == true) << "Values are not equal.";
        }

    void valueOf_double_test(double _nValue)
        {
            valueOf_double_test_impl(_nValue);

            // test also the negative part.
            double nNegativeValue = -_nValue;
            valueOf_double_test_impl(nNegativeValue);
        }
}; // class valueOf

TEST_F(valueOf, valueOf_float_test_001)
{
    // this is demonstration code
    // ASSERT_TRUE(1 == 1) << "a message";
    float nValue = 3.0f;
    valueOf_float_test(nValue);
}

TEST_F(valueOf, valueOf_float_test_002)
{
    float nValue = 3.5f;
    valueOf_float_test(nValue);
}

TEST_F(valueOf, valueOf_float_test_003)
{
    float nValue = 3.0625f;
    valueOf_float_test(nValue);
}

TEST_F(valueOf, valueOf_float_test_004)
{
    float nValue = 3.502525f;
    valueOf_float_test(nValue);
}

TEST_F(valueOf, valueOf_float_test_005)
{
    float nValue = 3.141592f;
    valueOf_float_test(nValue);
}

TEST_F(valueOf, valueOf_float_test_006)
{
    float nValue = 3.5025255f;
    valueOf_float_test(nValue);
}

TEST_F(valueOf, valueOf_float_test_007)
{
    float nValue = 3.0039062f;
    valueOf_float_test(nValue);
}

TEST_F(valueOf, valueOf_double_test_001)
{
    double nValue = 3.0;
    valueOf_double_test(nValue);
}
TEST_F(valueOf, valueOf_double_test_002)
{
    double nValue = 3.5;
    valueOf_double_test(nValue);
}
TEST_F(valueOf, valueOf_double_test_003)
{
    double nValue = 3.0625;
    valueOf_double_test(nValue);
}
TEST_F(valueOf, valueOf_double_test_004)
{
    double nValue = 3.1415926535;
    valueOf_double_test(nValue);
}
TEST_F(valueOf, valueOf_double_test_005)
{
    double nValue = 3.141592653589793;
    valueOf_double_test(nValue);
}
TEST_F(valueOf, valueOf_double_test_006)
{
    double nValue = 3.1415926535897932;
    valueOf_double_test(nValue);
}
TEST_F(valueOf, valueOf_double_test_007)
{
    double nValue = 3.14159265358979323;
    valueOf_double_test(nValue);
}
TEST_F(valueOf, valueOf_double_test_008)
{
    double nValue = 3.141592653589793238462643;
    valueOf_double_test(nValue);
}


// -----------------------------------------------------------------------------
// - toDouble (tests)
// -----------------------------------------------------------------------------
class toDouble : public ::testing::Test
{

public:

    toDouble()
        {
            // testPrecision a;
        }



    // initialise your test code values here.
    void SetUp()
        {
        }

    void TearDown()
	{
	}

    void toDouble_test_impl(rtl::OString const& _sValue)
        {
            double nValueATOF = atof( _sValue.getStr() );

            // rtl::OUString suValue = rtl::OUString::createFromAscii( _sValue.getStr() );
            double nValueToDouble = _sValue.toDouble();

            bool bEqualResult = is_double_equal(nValueToDouble, nValueATOF);
            ASSERT_TRUE(bEqualResult == true) << "Values are not equal.";
        }

    void toDouble_test(rtl::OString const& _sValue)
        {
            toDouble_test_impl(_sValue);

            // test also the negativ part.
            rtl::OString sNegativValue("-");
            sNegativValue += _sValue;
            toDouble_test_impl(sNegativValue);
        }
}; // class toDouble

TEST_F(toDouble, toDouble_selftest)
{
    printf("Start selftest:\n");
    ASSERT_TRUE (is_double_equal(1.0, 1.01) == false);
    ASSERT_TRUE (is_double_equal(1.0, 1.001) == false);
    ASSERT_TRUE (is_double_equal(1.0, 1.0001) == false);
    ASSERT_TRUE (is_double_equal(1.0, 1.00001) == false);
    ASSERT_TRUE (is_double_equal(1.0, 1.000001) == false);
    ASSERT_TRUE (is_double_equal(1.0, 1.0000001) == false);
    ASSERT_TRUE (is_double_equal(1.0, 1.00000001) == false);
    ASSERT_TRUE (is_double_equal(1.0, 1.000000001) == false);
    ASSERT_TRUE (is_double_equal(1.0, 1.0000000001) == false);
    ASSERT_TRUE (is_double_equal(1.0, 1.00000000001) == false);
    ASSERT_TRUE (is_double_equal(1.0, 1.000000000001) == false);
    ASSERT_TRUE (is_double_equal(1.0, 1.0000000000001) == false);
    // we check til 14 values after comma
    ASSERT_TRUE (is_double_equal(1.0, 1.00000000000001) == true);
    ASSERT_TRUE (is_double_equal(1.0, 1.000000000000001) == true);
    ASSERT_TRUE (is_double_equal(1.0, 1.0000000000000001) == true);
    printf("Selftest done.\n");
}

TEST_F(toDouble, toDouble_test_3)
{
    rtl::OString sValue("3");
    toDouble_test(sValue);
}
TEST_F(toDouble, toDouble_test_3_5)
{
    rtl::OString sValue("3.5");
    toDouble_test(sValue);
}
TEST_F(toDouble, toDouble_test_3_0625)
{
    rtl::OString sValue("3.0625");
    toDouble_test(sValue);
}
TEST_F(toDouble, toDouble_test_pi)
{
    // value from http://www.angio.net/pi/digits/50.txt
    rtl::OString sValue("3.141592653589793238462643383279502884197169399375");
    toDouble_test(sValue);
}

TEST_F(toDouble, toDouble_test_1)
{
    rtl::OString sValue("1");
    toDouble_test(sValue);
}
TEST_F(toDouble, toDouble_test_10)
{
    rtl::OString sValue("10");
    toDouble_test(sValue);
}
TEST_F(toDouble, toDouble_test_100)
{
    rtl::OString sValue("100");
    toDouble_test(sValue);
}
TEST_F(toDouble, toDouble_test_1000)
{
    rtl::OString sValue("1000");
    toDouble_test(sValue);
}
TEST_F(toDouble, toDouble_test_10000)
{
    rtl::OString sValue("10000");
    toDouble_test(sValue);
}
TEST_F(toDouble, toDouble_test_1e99)
{
    rtl::OString sValue("1e99");
    toDouble_test(sValue);
}
TEST_F(toDouble, toDouble_test_1e_n99)
{
    rtl::OString sValue("1e-99");
    toDouble_test(sValue);
}
TEST_F(toDouble, toDouble_test_1e308)
{
    rtl::OString sValue("1e308");
    toDouble_test(sValue);
}

// -----------------------------------------------------------------------------
// - getToken (tests)
// -----------------------------------------------------------------------------
class getToken : public ::testing::Test
{

public:

    // initialise your test code values here.
    void SetUp()
        {
        }

    void TearDown()
        {
        }
}; // class getToken


TEST_F(getToken, getToken_000)
{
    rtl::OString sTokenStr;

    sal_Int32 nIndex = 0;
    do
    {
        rtl::OString sToken = sTokenStr.getToken( 0, ';', nIndex );
    }
    while ( nIndex >= 0 );
    // printf("Index %d\n", nIndex);
    // should not GPF
}

TEST_F(getToken, getToken_001)
{
    rtl::OString sTokenStr = "a;b";

    sal_Int32 nIndex = 0;

    rtl::OString sToken = sTokenStr.getToken( 0, ';', nIndex );
    ASSERT_TRUE(sToken.equals("a") == sal_True) << "Token should be a 'a'";

    /* rtl::OString */ sToken = sTokenStr.getToken( 0, ';', nIndex );
    ASSERT_TRUE(sToken.equals("b") == sal_True) << "Token should be a 'b'";
    ASSERT_TRUE(nIndex == -1) << "index should be negative";
}

TEST_F(getToken, getToken_002)
{
    rtl::OString sTokenStr = "a;b.c";

    sal_Int32 nIndex = 0;

    rtl::OString sToken = sTokenStr.getToken( 0, ';', nIndex );
    ASSERT_TRUE(sToken.equals("a") == sal_True) << "Token should be a 'a'";

    /* rtl::OString */ sToken = sTokenStr.getToken( 0, '.', nIndex );
    ASSERT_TRUE(sToken.equals("b") == sal_True) << "Token should be a 'b'";

    /* rtl::OString */ sToken = sTokenStr.getToken( 0, '.', nIndex );
    ASSERT_TRUE(sToken.equals("c") == sal_True) << "Token should be a 'c'";
    ASSERT_TRUE(nIndex == -1) << "index should be negative";
}

TEST_F(getToken, getToken_003)
{
    rtl::OString sTokenStr = "a;;b";

    sal_Int32 nIndex = 0;

    rtl::OString sToken = sTokenStr.getToken( 0, ';', nIndex );
    ASSERT_TRUE(sToken.equals("a") == sal_True) << "Token should be a 'a'";

    /* rtl::OString */ sToken = sTokenStr.getToken( 0, ';', nIndex );
    ASSERT_TRUE(sToken.getLength() == 0) << "Token should be empty";

    /* rtl::OString */ sToken = sTokenStr.getToken( 0, ';', nIndex );
    ASSERT_TRUE(sToken.equals("b") == sal_True) << "Token should be a 'b'";
    ASSERT_TRUE(nIndex == -1) << "index should be negative";
}

TEST_F(getToken, getToken_004)
{
    rtl::OString sTokenStr = "longer.then.ever.";

    sal_Int32 nIndex = 0;

    rtl::OString sToken = sTokenStr.getToken( 0, '.', nIndex );
    ASSERT_TRUE(sToken.equals("longer") == sal_True) << "Token should be 'longer'";

    /* rtl::OString */ sToken = sTokenStr.getToken( 0, '.', nIndex );
    ASSERT_TRUE(sToken.equals("then") == sal_True) << "Token should be 'then'";

    /* rtl::OString */ sToken = sTokenStr.getToken( 0, '.', nIndex );
    ASSERT_TRUE(sToken.equals("ever") == sal_True) << "Token should be 'ever'";

    /* rtl::OString */ sToken = sTokenStr.getToken( 0, '.', nIndex );
    ASSERT_TRUE(sToken.getLength() == 0) << "Token should be empty";

    ASSERT_TRUE(nIndex == -1) << "index should be negative";
}

// -----------------------------------------------------------------------------
// testing the method replaceAt( sal_Int32 index, sal_Int32 count,
// const OString& newStr )
// -----------------------------------------------------------------------------

// Developer note: Mindy Liu, 2004-04-23
// stollen from sal/qa/rtl_strings/rtl_OString.cxx

class replaceAt : public ::testing::Test
{

public:
    // initialise your test code values here.
    void SetUp()
        {
        }

    void TearDown()
        {
        }
    sal_Bool check_replaceAt( const rtl::OString* expVal, const rtl::OString* input,
        const rtl::OString* newStr, sal_Int32  index, sal_Int32 count)
    {
    	 ::rtl::OString aStr1;
        aStr1= input->replaceAt( index, count, *newStr );

        printf("the result OString is %s#\n", aStr1.getStr() );

        sal_Bool bRes = ( expVal->compareTo(aStr1) == 0 );
        return bRes;
    }
}; // class replaceAt

TEST_F(replaceAt, replaceAt_001)
{
    sal_Bool bRes = check_replaceAt(new rtl::OString("Java@Sun"),
		new rtl::OString("Sun java"), new rtl::OString("Java@Sun"), 0, 8 );
    ASSERT_TRUE(bRes == sal_True) << "string differs, replace whole string";
}

TEST_F(replaceAt, replaceAt_002)
{
    sal_Bool bRes = check_replaceAt(new rtl::OString("Sun Java desktop system"),
		new rtl::OString("Sun "), new rtl::OString("Java desktop system"), 10, 8 );
    ASSERT_TRUE(bRes == sal_True) << "index > length of input string";
}

TEST_F(replaceAt, replaceAt_003)
{
    sal_Bool bRes = check_replaceAt(new rtl::OString("SuJava desktop system"),
		new rtl::OString("Sun "), new rtl::OString("Java desktop system"), 2, 64 );
    ASSERT_TRUE(bRes == sal_True) << "larger count";
}

TEST_F(replaceAt, replaceAt_004)
{

    sal_Bool bRes = check_replaceAt(new rtl::OString("Java desktop system"),
		new rtl::OString("Sun "), new rtl::OString("Java desktop system"), -4, 8 );
    ASSERT_TRUE(bRes == sal_True) << "navigate index";
}
TEST_F(replaceAt, replaceAt_005)
{

    sal_Bool bRes = check_replaceAt(new rtl::OString("Sun Jesktop System"),
		new rtl::OString("Sun Java Desktop System"), new rtl::OString(""), 5, 5 );
    ASSERT_TRUE(bRes == sal_True) << "replace with null string";
}


} // namespace rtl_OString


int main(int argc, char **argv)
{
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}
