// Copyright 2015 Google Inc. All Rights Reserved.
//
// 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 "cobalt/cssom/computed_style.h"

#include <vector>

#include "cobalt/base/polymorphic_downcast.h"
#include "cobalt/cssom/absolute_url_value.h"
#include "cobalt/cssom/calc_value.h"
#include "cobalt/cssom/css_computed_style_data.h"
#include "cobalt/cssom/css_computed_style_declaration.h"
#include "cobalt/cssom/font_style_value.h"
#include "cobalt/cssom/font_weight_value.h"
#include "cobalt/cssom/keyword_value.h"
#include "cobalt/cssom/length_value.h"
#include "cobalt/cssom/percentage_value.h"
#include "cobalt/cssom/property_list_value.h"
#include "cobalt/cssom/rgba_color_value.h"
#include "cobalt/cssom/shadow_value.h"
#include "cobalt/cssom/transform_function_list_value.h"
#include "cobalt/cssom/translate_function.h"
#include "cobalt/cssom/url_value.h"
#include "cobalt/math/size.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace cobalt {
namespace cssom {

scoped_refptr<CSSComputedStyleDeclaration> CreateComputedStyleDeclaration(
    scoped_refptr<CSSComputedStyleData> computed_style) {
  scoped_refptr<CSSComputedStyleDeclaration> computed_style_declaration(
      new CSSComputedStyleDeclaration());
  computed_style_declaration->SetData(computed_style);
  return computed_style_declaration;
}

TEST(PromoteToComputedStyle, UnknownPropertyValueShouldBeEmpty) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());
  scoped_refptr<CSSComputedStyleDeclaration> computed_style_declaration(
      CreateComputedStyleDeclaration(computed_style));

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  EXPECT_EQ(
      computed_style_declaration->GetPropertyValue("cobalt_cobalt_cobalt"), "");
}

TEST(PromoteToComputedStyle, FontWeightShouldBeBoldAsSpecified) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());
  computed_style->set_font_weight(FontWeightValue::GetBoldAka700());

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  EXPECT_EQ(FontWeightValue::GetBoldAka700(),
            computed_style->font_weight().get());
}

TEST(PromoteToComputedStyle, LengthValueInEmShouldBeRelativeToParentFontSize) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());
  computed_style->set_font_size(new LengthValue(1.5f, kFontSizesAkaEmUnit));

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  parent_computed_style->set_font_size(new LengthValue(100, kPixelsUnit));
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  LengthValue* computed_font_size = base::polymorphic_downcast<LengthValue*>(
      computed_style->font_size().get());
  EXPECT_EQ(150, computed_font_size->value());
  EXPECT_EQ(kPixelsUnit, computed_font_size->unit());
}

TEST(PromoteToComputedStyle, LengthValueInRemShouldBeRelativeToRootFontSize) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());
  computed_style->set_font_size(
      new LengthValue(1.5f, kRootElementFontSizesAkaRemUnit));

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  parent_computed_style->set_font_size(new LengthValue(100, kPixelsUnit));
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  scoped_refptr<CSSComputedStyleData> root_computed_style(
      new CSSComputedStyleData());
  root_computed_style->set_font_size(new LengthValue(200, kPixelsUnit));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         root_computed_style, math::Size(), NULL);

  LengthValue* computed_font_size = base::polymorphic_downcast<LengthValue*>(
      computed_style->font_size().get());
  EXPECT_EQ(300, computed_font_size->value());
  EXPECT_EQ(kPixelsUnit, computed_font_size->unit());
}

TEST(PromoteToComputedStyle, LengthValueInVwVhShouldBeRelativeToViewportSize) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());
  computed_style->set_font_size(
      new LengthValue(2.0f, kViewportWidthPercentsAkaVwUnit));
  computed_style->set_line_height(
      new LengthValue(2.0f, kViewportHeightPercentsAkaVhUnit));

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(360, 240), NULL);

  LengthValue* computed_font_size = base::polymorphic_downcast<LengthValue*>(
      computed_style->font_size().get());
  EXPECT_EQ(7.2f, computed_font_size->value());
  EXPECT_EQ(kPixelsUnit, computed_font_size->unit());

  LengthValue* computed_line_height = base::polymorphic_downcast<LengthValue*>(
      computed_style->line_height().get());
  EXPECT_EQ(4.8f, computed_line_height->value());
  EXPECT_EQ(kPixelsUnit, computed_line_height->unit());
}

TEST(PromoteToComputedStyle, LengthValueInPixelsShouldBeLeftAsSpecified) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());
  computed_style->set_font_size(new LengthValue(50, kPixelsUnit));

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  LengthValue* computed_font_size = base::polymorphic_downcast<LengthValue*>(
      computed_style->font_size().get());
  EXPECT_EQ(50, computed_font_size->value());
  EXPECT_EQ(kPixelsUnit, computed_font_size->unit());
}

TEST(PromoteToComputedStyle, NormalLineHeightShouldBeLeftAsSpecified) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());
  computed_style->set_line_height(KeywordValue::GetNormal());

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  EXPECT_EQ(KeywordValue::GetNormal(), computed_style->line_height());
}

TEST(PromoteToComputedStyle, LineHeightInEmShouldBeComputedAfterFontSize) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());
  computed_style->set_font_size(new LengthValue(2, kFontSizesAkaEmUnit));
  computed_style->set_line_height(new LengthValue(1.5f, kFontSizesAkaEmUnit));

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  parent_computed_style->set_font_size(new LengthValue(100, kPixelsUnit));
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  LengthValue* computed_line_height = base::polymorphic_downcast<LengthValue*>(
      computed_style->line_height().get());
  EXPECT_EQ(300, computed_line_height->value());
  EXPECT_EQ(kPixelsUnit, computed_line_height->unit());
}

TEST(PromoteToComputedStyle, TextIndentInEmShouldBeComputedAfterFontSize) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());
  computed_style->set_font_size(new LengthValue(2, kFontSizesAkaEmUnit));
  computed_style->set_text_indent(new LengthValue(1.5f, kFontSizesAkaEmUnit));

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  parent_computed_style->set_font_size(new LengthValue(100, kPixelsUnit));
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  LengthValue* computed_text_indent = base::polymorphic_downcast<LengthValue*>(
      computed_style->text_indent().get());
  EXPECT_EQ(300, computed_text_indent->value());
  EXPECT_EQ(kPixelsUnit, computed_text_indent->unit());
}

TEST(PromoteToComputedStyle, BackgroundImageRelativeURL) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());

  scoped_ptr<PropertyListValue::Builder> background_image_builder(
      new PropertyListValue::Builder());
  background_image_builder->push_back(new URLValue("../test/sample.png"));
  scoped_refptr<PropertyListValue> background_image(
      new PropertyListValue(background_image_builder.Pass()));
  computed_style->set_background_image(background_image);

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  GURLMap property_key_to_base_url_map;
  property_key_to_base_url_map[kBackgroundImageProperty] =
      GURL("file:///computed_style_test/style_sheet.css");

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(),
                         &property_key_to_base_url_map);

  scoped_refptr<PropertyListValue> background_image_list =
      dynamic_cast<PropertyListValue*>(
          computed_style->background_image().get());
  ASSERT_TRUE(background_image_list);
  ASSERT_EQ(1, background_image_list->value().size());

  GURL value = base::polymorphic_downcast<AbsoluteURLValue*>(
                   background_image_list->value()[0].get())
                   ->value();

  EXPECT_EQ("file:///test/sample.png", value.spec());
}

TEST(PromoteToComputedStyle, BackgroundImageNone) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());

  scoped_ptr<PropertyListValue::Builder> background_image_builder(
      new PropertyListValue::Builder());
  background_image_builder->push_back(KeywordValue::GetNone());
  scoped_refptr<PropertyListValue> background_image(
      new PropertyListValue(background_image_builder.Pass()));
  computed_style->set_background_image(background_image);

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  GURLMap property_key_to_base_url_map;
  property_key_to_base_url_map[kBackgroundImageProperty] =
      GURL("file:///computed_style_test/document.html");

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(),
                         &property_key_to_base_url_map);

  scoped_refptr<PropertyListValue> background_image_list =
      dynamic_cast<PropertyListValue*>(
          computed_style->background_image().get());
  ASSERT_TRUE(background_image_list);
  ASSERT_EQ(1, background_image_list->value().size());

  EXPECT_EQ(KeywordValue::GetNone(), background_image_list->value()[0]);
}

TEST(PromoteToComputedStyle, BackgroundPositionWithInitialValue) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());

  scoped_refptr<PropertyValue> background_position(
      GetPropertyInitialValue(kBackgroundPositionProperty));
  computed_style->set_background_position(background_position);

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  scoped_refptr<PropertyListValue> background_position_list =
      dynamic_cast<PropertyListValue*>(
          computed_style->background_position().get());
  ASSERT_TRUE(background_position_list);
  ASSERT_EQ(2, background_position_list->value().size());

  CalcValue* left_value = base::polymorphic_downcast<CalcValue*>(
      background_position_list->value()[0].get());
  const LengthValue* left_length_value = left_value->length_value();
  EXPECT_FLOAT_EQ(0.0f, left_length_value->value());
  EXPECT_EQ(kPixelsUnit, left_length_value->unit());
  EXPECT_FLOAT_EQ(0.0f, left_value->percentage_value()->value());

  CalcValue* right_value = base::polymorphic_downcast<CalcValue*>(
      background_position_list->value()[1].get());
  const LengthValue* right_length_value = right_value->length_value();
  EXPECT_FLOAT_EQ(0.0f, right_length_value->value());
  EXPECT_EQ(kPixelsUnit, right_length_value->unit());
  EXPECT_FLOAT_EQ(0.0f, right_value->percentage_value()->value());
}

