1*3f982cf4SFabien Sanglard // Copyright 2020 The Chromium Authors. All rights reserved.
2*3f982cf4SFabien Sanglard // Use of this source code is governed by a BSD-style license that can be
3*3f982cf4SFabien Sanglard // found in the LICENSE file.
4*3f982cf4SFabien Sanglard
5*3f982cf4SFabien Sanglard #include "util/simple_fraction.h"
6*3f982cf4SFabien Sanglard
7*3f982cf4SFabien Sanglard #include <cmath>
8*3f982cf4SFabien Sanglard #include <limits>
9*3f982cf4SFabien Sanglard
10*3f982cf4SFabien Sanglard #include "gtest/gtest.h"
11*3f982cf4SFabien Sanglard
12*3f982cf4SFabien Sanglard namespace openscreen {
13*3f982cf4SFabien Sanglard
14*3f982cf4SFabien Sanglard namespace {
15*3f982cf4SFabien Sanglard
16*3f982cf4SFabien Sanglard constexpr int kMin = std::numeric_limits<int>::min();
17*3f982cf4SFabien Sanglard constexpr int kMax = std::numeric_limits<int>::max();
18*3f982cf4SFabien Sanglard
ExpectFromStringEquals(const char * s,const SimpleFraction & expected)19*3f982cf4SFabien Sanglard void ExpectFromStringEquals(const char* s, const SimpleFraction& expected) {
20*3f982cf4SFabien Sanglard const ErrorOr<SimpleFraction> f = SimpleFraction::FromString(std::string(s));
21*3f982cf4SFabien Sanglard EXPECT_TRUE(f.is_value()) << "from string: '" << s << "'";
22*3f982cf4SFabien Sanglard EXPECT_EQ(expected, f.value());
23*3f982cf4SFabien Sanglard }
24*3f982cf4SFabien Sanglard
ExpectFromStringError(const char * s)25*3f982cf4SFabien Sanglard void ExpectFromStringError(const char* s) {
26*3f982cf4SFabien Sanglard const auto f = SimpleFraction::FromString(std::string(s));
27*3f982cf4SFabien Sanglard EXPECT_TRUE(f.is_error()) << "from string: '" << s << "'";
28*3f982cf4SFabien Sanglard }
29*3f982cf4SFabien Sanglard } // namespace
30*3f982cf4SFabien Sanglard
TEST(SimpleFractionTest,FromStringParsesCorrectFractions)31*3f982cf4SFabien Sanglard TEST(SimpleFractionTest, FromStringParsesCorrectFractions) {
32*3f982cf4SFabien Sanglard ExpectFromStringEquals("1/2", SimpleFraction{1, 2});
33*3f982cf4SFabien Sanglard ExpectFromStringEquals("99/3", SimpleFraction{99, 3});
34*3f982cf4SFabien Sanglard ExpectFromStringEquals("-1/2", SimpleFraction{-1, 2});
35*3f982cf4SFabien Sanglard ExpectFromStringEquals("-13/-37", SimpleFraction{-13, -37});
36*3f982cf4SFabien Sanglard ExpectFromStringEquals("1/0", SimpleFraction{1, 0});
37*3f982cf4SFabien Sanglard ExpectFromStringEquals("1", SimpleFraction{1, 1});
38*3f982cf4SFabien Sanglard ExpectFromStringEquals("0", SimpleFraction{0, 1});
39*3f982cf4SFabien Sanglard ExpectFromStringEquals("-20", SimpleFraction{-20, 1});
40*3f982cf4SFabien Sanglard ExpectFromStringEquals("100", SimpleFraction{100, 1});
41*3f982cf4SFabien Sanglard }
42*3f982cf4SFabien Sanglard
TEST(SimpleFractionTest,FromStringErrorsOnInvalid)43*3f982cf4SFabien Sanglard TEST(SimpleFractionTest, FromStringErrorsOnInvalid) {
44*3f982cf4SFabien Sanglard ExpectFromStringError("");
45*3f982cf4SFabien Sanglard ExpectFromStringError("/");
46*3f982cf4SFabien Sanglard ExpectFromStringError("1/");
47*3f982cf4SFabien Sanglard ExpectFromStringError("/1");
48*3f982cf4SFabien Sanglard ExpectFromStringError("888/");
49*3f982cf4SFabien Sanglard ExpectFromStringError("1/2/3");
50*3f982cf4SFabien Sanglard ExpectFromStringError("not a fraction at all");
51*3f982cf4SFabien Sanglard }
52*3f982cf4SFabien Sanglard
TEST(SimpleFractionTest,Equality)53*3f982cf4SFabien Sanglard TEST(SimpleFractionTest, Equality) {
54*3f982cf4SFabien Sanglard EXPECT_EQ((SimpleFraction{1, 2}), (SimpleFraction{1, 2}));
55*3f982cf4SFabien Sanglard EXPECT_EQ((SimpleFraction{1, 0}), (SimpleFraction{1, 0}));
56*3f982cf4SFabien Sanglard EXPECT_NE((SimpleFraction{1, 2}), (SimpleFraction{1, 3}));
57*3f982cf4SFabien Sanglard
58*3f982cf4SFabien Sanglard // We currently don't do any reduction.
59*3f982cf4SFabien Sanglard EXPECT_NE((SimpleFraction{2, 4}), (SimpleFraction{1, 2}));
60*3f982cf4SFabien Sanglard EXPECT_NE((SimpleFraction{9, 10}), (SimpleFraction{-9, -10}));
61*3f982cf4SFabien Sanglard }
62*3f982cf4SFabien Sanglard
TEST(SimpleFractionTest,Definition)63*3f982cf4SFabien Sanglard TEST(SimpleFractionTest, Definition) {
64*3f982cf4SFabien Sanglard EXPECT_TRUE((SimpleFraction{kMin, 1}).is_defined());
65*3f982cf4SFabien Sanglard EXPECT_TRUE((SimpleFraction{kMax, 1}).is_defined());
66*3f982cf4SFabien Sanglard
67*3f982cf4SFabien Sanglard EXPECT_FALSE((SimpleFraction{kMin, 0}).is_defined());
68*3f982cf4SFabien Sanglard EXPECT_FALSE((SimpleFraction{kMax, 0}).is_defined());
69*3f982cf4SFabien Sanglard EXPECT_FALSE((SimpleFraction{0, 0}).is_defined());
70*3f982cf4SFabien Sanglard EXPECT_FALSE((SimpleFraction{-0, -0}).is_defined());
71*3f982cf4SFabien Sanglard }
72*3f982cf4SFabien Sanglard
TEST(SimpleFractionTest,Positivity)73*3f982cf4SFabien Sanglard TEST(SimpleFractionTest, Positivity) {
74*3f982cf4SFabien Sanglard EXPECT_TRUE((SimpleFraction{1234, 20}).is_positive());
75*3f982cf4SFabien Sanglard EXPECT_TRUE((SimpleFraction{kMax - 1, 20}).is_positive());
76*3f982cf4SFabien Sanglard EXPECT_TRUE((SimpleFraction{0, kMax}).is_positive());
77*3f982cf4SFabien Sanglard EXPECT_TRUE((SimpleFraction{kMax, 1}).is_positive());
78*3f982cf4SFabien Sanglard
79*3f982cf4SFabien Sanglard // Since C++ doesn't have a truly negative zero, this is positive.
80*3f982cf4SFabien Sanglard EXPECT_TRUE((SimpleFraction{-0, 1}).is_positive());
81*3f982cf4SFabien Sanglard
82*3f982cf4SFabien Sanglard EXPECT_FALSE((SimpleFraction{0, kMin}).is_positive());
83*3f982cf4SFabien Sanglard EXPECT_FALSE((SimpleFraction{-0, -1}).is_positive());
84*3f982cf4SFabien Sanglard EXPECT_FALSE((SimpleFraction{kMin + 1, 20}).is_positive());
85*3f982cf4SFabien Sanglard EXPECT_FALSE((SimpleFraction{kMin, 1}).is_positive());
86*3f982cf4SFabien Sanglard EXPECT_FALSE((SimpleFraction{kMin, 0}).is_positive());
87*3f982cf4SFabien Sanglard EXPECT_FALSE((SimpleFraction{kMax, 0}).is_positive());
88*3f982cf4SFabien Sanglard EXPECT_FALSE((SimpleFraction{0, 0}).is_positive());
89*3f982cf4SFabien Sanglard EXPECT_FALSE((SimpleFraction{-0, -0}).is_positive());
90*3f982cf4SFabien Sanglard }
91*3f982cf4SFabien Sanglard
TEST(SimpleFractionTest,CastToDouble)92*3f982cf4SFabien Sanglard TEST(SimpleFractionTest, CastToDouble) {
93*3f982cf4SFabien Sanglard EXPECT_DOUBLE_EQ(0.0, static_cast<double>(SimpleFraction{0, 1}));
94*3f982cf4SFabien Sanglard EXPECT_DOUBLE_EQ(1.0, static_cast<double>(SimpleFraction{1, 1}));
95*3f982cf4SFabien Sanglard EXPECT_TRUE(std::isnan(static_cast<double>(SimpleFraction{1, 0})));
96*3f982cf4SFabien Sanglard EXPECT_DOUBLE_EQ(1.0, static_cast<double>(SimpleFraction{kMax, kMax}));
97*3f982cf4SFabien Sanglard EXPECT_DOUBLE_EQ(1.0, static_cast<double>(SimpleFraction{kMin, kMin}));
98*3f982cf4SFabien Sanglard }
99*3f982cf4SFabien Sanglard
100*3f982cf4SFabien Sanglard } // namespace openscreen
101