1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "ui/gfx/break_list.h"
6 
7 #include <stddef.h>
8 
9 #include "base/stl_util.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 #include "third_party/skia/include/core/SkColor.h"
12 #include "ui/gfx/range/range.h"
13 
14 namespace gfx {
15 
16 class BreakListTest : public testing::Test {};
17 
TEST_F(BreakListTest,SetValue)18 TEST_F(BreakListTest, SetValue) {
19   // Check the default values applied to new instances.
20   BreakList<bool> style_breaks(false);
21   EXPECT_TRUE(style_breaks.EqualsValueForTesting(false));
22   style_breaks.SetValue(true);
23   EXPECT_TRUE(style_breaks.EqualsValueForTesting(true));
24 
25   // Ensure that setting values works correctly.
26   BreakList<SkColor> color_breaks(SK_ColorRED);
27   EXPECT_TRUE(color_breaks.EqualsValueForTesting(SK_ColorRED));
28   color_breaks.SetValue(SK_ColorBLACK);
29   EXPECT_TRUE(color_breaks.EqualsValueForTesting(SK_ColorBLACK));
30 }
31 
TEST_F(BreakListTest,ApplyValue)32 TEST_F(BreakListTest, ApplyValue) {
33   BreakList<bool> breaks(false);
34   const size_t max = 99;
35   breaks.SetMax(max);
36 
37   // Ensure ApplyValue is a no-op on invalid and empty ranges.
38   breaks.ApplyValue(true, Range::InvalidRange());
39   EXPECT_TRUE(breaks.EqualsValueForTesting(false));
40   for (size_t i = 0; i < 3; ++i) {
41     breaks.ApplyValue(true, Range(i, i));
42     EXPECT_TRUE(breaks.EqualsValueForTesting(false));
43   }
44 
45   // Apply a value to a valid range, check breaks; repeating should be no-op.
46   std::vector<std::pair<size_t, bool> > expected;
47   expected.push_back(std::pair<size_t, bool>(0, false));
48   expected.push_back(std::pair<size_t, bool>(2, true));
49   expected.push_back(std::pair<size_t, bool>(3, false));
50   for (size_t i = 0; i < 2; ++i) {
51     breaks.ApplyValue(true, Range(2, 3));
52     EXPECT_TRUE(breaks.EqualsForTesting(expected));
53   }
54 
55   // Ensure setting a value overrides the ranged value.
56   breaks.SetValue(true);
57   EXPECT_TRUE(breaks.EqualsValueForTesting(true));
58 
59   // Ensure applying a value over [0, |max|) is the same as setting a value.
60   breaks.ApplyValue(false, Range(0, max));
61   EXPECT_TRUE(breaks.EqualsValueForTesting(false));
62 
63   // Ensure applying a value that is already applied has no effect.
64   breaks.ApplyValue(false, Range(0, 2));
65   breaks.ApplyValue(false, Range(3, 6));
66   breaks.ApplyValue(false, Range(7, max));
67   EXPECT_TRUE(breaks.EqualsValueForTesting(false));
68 
69   // Ensure applying an identical neighboring value merges the ranges.
70   breaks.ApplyValue(true, Range(0, 3));
71   breaks.ApplyValue(true, Range(3, 6));
72   breaks.ApplyValue(true, Range(6, max));
73   EXPECT_TRUE(breaks.EqualsValueForTesting(true));
74 
75   // Ensure applying a value with the same range overrides the ranged value.
76   breaks.ApplyValue(false, Range(2, 3));
77   breaks.ApplyValue(true, Range(2, 3));
78   EXPECT_TRUE(breaks.EqualsValueForTesting(true));
79 
80   // Ensure applying a value with a containing range overrides contained values.
81   breaks.ApplyValue(false, Range(0, 1));
82   breaks.ApplyValue(false, Range(2, 3));
83   breaks.ApplyValue(true, Range(0, 3));
84   EXPECT_TRUE(breaks.EqualsValueForTesting(true));
85   breaks.ApplyValue(false, Range(4, 5));
86   breaks.ApplyValue(false, Range(6, 7));
87   breaks.ApplyValue(false, Range(8, 9));
88   breaks.ApplyValue(true, Range(4, 9));
89   EXPECT_TRUE(breaks.EqualsValueForTesting(true));
90 
91   // Ensure applying various overlapping values yields the intended results.
92   breaks.ApplyValue(false, Range(1, 4));
93   breaks.ApplyValue(false, Range(5, 8));
94   breaks.ApplyValue(true, Range(0, 2));
95   breaks.ApplyValue(true, Range(3, 6));
96   breaks.ApplyValue(true, Range(7, max));
97   std::vector<std::pair<size_t, bool> > overlap;
98   overlap.push_back(std::pair<size_t, bool>(0, true));
99   overlap.push_back(std::pair<size_t, bool>(2, false));
100   overlap.push_back(std::pair<size_t, bool>(3, true));
101   overlap.push_back(std::pair<size_t, bool>(6, false));
102   overlap.push_back(std::pair<size_t, bool>(7, true));
103   EXPECT_TRUE(breaks.EqualsForTesting(overlap));
104 }
105 
TEST_F(BreakListTest,SetMax)106 TEST_F(BreakListTest, SetMax) {
107   // Ensure values adjust to accommodate max position changes.
108   BreakList<bool> breaks(false);
109   breaks.SetMax(9);
110   breaks.ApplyValue(true, Range(0, 2));
111   breaks.ApplyValue(true, Range(3, 6));
112   breaks.ApplyValue(true, Range(7, 9));
113 
114   std::vector<std::pair<size_t, bool> > expected;
115   expected.push_back(std::pair<size_t, bool>(0, true));
116   expected.push_back(std::pair<size_t, bool>(2, false));
117   expected.push_back(std::pair<size_t, bool>(3, true));
118   expected.push_back(std::pair<size_t, bool>(6, false));
119   expected.push_back(std::pair<size_t, bool>(7, true));
120   EXPECT_TRUE(breaks.EqualsForTesting(expected));
121 
122   // Setting a smaller max should remove any corresponding breaks.
123   breaks.SetMax(7);
124   expected.resize(4);
125   EXPECT_TRUE(breaks.EqualsForTesting(expected));
126   breaks.SetMax(4);
127   expected.resize(3);
128   EXPECT_TRUE(breaks.EqualsForTesting(expected));
129   breaks.SetMax(4);
130   EXPECT_TRUE(breaks.EqualsForTesting(expected));
131 
132   // Setting a larger max should not change any breaks.
133   breaks.SetMax(50);
134   EXPECT_TRUE(breaks.EqualsForTesting(expected));
135 }
136 
TEST_F(BreakListTest,GetBreakAndRange)137 TEST_F(BreakListTest, GetBreakAndRange) {
138   BreakList<bool> breaks(false);
139   breaks.SetMax(8);
140   breaks.ApplyValue(true, Range(1, 2));
141   breaks.ApplyValue(true, Range(4, 6));
142 
143   struct {
144     size_t position;
145     size_t break_index;
146     Range range;
147   } cases[] = {
148     { 0, 0, Range(0, 1) },
149     { 1, 1, Range(1, 2) },
150     { 2, 2, Range(2, 4) },
151     { 3, 2, Range(2, 4) },
152     { 4, 3, Range(4, 6) },
153     { 5, 3, Range(4, 6) },
154     { 6, 4, Range(6, 8) },
155     { 7, 4, Range(6, 8) },
156     // Positions at or beyond the max simply return the last break and range.
157     { 8, 4, Range(6, 8) },
158     { 9, 4, Range(6, 8) },
159   };
160 
161   for (size_t i = 0; i < base::size(cases); ++i) {
162     BreakList<bool>::const_iterator it = breaks.GetBreak(cases[i].position);
163     EXPECT_EQ(breaks.breaks()[cases[i].break_index], *it);
164     EXPECT_EQ(breaks.GetRange(it), cases[i].range);
165   }
166 }
167 
168 }  // namespace gfx
169