blob: e7226092de11eb7c179e1f188a55e3524b7d217d [file] [log] [blame]
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/views/controls/styled_label.h"
#include <stddef.h>
#include <memory>
#include <string>
#include "base/macros.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/base/ui_base_features.h"
#include "ui/gfx/font_list.h"
#include "ui/views/border.h"
#include "ui/views/controls/link.h"
#include "ui/views/controls/styled_label_listener.h"
#include "ui/views/style/typography.h"
#include "ui/views/test/test_layout_provider.h"
#include "ui/views/test/views_test_base.h"
#include "ui/views/widget/widget.h"
using base::ASCIIToUTF16;
namespace views {
namespace {
enum class SecondaryUiMode { NON_MD, MD };
std::string SecondaryUiModeToString(
const ::testing::TestParamInfo<SecondaryUiMode>& info) {
return info.param == SecondaryUiMode::MD ? "MD" : "NonMD";
}
} // namespace
class StyledLabelTest : public ViewsTestBase, public StyledLabelListener {
public:
StyledLabelTest() {}
~StyledLabelTest() override {}
// StyledLabelListener implementation.
void StyledLabelLinkClicked(StyledLabel* label,
const gfx::Range& range,
int event_flags) override {}
protected:
StyledLabel* styled() { return styled_.get(); }
void InitStyledLabel(const std::string& ascii_text) {
styled_.reset(new StyledLabel(ASCIIToUTF16(ascii_text), this));
styled_->set_owned_by_client();
}
int StyledLabelContentHeightForWidth(int w) {
return styled_->GetHeightForWidth(w) - styled_->GetInsets().height();
}
private:
std::unique_ptr<StyledLabel> styled_;
DISALLOW_COPY_AND_ASSIGN(StyledLabelTest);
};
// StyledLabelTest harness that runs both with and without secondary UI set to
// MD.
class MDStyledLabelTest
: public StyledLabelTest,
public ::testing::WithParamInterface<SecondaryUiMode> {
public:
MDStyledLabelTest() {}
// StyledLabelTest:
void SetUp() override {
// This works while StyledLabelTest has no SetUp() of its own. Otherwise the
// mode should be set after ViewsTestBase::SetUp(), but before the rest of
// StyledLabelTest::SetUp(), so that StyledLabelTest::SetUp() obeys the MD
// setting.
StyledLabelTest::SetUp();
if (GetParam() == SecondaryUiMode::MD)
scoped_feature_list_.InitAndEnableFeature(features::kSecondaryUiMd);
else
scoped_feature_list_.InitAndDisableFeature(features::kSecondaryUiMd);
}
private:
base::test::ScopedFeatureList scoped_feature_list_;
DISALLOW_COPY_AND_ASSIGN(MDStyledLabelTest);
};
TEST_F(StyledLabelTest, NoWrapping) {
const std::string text("This is a test block of text");
InitStyledLabel(text);
Label label(ASCIIToUTF16(text));
const gfx::Size label_preferred_size = label.GetPreferredSize();
EXPECT_EQ(label_preferred_size.height(),
StyledLabelContentHeightForWidth(label_preferred_size.width() * 2));
}
TEST_F(StyledLabelTest, TrailingWhitespaceiIgnored) {
const std::string text("This is a test block of text ");
InitStyledLabel(text);
styled()->SetBounds(0, 0, 1000, 1000);
styled()->Layout();
ASSERT_EQ(1, styled()->child_count());
ASSERT_EQ(std::string(Label::kViewClassName),
styled()->child_at(0)->GetClassName());
EXPECT_EQ(ASCIIToUTF16("This is a test block of text"),
static_cast<Label*>(styled()->child_at(0))->text());
}
TEST_F(StyledLabelTest, RespectLeadingWhitespace) {
const std::string text(" This is a test block of text");
InitStyledLabel(text);
styled()->SetBounds(0, 0, 1000, 1000);
styled()->Layout();
ASSERT_EQ(1, styled()->child_count());
ASSERT_EQ(std::string(Label::kViewClassName),
styled()->child_at(0)->GetClassName());
EXPECT_EQ(ASCIIToUTF16(" This is a test block of text"),
static_cast<Label*>(styled()->child_at(0))->text());
}
TEST_F(StyledLabelTest, RespectLeadingSpacesInNonFirstLine) {
const std::string indented_line = " indented line";
const std::string text(std::string("First line\n") + indented_line);
InitStyledLabel(text);
styled()->SetBounds(0, 0, 1000, 1000);
styled()->Layout();
ASSERT_EQ(2, styled()->child_count());
ASSERT_EQ(std::string(Label::kViewClassName),
styled()->child_at(0)->GetClassName());
EXPECT_EQ(ASCIIToUTF16(indented_line),
static_cast<Label*>(styled()->child_at(1))->text());
}
TEST_F(StyledLabelTest, CorrectWrapAtNewline) {
const std::string first_line = "Line one";
const std::string second_line = " two";
const std::string multiline_text(first_line + "\n" + second_line);
InitStyledLabel(multiline_text);
Label label(ASCIIToUTF16(first_line));
gfx::Size label_preferred_size = label.GetPreferredSize();
// Correct handling of \n and label width limit encountered at the same place
styled()->SetBounds(0, 0, label_preferred_size.width(), 1000);
styled()->Layout();
ASSERT_EQ(2, styled()->child_count());
ASSERT_EQ(std::string(Label::kViewClassName),
styled()->child_at(1)->GetClassName());
EXPECT_EQ(ASCIIToUTF16(first_line),
static_cast<Label*>(styled()->child_at(0))->text());
EXPECT_EQ(ASCIIToUTF16(second_line),
static_cast<Label*>(styled()->child_at(1))->text());
EXPECT_EQ(styled()->GetHeightForWidth(1000),
styled()->child_at(1)->bounds().bottom());
}
TEST_F(StyledLabelTest, FirstLineNotEmptyWhenLeadingWhitespaceTooLong) {
const std::string text(" a");
InitStyledLabel(text);
Label label(ASCIIToUTF16(text));
gfx::Size label_preferred_size = label.GetPreferredSize();
styled()->SetBounds(0, 0, label_preferred_size.width() / 2, 1000);
styled()->Layout();
ASSERT_EQ(1, styled()->child_count());
ASSERT_EQ(std::string(Label::kViewClassName),
styled()->child_at(0)->GetClassName());
EXPECT_EQ(ASCIIToUTF16("a"),
static_cast<Label*>(styled()->child_at(0))->text());
EXPECT_EQ(label_preferred_size.height(),
styled()->GetHeightForWidth(label_preferred_size.width() / 2));
}
TEST_F(StyledLabelTest, BasicWrapping) {
const std::string text("This is a test block of text");
InitStyledLabel(text);
Label label(ASCIIToUTF16(text.substr(0, text.size() * 2 / 3)));
gfx::Size label_preferred_size = label.GetPreferredSize();
EXPECT_EQ(label_preferred_size.height() * 2,
StyledLabelContentHeightForWidth(label_preferred_size.width()));
// Also respect the border.
styled()->SetBorder(CreateEmptyBorder(3, 3, 3, 3));
styled()->SetBounds(
0,
0,
styled()->GetInsets().width() + label_preferred_size.width(),
styled()->GetInsets().height() + 2 * label_preferred_size.height());
styled()->Layout();
ASSERT_EQ(2, styled()->child_count());
EXPECT_EQ(3, styled()->child_at(0)->x());
EXPECT_EQ(3, styled()->child_at(0)->y());
EXPECT_EQ(styled()->height() - 3, styled()->child_at(1)->bounds().bottom());
}
TEST_F(StyledLabelTest, AllowEmptyLines) {
const std::string text("one");
InitStyledLabel(text);
int default_height = styled()->GetHeightForWidth(1000);
const std::string multiline_text("one\n\nthree");
InitStyledLabel(multiline_text);
styled()->SetBounds(0, 0, 1000, 1000);
styled()->Layout();
EXPECT_EQ(3 * default_height, styled()->GetHeightForWidth(1000));
ASSERT_EQ(2, styled()->child_count());
EXPECT_EQ(styled()->GetHeightForWidth(1000),
styled()->child_at(1)->bounds().bottom());
}
TEST_F(StyledLabelTest, WrapLongWords) {
const std::string text("ThisIsTextAsASingleWord");
InitStyledLabel(text);
Label label(ASCIIToUTF16(text.substr(0, text.size() * 2 / 3)));
gfx::Size label_preferred_size = label.GetPreferredSize();
EXPECT_EQ(label_preferred_size.height() * 2,
StyledLabelContentHeightForWidth(label_preferred_size.width()));
styled()->SetBounds(
0, 0, styled()->GetInsets().width() + label_preferred_size.width(),
styled()->GetInsets().height() + 2 * label_preferred_size.height());
styled()->Layout();
ASSERT_EQ(2, styled()->child_count());
ASSERT_EQ(gfx::Point(), styled()->origin());
EXPECT_EQ(gfx::Point(), styled()->child_at(0)->origin());
EXPECT_EQ(gfx::Point(0, styled()->height() / 2),
styled()->child_at(1)->origin());
EXPECT_FALSE(static_cast<Label*>(styled()->child_at(0))->text().empty());
EXPECT_FALSE(static_cast<Label*>(styled()->child_at(1))->text().empty());
EXPECT_EQ(ASCIIToUTF16(text),
static_cast<Label*>(styled()->child_at(0))->text() +
static_cast<Label*>(styled()->child_at(1))->text());
}
TEST_P(MDStyledLabelTest, CreateLinks) {
const std::string text("This is a test block of text.");
InitStyledLabel(text);
// Without links, there should be no focus border.
EXPECT_TRUE(styled()->GetInsets().IsEmpty());
// Now let's add some links.
styled()->AddStyleRange(gfx::Range(0, 1),
StyledLabel::RangeStyleInfo::CreateForLink());
styled()->AddStyleRange(gfx::Range(1, 2),
StyledLabel::RangeStyleInfo::CreateForLink());
styled()->AddStyleRange(gfx::Range(10, 11),
StyledLabel::RangeStyleInfo::CreateForLink());
styled()->AddStyleRange(gfx::Range(12, 13),
StyledLabel::RangeStyleInfo::CreateForLink());
if (GetParam() == SecondaryUiMode::MD) {
// Insets shouldn't change under MD when links are added, since the links
// indicate focus by adding an underline instead.
EXPECT_TRUE(styled()->GetInsets().IsEmpty());
} else {
// Now there should be a focus border because there are non-empty Links.
EXPECT_FALSE(styled()->GetInsets().IsEmpty());
}
// Verify layout creates the right number of children.
styled()->SetBounds(0, 0, 1000, 1000);
styled()->Layout();
EXPECT_EQ(7, styled()->child_count());
}
TEST_P(MDStyledLabelTest, DontBreakLinks) {
const std::string text("This is a test block of text, ");
const std::string link_text("and this should be a link");
InitStyledLabel(text + link_text);
styled()->AddStyleRange(
gfx::Range(static_cast<uint32_t>(text.size()),
static_cast<uint32_t>(text.size() + link_text.size())),
StyledLabel::RangeStyleInfo::CreateForLink());
Label label(ASCIIToUTF16(text + link_text.substr(0, link_text.size() / 2)));
gfx::Size label_preferred_size = label.GetPreferredSize();
int pref_height = styled()->GetHeightForWidth(label_preferred_size.width());
EXPECT_EQ(label_preferred_size.height() * 2,
pref_height - styled()->GetInsets().height());
styled()->SetBounds(0, 0, label_preferred_size.width(), pref_height);
styled()->Layout();
ASSERT_EQ(2, styled()->child_count());
if (GetParam() == SecondaryUiMode::MD) {
// No additional insets should be added under MD.
EXPECT_EQ(0, styled()->child_at(0)->x());
} else {
// The label has no focus border while, when non-MD, the link (and thus
// overall styled label) does, so the label should be inset by the width of
// the focus border.
EXPECT_EQ(Link::kFocusBorderPadding, styled()->child_at(0)->x());
}
// The Link shouldn't be offset (it grows in size under non-MD instead).
EXPECT_EQ(0, styled()->child_at(1)->x());
}
TEST_F(StyledLabelTest, StyledRangeWithDisabledLineWrapping) {
const std::string text("This is a test block of text, ");
const std::string unbreakable_text("and this should not be broken");
InitStyledLabel(text + unbreakable_text);
StyledLabel::RangeStyleInfo style_info;
style_info.disable_line_wrapping = true;
styled()->AddStyleRange(
gfx::Range(static_cast<uint32_t>(text.size()),
static_cast<uint32_t>(text.size() + unbreakable_text.size())),
style_info);
Label label(ASCIIToUTF16(
text + unbreakable_text.substr(0, unbreakable_text.size() / 2)));
gfx::Size label_preferred_size = label.GetPreferredSize();
int pref_height = styled()->GetHeightForWidth(label_preferred_size.width());
EXPECT_EQ(label_preferred_size.height() * 2,
pref_height - styled()->GetInsets().height());
styled()->SetBounds(0, 0, label_preferred_size.width(), pref_height);
styled()->Layout();
ASSERT_EQ(2, styled()->child_count());
EXPECT_EQ(0, styled()->child_at(0)->x());
EXPECT_EQ(0, styled()->child_at(1)->x());
}
TEST_F(StyledLabelTest, StyledRangeCustomFontUnderlined) {
const std::string text("This is a test block of text, ");
const std::string underlined_text("and this should be undelined");
InitStyledLabel(text + underlined_text);
StyledLabel::RangeStyleInfo style_info;
style_info.tooltip = ASCIIToUTF16("tooltip");
style_info.custom_font =
styled()->GetDefaultFontList().DeriveWithStyle(gfx::Font::UNDERLINE);
styled()->AddStyleRange(
gfx::Range(static_cast<uint32_t>(text.size()),
static_cast<uint32_t>(text.size() + underlined_text.size())),
style_info);
styled()->SetBounds(0, 0, 1000, 1000);
styled()->Layout();
ASSERT_EQ(2, styled()->child_count());
ASSERT_EQ(std::string(Label::kViewClassName),
styled()->child_at(1)->GetClassName());
EXPECT_EQ(
gfx::Font::UNDERLINE,
static_cast<Label*>(styled()->child_at(1))->font_list().GetFontStyle());
}
TEST_F(StyledLabelTest, StyledRangeTextStyleBold) {
test::TestLayoutProvider bold_provider;
const std::string bold_text(
"This is a block of text whose style will be set to BOLD in the test");
const std::string text(" normal text");
InitStyledLabel(bold_text + text);
// Pretend disabled text becomes bold for testing.
bold_provider.SetFont(
style::CONTEXT_LABEL, style::STYLE_DISABLED,
styled()->GetDefaultFontList().DeriveWithWeight(gfx::Font::Weight::BOLD));
StyledLabel::RangeStyleInfo style_info;
style_info.text_style = style::STYLE_DISABLED;
styled()->AddStyleRange(
gfx::Range(0u, static_cast<uint32_t>(bold_text.size())), style_info);
// Calculate the bold text width if it were a pure label view, both with bold
// and normal style.
Label label(ASCIIToUTF16(bold_text));
const gfx::Size normal_label_size = label.GetPreferredSize();
label.SetFontList(
label.font_list().DeriveWithWeight(gfx::Font::Weight::BOLD));
const gfx::Size bold_label_size = label.GetPreferredSize();
ASSERT_GE(bold_label_size.width(), normal_label_size.width());
// Set the width so |bold_text| doesn't fit on a single line with bold style,
// but does with normal font style.
int styled_width = (normal_label_size.width() + bold_label_size.width()) / 2;
int pref_height = styled()->GetHeightForWidth(styled_width);
// Sanity check that |bold_text| with normal font style would fit on a single
// line in a styled label with width |styled_width|.
StyledLabel unstyled(ASCIIToUTF16(bold_text), this);
unstyled.SetBounds(0, 0, styled_width, pref_height);
unstyled.Layout();
EXPECT_EQ(1, unstyled.child_count());
styled()->SetBounds(0, 0, styled_width, pref_height);
styled()->Layout();
ASSERT_EQ(3, styled()->child_count());
// The bold text should be broken up into two parts.
ASSERT_EQ(std::string(Label::kViewClassName),
styled()->child_at(0)->GetClassName());
EXPECT_EQ(
gfx::Font::Weight::BOLD,
static_cast<Label*>(styled()->child_at(0))->font_list().GetFontWeight());
ASSERT_EQ(std::string(Label::kViewClassName),
styled()->child_at(1)->GetClassName());
EXPECT_EQ(
gfx::Font::Weight::BOLD,
static_cast<Label*>(styled()->child_at(1))->font_list().GetFontWeight());
ASSERT_EQ(std::string(Label::kViewClassName),
styled()->child_at(2)->GetClassName());
EXPECT_EQ(
gfx::Font::NORMAL,
static_cast<Label*>(styled()->child_at(2))->font_list().GetFontStyle());
// The second bold part should start on a new line.
EXPECT_EQ(0, styled()->child_at(0)->x());
EXPECT_EQ(0, styled()->child_at(1)->x());
EXPECT_EQ(styled()->child_at(1)->bounds().right(),
styled()->child_at(2)->x());
}
TEST_F(StyledLabelTest, Color) {
const std::string text_red("RED");
const std::string text_link("link");
const std::string text("word");
InitStyledLabel(text_red + text_link + text);
StyledLabel::RangeStyleInfo style_info_red;
style_info_red.override_color = SK_ColorRED;
styled()->AddStyleRange(
gfx::Range(0u, static_cast<uint32_t>(text_red.size())), style_info_red);
StyledLabel::RangeStyleInfo style_info_link =
StyledLabel::RangeStyleInfo::CreateForLink();
styled()->AddStyleRange(
gfx::Range(static_cast<uint32_t>(text_red.size()),
static_cast<uint32_t>(text_red.size() + text_link.size())),
style_info_link);
styled()->SetBounds(0, 0, 1000, 1000);
styled()->Layout();
Widget* widget = new Widget();
Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
widget->Init(params);
View* container = new View();
widget->SetContentsView(container);
container->AddChildView(styled());
// Obtain the default text color for a label.
Label* label = new Label(ASCIIToUTF16(text));
container->AddChildView(label);
const SkColor kDefaultTextColor = label->enabled_color();
// Obtain the default text color for a link.
Link* link = new Link(ASCIIToUTF16(text_link));
container->AddChildView(link);
const SkColor kDefaultLinkColor = link->enabled_color();
EXPECT_EQ(SK_ColorRED,
static_cast<Label*>(styled()->child_at(0))->enabled_color());
EXPECT_EQ(kDefaultLinkColor,
static_cast<Label*>(styled()->child_at(1))->enabled_color());
EXPECT_EQ(kDefaultTextColor,
static_cast<Label*>(styled()->child_at(2))->enabled_color());
// Test adjusted color readability.
styled()->SetDisplayedOnBackgroundColor(SK_ColorBLACK);
styled()->Layout();
label->SetBackgroundColor(SK_ColorBLACK);
const SkColor kAdjustedTextColor = label->enabled_color();
EXPECT_NE(kAdjustedTextColor, kDefaultTextColor);
EXPECT_EQ(kAdjustedTextColor,
static_cast<Label*>(styled()->child_at(2))->enabled_color());
widget->CloseNow();
}
TEST_P(MDStyledLabelTest, StyledRangeWithTooltip) {
const std::string text("This is a test block of text, ");
const std::string tooltip_text("this should have a tooltip,");
const std::string normal_text(" this should not have a tooltip, ");
const std::string link_text("and this should be a link");
const size_t tooltip_start = text.size();
const size_t link_start =
text.size() + tooltip_text.size() + normal_text.size();
InitStyledLabel(text + tooltip_text + normal_text + link_text);
StyledLabel::RangeStyleInfo tooltip_style;
tooltip_style.tooltip = ASCIIToUTF16("tooltip");
styled()->AddStyleRange(
gfx::Range(static_cast<uint32_t>(tooltip_start),
static_cast<uint32_t>(tooltip_start + tooltip_text.size())),
tooltip_style);
styled()->AddStyleRange(
gfx::Range(static_cast<uint32_t>(link_start),
static_cast<uint32_t>(link_start + link_text.size())),
StyledLabel::RangeStyleInfo::CreateForLink());
// Break line inside the range with the tooltip.
Label label(ASCIIToUTF16(
text + tooltip_text.substr(0, tooltip_text.size() - 3)));
gfx::Size label_preferred_size = label.GetPreferredSize();
int pref_height = styled()->GetHeightForWidth(label_preferred_size.width());
EXPECT_EQ(label_preferred_size.height() * 3,
pref_height - styled()->GetInsets().height());
styled()->SetBounds(0, 0, label_preferred_size.width(), pref_height);
styled()->Layout();
EXPECT_EQ(label_preferred_size.width(), styled()->width());
ASSERT_EQ(5, styled()->child_count());
if (GetParam() == SecondaryUiMode::MD) {
// In MD, the labels shouldn't be offset to cater for focus rings.
EXPECT_EQ(0, styled()->child_at(0)->x());
EXPECT_EQ(0, styled()->child_at(2)->x());
} else {
// The labels have no focus border while the link (and thus overall styled
// label) does, so the labels should be inset by the width of the focus
// border.
EXPECT_EQ(Link::kFocusBorderPadding, styled()->child_at(0)->x());
EXPECT_EQ(Link::kFocusBorderPadding, styled()->child_at(2)->x());
}
EXPECT_EQ(styled()->child_at(0)->bounds().right(),
styled()->child_at(1)->x());
EXPECT_EQ(styled()->child_at(2)->bounds().right(),
styled()->child_at(3)->x());
EXPECT_EQ(0, styled()->child_at(4)->x());
base::string16 tooltip;
EXPECT_TRUE(
styled()->child_at(1)->GetTooltipText(gfx::Point(1, 1), &tooltip));
EXPECT_EQ(ASCIIToUTF16("tooltip"), tooltip);
EXPECT_TRUE(
styled()->child_at(2)->GetTooltipText(gfx::Point(1, 1), &tooltip));
EXPECT_EQ(ASCIIToUTF16("tooltip"), tooltip);
}
TEST_F(StyledLabelTest, SetTextContextAndDefaultStyle) {
const std::string text("This is a test block of text.");
InitStyledLabel(text);
styled()->SetTextContext(style::CONTEXT_DIALOG_TITLE);
styled()->SetDefaultTextStyle(style::STYLE_DISABLED);
Label label(ASCIIToUTF16(text), style::CONTEXT_DIALOG_TITLE,
style::STYLE_DISABLED);
styled()->SetBounds(0,
0,
label.GetPreferredSize().width(),
label.GetPreferredSize().height());
// Make sure we have the same sizing as a label with the same style.
EXPECT_EQ(label.GetPreferredSize().height(), styled()->height());
EXPECT_EQ(label.GetPreferredSize().width(), styled()->width());
styled()->Layout();
ASSERT_EQ(1, styled()->child_count());
Label* sublabel = static_cast<Label*>(styled()->child_at(0));
EXPECT_EQ(style::CONTEXT_DIALOG_TITLE, sublabel->text_context());
EXPECT_NE(SK_ColorBLACK, label.enabled_color()); // Sanity check,
EXPECT_EQ(label.enabled_color(), sublabel->enabled_color());
}
TEST_F(StyledLabelTest, LineHeight) {
const std::string text("one");
InitStyledLabel(text);
int default_height = styled()->GetHeightForWidth(100);
const std::string newline_text("one\ntwo\nthree");
InitStyledLabel(newline_text);
styled()->SetLineHeight(18);
EXPECT_EQ(18 * 2 + default_height, styled()->GetHeightForWidth(100));
}
TEST_F(StyledLabelTest, HandleEmptyLayout) {
const std::string text("This is a test block of text.");
InitStyledLabel(text);
styled()->Layout();
EXPECT_EQ(0, styled()->child_count());
}
TEST_F(StyledLabelTest, CacheSize) {
const int preferred_height = 50;
const int preferred_width = 100;
const std::string text("This is a test block of text.");
const base::string16 another_text(base::ASCIIToUTF16(
"This is a test block of text. This text is much longer than previous"));
InitStyledLabel(text);
// we should be able to calculate height without any problem
// no controls should be created
int precalculated_height = styled()->GetHeightForWidth(preferred_width);
EXPECT_LT(0, precalculated_height);
EXPECT_EQ(0, styled()->child_count());
styled()->SetBounds(0, 0, preferred_width, preferred_height);
styled()->Layout();
// controls should be created after layout
// height should be the same as precalculated
int real_height = styled()->GetHeightForWidth(styled()->width());
View* first_child_after_layout = styled()->has_children() ?
styled()->child_at(0) : nullptr;
EXPECT_LT(0, styled()->child_count());
EXPECT_LT(0, real_height);
EXPECT_EQ(real_height, precalculated_height);
// another call to Layout should not kill and recreate all controls
styled()->Layout();
View* first_child_after_second_layout = styled()->has_children() ?
styled()->child_at(0) : nullptr;
EXPECT_EQ(first_child_after_layout, first_child_after_second_layout);
// if text is changed:
// layout should be recalculated
// all controls should be recreated
styled()->SetText(another_text);
int updated_height = styled()->GetHeightForWidth(styled()->width());
EXPECT_NE(updated_height, real_height);
View* first_child_after_text_update = styled()->has_children() ?
styled()->child_at(0) : nullptr;
EXPECT_NE(first_child_after_text_update, first_child_after_layout);
}
TEST_F(StyledLabelTest, Border) {
const std::string text("One line");
InitStyledLabel(text);
Label label(ASCIIToUTF16(text));
gfx::Size label_preferred_size = label.GetPreferredSize();
styled()->SetBorder(
CreateEmptyBorder(5 /*top*/, 10 /*left*/, 6 /*bottom*/, 20 /*right*/));
styled()->SetBounds(0, 0, 1000, 0);
styled()->Layout();
EXPECT_EQ(
label_preferred_size.height() + 5 /*top border*/ + 6 /*bottom border*/,
styled()->GetPreferredSize().height());
EXPECT_EQ(
label_preferred_size.width() + 10 /*left border*/ + 20 /*right border*/,
styled()->GetPreferredSize().width());
}
INSTANTIATE_TEST_CASE_P(,
MDStyledLabelTest,
::testing::Values(SecondaryUiMode::MD,
SecondaryUiMode::NON_MD),
&SecondaryUiModeToString);
} // namespace views