// Copyright 2016 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/css_computed_style_data.h"

#include "cobalt/cssom/font_style_value.h"
#include "cobalt/cssom/font_weight_value.h"
#include "cobalt/cssom/keyword_value.h"

#include "testing/gtest/include/gtest/gtest.h"

namespace cobalt {
namespace cssom {

TEST(CSSComputedStyleDataPropertySetMatcherTest,
     NoDeclaredPropertiesShouldMatch) {
  scoped_refptr<CSSComputedStyleData> style_1 = new CSSComputedStyleData();
  scoped_refptr<CSSComputedStyleData> style_2 = new CSSComputedStyleData();

  PropertyKeyVector properties;
  properties.push_back(kBackgroundColorProperty);
  CSSComputedStyleData::PropertySetMatcher matcher(properties);

  EXPECT_TRUE(matcher.DoDeclaredPropertiesMatch(style_1, style_2));
}

TEST(CSSComputedStyleDataPropertySetMatcherTest,
     NoDeclaredPropertiesInPropertySetShouldMatch) {
  scoped_refptr<CSSComputedStyleData> style_1 = new CSSComputedStyleData();
  style_1->set_font_family(KeywordValue::GetSerif());

  scoped_refptr<CSSComputedStyleData> style_2 = new CSSComputedStyleData();
  style_2->set_font_family(KeywordValue::GetSansSerif());

  PropertyKeyVector properties;
  properties.push_back(kBackgroundColorProperty);
  CSSComputedStyleData::PropertySetMatcher matcher(properties);

  EXPECT_TRUE(matcher.DoDeclaredPropertiesMatch(style_1, style_2));
}

TEST(CSSComputedStyleDataPropertySetMatcherTest,
     SingleDeclaredPropertyMissingFromSecondStyleDataShouldNotMatch) {
  scoped_refptr<CSSComputedStyleData> style_1 = new CSSComputedStyleData();
  style_1->set_font_family(KeywordValue::GetSerif());

  scoped_refptr<CSSComputedStyleData> style_2 = new CSSComputedStyleData();

  PropertyKeyVector properties;
  properties.push_back(kFontFamilyProperty);
  CSSComputedStyleData::PropertySetMatcher matcher(properties);

  EXPECT_FALSE(matcher.DoDeclaredPropertiesMatch(style_1, style_2));
}

TEST(CSSComputedStyleDataPropertySetMatcherTest,
     SingleDeclaredPropertyMissingFromFirstStyleDataShouldNotMatch) {
  scoped_refptr<CSSComputedStyleData> style_1 = new CSSComputedStyleData();

  scoped_refptr<CSSComputedStyleData> style_2 = new CSSComputedStyleData();
  style_2->set_font_family(KeywordValue::GetSansSerif());

  PropertyKeyVector properties;
  properties.push_back(kFontFamilyProperty);
  CSSComputedStyleData::PropertySetMatcher matcher(properties);

  EXPECT_FALSE(matcher.DoDeclaredPropertiesMatch(style_1, style_2));
}

TEST(CSSComputedStyleDataPropertySetMatcherTest,
     SingleEqualDeclaredPropertyShouldMatch) {
  scoped_refptr<CSSComputedStyleData> style_1 = new CSSComputedStyleData();
  style_1->set_font_family(KeywordValue::GetSerif());

  scoped_refptr<CSSComputedStyleData> style_2 = new CSSComputedStyleData();
  style_2->set_font_family(KeywordValue::GetSerif());

  PropertyKeyVector properties;
  properties.push_back(kFontFamilyProperty);
  properties.push_back(kFontStyleProperty);
  CSSComputedStyleData::PropertySetMatcher matcher(properties);

  EXPECT_TRUE(matcher.DoDeclaredPropertiesMatch(style_1, style_2));
}

TEST(CSSComputedStyleDataPropertySetMatcherTest,
     DeclaredPropertiesMissingFromFirstStyleDataShouldNotMatch) {
  scoped_refptr<CSSComputedStyleData> style_1 = new CSSComputedStyleData();
  style_1->set_font_family(KeywordValue::GetSerif());

  scoped_refptr<CSSComputedStyleData> style_2 = new CSSComputedStyleData();
  style_2->set_font_family(KeywordValue::GetSerif());
  style_2->set_font_style(FontStyleValue::GetItalic());

  PropertyKeyVector properties;
  properties.push_back(kFontFamilyProperty);
  properties.push_back(kFontStyleProperty);
  CSSComputedStyleData::PropertySetMatcher matcher(properties);

  EXPECT_FALSE(matcher.DoDeclaredPropertiesMatch(style_1, style_2));
}

TEST(CSSComputedStyleDataPropertySetMatcherTest,
     DeclaredPropertiesMissingFromSecondStyleDataShouldNotMatch) {
  scoped_refptr<CSSComputedStyleData> style_1 = new CSSComputedStyleData();
  style_1->set_font_family(KeywordValue::GetSerif());
  style_1->set_font_style(FontStyleValue::GetItalic());

  scoped_refptr<CSSComputedStyleData> style_2 = new CSSComputedStyleData();
  style_2->set_font_family(KeywordValue::GetSerif());

  PropertyKeyVector properties;
  properties.push_back(kFontFamilyProperty);
  properties.push_back(kFontStyleProperty);
  CSSComputedStyleData::PropertySetMatcher matcher(properties);

  EXPECT_FALSE(matcher.DoDeclaredPropertiesMatch(style_1, style_2));
}

TEST(CSSComputedStyleDataPropertySetMatcherTest,
     UnequalDeclaredPropertiesShouldNotMatch) {
  scoped_refptr<CSSComputedStyleData> style_1 = new CSSComputedStyleData();
  style_1->set_font_family(KeywordValue::GetSerif());
  style_1->set_font_style(FontStyleValue::GetItalic());

  scoped_refptr<CSSComputedStyleData> style_2 = new CSSComputedStyleData();
  style_2->set_font_family(KeywordValue::GetSerif());
  style_2->set_font_style(FontStyleValue::GetOblique());

  PropertyKeyVector properties;
  properties.push_back(kFontFamilyProperty);
  properties.push_back(kFontStyleProperty);
  CSSComputedStyleData::PropertySetMatcher matcher(properties);

  EXPECT_FALSE(matcher.DoDeclaredPropertiesMatch(style_1, style_2));
}

TEST(CSSComputedStyleDataPropertySetMatcherTest,
     DifferentDeclaredPropertiesShouldNotMatch) {
  scoped_refptr<CSSComputedStyleData> style_1 = new CSSComputedStyleData();
  style_1->set_font_family(KeywordValue::GetSerif());
  style_1->set_font_style(FontStyleValue::GetItalic());

  scoped_refptr<CSSComputedStyleData> style_2 = new CSSComputedStyleData();
  style_2->set_font_family(KeywordValue::GetSerif());
  style_2->set_font_weight(FontWeightValue::GetBoldAka700());

  PropertyKeyVector properties;
  properties.push_back(kFontFamilyProperty);
  properties.push_back(kFontStyleProperty);
  properties.push_back(kFontWeightProperty);
  CSSComputedStyleData::PropertySetMatcher matcher(properties);

  EXPECT_FALSE(matcher.DoDeclaredPropertiesMatch(style_1, style_2));
}

TEST(CSSComputedStyleDataPropertySetMatcherTest,
     EqualDeclaredPropertiesShouldMatch) {
  scoped_refptr<CSSComputedStyleData> style_1 = new CSSComputedStyleData();
  style_1->set_font_family(KeywordValue::GetSerif());
  style_1->set_font_style(FontStyleValue::GetItalic());
  style_1->set_font_weight(FontWeightValue::GetLightAka300());

  scoped_refptr<CSSComputedStyleData> style_2 = new CSSComputedStyleData();
  style_2->set_font_family(KeywordValue::GetSerif());
  style_2->set_font_style(FontStyleValue::GetItalic());
  style_2->set_font_weight(FontWeightValue::GetBoldAka700());

  PropertyKeyVector properties;
  properties.push_back(kFontFamilyProperty);
  properties.push_back(kFontStyleProperty);
  CSSComputedStyleData::PropertySetMatcher matcher(properties);

  EXPECT_TRUE(matcher.DoDeclaredPropertiesMatch(style_1, style_2));
}

}  // namespace cssom
}  // namespace cobalt