TEST(PromoteToComputedStyle, BackgroundPositionOneValueWithoutKeywordValue) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());

  // background-position: 3em;
  scoped_ptr<PropertyListValue::Builder> background_position_builder(
      new PropertyListValue::Builder());
  background_position_builder->push_back(
      new LengthValue(3, kFontSizesAkaEmUnit));
  scoped_refptr<PropertyListValue> background_position(
      new PropertyListValue(background_position_builder.Pass()));
  computed_style->set_background_position(background_position);

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  scoped_refptr<PropertyListValue> background_position_list =
      dynamic_cast<PropertyListValue*>(
          computed_style->background_position().get());
  ASSERT_TRUE(background_position_list);
  ASSERT_EQ(2, background_position_list->value().size());

  CalcValue* left_value = base::polymorphic_downcast<CalcValue*>(
      background_position_list->value()[0].get());
  const LengthValue* left_length_value = left_value->length_value();
  EXPECT_FLOAT_EQ(48.0f, left_length_value->value());
  EXPECT_EQ(kPixelsUnit, left_length_value->unit());
  EXPECT_FLOAT_EQ(0.0f, left_value->percentage_value()->value());

  CalcValue* right_value = base::polymorphic_downcast<CalcValue*>(
      background_position_list->value()[1].get());
  const LengthValue* right_length_value = right_value->length_value();
  EXPECT_FLOAT_EQ(0.0f, right_length_value->value());
  EXPECT_EQ(kPixelsUnit, right_length_value->unit());
  EXPECT_FLOAT_EQ(0.5f, right_value->percentage_value()->value());
}

TEST(PromoteToComputedStyle, BackgroundPositionOneKeywordValue) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());

  // background-position: bottom;
  scoped_ptr<PropertyListValue::Builder> background_position_builder(
      new PropertyListValue::Builder());
  background_position_builder->push_back(KeywordValue::GetBottom());
  scoped_refptr<PropertyListValue> background_position(
      new PropertyListValue(background_position_builder.Pass()));
  computed_style->set_background_position(background_position);

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  scoped_refptr<PropertyListValue> background_position_list =
      dynamic_cast<PropertyListValue*>(
          computed_style->background_position().get());
  ASSERT_TRUE(background_position_list);
  ASSERT_EQ(2, background_position_list->value().size());

  CalcValue* left_value = base::polymorphic_downcast<CalcValue*>(
      background_position_list->value()[0].get());
  const LengthValue* left_length_value = left_value->length_value();
  EXPECT_FLOAT_EQ(0.0f, left_length_value->value());
  EXPECT_EQ(kPixelsUnit, left_length_value->unit());
  EXPECT_FLOAT_EQ(0.5f, left_value->percentage_value()->value());

  CalcValue* right_value = base::polymorphic_downcast<CalcValue*>(
      background_position_list->value()[1].get());
  const LengthValue* right_length_value = right_value->length_value();
  EXPECT_FLOAT_EQ(0.0f, right_length_value->value());
  EXPECT_EQ(kPixelsUnit, right_length_value->unit());
  EXPECT_FLOAT_EQ(1.0f, right_value->percentage_value()->value());
}

TEST(PromoteToComputedStyle, BackgroundPositionTwoValuesWithoutKeywordValue) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());

  // background-position: 3em 40px;
  scoped_ptr<PropertyListValue::Builder> background_position_builder(
      new PropertyListValue::Builder());
  background_position_builder->push_back(
      new LengthValue(3, kFontSizesAkaEmUnit));
  background_position_builder->push_back(new LengthValue(40, kPixelsUnit));
  scoped_refptr<PropertyListValue> background_position(
      new PropertyListValue(background_position_builder.Pass()));
  computed_style->set_background_position(background_position);

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  scoped_refptr<PropertyListValue> background_position_list =
      dynamic_cast<PropertyListValue*>(
          computed_style->background_position().get());
  ASSERT_TRUE(background_position_list);
  ASSERT_EQ(2, background_position_list->value().size());

  CalcValue* left_value = base::polymorphic_downcast<CalcValue*>(
      background_position_list->value()[0].get());
  const LengthValue* left_length_value = left_value->length_value();
  EXPECT_FLOAT_EQ(48.0f, left_length_value->value());
  EXPECT_EQ(kPixelsUnit, left_length_value->unit());
  EXPECT_FLOAT_EQ(0.0f, left_value->percentage_value()->value());

  CalcValue* right_value = base::polymorphic_downcast<CalcValue*>(
      background_position_list->value()[1].get());
  const LengthValue* right_length_value = right_value->length_value();
  EXPECT_FLOAT_EQ(40.0f, right_length_value->value());
  EXPECT_EQ(kPixelsUnit, right_length_value->unit());
  EXPECT_FLOAT_EQ(0.0f, right_value->percentage_value()->value());
}

TEST(PromoteToComputedStyle, BackgroundPositionTwoValuesWithOneKeyword) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());

  // background-position: 67% center;
  scoped_ptr<PropertyListValue::Builder> background_position_builder(
      new PropertyListValue::Builder());
  background_position_builder->push_back(new PercentageValue(0.67f));
  background_position_builder->push_back(KeywordValue::GetCenter());
  scoped_refptr<PropertyListValue> background_position(
      new PropertyListValue(background_position_builder.Pass()));
  computed_style->set_background_position(background_position);

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  scoped_refptr<PropertyListValue> background_position_list =
      dynamic_cast<PropertyListValue*>(
          computed_style->background_position().get());
  ASSERT_TRUE(background_position_list);
  ASSERT_EQ(2, background_position_list->value().size());

  CalcValue* left_value = base::polymorphic_downcast<CalcValue*>(
      background_position_list->value()[0].get());
  const LengthValue* left_length_value = left_value->length_value();
  EXPECT_FLOAT_EQ(0.0f, left_length_value->value());
  EXPECT_EQ(kPixelsUnit, left_length_value->unit());
  EXPECT_FLOAT_EQ(0.67f, left_value->percentage_value()->value());

  CalcValue* right_value = base::polymorphic_downcast<CalcValue*>(
      background_position_list->value()[1].get());
  const LengthValue* right_length_value = right_value->length_value();
  EXPECT_FLOAT_EQ(0.0f, right_length_value->value());
  EXPECT_EQ(kPixelsUnit, right_length_value->unit());
  EXPECT_FLOAT_EQ(0.50f, right_value->percentage_value()->value());
}

TEST(PromoteToComputedStyle, BackgroundPositionTwoValuesWithTwoKeywords) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());

  // background-position: right bottom;
  scoped_ptr<PropertyListValue::Builder> background_position_builder(
      new PropertyListValue::Builder());
  background_position_builder->push_back(KeywordValue::GetRight());
  background_position_builder->push_back(KeywordValue::GetBottom());
  scoped_refptr<PropertyListValue> background_position(
      new PropertyListValue(background_position_builder.Pass()));
  computed_style->set_background_position(background_position);

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  scoped_refptr<PropertyListValue> background_position_list =
      dynamic_cast<PropertyListValue*>(
          computed_style->background_position().get());
  ASSERT_TRUE(background_position_list);
  ASSERT_EQ(2, background_position_list->value().size());

  CalcValue* left_value = base::polymorphic_downcast<CalcValue*>(
      background_position_list->value()[0].get());
  const LengthValue* left_length_value = left_value->length_value();
  EXPECT_FLOAT_EQ(0.0f, left_length_value->value());
  EXPECT_EQ(kPixelsUnit, left_length_value->unit());
  EXPECT_FLOAT_EQ(1.0f, left_value->percentage_value()->value());

  CalcValue* right_value = base::polymorphic_downcast<CalcValue*>(
      background_position_list->value()[1].get());
  const LengthValue* right_length_value = right_value->length_value();
  EXPECT_FLOAT_EQ(0.0f, right_length_value->value());
  EXPECT_EQ(kPixelsUnit, right_length_value->unit());
  EXPECT_FLOAT_EQ(1.0f, right_value->percentage_value()->value());
}

TEST(PromoteToComputedStyle, BackgroundPositionTwoValuesWithTwoCenterKeywords) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());

  // background-position: center center;
  scoped_ptr<PropertyListValue::Builder> background_position_builder(
      new PropertyListValue::Builder());
  background_position_builder->push_back(KeywordValue::GetCenter());
  background_position_builder->push_back(KeywordValue::GetCenter());
  scoped_refptr<PropertyListValue> background_position(
      new PropertyListValue(background_position_builder.Pass()));
  computed_style->set_background_position(background_position);

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  scoped_refptr<PropertyListValue> background_position_list =
      dynamic_cast<PropertyListValue*>(
          computed_style->background_position().get());
  ASSERT_TRUE(background_position_list);
  ASSERT_EQ(2, background_position_list->value().size());

  CalcValue* left_value = base::polymorphic_downcast<CalcValue*>(
      background_position_list->value()[0].get());
  const LengthValue* left_length_value = left_value->length_value();
  EXPECT_FLOAT_EQ(0.0f, left_length_value->value());
  EXPECT_EQ(kPixelsUnit, left_length_value->unit());
  EXPECT_FLOAT_EQ(0.5f, left_value->percentage_value()->value());

  CalcValue* right_value = base::polymorphic_downcast<CalcValue*>(
      background_position_list->value()[1].get());
  const LengthValue* right_length_value = right_value->length_value();
  EXPECT_FLOAT_EQ(0.0f, right_length_value->value());
  EXPECT_EQ(kPixelsUnit, right_length_value->unit());
  EXPECT_FLOAT_EQ(0.5f, right_value->percentage_value()->value());
}

