| Index: tools/json_schema_compiler/test/features_generation_unittest.cc
|
| diff --git a/tools/json_schema_compiler/test/features_generation_unittest.cc b/tools/json_schema_compiler/test/features_generation_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..7a175a05dc97b5cd394067b91760e9c37a333065
|
| --- /dev/null
|
| +++ b/tools/json_schema_compiler/test/features_generation_unittest.cc
|
| @@ -0,0 +1,226 @@
|
| +// Copyright 2016 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "extensions/common/features/api_feature.h"
|
| +#include "extensions/common/features/complex_feature.h"
|
| +#include "extensions/common/features/feature.h"
|
| +#include "extensions/common/features/simple_feature.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +#include "tools/json_schema_compiler/test/features_test.h"
|
| +
|
| +namespace extensions {
|
| +
|
| +namespace {
|
| +
|
| +template <typename T>
|
| +void ExpectVectorsEqual(std::vector<T> expected,
|
| + std::vector<T> actual,
|
| + const std::string& name) {
|
| + std::sort(expected.begin(), expected.end());
|
| + std::sort(actual.begin(), actual.end());
|
| + EXPECT_EQ(expected, actual) << name;
|
| +}
|
| +
|
| +SimpleFeature::Location kDefaultLocation = SimpleFeature::UNSPECIFIED_LOCATION;
|
| +const int kDefaultMinVersion = 0;
|
| +const int kDefaultMaxVersion = 0;
|
| +const bool kDefaultAutoGrant = true;
|
| +const bool kDefaultInternal = false;
|
| +
|
| +} // namespace
|
| +
|
| +// A utility object for comparing a feature with its expected value.
|
| +struct FeatureComparator {
|
| + public:
|
| + FeatureComparator(const std::string& name);
|
| + ~FeatureComparator();
|
| +
|
| + void CompareFeature(SimpleFeature* feature);
|
| +
|
| + std::string name;
|
| + std::vector<std::string> blacklist;
|
| + std::vector<std::string> whitelist;
|
| + std::vector<std::string> dependencies;
|
| + std::vector<Manifest::Type> extension_types;
|
| + std::vector<Feature::Context> contexts;
|
| + std::vector<Feature::Platform> platforms;
|
| + URLPatternSet matches;
|
| + SimpleFeature::Location location;
|
| + int min_manifest_version;
|
| + int max_manifest_version;
|
| + bool component_extensions_auto_granted;
|
| + std::string command_line_switch;
|
| + std::unique_ptr<version_info::Channel> channel;
|
| + bool internal;
|
| +};
|
| +
|
| +FeatureComparator::FeatureComparator(const std::string& name)
|
| + : name(name),
|
| + location(kDefaultLocation),
|
| + min_manifest_version(kDefaultMinVersion),
|
| + max_manifest_version(kDefaultMaxVersion),
|
| + component_extensions_auto_granted(kDefaultAutoGrant),
|
| + internal(kDefaultInternal) {}
|
| +
|
| +FeatureComparator::~FeatureComparator() {}
|
| +
|
| +void FeatureComparator::CompareFeature(SimpleFeature* feature) {
|
| + ASSERT_TRUE(feature);
|
| + EXPECT_EQ(name, feature->name());
|
| + ExpectVectorsEqual(blacklist, feature->blacklist(), name);
|
| + ExpectVectorsEqual(whitelist, feature->whitelist(), name);
|
| + ExpectVectorsEqual(dependencies, feature->dependencies(), name);
|
| + ExpectVectorsEqual(extension_types, feature->extension_types(), name);
|
| + ExpectVectorsEqual(contexts, feature->contexts(), name);
|
| + ExpectVectorsEqual(platforms, feature->platforms(), name);
|
| + EXPECT_EQ(matches, feature->matches()) << name;
|
| + EXPECT_EQ(location, feature->location()) << name;
|
| + EXPECT_EQ(min_manifest_version, feature->min_manifest_version()) << name;
|
| + EXPECT_EQ(max_manifest_version, feature->max_manifest_version()) << name;
|
| + EXPECT_EQ(component_extensions_auto_granted,
|
| + feature->component_extensions_auto_granted())
|
| + << name;
|
| + EXPECT_EQ(command_line_switch, feature->command_line_switch()) << name;
|
| + ASSERT_EQ(channel.get() != nullptr, feature->has_channel()) << name;
|
| + if (channel)
|
| + EXPECT_EQ(*channel, feature->channel()) << name;
|
| + EXPECT_EQ(internal, feature->IsInternal()) << name;
|
| +}
|
| +
|
| +TEST(FeaturesGenerationTest, FeaturesTest) {
|
| + TestAPIFeatureProvider provider;
|
| +
|
| + auto GetAPIFeature = [&provider](const std::string& name) {
|
| + Feature* feature = provider.GetFeature(name);
|
| + // Shame we can't test this more safely, but if our feature is declared as
|
| + // the wrong class, things should blow up in a spectacular fashion.
|
| + return static_cast<APIFeature*>(feature);
|
| + };
|
| +
|
| + // Check some simple features for accuracy.
|
| + {
|
| + APIFeature* feature = GetAPIFeature("alpha");
|
| + FeatureComparator comparator("alpha");
|
| + comparator.dependencies = {"permission:alpha"};
|
| + comparator.contexts = {Feature::BLESSED_EXTENSION_CONTEXT};
|
| + comparator.channel.reset(
|
| + new version_info::Channel(version_info::Channel::STABLE));
|
| + comparator.CompareFeature(feature);
|
| + }
|
| + {
|
| + APIFeature* feature = GetAPIFeature("beta");
|
| + FeatureComparator comparator("beta");
|
| + comparator.extension_types = {Manifest::TYPE_EXTENSION,
|
| + Manifest::TYPE_PLATFORM_APP};
|
| + comparator.whitelist = {"aaa", "bbb"};
|
| + comparator.blacklist = {"zzz", "yyy"};
|
| + comparator.component_extensions_auto_granted = false;
|
| + comparator.CompareFeature(feature);
|
| + }
|
| + {
|
| + APIFeature* feature = GetAPIFeature("gamma");
|
| + FeatureComparator comparator("gamma");
|
| + comparator.channel.reset(
|
| + new version_info::Channel(version_info::Channel::BETA));
|
| + comparator.platforms = {Feature::WIN_PLATFORM, Feature::MACOSX_PLATFORM};
|
| + comparator.contexts = {Feature::BLESSED_EXTENSION_CONTEXT};
|
| + comparator.extension_types = {Manifest::TYPE_EXTENSION};
|
| + comparator.internal = true;
|
| + comparator.CompareFeature(feature);
|
| +
|
| + // A child feature should inherit all fields from its parent, except in the
|
| + // case that it specifies its own value. Thus, we reuse |comparator|.
|
| + feature = GetAPIFeature("gamma.child");
|
| + comparator.name = "gamma.child";
|
| + comparator.dependencies = {"permission:gamma.child"};
|
| + comparator.whitelist = {"ccc"};
|
| + comparator.platforms = {Feature::LINUX_PLATFORM};
|
| + comparator.CompareFeature(feature);
|
| + }
|
| + {
|
| + // Features that specify 'noparent' should not inherit features from any
|
| + // other feature.
|
| + APIFeature* feature = GetAPIFeature("gamma.unparented");
|
| + FeatureComparator comparator("gamma.unparented");
|
| + comparator.blacklist = {"ddd"};
|
| + comparator.contexts = {Feature::UNBLESSED_EXTENSION_CONTEXT};
|
| + comparator.CompareFeature(feature);
|
| + }
|
| + {
|
| + APIFeature* feature = GetAPIFeature("delta");
|
| + FeatureComparator comparator("delta");
|
| + comparator.contexts = {Feature::BLESSED_EXTENSION_CONTEXT,
|
| + Feature::WEBUI_CONTEXT};
|
| + comparator.matches.AddPattern(
|
| + URLPattern(URLPattern::SCHEME_ALL, "*://example.com/*"));
|
| + comparator.CompareFeature(feature);
|
| + }
|
| + {
|
| + // Omega is imported from a second .json file.
|
| + APIFeature* feature = GetAPIFeature("omega");
|
| + FeatureComparator comparator("omega");
|
| + comparator.contexts = {Feature::WEB_PAGE_CONTEXT};
|
| + comparator.min_manifest_version = 2;
|
| + comparator.CompareFeature(feature);
|
| + }
|
| + {
|
| + // Features specifying 'nocompile' should not be generated at all.
|
| + APIFeature* feature = GetAPIFeature("uncompiled");
|
| + EXPECT_FALSE(feature);
|
| + }
|
| +
|
| + // Test complex features.
|
| + {
|
| + ComplexFeature* feature =
|
| + static_cast<ComplexFeature*>(provider.GetFeature("complex"));
|
| + ASSERT_TRUE(feature);
|
| + EXPECT_EQ(2u, feature->features_.size());
|
| + // Find the default parent. This is a little tedious because it might not
|
| + // be guaranteed that the default_parent is in a specific index, but it
|
| + // specifies channel as 'stable'.
|
| + SimpleFeature* default_parent = nullptr;
|
| + SimpleFeature* other_parent = nullptr;
|
| + {
|
| + SimpleFeature* parent1 =
|
| + static_cast<SimpleFeature*>(feature->features_[0].get());
|
| + SimpleFeature* parent2 =
|
| + static_cast<SimpleFeature*>(feature->features_[1].get());
|
| + if (parent1->channel() == version_info::Channel::STABLE) {
|
| + default_parent = parent1;
|
| + other_parent = parent2;
|
| + } else {
|
| + other_parent = parent1;
|
| + default_parent = parent2;
|
| + }
|
| + }
|
| + {
|
| + // Check the default parent.
|
| + FeatureComparator comparator("complex");
|
| + comparator.channel.reset(
|
| + new version_info::Channel(version_info::Channel::STABLE));
|
| + comparator.contexts = {Feature::BLESSED_EXTENSION_CONTEXT};
|
| + comparator.extension_types = {Manifest::TYPE_EXTENSION};
|
| + comparator.CompareFeature(default_parent);
|
| + // Check the child of the complex feature. It should inherit its
|
| + // properties from the default parent.
|
| + APIFeature* child_feature = GetAPIFeature("complex.child");
|
| + comparator.name = "complex.child";
|
| + comparator.platforms = {Feature::WIN_PLATFORM};
|
| + comparator.dependencies = {"permission:complex.child"};
|
| + comparator.CompareFeature(child_feature);
|
| + }
|
| + {
|
| + // Finally, check the branch of the complex feature.
|
| + FeatureComparator comparator("complex");
|
| + comparator.channel.reset(
|
| + new version_info::Channel(version_info::Channel::BETA));
|
| + comparator.contexts = {Feature::BLESSED_EXTENSION_CONTEXT};
|
| + comparator.extension_types = {Manifest::TYPE_EXTENSION};
|
| + comparator.whitelist = {"aaa"};
|
| + comparator.CompareFeature(other_parent);
|
| + }
|
| + }
|
| +}
|
| +
|
| +} // namespace extensions
|
|
|