/**************************************************************
 *
 * 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_tools.hxx"
// autogenerated file with codegen.pl

#include "gtest/gtest.h"
#include <rtl/math.hxx>
#include <tools/fract.hxx>

#include <stdio.h>

namespace tools
{

class FractionTest : public ::testing::Test
{
public:
    void SetUp()
    {
    }

    void TearDown()
    {
    }
};

TEST_F(FractionTest, testFraction)
{
    const Fraction aFract(1082130431,1073741824);
    ASSERT_TRUE(rtl::math::approxEqual((double)aFract,1.007812499068677)) << "Fraction #1 not approximately equal to 1.007812499068677";

    Fraction aFract2( aFract );
    aFract2.ReduceInaccurate(8);
    ASSERT_TRUE(aFract2.GetNumerator() == 1 &&
                aFract2.GetDenominator() == 1) << "Fraction #2 not 1";

    Fraction aFract3( 0x7AAAAAAA, 0x35555555 );
    ASSERT_TRUE(aFract3.GetNumerator() == 0x7AAAAAAA &&
                aFract3.GetDenominator() == 0x35555555) << "Fraction #3 cancellation wrong";
    aFract3.ReduceInaccurate(30);
    ASSERT_TRUE(aFract3.GetNumerator() == 0x7AAAAAAA &&
                aFract3.GetDenominator() == 0x35555555) << "Fraction #3 ReduceInaccurate errorneously cut precision";

    aFract3.ReduceInaccurate(29);
    ASSERT_TRUE(aFract3.GetNumerator() == 0x3D555555 &&
                aFract3.GetDenominator() == 0x1AAAAAAA) << "Fraction #3 reduce to 29 bits failed";

    aFract3.ReduceInaccurate(9);
    ASSERT_TRUE(aFract3.GetNumerator() == 0x0147 &&
                aFract3.GetDenominator() == 0x008E) << "Fraction #3 reduce to 9 bits failed";

    aFract3.ReduceInaccurate(1);
    ASSERT_TRUE(aFract3.GetNumerator() == 2 &&
                aFract3.GetDenominator() == 1) << "Fraction #3 reduce to 1 bit failed";

    aFract3.ReduceInaccurate(0);
    ASSERT_TRUE(aFract3.GetNumerator() == 2 &&
                aFract3.GetDenominator() == 1) << "Fraction #3 reduce to 0 bits failed";

#if SAL_TYPES_SIZEOFLONG == 8
    Fraction aFract4(0x7AAAAAAAAAAAAAAA, 0x3555555555555555);
    ASSERT_TRUE(aFract4.GetNumerator() == 0x7AAAAAAAAAAAAAAA &&
                aFract4.GetDenominator() == 0x3555555555555555) << "Fraction #4 cancellation wrong";
    aFract4.ReduceInaccurate(62);
    ASSERT_TRUE(aFract4.GetNumerator() == 0x7AAAAAAAAAAAAAAA &&
                aFract4.GetDenominator() == 0x3555555555555555) << "Fraction #4 ReduceInaccurate errorneously cut precision";

    aFract4.ReduceInaccurate(61);
    ASSERT_TRUE(aFract4.GetNumerator() == 0x3D55555555555555 &&
                aFract4.GetDenominator() == 0x1AAAAAAAAAAAAAAA) << "Fraction #4 ReduceInaccurate reduce to 61 bit failed";
#endif
}

} // namespace tools


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