TEST(PromoteToComputedStyle, BackgroundPositionWithThreeValues) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());

  // background-position: top 80% left;
  scoped_ptr<PropertyListValue::Builder> background_position_builder(
      new PropertyListValue::Builder());
  background_position_builder->push_back(KeywordValue::GetTop());
  background_position_builder->push_back(new PercentageValue(0.8f));
  background_position_builder->push_back(KeywordValue::GetLeft());
  scoped_refptr<PropertyListValue> background_position(
      new PropertyListValue(background_position_builder.Pass()));
  computed_style->set_background_position(background_position);

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  scoped_refptr<PropertyListValue> background_position_list =
      dynamic_cast<PropertyListValue*>(
          computed_style->background_position().get());
  ASSERT_TRUE(background_position_list);
  ASSERT_EQ(2, background_position_list->value().size());

  CalcValue* left_value = base::polymorphic_downcast<CalcValue*>(
      background_position_list->value()[0].get());
  const LengthValue* left_length_value = left_value->length_value();
  EXPECT_FLOAT_EQ(0.0f, left_length_value->value());
  EXPECT_EQ(kPixelsUnit, left_length_value->unit());
  EXPECT_FLOAT_EQ(0.0f, left_value->percentage_value()->value());

  CalcValue* right_value = base::polymorphic_downcast<CalcValue*>(
      background_position_list->value()[1].get());
  const LengthValue* right_length_value = right_value->length_value();
  EXPECT_FLOAT_EQ(0.0f, right_length_value->value());
  EXPECT_EQ(kPixelsUnit, right_length_value->unit());
  EXPECT_FLOAT_EQ(0.8f, right_value->percentage_value()->value());
}

TEST(PromoteToComputedStyle, BackgroundPositionWithThreeValuesHaveCenter) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());

  // background-position: center left 80%;
  scoped_ptr<PropertyListValue::Builder> background_position_builder(
      new PropertyListValue::Builder());
  background_position_builder->push_back(KeywordValue::GetCenter());
  background_position_builder->push_back(KeywordValue::GetLeft());
  background_position_builder->push_back(new PercentageValue(0.8f));
  scoped_refptr<PropertyListValue> background_position(
      new PropertyListValue(background_position_builder.Pass()));
  computed_style->set_background_position(background_position);

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  scoped_refptr<PropertyListValue> background_position_list =
      dynamic_cast<PropertyListValue*>(
          computed_style->background_position().get());
  ASSERT_TRUE(background_position_list);
  ASSERT_EQ(2, background_position_list->value().size());

  CalcValue* left_value = base::polymorphic_downcast<CalcValue*>(
      background_position_list->value()[0].get());
  const LengthValue* left_length_value = left_value->length_value();
  EXPECT_FLOAT_EQ(0.0f, left_length_value->value());
  EXPECT_EQ(kPixelsUnit, left_length_value->unit());
  EXPECT_FLOAT_EQ(0.8f, left_value->percentage_value()->value());

  CalcValue* right_value = base::polymorphic_downcast<CalcValue*>(
      background_position_list->value()[1].get());
  const LengthValue* right_length_value = right_value->length_value();
  EXPECT_FLOAT_EQ(0.0f, right_length_value->value());
  EXPECT_EQ(kPixelsUnit, right_length_value->unit());
  EXPECT_FLOAT_EQ(0.5f, right_value->percentage_value()->value());
}

TEST(PromoteToComputedStyle, BackgroundPositionWithFourValues) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());

  // background-position: bottom 80% right 50px;
  scoped_ptr<PropertyListValue::Builder> background_position_builder(
      new PropertyListValue::Builder());
  background_position_builder->push_back(KeywordValue::GetBottom());
  background_position_builder->push_back(new PercentageValue(0.8f));
  background_position_builder->push_back(KeywordValue::GetRight());
  background_position_builder->push_back(new LengthValue(50, kPixelsUnit));
  scoped_refptr<PropertyListValue> background_position(
      new PropertyListValue(background_position_builder.Pass()));
  computed_style->set_background_position(background_position);

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  scoped_refptr<PropertyListValue> background_position_list =
      dynamic_cast<PropertyListValue*>(
          computed_style->background_position().get());
  ASSERT_TRUE(background_position_list);
  ASSERT_EQ(2, background_position_list->value().size());

  CalcValue* left_value = base::polymorphic_downcast<CalcValue*>(
      background_position_list->value()[0].get());
  const LengthValue* left_length_value = left_value->length_value();
  EXPECT_FLOAT_EQ(-50.0f, left_length_value->value());
  EXPECT_EQ(kPixelsUnit, left_length_value->unit());
  EXPECT_FLOAT_EQ(1.0f, left_value->percentage_value()->value());

  CalcValue* right_value = base::polymorphic_downcast<CalcValue*>(
      background_position_list->value()[1].get());
  const LengthValue* right_length_value = right_value->length_value();
  EXPECT_FLOAT_EQ(0.0f, right_length_value->value());
  EXPECT_EQ(kPixelsUnit, right_length_value->unit());
  EXPECT_FLOAT_EQ(0.2f, right_value->percentage_value()->value());
}

TEST(PromoteToComputedStyle, BackgroundSizeEmToPixel) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());

  scoped_ptr<PropertyListValue::Builder> background_size_builder(
      new PropertyListValue::Builder());
  background_size_builder->push_back(new LengthValue(3, kFontSizesAkaEmUnit));
  background_size_builder->push_back(new LengthValue(40, kPixelsUnit));
  scoped_refptr<PropertyListValue> background_size(
      new PropertyListValue(background_size_builder.Pass()));
  computed_style->set_background_size(background_size);

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  scoped_refptr<PropertyListValue> background_size_list =
      dynamic_cast<PropertyListValue*>(computed_style->background_size().get());
  ASSERT_TRUE(background_size_list);
  ASSERT_EQ(2, background_size_list->value().size());

  LengthValue* first_value = base::polymorphic_downcast<LengthValue*>(
      background_size_list->value()[0].get());
  EXPECT_FLOAT_EQ(48.0f, first_value->value());
  EXPECT_EQ(kPixelsUnit, first_value->unit());

  LengthValue* second_value = base::polymorphic_downcast<LengthValue*>(
      background_size_list->value()[1].get());
  EXPECT_FLOAT_EQ(40.0f, second_value->value());
  EXPECT_EQ(kPixelsUnit, second_value->unit());
}

TEST(PromoteToComputedStyle, BackgroundSizeKeywordNotChanged) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());
  computed_style->set_background_size(KeywordValue::GetContain());

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  EXPECT_EQ(KeywordValue::GetContain(), computed_style->background_size());
}

TEST(PromoteToComputedStyle, BorderRadiusEmToPixel) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());
  computed_style->set_border_radius(new LengthValue(3, kFontSizesAkaEmUnit));

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  LengthValue* border_radius = base::polymorphic_downcast<LengthValue*>(
      computed_style->border_radius().get());
  EXPECT_FLOAT_EQ(48.0f, border_radius->value());
  EXPECT_EQ(kPixelsUnit, border_radius->unit());
}

TEST(PromoteToComputedStyle, BorderColorWithInitialValue) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());
  computed_style->set_border_bottom_color(KeywordValue::GetInitial());
  computed_style->set_color(RGBAColorValue::GetAqua());

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  scoped_refptr<RGBAColorValue> border_bottom_color =
      dynamic_cast<RGBAColorValue*>(
          computed_style->border_bottom_color().get());
  ASSERT_TRUE(border_bottom_color);
  EXPECT_EQ(0x00FFFFFF, border_bottom_color->value());
}

TEST(PromoteToComputedStyle, BorderColorWithCurrentColorValue) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());
  computed_style->set_border_left_color(KeywordValue::GetCurrentColor());
  computed_style->set_color(RGBAColorValue::GetAqua());

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  scoped_refptr<RGBAColorValue> border_color =
      dynamic_cast<RGBAColorValue*>(computed_style->border_left_color().get());
  ASSERT_TRUE(border_color);
  EXPECT_EQ(0x00FFFFFF, border_color->value());
}

TEST(PromoteToComputedStyle, BorderWidthWithBorderStyleNone) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());
  computed_style->set_border_top_style(KeywordValue::GetNone());
  computed_style->set_border_top_width(new LengthValue(2, kFontSizesAkaEmUnit));

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  scoped_refptr<LengthValue> border_top_width =
      dynamic_cast<LengthValue*>(computed_style->border_top_width().get());
  ASSERT_TRUE(border_top_width);
  EXPECT_EQ(0, border_top_width->value());
  EXPECT_EQ(kPixelsUnit, border_top_width->unit());
}

