| // Copyright 2017-2020 The Verible Authors. | |
| // | |
| // Licensed 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. | |
| #include "common/util/interval.h" | |
| #include <sstream> | |
| #include "gmock/gmock.h" | |
| #include "gtest/gtest.h" | |
| namespace verible { | |
| namespace { | |
| using interval_type = Interval<int>; | |
| TEST(IntervalTest, IsEmpty) { | |
| const interval_type ii{1, 1}; | |
| EXPECT_TRUE(ii.valid()); | |
| EXPECT_TRUE(ii.empty()); | |
| EXPECT_EQ(ii.length(), 0); | |
| for (int i = -1; i < 3; ++i) { | |
| EXPECT_FALSE(ii.contains(i)); | |
| EXPECT_FALSE(ii.contains({i, i + 1})); | |
| EXPECT_FALSE(ii.contains(i, i + 1)); | |
| } | |
| EXPECT_FALSE(ii.contains(0, 0)); | |
| EXPECT_TRUE(ii.contains(1, 1)); // even if interval is empty | |
| EXPECT_FALSE(ii.contains(2, 2)); | |
| EXPECT_FALSE(ii.contains({0, 0})); | |
| EXPECT_TRUE(ii.contains({1, 1})); // even if interval is empty | |
| EXPECT_FALSE(ii.contains({2, 2})); | |
| for (int i = -1; i < 3; ++i) { | |
| for (int j = i; j < 3; ++j) { | |
| EXPECT_FALSE(ii.contains({i, j}) && i != 1 && j != 1); | |
| EXPECT_FALSE(ii.contains(i, j) && i != 1 && j != 1); | |
| } | |
| } | |
| } | |
| TEST(IntervalTest, NotEmptyLengthOne) { | |
| const interval_type ii{1, 2}; | |
| EXPECT_TRUE(ii.valid()); | |
| EXPECT_FALSE(ii.empty()); | |
| EXPECT_EQ(ii.length(), 1); | |
| EXPECT_FALSE(ii.contains(0)); | |
| EXPECT_TRUE(ii.contains(1)); | |
| EXPECT_FALSE(ii.contains(2)); | |
| EXPECT_FALSE(ii.contains({0, 1})); | |
| EXPECT_TRUE(ii.contains({1, 2})); | |
| EXPECT_FALSE(ii.contains({2, 3})); | |
| EXPECT_FALSE(ii.contains({0, 2})); | |
| EXPECT_FALSE(ii.contains({1, 3})); | |
| EXPECT_FALSE(ii.contains({0, 3})); | |
| } | |
| TEST(IntervalTest, NotEmptyLengthGreaterThanOne) { | |
| const interval_type ii{5, 8}; | |
| EXPECT_TRUE(ii.valid()); | |
| EXPECT_FALSE(ii.empty()); | |
| EXPECT_EQ(ii.length(), 3); | |
| for (int i = 3; i < 9; ++i) { | |
| for (int j = i; j < 9; ++j) { | |
| EXPECT_EQ(ii.contains({i, j}), i >= 5 && j <= 8); | |
| EXPECT_EQ(ii.contains(i, j), i >= 5 && j <= 8); | |
| } | |
| } | |
| } | |
| TEST(IntervalTest, Invalid) { | |
| const interval_type ii{2, 1}; | |
| EXPECT_FALSE(ii.valid()); | |
| EXPECT_FALSE(ii.empty()); | |
| // other methods considered undefined for invalid intervals | |
| } | |
| TEST(IntervalTest, Equality) { | |
| const interval_type i1{2, 2}, i2({2, 2}); // different constructors | |
| EXPECT_EQ(i1, i2); | |
| EXPECT_EQ(i2, i1); | |
| const interval_type i3{1, 2}, i4{2, 3}, i5{1, 3}; | |
| EXPECT_NE(i1, i3); | |
| EXPECT_NE(i1, i4); | |
| EXPECT_NE(i1, i5); | |
| EXPECT_NE(i3, i1); | |
| EXPECT_NE(i4, i1); | |
| EXPECT_NE(i5, i1); | |
| } | |
| TEST(IntervalTest, Stream) { | |
| const interval_type ii{1, 2}; | |
| std::ostringstream stream; | |
| stream << ii; | |
| EXPECT_EQ(stream.str(), "[1, 2)"); | |
| } | |
| TEST(ParseInclusiveRangeTest, EmptyStrings) { | |
| interval_type interval; | |
| { | |
| std::ostringstream errstream; | |
| EXPECT_FALSE(ParseInclusiveRange(&interval, "", "1", &errstream)); | |
| EXPECT_FALSE(errstream.str().empty()); | |
| } | |
| { | |
| std::ostringstream errstream; | |
| EXPECT_FALSE(ParseInclusiveRange(&interval, "1", "", &errstream)); | |
| EXPECT_FALSE(errstream.str().empty()); | |
| } | |
| } | |
| TEST(FormatInclusiveRangeTest, Singleton) { | |
| const interval_type ii{5, 6}; | |
| { | |
| std::ostringstream stream; | |
| ii.FormatInclusive(stream, false); | |
| EXPECT_EQ(stream.str(), "5-5"); | |
| } | |
| { | |
| std::ostringstream stream; | |
| ii.FormatInclusive(stream, true); | |
| EXPECT_EQ(stream.str(), "5"); | |
| } | |
| } | |
| TEST(FormatInclusiveRangeTest, LargerThanOne) { | |
| const interval_type ii{7, 9}; | |
| { | |
| std::ostringstream stream; | |
| ii.FormatInclusive(stream, false); | |
| EXPECT_EQ(stream.str(), "7-8"); | |
| } | |
| { | |
| std::ostringstream stream; | |
| ii.FormatInclusive(stream, true); | |
| EXPECT_EQ(stream.str(), "7-8"); | |
| } | |
| } | |
| TEST(ParseInclusiveRangeTest, ValidRangeSingleValue) { | |
| interval_type interval; | |
| std::ostringstream errstream; | |
| EXPECT_TRUE(ParseInclusiveRange(&interval, "3", "3", &errstream)); | |
| EXPECT_TRUE(errstream.str().empty()); | |
| EXPECT_EQ(interval.min, 3); | |
| EXPECT_EQ(interval.max, 4); // half-open | |
| } | |
| TEST(ParseInclusiveRangeTest, ValidRangeBigInterval) { | |
| interval_type interval; | |
| std::ostringstream errstream; | |
| EXPECT_TRUE(ParseInclusiveRange(&interval, "3", "30", &errstream)); | |
| EXPECT_TRUE(errstream.str().empty()); | |
| EXPECT_EQ(interval.min, 3); | |
| EXPECT_EQ(interval.max, 31); // half-open | |
| } | |
| TEST(ParseInclusiveRangeTest, ValidRangeReversed) { | |
| interval_type interval; | |
| std::ostringstream errstream; | |
| EXPECT_TRUE(ParseInclusiveRange(&interval, "5", "3", &errstream)); | |
| EXPECT_TRUE(errstream.str().empty()); | |
| EXPECT_EQ(interval.min, 3); | |
| EXPECT_EQ(interval.max, 6); // half-open | |
| } | |
| } // namespace | |
| } // namespace verible |