summaryrefslogtreecommitdiffstats
path: root/tools/json_schema_compiler
diff options
context:
space:
mode:
authorcalamity@chromium.org <calamity@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-22 12:06:51 +0000
committercalamity@chromium.org <calamity@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-22 12:06:51 +0000
commit2111fff9b9b9cb753c2041bb101d91a5288ec642 (patch)
treeaf944382f924324f9a85b578efc44c4272cdec6c /tools/json_schema_compiler
parent800892e772f745e18f0a57058e9dc2696bc6a167 (diff)
downloadchromium_src-2111fff9b9b9cb753c2041bb101d91a5288ec642.zip
chromium_src-2111fff9b9b9cb753c2041bb101d91a5288ec642.tar.gz
chromium_src-2111fff9b9b9cb753c2041bb101d91a5288ec642.tar.bz2
Add enum support to json_schema_compiler
json_schema_compiler: add support for enum properties and tests for enums BUG= TEST= Review URL: http://codereview.chromium.org/9424045 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@123026 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'tools/json_schema_compiler')
-rw-r--r--tools/json_schema_compiler/cc_generator.py86
-rw-r--r--tools/json_schema_compiler/compiler.py9
-rw-r--r--tools/json_schema_compiler/cpp_type_generator.py21
-rw-r--r--tools/json_schema_compiler/cpp_util.py1
-rw-r--r--tools/json_schema_compiler/h_generator.py43
-rw-r--r--tools/json_schema_compiler/model.py7
-rw-r--r--tools/json_schema_compiler/test/enums.json89
-rw-r--r--tools/json_schema_compiler/test/enums_unittest.cc131
-rw-r--r--tools/json_schema_compiler/test/json_schema_compiler_tests.gyp1
9 files changed, 343 insertions, 45 deletions
diff --git a/tools/json_schema_compiler/cc_generator.py b/tools/json_schema_compiler/cc_generator.py
index 24007d4..cc9214e 100644
--- a/tools/json_schema_compiler/cc_generator.py
+++ b/tools/json_schema_compiler/cc_generator.py
@@ -106,6 +106,8 @@ class CCGenerator(object):
.Append()
)
for prop in type_.properties.values():
+ c.Concat(self._InitializePropertyToDefault(prop, 'out'))
+ for prop in type_.properties.values():
c.Concat(self._GenerateTypePopulateProperty(prop, 'dict', 'out'))
(c.Append('return true;')
.Eblock('}')
@@ -165,14 +167,34 @@ class CCGenerator(object):
var: variable with value to create from
"""
c = code.Code()
- if prop.optional:
- c.Sblock('if (%s.get())' % var)
- if prop.type_ == PropertyType.ARRAY:
- c.Append('%s;' % self._util_cc_helper.PopulateDictionaryFromArray(
- prop, var, prop.name, dst))
+ if prop.type_ == PropertyType.ENUM:
+ c.Sblock('switch (%s) {' % var)
+ for enum_value in prop.enum_values:
+ (c.Append('case %s: {' %
+ self._cpp_type_generator.GetEnumValue(prop, enum_value))
+ .Append(' %s->SetWithoutPathExpansion('
+ '"%s", Value::CreateStringValue("%s"));' %
+ (dst, prop.name, enum_value))
+ .Append(' break;')
+ .Append('}')
+ )
+ # C++ requires the entire enum to be handled by a switch.
+ if prop.optional:
+ (c.Append('case %s: {' %
+ self._cpp_type_generator.GetEnumNoneValue(prop))
+ .Append(' break;')
+ .Append('}')
+ )
+ c.Eblock('}')
else:
- c.Append('%s->SetWithoutPathExpansion("%s", %s);' %
- (dst, prop.name, cpp_util.CreateValueFromSingleProperty(prop, var)))
+ if prop.optional:
+ c.Sblock('if (%s.get())' % var)
+ if prop.type_ == PropertyType.ARRAY:
+ c.Append('%s;' % self._util_cc_helper.PopulateDictionaryFromArray(
+ prop, var, prop.name, dst))
+ else:
+ c.Append('%s->SetWithoutPathExpansion("%s", %s);' %
+ (dst, prop.name, cpp_util.CreateValueFromSingleProperty(prop, var)))
return c
def _GenerateFunction(self, function):
@@ -242,6 +264,9 @@ class CCGenerator(object):
)
c.Substitute({'classname': classname})
+ for param in function.params:
+ c.Concat(self._InitializePropertyToDefault(param, 'params'))
+
for i, param in enumerate(function.params):
# Any failure will cause this function to return. If any argument is
# incorrect or missing, those following it are not processed. Note that
@@ -327,13 +352,30 @@ class CCGenerator(object):
# util_cc_helper deals with optional and required arrays
(c.Append('ListValue* list = NULL;')
.Append('if (!%(value_var)s->GetAsList(&list))')
- .Append(' return %s;' % failure_value)
+ .Append(' return %(failure_value)s;')
.Append('if (!%s)' % self._util_cc_helper.PopulateArrayFromList(
prop, 'list', dst + '->' + prop.unix_name))
- .Append(' return %s;' % failure_value)
+ .Append(' return %(failure_value)s;')
)
elif prop.type_ == PropertyType.CHOICES:
return self._GeneratePopulateChoices(prop, value_var, dst, failure_value)
+ elif prop.type_ == PropertyType.ENUM:
+ (c.Append('std::string enum_temp;')
+ .Append('if (!%(value_var)s->GetAsString(&enum_temp))')
+ .Append(' return %(failure_value)s;')
+ )
+ for i, enum_value in enumerate(prop.enum_values):
+ (c.Append(
+ ('if' if i == 0 else 'else if') +
+ '(enum_temp == "%s")' % enum_value)
+ .Append(' %s->%s = %s;' % (
+ dst,
+ prop.unix_name,
+ self._cpp_type_generator.GetEnumValue(prop, enum_value)))
+ )
+ (c.Append('else')
+ .Append(' return %(failure_value)s;')
+ )
else:
raise NotImplementedError(prop.type_)
c.Eblock('}')
@@ -356,13 +398,11 @@ class CCGenerator(object):
value_var: a Value* that should represent |prop|.
dst: the object with |prop| as a member.
failure_value: the value to return if |prop| cannot be extracted from
- |value_var|
+ |value_var|.
"""
type_var = '%s->%s_type' % (dst, prop.unix_name)
c = code.Code()
- c.Append('%s = %s;' %
- (type_var, self._cpp_type_generator.GetChoiceEnumNoneValue(prop)))
c.Sblock('switch (%s->GetType()) {' % value_var)
for choice in self._cpp_type_generator.GetExpandedChoicesInParams([prop]):
(c.Sblock('case %s: {' % cpp_util.GetValueType(choice))
@@ -370,8 +410,8 @@ class CCGenerator(object):
choice, value_var, dst, failure_value, check_type=False))
.Append('%s = %s;' %
(type_var,
- self._cpp_type_generator.GetChoiceEnumValue(
- prop, choice.type_)))
+ self._cpp_type_generator.GetEnumValue(
+ prop, choice.type_.name)))
.Append('break;')
.Eblock('}')
)
@@ -421,3 +461,21 @@ class CCGenerator(object):
c.Eblock('}')
return c
+
+ def _InitializePropertyToDefault(self, prop, dst):
+ """Initialize a model.Property to its default value inside an object.
+
+ dst: Type*
+ """
+ c = code.Code()
+ if prop.type_ in (PropertyType.ENUM, PropertyType.CHOICES):
+ if prop.optional:
+ prop_name = prop.unix_name
+ if prop.type_ == PropertyType.CHOICES:
+ prop_name = prop.unix_name + '_type'
+ c.Append('%s->%s = %s;' % (
+ dst,
+ prop_name,
+ self._cpp_type_generator.GetEnumNoneValue(prop)))
+ return c
+
diff --git a/tools/json_schema_compiler/compiler.py b/tools/json_schema_compiler/compiler.py
index d5f0802..6d3dd63 100644
--- a/tools/json_schema_compiler/compiler.py
+++ b/tools/json_schema_compiler/compiler.py
@@ -78,10 +78,11 @@ if __name__ == '__main__':
type_generator.AddNamespace(
referenced_namespace,
referenced_namespace.unix_name)
- cc_generator = cc_generator.CCGenerator(namespace, type_generator)
- cc_code = cc_generator.Generate().Render()
- h_generator = h_generator.HGenerator(namespace, type_generator)
- h_code = h_generator.Generate().Render()
+
+ h_code = (h_generator.HGenerator(namespace, type_generator)
+ .Generate().Render())
+ cc_code = (cc_generator.CCGenerator(namespace, type_generator)
+ .Generate().Render())
if dest_dir:
with open(
diff --git a/tools/json_schema_compiler/cpp_type_generator.py b/tools/json_schema_compiler/cpp_type_generator.py
index 793ae13..186a616 100644
--- a/tools/json_schema_compiler/cpp_type_generator.py
+++ b/tools/json_schema_compiler/cpp_type_generator.py
@@ -82,20 +82,19 @@ class CppTypeGenerator(object):
return Code().Append('} // %s' %
self.GetCppNamespaceName(self._namespace))
- def GetChoiceEnumNoneValue(self, prop):
- """Gets the enum value of the choices in the given model.Property
- indicating no choice has been set.
+ def GetEnumNoneValue(self, prop):
+ """Gets the enum value in the given model.Property indicating no value has
+ been set.
"""
return '%s_NONE' % prop.unix_name.upper()
- def GetChoiceEnumValue(self, prop, type_):
- """Gets the enum value of the choices in the given model.Property of the
- given type.
+ def GetEnumValue(self, prop, enum_value):
+ """Gets the enum value of the given model.Property of the given type.
e.g VAR_STRING
"""
- assert prop.choices[type_]
- return '%s_%s' % (prop.unix_name.upper(), type_.name)
+ return '%s_%s' % (
+ prop.unix_name.upper(), cpp_util.Classname(enum_value.upper()))
def GetChoicesEnumType(self, prop):
"""Gets the type of the enum for the given model.Property.
@@ -133,6 +132,8 @@ class CppTypeGenerator(object):
cpp_type = 'double'
elif prop.type_ == PropertyType.STRING:
cpp_type = 'std::string'
+ elif prop.type_ == PropertyType.ENUM:
+ cpp_type = cpp_util.Classname(prop.name)
elif prop.type_ == PropertyType.ANY:
cpp_type = 'DictionaryValue'
elif prop.type_ == PropertyType.ARRAY:
@@ -148,7 +149,9 @@ class CppTypeGenerator(object):
else:
raise NotImplementedError(prop.type_)
- if wrap_optional and prop.optional:
+ # Enums aren't wrapped because C++ won't allow it. Optional enums have a
+ # NONE value generated instead.
+ if wrap_optional and prop.optional and prop.type_ != PropertyType.ENUM:
cpp_type = 'scoped_ptr<%s> ' % cpp_type
if pad_for_generics:
return cpp_type
diff --git a/tools/json_schema_compiler/cpp_util.py b/tools/json_schema_compiler/cpp_util.py
index 1c4575a..83d5265 100644
--- a/tools/json_schema_compiler/cpp_util.py
+++ b/tools/json_schema_compiler/cpp_util.py
@@ -48,6 +48,7 @@ def GetValueType(prop):
PropertyType.INTEGER: 'Value::TYPE_INTEGER',
PropertyType.BOOLEAN: 'Value::TYPE_BOOLEAN',
PropertyType.DOUBLE: 'Value::TYPE_DOUBLE',
+ PropertyType.ENUM: 'Value::TYPE_STRING',
PropertyType.REF: 'Value::TYPE_DICTIONARY',
PropertyType.OBJECT: 'Value::TYPE_DICTIONARY',
PropertyType.ARRAY: 'Value::TYPE_LIST'
diff --git a/tools/json_schema_compiler/h_generator.py b/tools/json_schema_compiler/h_generator.py
index 7b83622..dfa4494 100644
--- a/tools/json_schema_compiler/h_generator.py
+++ b/tools/json_schema_compiler/h_generator.py
@@ -79,10 +79,36 @@ class HGenerator(object):
)
return c
+ def _GenerateEnumDeclaration(self, enum_name, prop, values):
+ c = code.Code()
+ c.Sblock('enum %s {' % enum_name)
+ if prop.optional:
+ c.Append(self._cpp_type_generator.GetEnumNoneValue(prop) + ',')
+ for value in values:
+ c.Append(self._cpp_type_generator.GetEnumValue(prop, value) + ',')
+ (c.Eblock('};')
+ .Append()
+ )
+ return c
+
def _GenerateFields(self, props):
"""Generates the field declarations when declaring a type.
"""
c = code.Code()
+ # Generate the enums needed for any fields with "choices"
+ for prop in props:
+ if prop.type_ == PropertyType.CHOICES:
+ enum_name = self._cpp_type_generator.GetChoicesEnumType(prop)
+ c.Concat(self._GenerateEnumDeclaration(
+ enum_name,
+ prop,
+ [choice.type_.name for choice in prop.choices.values()]))
+ c.Append('%s %s_type;' % (enum_name, prop.unix_name))
+ elif prop.type_ == PropertyType.ENUM:
+ c.Concat(self._GenerateEnumDeclaration(
+ self._cpp_type_generator.GetType(prop),
+ prop,
+ prop.enum_values))
for prop in self._cpp_type_generator.GetExpandedChoicesInParams(props):
if prop.description:
c.Comment(prop.description)
@@ -90,23 +116,6 @@ class HGenerator(object):
self._cpp_type_generator.GetType(prop, wrap_optional=True),
prop.unix_name))
c.Append()
- # Generate the enums needed for any fields with "choices"
- for prop in props:
- if prop.type_ == PropertyType.CHOICES:
- c.Sblock('enum %(enum_type)s {')
- c.Append(self._cpp_type_generator.GetChoiceEnumNoneValue(prop) + ',')
- for choice in prop.choices.values():
- c.Append(
- self._cpp_type_generator.GetChoiceEnumValue(prop, choice.type_)
- + ',')
- (c.Eblock('};')
- .Append()
- .Append('%(enum_type)s %(name)s_type;')
- )
- c.Substitute({
- 'enum_type': self._cpp_type_generator.GetChoicesEnumType(prop),
- 'name': prop.unix_name
- })
return c
def _GenerateType(self, type_, serializable=True):
diff --git a/tools/json_schema_compiler/model.py b/tools/json_schema_compiler/model.py
index c8a3c9a..5ff394a 100644
--- a/tools/json_schema_compiler/model.py
+++ b/tools/json_schema_compiler/model.py
@@ -109,7 +109,6 @@ class Function(object):
self.params.append(Property(param['name'], param))
assert (self.callback), self.name + " does not support callback"
-# TODO(calamity): handle Enum
class Property(object):
"""A property of a type OR a parameter to a function.
@@ -137,6 +136,11 @@ class Property(object):
if '$ref' in json:
self.ref_type = json['$ref']
self.type_ = PropertyType.REF
+ elif 'enum' in json:
+ self.enum_values = []
+ for value in json['enum']:
+ self.enum_values.append(value)
+ self.type_ = PropertyType.ENUM
elif 'type' in json:
json_type = json['type']
if json_type == 'string':
@@ -220,6 +224,7 @@ class PropertyType(object):
DOUBLE = _Info(True, "DOUBLE")
BOOLEAN = _Info(True, "BOOLEAN")
STRING = _Info(True, "STRING")
+ ENUM = _Info(False, "ENUM")
ARRAY = _Info(False, "ARRAY")
REF = _Info(False, "REF")
CHOICES = _Info(False, "CHOICES")
diff --git a/tools/json_schema_compiler/test/enums.json b/tools/json_schema_compiler/test/enums.json
new file mode 100644
index 0000000..51e1fd41
--- /dev/null
+++ b/tools/json_schema_compiler/test/enums.json
@@ -0,0 +1,89 @@
+[
+ {
+ "namespace": "enums",
+ "types": [
+ {
+ "id": "EnumType",
+ "type": "object",
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": ["one", "two", "three"]
+ }
+ }
+ },
+ {
+ "id": "OptionalEnumType",
+ "type": "object",
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": ["one", "two", "three"],
+ "optional": true
+ }
+ }
+ }
+ ],
+ "functions": [
+ {
+ "name": "takesEnum",
+ "type": "function",
+ "description": "Takes an enum as its parameter.",
+ "parameters": [
+ {
+ "name": "state",
+ "type": "string",
+ "enum": ["foo", "bar", "baz"]
+ },
+ {
+ "name": "callback",
+ "type": "function",
+ "parameters": []
+ }
+ ]
+ },
+ {
+ "name": "takesOptionalEnum",
+ "type": "function",
+ "description": "Takes an enum as its parameter.",
+ "parameters": [
+ {
+ "name": "state",
+ "type": "string",
+ "enum": ["foo", "bar", "baz"],
+ "optional": true
+ },
+ {
+ "name": "callback",
+ "type": "function",
+ "parameters": []
+ }
+ ]
+ },
+ {
+ "name": "takesMultipleOptionalEnums",
+ "type": "function",
+ "description": "Takes two enums as parameters.",
+ "parameters": [
+ {
+ "name": "state",
+ "type": "string",
+ "enum": ["foo", "bar", "baz"],
+ "optional": true
+ },
+ {
+ "name": "type",
+ "type": "string",
+ "enum": ["foo", "ding", "dong"],
+ "optional": true
+ },
+ {
+ "name": "callback",
+ "type": "function",
+ "parameters": []
+ }
+ ]
+ }
+ ]
+ }
+]
diff --git a/tools/json_schema_compiler/test/enums_unittest.cc b/tools/json_schema_compiler/test/enums_unittest.cc
new file mode 100644
index 0000000..14eece2
--- /dev/null
+++ b/tools/json_schema_compiler/test/enums_unittest.cc
@@ -0,0 +1,131 @@
+// Copyright (c) 2012 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 "tools/json_schema_compiler/test/enums.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+using namespace test::api::enums;
+
+TEST(JsonSchemaCompilerEnumsTest, EnumTypePopulate) {
+ {
+ scoped_ptr<EnumType> enum_type(new EnumType());
+ scoped_ptr<DictionaryValue> value(new DictionaryValue());
+ value->Set("type", Value::CreateStringValue("one"));
+ EXPECT_TRUE(EnumType::Populate(*value, enum_type.get()));
+ EXPECT_EQ(EnumType::TYPE_ONE, enum_type->type);
+ EXPECT_TRUE(value->Equals(enum_type->ToValue().get()));
+ }
+ {
+ scoped_ptr<EnumType> enum_type(new EnumType());
+ scoped_ptr<DictionaryValue> value(new DictionaryValue());
+ value->Set("type", Value::CreateStringValue("invalid"));
+ EXPECT_FALSE(EnumType::Populate(*value, enum_type.get()));
+ }
+}
+
+TEST(JsonSchemaCompilerEnumsTest, OptionalEnumTypePopulate) {
+ {
+ scoped_ptr<OptionalEnumType> enum_type(new OptionalEnumType());
+ scoped_ptr<DictionaryValue> value(new DictionaryValue());
+ value->Set("type", Value::CreateStringValue("two"));
+ EXPECT_TRUE(OptionalEnumType::Populate(*value, enum_type.get()));
+ EXPECT_EQ(OptionalEnumType::TYPE_TWO, enum_type->type);
+ EXPECT_TRUE(value->Equals(enum_type->ToValue().get()));
+ }
+ {
+ scoped_ptr<OptionalEnumType> enum_type(new OptionalEnumType());
+ scoped_ptr<DictionaryValue> value(new DictionaryValue());
+ EXPECT_TRUE(OptionalEnumType::Populate(*value, enum_type.get()));
+ EXPECT_EQ(OptionalEnumType::TYPE_NONE, enum_type->type);
+ EXPECT_TRUE(value->Equals(enum_type->ToValue().get()));
+ }
+ {
+ scoped_ptr<OptionalEnumType> enum_type(new OptionalEnumType());
+ scoped_ptr<DictionaryValue> value(new DictionaryValue());
+ value->Set("type", Value::CreateStringValue("invalid"));
+ EXPECT_FALSE(OptionalEnumType::Populate(*value, enum_type.get()));
+ }
+}
+
+TEST(JsonSchemaCompilerEnumsTest, TakesEnumParamsCreate) {
+ {
+ scoped_ptr<ListValue> params_value(new ListValue());
+ params_value->Append(Value::CreateStringValue("baz"));
+ scoped_ptr<TakesEnum::Params> params(
+ TakesEnum::Params::Create(*params_value));
+ EXPECT_TRUE(params.get());
+ EXPECT_EQ(TakesEnum::Params::STATE_BAZ, params->state);
+ }
+ {
+ scoped_ptr<ListValue> params_value(new ListValue());
+ params_value->Append(Value::CreateStringValue("invalid"));
+ scoped_ptr<TakesEnum::Params> params(
+ TakesEnum::Params::Create(*params_value));
+ EXPECT_FALSE(params.get());
+ }
+}
+
+TEST(JsonSchemaCompilerEnumsTest, TakesOptionalEnumParamsCreate) {
+ {
+ scoped_ptr<ListValue> params_value(new ListValue());
+ params_value->Append(Value::CreateStringValue("baz"));
+ scoped_ptr<TakesOptionalEnum::Params> params(
+ TakesOptionalEnum::Params::Create(*params_value));
+ EXPECT_TRUE(params.get());
+ EXPECT_EQ(TakesOptionalEnum::Params::STATE_BAZ, params->state);
+ }
+ {
+ scoped_ptr<ListValue> params_value(new ListValue());
+ scoped_ptr<TakesOptionalEnum::Params> params(
+ TakesOptionalEnum::Params::Create(*params_value));
+ EXPECT_TRUE(params.get());
+ EXPECT_EQ(TakesOptionalEnum::Params::STATE_NONE, params->state);
+ }
+ {
+ scoped_ptr<ListValue> params_value(new ListValue());
+ params_value->Append(Value::CreateStringValue("invalid"));
+ scoped_ptr<TakesOptionalEnum::Params> params(
+ TakesOptionalEnum::Params::Create(*params_value));
+ EXPECT_FALSE(params.get());
+ }
+}
+
+TEST(JsonSchemaCompilerEnumsTest, TakesMultipleOptionalEnumsParamsCreate) {
+ {
+ scoped_ptr<ListValue> params_value(new ListValue());
+ params_value->Append(Value::CreateStringValue("foo"));
+ params_value->Append(Value::CreateStringValue("foo"));
+ scoped_ptr<TakesMultipleOptionalEnums::Params> params(
+ TakesMultipleOptionalEnums::Params::Create(*params_value));
+ EXPECT_TRUE(params.get());
+ EXPECT_EQ(TakesMultipleOptionalEnums::Params::STATE_FOO, params->state);
+ EXPECT_EQ(TakesMultipleOptionalEnums::Params::TYPE_FOO, params->type);
+ }
+ {
+ scoped_ptr<ListValue> params_value(new ListValue());
+ params_value->Append(Value::CreateStringValue("foo"));
+ scoped_ptr<TakesMultipleOptionalEnums::Params> params(
+ TakesMultipleOptionalEnums::Params::Create(*params_value));
+ EXPECT_TRUE(params.get());
+ EXPECT_EQ(TakesMultipleOptionalEnums::Params::STATE_FOO, params->state);
+ EXPECT_EQ(TakesMultipleOptionalEnums::Params::TYPE_NONE, params->type);
+ }
+ {
+ scoped_ptr<ListValue> params_value(new ListValue());
+ scoped_ptr<TakesMultipleOptionalEnums::Params> params(
+ TakesMultipleOptionalEnums::Params::Create(*params_value));
+ EXPECT_TRUE(params.get());
+ EXPECT_EQ(TakesMultipleOptionalEnums::Params::STATE_NONE, params->state);
+ EXPECT_EQ(TakesMultipleOptionalEnums::Params::TYPE_NONE, params->type);
+ }
+ {
+ scoped_ptr<ListValue> params_value(new ListValue());
+ params_value->Append(Value::CreateStringValue("baz"));
+ params_value->Append(Value::CreateStringValue("invalid"));
+ scoped_ptr<TakesMultipleOptionalEnums::Params> params(
+ TakesMultipleOptionalEnums::Params::Create(*params_value));
+ EXPECT_FALSE(params.get());
+ }
+}
diff --git a/tools/json_schema_compiler/test/json_schema_compiler_tests.gyp b/tools/json_schema_compiler/test/json_schema_compiler_tests.gyp
index 7781842..d22d83f 100644
--- a/tools/json_schema_compiler/test/json_schema_compiler_tests.gyp
+++ b/tools/json_schema_compiler/test/json_schema_compiler_tests.gyp
@@ -13,6 +13,7 @@
'array.json',
'choices.json',
'crossref.json',
+ 'enums.json',
'simple_api.json',
],
'cc_dir': 'tools/json_schema_compiler/test',