TEST(PromoteToComputedStyle, BorderWidthInEmShouldBeComputedAfterFontSize) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());
  computed_style->set_border_left_style(KeywordValue::GetSolid());
  computed_style->set_font_size(new LengthValue(2, kFontSizesAkaEmUnit));
  computed_style->set_border_left_width(
      new LengthValue(2, kFontSizesAkaEmUnit));

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  parent_computed_style->set_font_size(new LengthValue(100, kPixelsUnit));
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  scoped_refptr<LengthValue> border_left_width =
      dynamic_cast<LengthValue*>(computed_style->border_left_width().get());
  EXPECT_EQ(400, border_left_width->value());
  EXPECT_EQ(kPixelsUnit, border_left_width->unit());
}

TEST(PromoteToComputedStyle, BoxShadowWithEmLengthAndColor) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());

  scoped_ptr<PropertyListValue::Builder> builder(
      new PropertyListValue::Builder());

  std::vector<scoped_refptr<LengthValue> > lengths;
  lengths.push_back(new LengthValue(100, kPixelsUnit));
  lengths.push_back(new LengthValue(10, kFontSizesAkaEmUnit));

  scoped_refptr<ShadowValue> shadow(
      new ShadowValue(lengths, RGBAColorValue::GetAqua(), false));
  builder->push_back(shadow);

  computed_style->set_box_shadow(new PropertyListValue(builder.Pass()));

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  parent_computed_style->set_font_size(new LengthValue(50, kPixelsUnit));
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  scoped_refptr<PropertyListValue> box_shadow_list =
      dynamic_cast<PropertyListValue*>(computed_style->box_shadow().get());
  DCHECK_EQ(1u, box_shadow_list->value().size());

  scoped_refptr<ShadowValue> box_shadow =
      dynamic_cast<ShadowValue*>(box_shadow_list->value()[0].get());

  EXPECT_EQ(100.0f, box_shadow->offset_x()->value());
  EXPECT_EQ(kPixelsUnit, box_shadow->offset_x()->unit());

  EXPECT_EQ(500.0f, box_shadow->offset_y()->value());
  EXPECT_EQ(kPixelsUnit, box_shadow->offset_y()->unit());

  scoped_refptr<RGBAColorValue> color =
      dynamic_cast<RGBAColorValue*>(box_shadow->color().get());
  ASSERT_TRUE(color);
  EXPECT_EQ(0x00FFFFFF, color->value());

  EXPECT_FALSE(box_shadow->has_inset());
}

TEST(PromoteToComputedStyle, BoxShadowWithInset) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());

  scoped_ptr<PropertyListValue::Builder> builder(
      new PropertyListValue::Builder());

  std::vector<scoped_refptr<LengthValue> > lengths;
  lengths.push_back(new LengthValue(100, kPixelsUnit));
  lengths.push_back(new LengthValue(30, kPixelsUnit));

  scoped_refptr<ShadowValue> shadow(
      new ShadowValue(lengths, RGBAColorValue::GetAqua(), true /*has_inset*/));
  builder->push_back(shadow);

  computed_style->set_box_shadow(new PropertyListValue(builder.Pass()));

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  scoped_refptr<PropertyListValue> box_shadow_list =
      dynamic_cast<PropertyListValue*>(computed_style->box_shadow().get());
  DCHECK_EQ(1u, box_shadow_list->value().size());

  scoped_refptr<ShadowValue> box_shadow =
      dynamic_cast<ShadowValue*>(box_shadow_list->value()[0].get());

  EXPECT_EQ(100.0f, box_shadow->offset_x()->value());
  EXPECT_EQ(kPixelsUnit, box_shadow->offset_x()->unit());

  EXPECT_EQ(30.0f, box_shadow->offset_y()->value());
  EXPECT_EQ(kPixelsUnit, box_shadow->offset_y()->unit());

  scoped_refptr<RGBAColorValue> color =
      dynamic_cast<RGBAColorValue*>(box_shadow->color().get());
  ASSERT_TRUE(color);
  EXPECT_EQ(0x00FFFFFF, color->value());

  EXPECT_TRUE(box_shadow->has_inset());
}

TEST(PromoteToComputedStyle, BoxShadowWithoutColor) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());

  scoped_ptr<PropertyListValue::Builder> builder(
      new PropertyListValue::Builder());

  std::vector<scoped_refptr<LengthValue> > lengths;
  lengths.push_back(new LengthValue(100, kPixelsUnit));
  lengths.push_back(new LengthValue(200, kPixelsUnit));

  scoped_refptr<ShadowValue> shadow(new ShadowValue(lengths, NULL, false));
  builder->push_back(shadow);

  computed_style->set_box_shadow(new PropertyListValue(builder.Pass()));

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  parent_computed_style->set_color(new RGBAColorValue(0x0047abff));
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  scoped_refptr<PropertyListValue> box_shadow_list =
      dynamic_cast<PropertyListValue*>(computed_style->box_shadow().get());
  DCHECK_EQ(1u, box_shadow_list->value().size());

  scoped_refptr<ShadowValue> box_shadow =
      dynamic_cast<ShadowValue*>(box_shadow_list->value()[0].get());

  EXPECT_EQ(100.0f, box_shadow->offset_x()->value());
  EXPECT_EQ(kPixelsUnit, box_shadow->offset_x()->unit());

  EXPECT_EQ(200.0f, box_shadow->offset_y()->value());
  EXPECT_EQ(kPixelsUnit, box_shadow->offset_y()->unit());

  ASSERT_TRUE(box_shadow->color());
  EXPECT_EQ(0x0047abff, box_shadow->color()->value());

  EXPECT_FALSE(box_shadow->has_inset());
}

TEST(PromoteToComputedStyle, BoxShadowWithShadowList) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());

  scoped_ptr<PropertyListValue::Builder> builder(
      new PropertyListValue::Builder());

  std::vector<scoped_refptr<LengthValue> > lengths_1;
  lengths_1.push_back(new LengthValue(100, kPixelsUnit));
  lengths_1.push_back(new LengthValue(30, kPixelsUnit));
  lengths_1.push_back(new LengthValue(3, kFontSizesAkaEmUnit));
  scoped_refptr<ShadowValue> shadow_1(
      new ShadowValue(lengths_1, NULL, true /*has_inset*/));
  builder->push_back(shadow_1);

  std::vector<scoped_refptr<LengthValue> > lengths_2;
  lengths_2.push_back(new LengthValue(2, kFontSizesAkaEmUnit));
  lengths_2.push_back(new LengthValue(40, kPixelsUnit));
  scoped_refptr<ShadowValue> shadow_2(new ShadowValue(
      lengths_2, RGBAColorValue::GetNavy(), false /*has_inset*/));

  builder->push_back(shadow_2);

  computed_style->set_box_shadow(new PropertyListValue(builder.Pass()));

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  parent_computed_style->set_font_size(new LengthValue(50, kPixelsUnit));
  parent_computed_style->set_color(new RGBAColorValue(0x0047ABFF));
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  scoped_refptr<PropertyListValue> box_shadow_list =
      dynamic_cast<PropertyListValue*>(computed_style->box_shadow().get());
  DCHECK_EQ(2u, box_shadow_list->value().size());

  float expected_length_value[2][3] = {
      {100.0f, 30.0f, 150.0f}, {100.0f, 40.0f, 0.0f},
  };
  float expected_color[2] = {0x0047ABFF, 0x000080FF};
  bool expected_has_inset[2] = {true, false};

  for (size_t i = 0; i < box_shadow_list->value().size(); ++i) {
    scoped_refptr<ShadowValue> box_shadow =
        dynamic_cast<ShadowValue*>(box_shadow_list->value()[i].get());

    if (i == 0) {
      EXPECT_TRUE(box_shadow->offset_x());
      EXPECT_TRUE(box_shadow->offset_y());
      EXPECT_TRUE(box_shadow->blur_radius());
      EXPECT_FALSE(box_shadow->spread_radius());
    } else {
      EXPECT_TRUE(box_shadow->offset_x());
      EXPECT_TRUE(box_shadow->offset_y());
      EXPECT_FALSE(box_shadow->blur_radius());
      EXPECT_FALSE(box_shadow->spread_radius());
    }

    for (int j = 0; j < ShadowValue::kMaxLengths; ++j) {
      scoped_refptr<LengthValue> length = box_shadow->lengths()[j];
      if (length) {
        EXPECT_EQ(expected_length_value[i][j], length->value());
        EXPECT_EQ(kPixelsUnit, length->unit());
      }
    }

    ASSERT_TRUE(box_shadow->color());
    EXPECT_EQ(expected_color[i], box_shadow->color()->value());

    EXPECT_EQ(expected_has_inset[i], box_shadow->has_inset());
  }
}

TEST(PromoteToComputedStyle, BoxShadowWithNone) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());

  computed_style->set_box_shadow(KeywordValue::GetNone());

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  EXPECT_EQ(KeywordValue::GetNone(), computed_style->box_shadow());
}

