// Copyright 2015 The Cobalt Authors. 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_top_left_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_top_left_radius =
      base::polymorphic_downcast<LengthValue*>(
          computed_style->border_top_left_radius().get());
  ASSERT_TRUE(border_top_left_radius);
  EXPECT_FLOAT_EQ(48.0f, border_top_left_radius->value());
  EXPECT_EQ(kPixelsUnit, border_top_left_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
