1// Copyright 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "tools/json_schema_compiler/test/error_generation.h" 6 7#include "base/json/json_writer.h" 8#include "base/strings/utf_string_conversions.h" 9#include "testing/gtest/include/gtest/gtest.h" 10#include "tools/json_schema_compiler/test/test_util.h" 11 12using namespace test::api::error_generation; 13using base::FundamentalValue; 14using json_schema_compiler::test_util::Dictionary; 15using json_schema_compiler::test_util::List; 16 17template <typename T> 18base::string16 GetPopulateError(const base::Value& value) { 19 base::string16 error; 20 T test_type; 21 T::Populate(value, &test_type, &error); 22 return error; 23} 24 25testing::AssertionResult EqualsUtf16(const std::string& expected, 26 const base::string16& actual) { 27 if (base::ASCIIToUTF16(expected) != actual) 28 return testing::AssertionFailure() << expected << " != " << actual; 29 return testing::AssertionSuccess(); 30} 31 32// GenerateTypePopulate errors 33 34TEST(JsonSchemaCompilerErrorTest, RequiredPropertyPopulate) { 35 { 36 scoped_ptr<base::DictionaryValue> value = Dictionary( 37 "string", new base::StringValue("bling")); 38 EXPECT_TRUE(EqualsUtf16("", GetPopulateError<TestType>(*value))); 39 } 40 { 41 scoped_ptr<base::BinaryValue> value(new base::BinaryValue()); 42 EXPECT_TRUE(EqualsUtf16("expected dictionary, got binary", 43 GetPopulateError<TestType>(*value))); 44 } 45} 46 47TEST(JsonSchemaCompilerErrorTest, UnexpectedTypePopulation) { 48 { 49 scoped_ptr<base::ListValue> value(new base::ListValue()); 50 EXPECT_TRUE(EqualsUtf16("", 51 GetPopulateError<ChoiceType::Integers>(*value))); 52 } 53 { 54 scoped_ptr<base::BinaryValue> value(new base::BinaryValue()); 55 EXPECT_TRUE(EqualsUtf16("expected integers or integer, got binary", 56 GetPopulateError<ChoiceType::Integers>(*value))); 57 } 58} 59 60// GenerateTypePopulateProperty errors 61 62TEST(JsonSchemaCompilerErrorTest, TypeIsRequired) { 63 { 64 scoped_ptr<base::DictionaryValue> value = Dictionary( 65 "integers", new FundamentalValue(5)); 66 EXPECT_TRUE(EqualsUtf16("", GetPopulateError<ChoiceType>(*value))); 67 } 68 { 69 scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue()); 70 EXPECT_TRUE(EqualsUtf16("'integers' is required", 71 GetPopulateError<ChoiceType>(*value))); 72 } 73} 74 75// GenerateParamsCheck errors 76 77TEST(JsonSchemaCompilerErrorTest, TooManyParameters) { 78 { 79 scoped_ptr<base::ListValue> params_value = List( 80 new FundamentalValue(5)); 81 base::string16 error; 82 EXPECT_TRUE(TestFunction::Params::Create(*params_value, &error)); 83 } 84 { 85 scoped_ptr<base::ListValue> params_value = List( 86 new FundamentalValue(5), 87 new FundamentalValue(5)); 88 base::string16 error; 89 EXPECT_FALSE(TestFunction::Params::Create(*params_value, &error)); 90 EXPECT_TRUE(EqualsUtf16("expected 1 arguments, got 2", error)); 91 } 92} 93 94// GenerateFunctionParamsCreate errors 95 96TEST(JsonSchemaCompilerErrorTest, ParamIsRequired) { 97 { 98 scoped_ptr<base::ListValue> params_value = List( 99 new FundamentalValue(5)); 100 base::string16 error; 101 EXPECT_TRUE(TestFunction::Params::Create(*params_value, &error)); 102 } 103 { 104 scoped_ptr<base::ListValue> params_value = List( 105 base::Value::CreateNullValue()); 106 base::string16 error; 107 EXPECT_FALSE(TestFunction::Params::Create(*params_value, &error)); 108 EXPECT_TRUE(EqualsUtf16("'num' is required", error)); 109 } 110} 111 112// GeneratePopulateVariableFromValue errors 113 114TEST(JsonSchemaCompilerErrorTest, WrongPropertyValueType) { 115 { 116 scoped_ptr<base::DictionaryValue> value = Dictionary( 117 "string", new base::StringValue("yes")); 118 EXPECT_TRUE(EqualsUtf16("", GetPopulateError<TestType>(*value))); 119 } 120 { 121 scoped_ptr<base::DictionaryValue> value = Dictionary( 122 "string", new FundamentalValue(1.1)); 123 EXPECT_TRUE(EqualsUtf16("'string': expected string, got number", 124 GetPopulateError<TestType>(*value))); 125 } 126} 127 128TEST(JsonSchemaCompilerErrorTest, WrongParameterCreationType) { 129 { 130 base::string16 error; 131 scoped_ptr<base::ListValue> params_value = List( 132 new base::StringValue("Yeah!")); 133 EXPECT_TRUE(TestString::Params::Create(*params_value, &error)); 134 } 135 { 136 scoped_ptr<base::ListValue> params_value = List( 137 new FundamentalValue(5)); 138 base::string16 error; 139 EXPECT_FALSE(TestTypeInObject::Params::Create(*params_value, &error)); 140 EXPECT_TRUE(EqualsUtf16("'paramObject': expected dictionary, got integer", 141 error)); 142 } 143} 144 145TEST(JsonSchemaCompilerErrorTest, WrongTypeValueType) { 146 { 147 scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue()); 148 EXPECT_TRUE(EqualsUtf16("", GetPopulateError<ObjectType>(*value))); 149 } 150 { 151 scoped_ptr<base::DictionaryValue> value = Dictionary( 152 "otherType", new FundamentalValue(1.1)); 153 ObjectType out; 154 base::string16 error; 155 EXPECT_TRUE(ObjectType::Populate(*value, &out, &error)); 156 EXPECT_TRUE(EqualsUtf16("'otherType': expected dictionary, got number", 157 error)); 158 EXPECT_EQ(NULL, out.other_type.get()); 159 } 160} 161 162TEST(JsonSchemaCompilerErrorTest, UnableToPopulateArray) { 163 { 164 scoped_ptr<base::ListValue> params_value = List( 165 new FundamentalValue(5)); 166 EXPECT_TRUE(EqualsUtf16("", 167 GetPopulateError<ChoiceType::Integers>(*params_value))); 168 } 169 { 170 scoped_ptr<base::ListValue> params_value = List( 171 new FundamentalValue(5), 172 new FundamentalValue(false)); 173 EXPECT_TRUE(EqualsUtf16("unable to populate array 'integers'", 174 GetPopulateError<ChoiceType::Integers>(*params_value))); 175 } 176} 177 178TEST(JsonSchemaCompilerErrorTest, BinaryTypeExpected) { 179 { 180 scoped_ptr<base::DictionaryValue> value = Dictionary( 181 "data", new base::BinaryValue()); 182 EXPECT_TRUE(EqualsUtf16("", GetPopulateError<BinaryData>(*value))); 183 } 184 { 185 scoped_ptr<base::DictionaryValue> value = Dictionary( 186 "data", new FundamentalValue(1.1)); 187 EXPECT_TRUE(EqualsUtf16("'data': expected binary, got number", 188 GetPopulateError<BinaryData>(*value))); 189 } 190} 191 192TEST(JsonSchemaCompilerErrorTest, ListExpected) { 193 { 194 scoped_ptr<base::DictionaryValue> value = Dictionary( 195 "TheArray", new base::ListValue()); 196 EXPECT_TRUE(EqualsUtf16("", GetPopulateError<ArrayObject>(*value))); 197 } 198 { 199 scoped_ptr<base::DictionaryValue> value = Dictionary( 200 "TheArray", new FundamentalValue(5)); 201 EXPECT_TRUE(EqualsUtf16("'TheArray': expected list, got integer", 202 GetPopulateError<ArrayObject>(*value))); 203 } 204} 205 206// GenerateStringToEnumConversion errors 207 208TEST(JsonSchemaCompilerErrorTest, BadEnumValue) { 209 { 210 scoped_ptr<base::DictionaryValue> value = Dictionary( 211 "enumeration", new base::StringValue("one")); 212 EXPECT_TRUE(EqualsUtf16("", GetPopulateError<HasEnumeration>(*value))); 213 } 214 { 215 scoped_ptr<base::DictionaryValue> value = Dictionary( 216 "enumeration", new base::StringValue("bad sauce")); 217 EXPECT_TRUE(EqualsUtf16("'Enumeration': expected \"one\" or \"two\" " 218 "or \"three\", got \"bad sauce\"", 219 GetPopulateError<HasEnumeration>(*value))); 220 } 221} 222 223// Warn but don't fail out errors 224 225TEST(JsonSchemaCompilerErrorTest, WarnOnOptionalFailure) { 226 { 227 scoped_ptr<base::DictionaryValue> value = Dictionary( 228 "string", new base::StringValue("bling")); 229 EXPECT_TRUE(EqualsUtf16("", GetPopulateError<OptionalTestType>(*value))); 230 } 231 { 232 scoped_ptr<base::DictionaryValue> value = Dictionary( 233 "string", new base::FundamentalValue(1)); 234 235 OptionalTestType out; 236 base::string16 error; 237 EXPECT_TRUE(OptionalTestType::Populate(*value, &out, &error)); 238 EXPECT_TRUE(EqualsUtf16("'string': expected string, got integer", 239 error)); 240 EXPECT_EQ(NULL, out.string.get()); 241 } 242} 243 244TEST(JsonSchemaCompilerErrorTest, OptionalBinaryTypeFailure) { 245 { 246 scoped_ptr<base::DictionaryValue> value = Dictionary( 247 "data", new base::BinaryValue()); 248 EXPECT_TRUE(EqualsUtf16("", GetPopulateError<OptionalBinaryData>(*value))); 249 } 250 { 251 // There's a bug with silent failures if the key doesn't exist. 252 scoped_ptr<base::DictionaryValue> value = Dictionary("data", 253 new base::FundamentalValue(1)); 254 255 OptionalBinaryData out; 256 base::string16 error; 257 EXPECT_TRUE(OptionalBinaryData::Populate(*value, &out, &error)); 258 EXPECT_TRUE(EqualsUtf16("'data': expected binary, got integer", 259 error)); 260 EXPECT_EQ(NULL, out.data.get()); 261 } 262} 263 264TEST(JsonSchemaCompilerErrorTest, OptionalArrayTypeFailure) { 265 { 266 scoped_ptr<base::DictionaryValue> value = Dictionary( 267 "TheArray", new base::ListValue()); 268 EXPECT_TRUE(EqualsUtf16("", GetPopulateError<ArrayObject>(*value))); 269 } 270 { 271 scoped_ptr<base::DictionaryValue> value = Dictionary( 272 "TheArray", new FundamentalValue(5)); 273 ArrayObject out; 274 base::string16 error; 275 EXPECT_TRUE(ArrayObject::Populate(*value, &out, &error)); 276 EXPECT_TRUE(EqualsUtf16("'TheArray': expected list, got integer", 277 error)); 278 EXPECT_EQ(NULL, out.the_array.get()); 279 } 280} 281 282TEST(JsonSchemaCompilerErrorTest, OptionalUnableToPopulateArray) { 283 { 284 scoped_ptr<base::ListValue> params_value = List( 285 new FundamentalValue(5)); 286 EXPECT_TRUE(EqualsUtf16("", 287 GetPopulateError<OptionalChoiceType::Integers>(*params_value))); 288 } 289 { 290 scoped_ptr<base::ListValue> params_value = List( 291 new FundamentalValue(5), 292 new FundamentalValue(false)); 293 OptionalChoiceType::Integers out; 294 base::string16 error; 295 EXPECT_TRUE(OptionalChoiceType::Integers::Populate(*params_value, &out, 296 &error)); 297 EXPECT_TRUE(EqualsUtf16("unable to populate array 'integers'", 298 error)); 299 EXPECT_EQ(NULL, out.as_integer.get()); 300 } 301} 302 303TEST(JsonSchemaCompilerErrorTest, MultiplePopulationErrors) { 304 { 305 306 scoped_ptr<base::DictionaryValue> value = Dictionary( 307 "TheArray", new FundamentalValue(5)); 308 ArrayObject out; 309 base::string16 error; 310 EXPECT_TRUE(ArrayObject::Populate(*value, &out, &error)); 311 EXPECT_TRUE(EqualsUtf16("'TheArray': expected list, got integer", 312 error)); 313 EXPECT_EQ(NULL, out.the_array.get()); 314 315 EXPECT_TRUE(ArrayObject::Populate(*value, &out, &error)); 316 EXPECT_TRUE(EqualsUtf16("'TheArray': expected list, got integer; " 317 "'TheArray': expected list, got integer", 318 error)); 319 EXPECT_EQ(NULL, out.the_array.get()); 320 } 321} 322 323TEST(JsonSchemaCompilerErrorTest, TooManyKeys) { 324 { 325 scoped_ptr<base::DictionaryValue> value = Dictionary( 326 "string", new base::StringValue("yes")); 327 EXPECT_TRUE(EqualsUtf16("", GetPopulateError<TestType>(*value))); 328 } 329 { 330 scoped_ptr<base::DictionaryValue> value = Dictionary( 331 "string", new base::StringValue("yes"), 332 "ohno", new base::StringValue("many values")); 333 EXPECT_TRUE(EqualsUtf16("found unexpected key 'ohno'", 334 GetPopulateError<TestType>(*value))); 335 } 336} 337