TEST(PromoteToComputedStyle, OutlineColorWithCurrentColorValue) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());
  computed_style->set_outline_color(KeywordValue::GetCurrentColor());
  computed_style->set_color(RGBAColorValue::GetAqua());

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  scoped_refptr<RGBAColorValue> outline_color =
      dynamic_cast<RGBAColorValue*>(computed_style->outline_color().get());
  ASSERT_TRUE(outline_color);
  EXPECT_EQ(0x00FFFFFF, outline_color->value());
}

TEST(PromoteToComputedStyle, OutlineWidthWithOutlineStyleNone) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());
  computed_style->set_outline_style(KeywordValue::GetNone());
  computed_style->set_outline_width(new LengthValue(2, kFontSizesAkaEmUnit));

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  scoped_refptr<LengthValue> outline_width =
      dynamic_cast<LengthValue*>(computed_style->outline_width().get());
  ASSERT_TRUE(outline_width);
  EXPECT_EQ(0, outline_width->value());
  EXPECT_EQ(kPixelsUnit, outline_width->unit());
}

TEST(PromoteToComputedStyle, OutlineWidthInEmShouldBeComputedAfterFontSize) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());
  computed_style->set_outline_style(KeywordValue::GetSolid());
  computed_style->set_font_size(new LengthValue(2, kFontSizesAkaEmUnit));
  computed_style->set_outline_width(new LengthValue(2, kFontSizesAkaEmUnit));

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  parent_computed_style->set_font_size(new LengthValue(100, kPixelsUnit));
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  scoped_refptr<LengthValue> outline_width =
      dynamic_cast<LengthValue*>(computed_style->outline_width().get());
  EXPECT_EQ(400, outline_width->value());
  EXPECT_EQ(kPixelsUnit, outline_width->unit());
}

TEST(PromoteToComputedStyle, TextDecorationWithCurrentColor) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());
  computed_style->set_text_decoration_color(KeywordValue::GetCurrentColor());
  computed_style->set_color(RGBAColorValue::GetAqua());

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  scoped_refptr<RGBAColorValue> text_decoration_color =
      dynamic_cast<RGBAColorValue*>(
          computed_style->text_decoration_color().get());
  ASSERT_TRUE(text_decoration_color);
  EXPECT_EQ(0x00FFFFFF, text_decoration_color->value());
}

TEST(PromoteToComputedStyle, TextShadowWithEmLengthAndColor) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());

  scoped_ptr<PropertyListValue::Builder> builder(
      new PropertyListValue::Builder());

  std::vector<scoped_refptr<LengthValue> > lengths;
  lengths.push_back(new LengthValue(100, kPixelsUnit));
  lengths.push_back(new LengthValue(10, kFontSizesAkaEmUnit));

  scoped_refptr<ShadowValue> shadow(
      new ShadowValue(lengths, RGBAColorValue::GetAqua(), false));
  builder->push_back(shadow);

  computed_style->set_text_shadow(new PropertyListValue(builder.Pass()));

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  parent_computed_style->set_font_size(new LengthValue(50, kPixelsUnit));
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  scoped_refptr<PropertyListValue> text_shadow_list =
      dynamic_cast<PropertyListValue*>(computed_style->text_shadow().get());
  DCHECK_EQ(1u, text_shadow_list->value().size());

  scoped_refptr<ShadowValue> text_shadow =
      dynamic_cast<ShadowValue*>(text_shadow_list->value()[0].get());

  EXPECT_EQ(100.0f, text_shadow->offset_x()->value());
  EXPECT_EQ(kPixelsUnit, text_shadow->offset_x()->unit());

  EXPECT_EQ(500.0f, text_shadow->offset_y()->value());
  EXPECT_EQ(kPixelsUnit, text_shadow->offset_y()->unit());

  ASSERT_TRUE(text_shadow->color());
  EXPECT_EQ(0x00FFFFFF, text_shadow->color()->value());

  EXPECT_FALSE(text_shadow->has_inset());
}

TEST(PromoteToComputedStyle, TextShadowWithoutColor) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());

  scoped_ptr<PropertyListValue::Builder> builder(
      new PropertyListValue::Builder());

  std::vector<scoped_refptr<LengthValue> > lengths;
  lengths.push_back(new LengthValue(100, kPixelsUnit));
  lengths.push_back(new LengthValue(200, kPixelsUnit));

  scoped_refptr<ShadowValue> shadow(new ShadowValue(lengths, NULL, false));
  builder->push_back(shadow);

  computed_style->set_text_shadow(new PropertyListValue(builder.Pass()));

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  parent_computed_style->set_color(new RGBAColorValue(0x0047abff));
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  scoped_refptr<PropertyListValue> text_shadow_list =
      dynamic_cast<PropertyListValue*>(computed_style->text_shadow().get());
  DCHECK_EQ(1u, text_shadow_list->value().size());

  scoped_refptr<ShadowValue> text_shadow =
      dynamic_cast<ShadowValue*>(text_shadow_list->value()[0].get());

  EXPECT_EQ(100.0f, text_shadow->offset_x()->value());
  EXPECT_EQ(kPixelsUnit, text_shadow->offset_x()->unit());

  EXPECT_EQ(200.0f, text_shadow->offset_y()->value());
  EXPECT_EQ(kPixelsUnit, text_shadow->offset_y()->unit());

  ASSERT_TRUE(text_shadow->color());
  EXPECT_EQ(0x0047abff, text_shadow->color()->value());

  EXPECT_FALSE(text_shadow->has_inset());
}

TEST(PromoteToComputedStyle, TextShadowWithShadowList) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());

  scoped_ptr<PropertyListValue::Builder> builder(
      new PropertyListValue::Builder());

  std::vector<scoped_refptr<LengthValue> > lengths_1;
  lengths_1.push_back(new LengthValue(100, kPixelsUnit));
  lengths_1.push_back(new LengthValue(30, kPixelsUnit));
  lengths_1.push_back(new LengthValue(3, kFontSizesAkaEmUnit));
  scoped_refptr<ShadowValue> shadow_1(new ShadowValue(lengths_1, NULL, false));
  builder->push_back(shadow_1);

  std::vector<scoped_refptr<LengthValue> > lengths_2;
  lengths_2.push_back(new LengthValue(2, kFontSizesAkaEmUnit));
  lengths_2.push_back(new LengthValue(40, kPixelsUnit));
  scoped_refptr<ShadowValue> shadow_2(
      new ShadowValue(lengths_2, RGBAColorValue::GetNavy(), false));

  builder->push_back(shadow_2);

  computed_style->set_text_shadow(new PropertyListValue(builder.Pass()));

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  parent_computed_style->set_font_size(new LengthValue(50, kPixelsUnit));
  parent_computed_style->set_color(new RGBAColorValue(0x0047ABFF));
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  scoped_refptr<PropertyListValue> text_shadow_list =
      dynamic_cast<PropertyListValue*>(computed_style->text_shadow().get());
  DCHECK_EQ(2u, text_shadow_list->value().size());

  float expected_length_value[2][3] = {
      {100.0f, 30.0f, 150.0f}, {100.0f, 40.0f, 0.0f},
  };
  float expected_color[2] = {0x0047ABFF, 0x000080FF};

  for (size_t i = 0; i < text_shadow_list->value().size(); ++i) {
    scoped_refptr<ShadowValue> text_shadow =
        dynamic_cast<ShadowValue*>(text_shadow_list->value()[i].get());

    if (i == 0) {
      EXPECT_TRUE(text_shadow->offset_x());
      EXPECT_TRUE(text_shadow->offset_y());
      EXPECT_TRUE(text_shadow->blur_radius());
      EXPECT_FALSE(text_shadow->spread_radius());
    } else {
      EXPECT_TRUE(text_shadow->offset_x());
      EXPECT_TRUE(text_shadow->offset_y());
      EXPECT_FALSE(text_shadow->blur_radius());
      EXPECT_FALSE(text_shadow->spread_radius());
    }

    for (size_t j = 0; j < ShadowValue::kMaxLengths; ++j) {
      scoped_refptr<LengthValue> length = text_shadow->lengths()[j];
      if (length) {
        EXPECT_EQ(expected_length_value[i][j], length->value());
        EXPECT_EQ(kPixelsUnit, length->unit());
      }
    }

    ASSERT_TRUE(text_shadow->color());
    EXPECT_EQ(expected_color[i], text_shadow->color()->value());

    EXPECT_FALSE(text_shadow->has_inset());
  }
}

TEST(PromoteToComputedStyle, TextShadowWithNone) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());

  computed_style->set_text_shadow(KeywordValue::GetNone());

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  EXPECT_EQ(KeywordValue::GetNone(), computed_style->text_shadow());
}

TEST(PromoteToComputedStyle, HeightPercentageInUnspecifiedHeightBlockIsAuto) {
  // If the height is specified as a percentage and the height of the containing
  // block is not specified explicitly, and this element is not absolutely
  // positioned, the value computes to 'auto'.
  //   https://www.w3.org/TR/CSS2/visudet.html#the-height-property
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());
  computed_style->set_height(new PercentageValue(0.50f));

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  EXPECT_EQ(KeywordValue::GetAuto(), parent_computed_style->height());
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  EXPECT_EQ(KeywordValue::GetAuto(), computed_style->height());
}

