// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/cssom/computed_style.h"

#include <vector>

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

namespace cobalt {
namespace cssom {

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

TEST(PromoteToComputedStyle, BorderRadiusEmToPixel) {
  scoped_refptr<CSSComputedStyleData> computed_style(
      new CSSComputedStyleData());
  computed_style->set_border_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
