summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorhebert.christopherj@chromium.org <hebert.christopherj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-29 19:40:43 +0000
committerhebert.christopherj@chromium.org <hebert.christopherj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-29 19:40:43 +0000
commitb02033a8bdf6765bdba6b5f9f30e1eaa6aef2149 (patch)
tree114a633847504f0d673c3ea9c1247e2434d31a4b /tools
parentcb6d3d9f3b3344a8e01eff11a514c3798d1a5cdf (diff)
downloadchromium_src-b02033a8bdf6765bdba6b5f9f30e1eaa6aef2149.zip
chromium_src-b02033a8bdf6765bdba6b5f9f30e1eaa6aef2149.tar.gz
chromium_src-b02033a8bdf6765bdba6b5f9f30e1eaa6aef2149.tar.bz2
JSON Schema Compiler now supports optional and required ARRAYs of ENUMS.
Before, PopulateArrayFromList() was used, which does not support ENUMS of arbitrary type. Now, we iterate through all elements in the ARRAY (of strings) and add the appropriate ENUM value to the list. BUG=133635 TEST=(in array_unittest.cc) Review URL: https://chromiumcodereview.appspot.com/10642011 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@144961 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'tools')
-rw-r--r--tools/json_schema_compiler/cc_generator.py80
-rw-r--r--tools/json_schema_compiler/test/arrays.json27
-rw-r--r--tools/json_schema_compiler/test/arrays_unittest.cc62
3 files changed, 140 insertions, 29 deletions
diff --git a/tools/json_schema_compiler/cc_generator.py b/tools/json_schema_compiler/cc_generator.py
index 3bba684..1a7f80c 100644
--- a/tools/json_schema_compiler/cc_generator.py
+++ b/tools/json_schema_compiler/cc_generator.py
@@ -498,12 +498,15 @@ 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 %(failure_value)s;')
- .Append('if (!%s)' % self._util_cc_helper.PopulateArrayFromList(
- self._cpp_type_generator.GetReferencedProperty(prop), 'list',
- dst + '->' + prop.unix_name, prop.optional))
- .Append(' return %(failure_value)s;')
- )
+ .Append(' return %(failure_value)s;'))
+ if prop.item_type.type_ == PropertyType.ENUM:
+ self._GenerateListValueToEnumArrayConversion(c, prop)
+ else:
+ (c.Append('if (!%s)' % self._util_cc_helper.PopulateArrayFromList(
+ self._cpp_type_generator.GetReferencedProperty(prop), 'list',
+ dst + '->' + prop.unix_name, prop.optional))
+ .Append(' return %(failure_value)s;')
+ )
elif prop.type_ == PropertyType.CHOICES:
type_var = '%(dst)s->%(name)s_type'
c.Sblock('switch (%(value_var)s->GetType()) {')
@@ -524,22 +527,10 @@ class CCGenerator(object):
)
c.Eblock('}')
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;')
- )
+ c.Sblock('{')
+ self._GenerateStringToEnumConversion(c, prop, value_var, 'enum_temp')
+ c.Append('%(dst)s->%(name)s = enum_temp;')
+ c.Eblock('}')
elif prop.type_ == PropertyType.BINARY:
# This is the same if the property is optional or not. We need a pointer
# to the BinaryValue to be able to populate it, so a scoped_ptr is used
@@ -565,6 +556,51 @@ class CCGenerator(object):
c.Substitute(sub)
return c
+ def _GenerateListValueToEnumArrayConversion(self, c, prop):
+ """Appends code that converts a ListValue of string contstants to
+ an array of enums in dst.
+ Leaves dst, name, and failure_value unsubstituted.
+
+ c: the Code object that is being appended to.
+ prop: the property that the code is populating.
+ """
+ accessor = '.'
+ if prop.optional:
+ c.Append('%(dst)s->%(name)s.reset(new std::vector<' + (
+ self._cpp_type_generator.GetType(prop.item_type) + '>);'))
+ accessor = '->'
+ c.Sblock('for (ListValue::iterator it = list->begin(); '
+ 'it != list->end(); ++it) {')
+ self._GenerateStringToEnumConversion(c, prop.item_type,
+ '(*it)', 'enum_temp')
+ c.Append('%(dst)s->%(name)s' + accessor + 'push_back(enum_temp);')
+ c.Eblock('}')
+
+ def _GenerateStringToEnumConversion(self, c, prop, value_var, enum_temp):
+ """Appends code that converts a string to an enum.
+ Leaves failure_value unsubstituded.
+
+ c: the code that is appended to.
+ prop: the property that the code is populating.
+ value_var: the string value that is being converted.
+ enum_temp: the name used to store the temporary enum value.
+ """
+ (c.Append('%s %s;' % (self._cpp_type_generator.GetType(prop), enum_temp))
+ .Append('std::string enum_as_string;')
+ .Append('if (!%s->GetAsString(&enum_as_string))' % value_var)
+ .Append(' return %(failure_value)s;')
+ )
+ for i, enum_value in enumerate(prop.enum_values):
+ (c.Append(
+ ('if' if i == 0 else 'else if') +
+ '(enum_as_string == "%s")' % enum_value)
+ .Append(' ' + enum_temp + ' = %s;' % (
+ self._cpp_type_generator.GetEnumValue(prop, enum_value)))
+ )
+ (c.Append('else')
+ .Append(' return %(failure_value)s;')
+ )
+
def _GeneratePropertyFunctions(self, param_namespace, params):
"""Generate the functions for structures generated by a property such as
CreateEnumValue for ENUMs and Populate/ToValue for Params/Result objects.
diff --git a/tools/json_schema_compiler/test/arrays.json b/tools/json_schema_compiler/test/arrays.json
index 5cb1607..c5fbe9b 100644
--- a/tools/json_schema_compiler/test/arrays.json
+++ b/tools/json_schema_compiler/test/arrays.json
@@ -3,6 +3,33 @@
"namespace": "arrays",
"types": [
{
+ "id": "EnumArrayType",
+ "type": "object",
+ "properties": {
+ "types": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": ["one", "two", "three"]
+ }
+ }
+ }
+ },
+ {
+ "id": "OptionalEnumArrayType",
+ "type": "object",
+ "properties": {
+ "types": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": ["one", "two", "three"]
+ },
+ "optional": true
+ }
+ }
+ },
+ {
"id": "BasicArrayType",
"type": "object",
"properties": {
diff --git a/tools/json_schema_compiler/test/arrays_unittest.cc b/tools/json_schema_compiler/test/arrays_unittest.cc
index b905d31..0709677 100644
--- a/tools/json_schema_compiler/test/arrays_unittest.cc
+++ b/tools/json_schema_compiler/test/arrays_unittest.cc
@@ -51,6 +51,54 @@ TEST(JsonSchemaCompilerArrayTest, BasicArrayType) {
}
}
+TEST(JsonSchemaCompilerArrayTest, EnumArrayType) {
+ std::vector<EnumArrayType::TypesElement> enums;
+ enums.push_back(EnumArrayType::TYPES_ELEMENT_ONE);
+ enums.push_back(EnumArrayType::TYPES_ELEMENT_TWO);
+ enums.push_back(EnumArrayType::TYPES_ELEMENT_THREE);
+
+ scoped_ptr<ListValue> types(new ListValue());
+ for (size_t i = 0; i < enums.size(); ++i)
+ types->Append(EnumArrayType::CreateEnumValue(enums[i]).release());
+
+ DictionaryValue value;
+ value.Set("types", types.release());
+
+ EnumArrayType enum_array_type;
+ EXPECT_TRUE(EnumArrayType::Populate(value, &enum_array_type));
+ EXPECT_EQ(enums, enum_array_type.types);
+}
+
+TEST(JsonSchemaCompilerArrayTest, OptionalEnumArrayType) {
+ {
+ std::vector<OptionalEnumArrayType::TypesElement> enums;
+ enums.push_back(OptionalEnumArrayType::TYPES_ELEMENT_ONE);
+ enums.push_back(OptionalEnumArrayType::TYPES_ELEMENT_TWO);
+ enums.push_back(OptionalEnumArrayType::TYPES_ELEMENT_THREE);
+
+ scoped_ptr<ListValue> types(new ListValue());
+ for (size_t i = 0; i < enums.size(); ++i)
+ types->Append(OptionalEnumArrayType::CreateEnumValue(enums[i]).release());
+
+ DictionaryValue value;
+ value.Set("types", types.release());
+
+ OptionalEnumArrayType enum_array_type;
+ EXPECT_TRUE(OptionalEnumArrayType::Populate(value, &enum_array_type));
+ EXPECT_EQ(enums, *enum_array_type.types);
+ }
+ {
+ DictionaryValue value;
+ scoped_ptr<ListValue> enum_array(new ListValue());
+ enum_array->Append(Value::CreateStringValue("invalid"));
+
+ value.Set("types", enum_array.release());
+ OptionalEnumArrayType enum_array_type;
+ EXPECT_FALSE(OptionalEnumArrayType::Populate(value, &enum_array_type));
+ EXPECT_TRUE(enum_array_type.types->empty());
+ }
+}
+
TEST(JsonSchemaCompilerArrayTest, RefArrayType) {
{
scoped_ptr<DictionaryValue> value(new DictionaryValue());
@@ -61,7 +109,7 @@ TEST(JsonSchemaCompilerArrayTest, RefArrayType) {
value->Set("refs", ref_array.release());
scoped_ptr<RefArrayType> ref_array_type(new RefArrayType());
EXPECT_TRUE(RefArrayType::Populate(*value, ref_array_type.get()));
- EXPECT_EQ((size_t) 3, ref_array_type->refs.size());
+ ASSERT_EQ(3u, ref_array_type->refs.size());
EXPECT_EQ(1, ref_array_type->refs[0]->val);
EXPECT_EQ(2, ref_array_type->refs[1]->val);
EXPECT_EQ(3, ref_array_type->refs[2]->val);
@@ -87,7 +135,7 @@ TEST(JsonSchemaCompilerArrayTest, IntegerArrayParamsCreate) {
scoped_ptr<IntegerArray::Params> params(
IntegerArray::Params::Create(*params_value));
EXPECT_TRUE(params.get());
- EXPECT_EQ((size_t) 3, params->nums.size());
+ ASSERT_EQ(3u, params->nums.size());
EXPECT_EQ(2, params->nums[0]);
EXPECT_EQ(4, params->nums[1]);
EXPECT_EQ(8, params->nums[2]);
@@ -103,7 +151,7 @@ TEST(JsonSchemaCompilerArrayTest, AnyArrayParamsCreate) {
scoped_ptr<AnyArray::Params> params(
AnyArray::Params::Create(*params_value));
EXPECT_TRUE(params.get());
- EXPECT_EQ((size_t) 3, params->anys.size());
+ ASSERT_EQ(3u, params->anys.size());
int int_temp = 0;
EXPECT_TRUE(params->anys[0]->value().GetAsInteger(&int_temp));
EXPECT_EQ(1, int_temp);
@@ -118,7 +166,7 @@ TEST(JsonSchemaCompilerArrayTest, ObjectArrayParamsCreate) {
scoped_ptr<ObjectArray::Params> params(
ObjectArray::Params::Create(*params_value));
EXPECT_TRUE(params.get());
- EXPECT_EQ((size_t) 2, params->objects.size());
+ ASSERT_EQ(2u, params->objects.size());
int object_val = 0;
EXPECT_TRUE(params->objects[0]->additional_properties.GetInteger(
"val", &object_val));
@@ -137,7 +185,7 @@ TEST(JsonSchemaCompilerArrayTest, RefArrayParamsCreate) {
scoped_ptr<RefArray::Params> params(
RefArray::Params::Create(*params_value));
EXPECT_TRUE(params.get());
- EXPECT_EQ((size_t) 2, params->refs.size());
+ ASSERT_EQ(2u, params->refs.size());
EXPECT_EQ(1, params->refs[0]->val);
EXPECT_EQ(2, params->refs[1]->val);
}
@@ -150,7 +198,7 @@ TEST(JsonSchemaCompilerArrayTest, ReturnIntegerArrayResultCreate) {
ListValue* list = NULL;
EXPECT_TRUE(result->GetAsList(&list));
int temp;
- EXPECT_EQ((size_t) 2, list->GetSize());
+ ASSERT_EQ(2u, list->GetSize());
EXPECT_TRUE(list->GetInteger(0, &temp));
EXPECT_EQ(1, temp);
EXPECT_TRUE(list->GetInteger(1, &temp));
@@ -166,7 +214,7 @@ TEST(JsonSchemaCompilerArrayTest, ReturnRefArrayResultCreate) {
scoped_ptr<Value> result(ReturnRefArray::Result::Create(items));
ListValue* list = NULL;
EXPECT_TRUE(result->GetAsList(&list));
- EXPECT_EQ((size_t) 2, list->GetSize());
+ ASSERT_EQ(2u, list->GetSize());
DictionaryValue* item_value = NULL;
int temp;
EXPECT_TRUE(list->GetDictionary(0, &item_value));