1 // Copyright (C) 2015-2019 Internet Systems Consortium, Inc. ("ISC")
2 //
3 // This Source Code Form is subject to the terms of the Mozilla Public
4 // License, v. 2.0. If a copy of the MPL was not distributed with this
5 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 
7 #include <config.h>
8 #include <util/optional.h>
9 #include <gtest/gtest.h>
10 
11 namespace {
12 
13 using namespace isc::util;
14 
15 // This test checks that the constructors work correctly.
TEST(OptionalTest,constructor)16 TEST(OptionalTest, constructor) {
17     // Explicitly set a value via constructor. The value becomes
18     // specified.
19     Optional<int> value1(10);
20     EXPECT_EQ(10, value1.get());
21     EXPECT_FALSE(value1.unspecified());
22 
23     // Do not set a value in a constructor. The value should be
24     // unspecified.
25     Optional<int> value2;
26     EXPECT_EQ(0, value2.get());
27     EXPECT_TRUE(value2.unspecified());
28 
29     // Use the non-default value for second parameter.
30     Optional<bool> value3(true, true);
31     EXPECT_TRUE(value3.get());
32     EXPECT_TRUE(value3.unspecified());
33 }
34 
35 // This test checks if the constructors for a string value
36 // work correctly.
TEST(OptionalTest,constructorString)37 TEST(OptionalTest, constructorString) {
38     Optional<std::string> value1("foo");
39     EXPECT_EQ("foo", value1.get());
40     EXPECT_FALSE(value1.unspecified());
41 
42     Optional<std::string> value2;
43     EXPECT_TRUE(value2.get().empty());
44     EXPECT_TRUE(value2.unspecified());
45 }
46 
47 // This test checks if the assignment operator assigning an actual
48 // value to the optional value works as expected.
TEST(OptionalTest,assignValue)49 TEST(OptionalTest, assignValue) {
50     Optional<int> value(10, true);
51     EXPECT_EQ(10, value.get());
52     EXPECT_TRUE(value.unspecified());
53 
54     // Assign a new value.
55     value = 111;
56     EXPECT_EQ(111, value.get());
57     EXPECT_FALSE(value.unspecified());
58 
59     // Assign another value.
60     value = 1000;
61     EXPECT_EQ(1000, value.get());
62     EXPECT_FALSE(value.unspecified());
63 }
64 
65 // This test checks if the assignment operator assigning an actual
66 // string value to the optional value works as expected.
TEST(OptionalTest,assignStringValue)67 TEST(OptionalTest, assignStringValue) {
68     Optional<std::string> value("foo");
69     EXPECT_EQ("foo", value.get());
70     EXPECT_FALSE(value.unspecified());
71 
72     value = "bar";
73     EXPECT_EQ("bar", value.get());
74     EXPECT_FALSE(value.unspecified());
75 
76     value = "foobar";
77     EXPECT_EQ("foobar", value.get());
78     EXPECT_FALSE(value.unspecified());
79 }
80 
81 // This test checks that it is possible to modify the flag that indicates
82 // if the value is specified or unspecified.
TEST(OptionalTest,modifyUnspecified)83 TEST(OptionalTest, modifyUnspecified) {
84     Optional<int> value;
85     EXPECT_TRUE(value.unspecified());
86 
87     value.unspecified(false);
88     EXPECT_FALSE(value.unspecified());
89 
90     value.unspecified(true);
91     EXPECT_TRUE(value.unspecified());
92 }
93 
94 // This test checks if the type case operator returns correct value.
TEST(OptionalTest,typeCastOperator)95 TEST(OptionalTest, typeCastOperator) {
96     Optional<int> value(-10);
97     EXPECT_EQ(-10, value.get());
98     EXPECT_FALSE(value.unspecified());
99 
100     int actual = value;
101     EXPECT_EQ(-10, actual);
102 }
103 
104 // This test checks if the type case operator returns correct string
105 // value.
TEST(OptionalTest,stringCastOperator)106 TEST(OptionalTest, stringCastOperator) {
107     Optional<std::string> value("xyz");
108     EXPECT_EQ("xyz", value.get());
109     EXPECT_FALSE(value.unspecified());
110 
111     std::string actual = value;
112     EXPECT_EQ("xyz", actual);
113 }
114 
115 // This test checks that the equality operators work as expected.
TEST(OptionalTest,equality)116 TEST(OptionalTest, equality) {
117     int exp_value = 1234;
118     Optional<int> value(1234);
119     EXPECT_TRUE(value == exp_value);
120     EXPECT_FALSE(value != exp_value);
121 }
122 
123 // This test checks that the equality operators for strings work as
124 // expected.
TEST(OptionalTest,stringEquality)125 TEST(OptionalTest, stringEquality) {
126     const char* exp_value = "foo";
127     Optional<std::string> value("foo");
128     EXPECT_TRUE(value == exp_value);
129     EXPECT_FALSE(value != exp_value);
130 }
131 
132 // This test checks that an exception is thrown when calling an empty()
133 // method on non-string optional value.
TEST(OptionalTest,empty)134 TEST(OptionalTest, empty) {
135     Optional<int> value(10);
136     EXPECT_THROW(value.empty(), isc::InvalidOperation);
137 }
138 
139 // This test checks that no exception is thrown when calling an empty()
140 // method on string optional value and that it returns an expected
141 // boolean value.
TEST(OptionalTest,stringEmpty)142 TEST(OptionalTest, stringEmpty) {
143     Optional<std::string> value("foo");
144     bool is_empty = true;
145     ASSERT_NO_THROW(is_empty = value.empty());
146     EXPECT_FALSE(is_empty);
147 
148     value = "";
149     ASSERT_NO_THROW(is_empty = value.empty());
150     EXPECT_TRUE(is_empty);
151 }
152 
153 } // end of anonymous namespace
154