TEST(PromoteToComputedStyle,
     MaxHeightPercentageInUnspecifiedHeightBlockIsNone) {
  // If the max-height is specified as a percentage and the height of the
  // containing block is not specified explicitly, and this element is not
  // absolutely positioned, the percentage value is treated as '0'.
  //   https://www.w3.org/TR/CSS2/visudet.html#propdef-max-height
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());
  computed_style->set_max_height(new PercentageValue(0.50f));

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  EXPECT_EQ(KeywordValue::GetAuto(), parent_computed_style->height());
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  EXPECT_EQ(KeywordValue::GetNone(), computed_style->max_height());
}

TEST(PromoteToComputedStyle,
     MinHeightPercentageInUnspecifiedHeightBlockIsZero) {
  // If the min-height is specified as a percentage and the height of the
  // containing block is not specified explicitly, and this element is not
  // absolutely positioned, the percentage value is treated as 'none'.
  //   https://www.w3.org/TR/CSS2/visudet.html#propdef-min-height
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());
  computed_style->set_min_height(new PercentageValue(0.50f));

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  EXPECT_EQ(KeywordValue::GetAuto(), parent_computed_style->height());
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  LengthValue* computed_min_height = base::polymorphic_downcast<LengthValue*>(
      computed_style->min_height().get());
  EXPECT_EQ(0, computed_min_height->value());
  EXPECT_EQ(kPixelsUnit, computed_min_height->unit());
}

TEST(PromoteToComputedStyle, MaxWidthPercentageInNegativeWidthBlockIsZero) {
  // If the max-width is specified as a percentage and the containing block's
  // width is negative, the used value is zero.
  //  https://www.w3.org/TR/CSS2/visudet.html#propdef-max-width
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());
  computed_style->set_max_width(new PercentageValue(0.50f));

  scoped_refptr<CSSComputedStyleData> grandparent_computed_style(
      new CSSComputedStyleData());
  scoped_refptr<CSSComputedStyleDeclaration>
      grandparent_computed_style_declaration(
          CreateComputedStyleDeclaration(grandparent_computed_style));

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  parent_computed_style->set_width(new LengthValue(-16, kPixelsUnit));
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(parent_computed_style,
                         grandparent_computed_style_declaration,
                         grandparent_computed_style, math::Size(), NULL);
  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         grandparent_computed_style, math::Size(), NULL);

  LengthValue* computed_max_width = base::polymorphic_downcast<LengthValue*>(
      computed_style->max_width().get());
  EXPECT_EQ(0, computed_max_width->value());
  EXPECT_EQ(kPixelsUnit, computed_max_width->unit());
}

TEST(PromoteToComputedStyle, MinWidthPercentageInNegativeWidthBlockIsZero) {
  // If the min-width is specified as a percentage and the containing block's
  // width is negative, the used value is zero.
  //  https://www.w3.org/TR/CSS2/visudet.html#propdef-min-width
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());
  computed_style->set_min_width(new PercentageValue(0.50f));

  scoped_refptr<CSSComputedStyleData> grandparent_computed_style(
      new CSSComputedStyleData());
  scoped_refptr<CSSComputedStyleDeclaration>
      grandparent_computed_style_declaration(
          CreateComputedStyleDeclaration(grandparent_computed_style));

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  parent_computed_style->set_width(new LengthValue(-16, kPixelsUnit));
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(parent_computed_style,
                         grandparent_computed_style_declaration,
                         grandparent_computed_style, math::Size(), NULL);
  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         grandparent_computed_style, math::Size(), NULL);

  LengthValue* computed_min_width = base::polymorphic_downcast<LengthValue*>(
      computed_style->min_width().get());
  EXPECT_EQ(0, computed_min_width->value());
  EXPECT_EQ(kPixelsUnit, computed_min_width->unit());
}

TEST(PromoteToComputedStyle, LineHeightPercentageIsRelativeToFontSize) {
  // The computed value of the property is this percentage multiplied by the
  // element's computed font size. Negative values are illegal.
  //   https://www.w3.org/TR/CSS21/visudet.html#line-height
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());
  computed_style->set_font_size(new LengthValue(100, kPixelsUnit));
  computed_style->set_line_height(new PercentageValue(0.75f));

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  LengthValue* computed_line_height = base::polymorphic_downcast<LengthValue*>(
      computed_style->line_height().get());
  EXPECT_EQ(75, computed_line_height->value());
  EXPECT_EQ(kPixelsUnit, computed_line_height->unit());
}

TEST(PromoteToComputedStyle, TransformOriginOneValueWithKeyword) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());

  // transform-origin: bottom;
  scoped_ptr<PropertyListValue::Builder> transform_origin_builder(
      new PropertyListValue::Builder());
  transform_origin_builder->push_back(KeywordValue::GetBottom());
  scoped_refptr<PropertyListValue> transform_origin(
      new PropertyListValue(transform_origin_builder.Pass()));
  computed_style->set_transform_origin(transform_origin);

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  scoped_refptr<PropertyListValue> transform_origin_list =
      dynamic_cast<PropertyListValue*>(
          computed_style->transform_origin().get());
  ASSERT_TRUE(transform_origin_list);
  ASSERT_EQ(3, transform_origin_list->value().size());

  CalcValue* first_value = base::polymorphic_downcast<CalcValue*>(
      transform_origin_list->value()[0].get());
  const LengthValue* first_length_value = first_value->length_value();
  EXPECT_FLOAT_EQ(0.0f, first_length_value->value());
  EXPECT_EQ(kPixelsUnit, first_length_value->unit());
  EXPECT_FLOAT_EQ(0.5f, first_value->percentage_value()->value());

  CalcValue* second_value = base::polymorphic_downcast<CalcValue*>(
      transform_origin_list->value()[1].get());
  const LengthValue* second_length_value = second_value->length_value();
  EXPECT_FLOAT_EQ(0.0f, second_length_value->value());
  EXPECT_EQ(kPixelsUnit, second_length_value->unit());
  EXPECT_FLOAT_EQ(1.0f, second_value->percentage_value()->value());

  LengthValue* third_value = base::polymorphic_downcast<LengthValue*>(
      transform_origin_list->value()[2].get());
  EXPECT_FLOAT_EQ(0.0f, third_value->value());
  EXPECT_EQ(kPixelsUnit, third_value->unit());
}

TEST(PromoteToComputedStyle, TransformOriginOneValueWithoutKeyword) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());

  // transform-origin: 3em;
  scoped_ptr<PropertyListValue::Builder> transform_origin_builder(
      new PropertyListValue::Builder());
  transform_origin_builder->push_back(new LengthValue(3, kFontSizesAkaEmUnit));
  scoped_refptr<PropertyListValue> transform_origin(
      new PropertyListValue(transform_origin_builder.Pass()));
  computed_style->set_transform_origin(transform_origin);

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  scoped_refptr<PropertyListValue> transform_origin_list =
      dynamic_cast<PropertyListValue*>(
          computed_style->transform_origin().get());
  ASSERT_TRUE(transform_origin_list);
  ASSERT_EQ(3, transform_origin_list->value().size());

  CalcValue* first_value = base::polymorphic_downcast<CalcValue*>(
      transform_origin_list->value()[0].get());
  const LengthValue* first_length_value = first_value->length_value();
  EXPECT_FLOAT_EQ(48.0f, first_length_value->value());
  EXPECT_EQ(kPixelsUnit, first_length_value->unit());
  EXPECT_FLOAT_EQ(0.0f, first_value->percentage_value()->value());

  CalcValue* second_value = base::polymorphic_downcast<CalcValue*>(
      transform_origin_list->value()[1].get());
  const LengthValue* second_length_value = second_value->length_value();
  EXPECT_FLOAT_EQ(0.0f, second_length_value->value());
  EXPECT_EQ(kPixelsUnit, second_length_value->unit());
  EXPECT_FLOAT_EQ(0.5f, second_value->percentage_value()->value());

  LengthValue* third_value = base::polymorphic_downcast<LengthValue*>(
      transform_origin_list->value()[2].get());
  EXPECT_FLOAT_EQ(0.0f, third_value->value());
  EXPECT_EQ(kPixelsUnit, third_value->unit());
}

TEST(PromoteToComputedStyle, TransformOriginTwoValuesWithoutKeywordValue) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());

  // transform-origin: 3em 40px;
  scoped_ptr<PropertyListValue::Builder> transform_origin_builder(
      new PropertyListValue::Builder());
  transform_origin_builder->push_back(new LengthValue(3, kFontSizesAkaEmUnit));
  transform_origin_builder->push_back(new LengthValue(40, kPixelsUnit));
  scoped_refptr<PropertyListValue> transform_origin(
      new PropertyListValue(transform_origin_builder.Pass()));
  computed_style->set_transform_origin(transform_origin);

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  scoped_refptr<PropertyListValue> transform_origin_list =
      dynamic_cast<PropertyListValue*>(
          computed_style->transform_origin().get());
  ASSERT_TRUE(transform_origin_list);
  ASSERT_EQ(3, transform_origin_list->value().size());

  CalcValue* first_value = base::polymorphic_downcast<CalcValue*>(
      transform_origin_list->value()[0].get());
  const LengthValue* first_length_value = first_value->length_value();
  EXPECT_FLOAT_EQ(48.0f, first_length_value->value());
  EXPECT_EQ(kPixelsUnit, first_length_value->unit());
  EXPECT_FLOAT_EQ(0.0f, first_value->percentage_value()->value());

  CalcValue* second_value = base::polymorphic_downcast<CalcValue*>(
      transform_origin_list->value()[1].get());
  const LengthValue* second_length_value = second_value->length_value();
  EXPECT_FLOAT_EQ(40.0f, second_length_value->value());
  EXPECT_EQ(kPixelsUnit, second_length_value->unit());
  EXPECT_FLOAT_EQ(0.0f, second_value->percentage_value()->value());

  LengthValue* third_value = base::polymorphic_downcast<LengthValue*>(
      transform_origin_list->value()[2].get());
  EXPECT_FLOAT_EQ(0.0f, third_value->value());
  EXPECT_EQ(kPixelsUnit, third_value->unit());
}

