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