TEST(PromoteToComputedStyle, TransformOriginTwoValuesWithOneKeyword) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());

  // transform-origin: right 20%;
  scoped_ptr<PropertyListValue::Builder> transform_origin_builder(
      new PropertyListValue::Builder());
  transform_origin_builder->push_back(KeywordValue::GetRight());
  transform_origin_builder->push_back(new PercentageValue(0.2f));
  scoped_refptr<PropertyListValue> transform_origin(
      new PropertyListValue(transform_origin_builder.Pass()));
  computed_style->set_transform_origin(transform_origin);

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  scoped_refptr<PropertyListValue> transform_origin_list =
      dynamic_cast<PropertyListValue*>(
          computed_style->transform_origin().get());
  ASSERT_TRUE(transform_origin_list);
  ASSERT_EQ(3, transform_origin_list->value().size());

  CalcValue* first_value = base::polymorphic_downcast<CalcValue*>(
      transform_origin_list->value()[0].get());
  const LengthValue* first_length_value = first_value->length_value();
  EXPECT_FLOAT_EQ(0.0f, first_length_value->value());
  EXPECT_EQ(kPixelsUnit, first_length_value->unit());
  EXPECT_FLOAT_EQ(1.0f, first_value->percentage_value()->value());

  CalcValue* second_value = base::polymorphic_downcast<CalcValue*>(
      transform_origin_list->value()[1].get());
  const LengthValue* second_length_value = second_value->length_value();
  EXPECT_FLOAT_EQ(0.0f, second_length_value->value());
  EXPECT_EQ(kPixelsUnit, second_length_value->unit());
  EXPECT_FLOAT_EQ(0.2f, second_value->percentage_value()->value());

  LengthValue* third_value = base::polymorphic_downcast<LengthValue*>(
      transform_origin_list->value()[2].get());
  EXPECT_FLOAT_EQ(0.0f, third_value->value());
  EXPECT_EQ(kPixelsUnit, third_value->unit());
}

TEST(PromoteToComputedStyle, TransformOriginTwoValuesWithoutKeyword) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());

  // transform-origin: 60% 80%;
  scoped_ptr<PropertyListValue::Builder> transform_origin_builder(
      new PropertyListValue::Builder());
  transform_origin_builder->push_back(new PercentageValue(0.6f));
  transform_origin_builder->push_back(new PercentageValue(0.8f));
  scoped_refptr<PropertyListValue> transform_origin(
      new PropertyListValue(transform_origin_builder.Pass()));
  computed_style->set_transform_origin(transform_origin);

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  scoped_refptr<PropertyListValue> transform_origin_list =
      dynamic_cast<PropertyListValue*>(
          computed_style->transform_origin().get());
  ASSERT_TRUE(transform_origin_list);
  ASSERT_EQ(3, transform_origin_list->value().size());

  CalcValue* first_value = base::polymorphic_downcast<CalcValue*>(
      transform_origin_list->value()[0].get());
  const LengthValue* first_length_value = first_value->length_value();
  EXPECT_FLOAT_EQ(0.0f, first_length_value->value());
  EXPECT_EQ(kPixelsUnit, first_length_value->unit());
  EXPECT_FLOAT_EQ(0.6f, first_value->percentage_value()->value());

  CalcValue* second_value = base::polymorphic_downcast<CalcValue*>(
      transform_origin_list->value()[1].get());
  const LengthValue* second_length_value = second_value->length_value();
  EXPECT_FLOAT_EQ(0.0f, second_length_value->value());
  EXPECT_EQ(kPixelsUnit, second_length_value->unit());
  EXPECT_FLOAT_EQ(0.8f, second_value->percentage_value()->value());

  LengthValue* third_value = base::polymorphic_downcast<LengthValue*>(
      transform_origin_list->value()[2].get());
  EXPECT_FLOAT_EQ(0.0f, third_value->value());
  EXPECT_EQ(kPixelsUnit, third_value->unit());
}

TEST(PromoteToComputedStyle, TransformOriginTwoKeywordValues) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());

  // transform-origin: top center;
  scoped_ptr<PropertyListValue::Builder> transform_origin_builder(
      new PropertyListValue::Builder());
  transform_origin_builder->push_back(KeywordValue::GetTop());
  transform_origin_builder->push_back(KeywordValue::GetCenter());
  scoped_refptr<PropertyListValue> transform_origin(
      new PropertyListValue(transform_origin_builder.Pass()));
  computed_style->set_transform_origin(transform_origin);

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  scoped_refptr<PropertyListValue> transform_origin_list =
      dynamic_cast<PropertyListValue*>(
          computed_style->transform_origin().get());
  ASSERT_TRUE(transform_origin_list);
  ASSERT_EQ(3, transform_origin_list->value().size());

  CalcValue* first_value = base::polymorphic_downcast<CalcValue*>(
      transform_origin_list->value()[0].get());
  const LengthValue* first_length_value = first_value->length_value();
  EXPECT_FLOAT_EQ(0.0f, first_length_value->value());
  EXPECT_EQ(kPixelsUnit, first_length_value->unit());
  EXPECT_FLOAT_EQ(0.5f, first_value->percentage_value()->value());

  CalcValue* second_value = base::polymorphic_downcast<CalcValue*>(
      transform_origin_list->value()[1].get());
  const LengthValue* second_length_value = second_value->length_value();
  EXPECT_FLOAT_EQ(0.0f, second_length_value->value());
  EXPECT_EQ(kPixelsUnit, second_length_value->unit());
  EXPECT_FLOAT_EQ(0.0f, second_value->percentage_value()->value());

  LengthValue* third_value = base::polymorphic_downcast<LengthValue*>(
      transform_origin_list->value()[2].get());
  EXPECT_FLOAT_EQ(0.0f, third_value->value());
  EXPECT_EQ(kPixelsUnit, third_value->unit());
}

TEST(PromoteToComputedStyle, TransformOriginThreeValues) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());

  // transform-origin: 30px top 50px;
  scoped_ptr<PropertyListValue::Builder> transform_origin_builder(
      new PropertyListValue::Builder());
  transform_origin_builder->push_back(new LengthValue(30.0f, kPixelsUnit));
  transform_origin_builder->push_back(KeywordValue::GetTop());
  transform_origin_builder->push_back(new LengthValue(50.0f, kPixelsUnit));
  scoped_refptr<PropertyListValue> transform_origin(
      new PropertyListValue(transform_origin_builder.Pass()));
  computed_style->set_transform_origin(transform_origin);

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  scoped_refptr<PropertyListValue> transform_origin_list =
      dynamic_cast<PropertyListValue*>(
          computed_style->transform_origin().get());
  ASSERT_TRUE(transform_origin_list);
  ASSERT_EQ(3, transform_origin_list->value().size());

  CalcValue* first_value = base::polymorphic_downcast<CalcValue*>(
      transform_origin_list->value()[0].get());
  const LengthValue* first_length_value = first_value->length_value();
  EXPECT_FLOAT_EQ(30.0f, first_length_value->value());
  EXPECT_EQ(kPixelsUnit, first_length_value->unit());
  EXPECT_FLOAT_EQ(0.0f, first_value->percentage_value()->value());

  CalcValue* second_value = base::polymorphic_downcast<CalcValue*>(
      transform_origin_list->value()[1].get());
  const LengthValue* second_length_value = second_value->length_value();
  EXPECT_FLOAT_EQ(0.0f, second_length_value->value());
  EXPECT_EQ(kPixelsUnit, second_length_value->unit());
  EXPECT_FLOAT_EQ(0.0f, second_value->percentage_value()->value());

  LengthValue* third_value = base::polymorphic_downcast<LengthValue*>(
      transform_origin_list->value()[2].get());
  EXPECT_FLOAT_EQ(50.0f, third_value->value());
  EXPECT_EQ(kPixelsUnit, third_value->unit());
}

TEST(PromoteToComputedStyle, TransformRelativeUnitShouldBeConvertedToAbsolute) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());

  // transform: translateX(2em);
  TransformFunctionListValue::Builder transform_builder;
  transform_builder.push_back(new TranslateFunction(
      TranslateFunction::kXAxis, new LengthValue(2.0f, kFontSizesAkaEmUnit)));
  scoped_refptr<TransformFunctionListValue> transform(
      new TransformFunctionListValue(transform_builder.Pass()));
  computed_style->set_transform(transform);

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  parent_computed_style->set_font_size(new LengthValue(100, kPixelsUnit));
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  scoped_refptr<TransformFunctionListValue> computed_transform =
      dynamic_cast<TransformFunctionListValue*>(
          computed_style->transform().get());
  ASSERT_TRUE(computed_transform);
  ASSERT_EQ(1, computed_transform->value().size());

  const TranslateFunction* computed_function =
      base::polymorphic_downcast<const TranslateFunction*>(
          computed_transform->value()[0]);
  ASSERT_TRUE(computed_function);
  EXPECT_FLOAT_EQ(200.0f, computed_function->offset_as_length()->value());
  EXPECT_EQ(kPixelsUnit, computed_function->offset_as_length()->unit());
}

TEST(PromoteToComputedStyle,
     InheritedAnimatablePropertyShouldAlwaysBeDeclared) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  parent_computed_style->set_color(RGBAColorValue::GetAqua());
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  // Verify that we're testing an inherited and animatable property.
  ASSERT_TRUE(GetPropertyInheritance(kColorProperty) &&
              GetPropertyAnimatable(kColorProperty));

  // For each inherited, animatable property, the property value should be set
  // to inherited if it is not already declared in PromoteToComputedStyle().
  // This causes the value to be  explicitly set within the CSSComputedStyleData
  // and ensures that the original value will be available for transitions
  // (which need to know the before and after state of the property) even when
  // the property is inherited from a parent that has changed.
  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  // Verify that the color is declared in the child even though it was not
  // explicitly declared.
  ASSERT_TRUE(computed_style->IsDeclared(kColorProperty));
}

TEST(PromoteToComputedStyle,
     DeclaredPropertiesInheritedFromParentShouldRemainValidWhenSetToSameValue) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  parent_computed_style->set_color(
      new RGBAColorValue(uint8(10), uint8(10), uint8(10), uint8(10)));
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  // Verify that we're testing an inherited and animatable property.
  ASSERT_TRUE(GetPropertyInheritance(kColorProperty) &&
              GetPropertyAnimatable(kColorProperty));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  // Verify that the declared properties inherited from the parent are valid.
  ASSERT_TRUE(computed_style->AreDeclaredPropertiesInheritedFromParentValid());

  parent_computed_style = new CSSComputedStyleData();
  parent_computed_style->set_color(
      new RGBAColorValue(uint8(10), uint8(10), uint8(10), uint8(10)));
  parent_computed_style_declaration->SetData(parent_computed_style);

  // Verify that the declared properties inherited from the parent are still
  // valid.
  ASSERT_TRUE(computed_style->AreDeclaredPropertiesInheritedFromParentValid());
}

TEST(PromoteToComputedStyle,
     InheritedAnimatablePropertyShouldRetainValueAfterParentValueChanges) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  parent_computed_style->set_color(RGBAColorValue::GetAqua());
  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));

  // Verify that we're testing an inherited and animatable property.
  ASSERT_TRUE(GetPropertyInheritance(kColorProperty) &&
              GetPropertyAnimatable(kColorProperty));

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         parent_computed_style, math::Size(), NULL);

  // Verify that the child's color is Aqua and matches the parent's color.
  EXPECT_EQ(RGBAColorValue::GetAqua(), computed_style->color());
  EXPECT_EQ(parent_computed_style->color(), computed_style->color());

  // Verify that the declared properties inherited from the parent are valid.
  ASSERT_TRUE(computed_style->AreDeclaredPropertiesInheritedFromParentValid());

  parent_computed_style = new CSSComputedStyleData();
  parent_computed_style->set_color(RGBAColorValue::GetNavy());
  parent_computed_style_declaration->SetData(parent_computed_style);

  // Verify that the color is still Aqua but that it no longer matches the
  // parent's color.
  EXPECT_EQ(RGBAColorValue::GetAqua(), computed_style->color());
  EXPECT_NE(parent_computed_style->color(), computed_style->color());

  // Verify that the declared properties inherited from the parent are no
  // longer valid.
  ASSERT_FALSE(computed_style->AreDeclaredPropertiesInheritedFromParentValid());
}

TEST(UpdateInheritedData,
     UpdateInheritedDataShouldFixInheritedDataAfterItIsAdded) {
  scoped_refptr<CSSComputedStyleData> grandparent_computed_style(
      new CSSComputedStyleData());
  scoped_refptr<CSSComputedStyleDeclaration>
      grandparent_computed_style_declaration(
          CreateComputedStyleDeclaration(grandparent_computed_style));

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  // The parent should initially have the default value of normal.
  EXPECT_EQ(FontStyleValue::GetNormal(), parent_computed_style->font_style());

  PromoteToComputedStyle(parent_computed_style,
                         grandparent_computed_style_declaration,
                         grandparent_computed_style, math::Size(), NULL);
  // The parent should still have the default value of normal.
  EXPECT_EQ(FontStyleValue::GetNormal(), parent_computed_style->font_style());

  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         grandparent_computed_style, math::Size(), NULL);

  // The child should have the default value of normal.
  EXPECT_EQ(FontStyleValue::GetNormal(), computed_style->font_style());

  grandparent_computed_style = new CSSComputedStyleData();
  grandparent_computed_style->set_font_style(FontStyleValue::GetOblique());
  grandparent_computed_style_declaration->SetData(grandparent_computed_style);

  // Even though the grandparent has changed, the child should have the original
  // default value of normal until UpdateInheritedData() is called.
  EXPECT_EQ(FontStyleValue::GetNormal(), computed_style->font_style());
  parent_computed_style_declaration->UpdateInheritedData();

  // Now that UpdateInheritedData() has been called, the child should have the
  // new inherited value of oblique.
  EXPECT_EQ(FontStyleValue::GetOblique(), computed_style->font_style());
}

TEST(UpdateInheritedData,
     UpdateInheritedDataShouldFixInheritedDataAfterItIsRemoved) {
  scoped_refptr<CSSComputedStyleData> grandparent_computed_style(
      new CSSComputedStyleData());
  grandparent_computed_style->set_font_style(FontStyleValue::GetItalic());
  scoped_refptr<CSSComputedStyleDeclaration>
      grandparent_computed_style_declaration(
          CreateComputedStyleDeclaration(grandparent_computed_style));

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  // The parent should initially have the default value of normal.
  EXPECT_EQ(FontStyleValue::GetNormal(), parent_computed_style->font_style());

  PromoteToComputedStyle(parent_computed_style,
                         grandparent_computed_style_declaration,
                         grandparent_computed_style, math::Size(), NULL);
  // The parent should now have the inherited value of italic.
  EXPECT_EQ(FontStyleValue::GetItalic(), parent_computed_style->font_style());

  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         grandparent_computed_style, math::Size(), NULL);

  // The child should have the inherited value of italic.
  EXPECT_EQ(FontStyleValue::GetItalic(), computed_style->font_style());

  grandparent_computed_style = new CSSComputedStyleData();
  grandparent_computed_style_declaration->SetData(grandparent_computed_style);

  // Even though the grandparent has changed, the child should have the original
  // inherited value of italic until UpdateInheritedData() is called.
  EXPECT_EQ(FontStyleValue::GetItalic(), computed_style->font_style());
  parent_computed_style_declaration->UpdateInheritedData();

  // Now that UpdateInheritedData() has been called, the child should have the
  // default value of normal.
  EXPECT_EQ(FontStyleValue::GetNormal(), computed_style->font_style());
}

TEST(UpdateInheritedData,
     UpdateInheritedDataShouldFixInheritedDataAfterItChanges) {
  scoped_refptr<CSSComputedStyleData> grandparent_computed_style(
      new CSSComputedStyleData());
  grandparent_computed_style->set_font_style(FontStyleValue::GetItalic());
  scoped_refptr<CSSComputedStyleDeclaration>
      grandparent_computed_style_declaration(
          CreateComputedStyleDeclaration(grandparent_computed_style));

  scoped_refptr<CSSComputedStyleData> parent_computed_style(
      new CSSComputedStyleData());
  // The parent should initially have the default value of normal.
  EXPECT_EQ(FontStyleValue::GetNormal(), parent_computed_style->font_style());

  PromoteToComputedStyle(parent_computed_style,
                         grandparent_computed_style_declaration,
                         grandparent_computed_style, math::Size(), NULL);
  // The parent should now have the inherited value of italic.
  EXPECT_EQ(FontStyleValue::GetItalic(), parent_computed_style->font_style());

  scoped_refptr<CSSComputedStyleDeclaration> parent_computed_style_declaration(
      CreateComputedStyleDeclaration(parent_computed_style));
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());

  PromoteToComputedStyle(computed_style, parent_computed_style_declaration,
                         grandparent_computed_style, math::Size(), NULL);

  // The child should have the inherited value of italic.
  EXPECT_EQ(FontStyleValue::GetItalic(), computed_style->font_style());

  grandparent_computed_style = new CSSComputedStyleData();
  grandparent_computed_style->set_font_style(FontStyleValue::GetOblique());
  grandparent_computed_style_declaration->SetData(grandparent_computed_style);

  // Even though the grandparent has changed, the child should have the original
  // inherited value of italic until UpdateInheritedData() is called.
  EXPECT_EQ(FontStyleValue::GetItalic(), computed_style->font_style());
  parent_computed_style_declaration->UpdateInheritedData();

  // Now that UpdateInheritedData() has been called, the child should have the
  // new inherited value of oblique.
  EXPECT_EQ(FontStyleValue::GetOblique(), computed_style->font_style());
}

}  // namespace cssom
}  // namespace cobalt
