skir-codemirror-plugin 1.0.4 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/json/schema_validator.js +6 -9
- package/dist/json/schema_validator.js.map +1 -1
- package/dist/json/schema_validator.test.js +46 -1
- package/dist/json/schema_validator.test.js.map +1 -1
- package/package.json +1 -1
- package/src/json/schema_validator.test.ts +50 -1
- package/src/json/schema_validator.ts +6 -10
|
@@ -183,7 +183,7 @@ class SchemaValidator {
|
|
|
183
183
|
this.errors.push({
|
|
184
184
|
kind: "error",
|
|
185
185
|
segment: value.segment,
|
|
186
|
-
message: "Expected:
|
|
186
|
+
message: "Expected: constant variant",
|
|
187
187
|
});
|
|
188
188
|
}
|
|
189
189
|
else if (name === "unknown" || name === "UNKNOWN" || fieldDef) {
|
|
@@ -233,24 +233,21 @@ class SchemaValidator {
|
|
|
233
233
|
return;
|
|
234
234
|
}
|
|
235
235
|
const kind = JSON.parse(kindKv.value.jsonCode);
|
|
236
|
-
const
|
|
237
|
-
|
|
238
|
-
if (!isLowercase && !isUppercase) {
|
|
236
|
+
const variantDef = nameToVariantDef[kind];
|
|
237
|
+
if (!variantDef) {
|
|
239
238
|
this.errors.push({
|
|
240
239
|
kind: "error",
|
|
241
240
|
segment: kindKv.value.segment,
|
|
242
|
-
message: "
|
|
241
|
+
message: "Unknown variant",
|
|
243
242
|
});
|
|
244
243
|
return;
|
|
245
244
|
}
|
|
246
|
-
|
|
247
|
-
if (!variantDef) {
|
|
245
|
+
else if (variantDef.type === undefined) {
|
|
248
246
|
this.errors.push({
|
|
249
247
|
kind: "error",
|
|
250
248
|
segment: kindKv.value.segment,
|
|
251
|
-
message: "
|
|
249
|
+
message: "Expected: wrapper variant",
|
|
252
250
|
});
|
|
253
|
-
return;
|
|
254
251
|
}
|
|
255
252
|
const valueKv = object.keyValues["value"];
|
|
256
253
|
if (!valueKv) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema_validator.js","sourceRoot":"","sources":["../../src/json/schema_validator.ts"],"names":[],"mappings":"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","sourcesContent":["import { primitiveSerializer } from \"skir-client\";\nimport { toJson } from \"./to_json\";\nimport type {\n EnumDefinition,\n FieldDefinition,\n Hint,\n JsonError,\n JsonObject,\n JsonValue,\n MutableTypeHint,\n Path,\n PrimitiveType,\n RecordDefinition,\n TypeDefinition,\n TypeHint,\n TypeSignature,\n ValidationResult,\n VariantDefinition,\n} from \"./types\";\n\nexport function validateSchema(\n value: JsonValue,\n schema: TypeDefinition,\n): ValidationResult {\n const idToRecordDef: { [id: string]: RecordDefinition } = {};\n for (const record of schema.records) {\n idToRecordDef[record.id] = record;\n }\n\n const validator = new SchemaValidator(idToRecordDef);\n const root: Path = { kind: \"root\" };\n validator.validate(value, root, schema.type);\n const pathToTypeHint = new Map<Path, TypeHint>();\n for (const hint of validator.hints) {\n const { valueContext } = hint;\n if (valueContext) {\n pathToTypeHint.set(valueContext.path, hint);\n }\n }\n return {\n errors: validator.errors,\n hints: validator.hints,\n rootTypeHint: validator.rootTypeHint,\n pathToTypeHint: pathToTypeHint,\n };\n}\n\nclass SchemaValidator {\n constructor(readonly idToRecordDef: { [id: string]: RecordDefinition }) {}\n readonly errors: JsonError[] = [];\n readonly hints: Hint[] = [];\n private readonly typeHintStack: MutableTypeHint[] = [];\n rootTypeHint: TypeHint | undefined;\n\n validate(\n value: JsonValue,\n path: Path,\n schema: TypeSignature,\n optionalSchema?: TypeSignature,\n ): void {\n const { idToRecordDef, typeHintStack } = this;\n value.expectedType = schema;\n // For every call to pushTypeHint() there emust be one call to typeHintStack.pop()\n const pushTypeHint = (options?: {\n enumDefinition?: EnumDefinition;\n }): void => {\n const typeDesc = getTypeDesc(optionalSchema ?? schema);\n const typeDoc = getTypeDoc(schema, idToRecordDef);\n const message = [typeDesc];\n if (typeDoc) {\n message.push(typeDoc);\n }\n if (value.kind === \"array\") {\n const { length } = value.values;\n if (length) {\n message.push(`Length: ${length}`);\n }\n }\n const hint: MutableTypeHint = {\n segment: value.firstToken,\n message: message.length === 1 ? message[0] : message,\n valueContext: { value, path },\n childHints: [],\n enumDefinition: options?.enumDefinition,\n };\n if (typeHintStack.length) {\n const topOfStack = typeHintStack[typeHintStack.length - 1];\n topOfStack.childHints.push(hint);\n } else {\n this.rootTypeHint = hint;\n }\n this.hints.push(hint);\n typeHintStack.push(hint);\n };\n switch (schema.kind) {\n case \"array\": {\n if (value.kind === \"array\") {\n pushTypeHint();\n for (const [index, item] of value.values.entries()) {\n const { key_extractor: keyExtractor, item: itemSchema } =\n schema.value;\n const itemKey = extractItemKey(item, keyExtractor);\n const itemPath: Path = {\n kind: \"array-item\",\n index: index,\n key: itemKey,\n arrayPath: path,\n };\n this.validate(item, itemPath, itemSchema);\n }\n typeHintStack.pop();\n } else {\n this.errors.push({\n kind: \"error\",\n segment: value.segment,\n message: \"Expected: array\",\n });\n }\n break;\n }\n case \"optional\": {\n if (value.kind === \"literal\" && value.jsonCode === \"null\") {\n pushTypeHint();\n typeHintStack.pop();\n } else {\n this.validate(value, path, schema.value, schema);\n }\n break;\n }\n case \"primitive\": {\n const primitiveType = schema.value;\n if (primitiveType === \"timestamp\") {\n if (this.validateTimestamp(value)) {\n pushTypeHint();\n typeHintStack.pop();\n }\n } else if (hasPrimitiveType(value, primitiveType)) {\n pushTypeHint();\n typeHintStack.pop();\n } else {\n this.errors.push({\n kind: \"error\",\n segment: value.firstToken,\n message: `Expected: ${primitiveType}`,\n });\n }\n break;\n }\n case \"record\": {\n const recordDef = idToRecordDef[schema.value];\n if (recordDef.kind === \"struct\") {\n const nameToFieldDef: { [name: string]: FieldDefinition } = {};\n recordDef.fields.forEach((field) => {\n nameToFieldDef[field.name] = field;\n });\n if (value.kind === \"object\") {\n pushTypeHint();\n for (const keyValue of Object.values(value.keyValues)) {\n const { key, value } = keyValue;\n const fieldDef = nameToFieldDef[key];\n if (fieldDef) {\n if (fieldDef.doc) {\n this.hints.push({\n segment: keyValue.keySegment,\n message: fieldDef.doc,\n });\n }\n const valuePath: Path = {\n kind: \"field-value\",\n fieldName: key,\n structPath: path,\n };\n this.validate(value, valuePath, fieldDef.type!);\n } else {\n this.errors.push({\n kind: \"error\",\n segment: keyValue.keySegment,\n message: \"Unknown field\",\n });\n }\n }\n typeHintStack.pop();\n } else {\n this.errors.push({\n kind: \"error\",\n segment: value.firstToken,\n message: \"Expected: object\",\n });\n }\n } else {\n // Enum\n const nameToVariantDef: { [name: string]: VariantDefinition } = {};\n recordDef.variants.forEach((variant) => {\n nameToVariantDef[variant.name.toLowerCase()] = variant;\n nameToVariantDef[variant.name.toUpperCase()] = variant;\n });\n if (value.kind === \"object\") {\n pushTypeHint();\n this.validateEnumObject(value, path, nameToVariantDef);\n typeHintStack.pop();\n } else if (value.kind === \"literal\" && value.type === \"string\") {\n const name = JSON.parse(value.jsonCode);\n const fieldDef = nameToVariantDef[name];\n if (fieldDef && fieldDef.type) {\n this.errors.push({\n kind: \"error\",\n segment: value.segment,\n message: \"Expected: uppercase variant name\",\n });\n } else if (name === \"unknown\" || name === \"UNKNOWN\" || fieldDef) {\n pushTypeHint({ enumDefinition: recordDef });\n typeHintStack.pop();\n } else {\n this.errors.push({\n kind: \"error\",\n segment: value.segment,\n message: \"Unknown variant\",\n });\n }\n } else {\n this.errors.push({\n kind: \"error\",\n segment: value.firstToken,\n message: \"Expected: object or string\",\n });\n }\n }\n break;\n }\n default: {\n const _: never = schema;\n throw new Error(_);\n }\n }\n }\n\n validateEnumObject(\n object: JsonObject,\n enumPath: Path,\n nameToVariantDef: { [name: string]: VariantDefinition },\n ): void {\n const kindKv = object.keyValues[\"kind\"];\n if (!kindKv) {\n this.errors.push({\n kind: \"error\",\n segment: object.segment,\n message: \"Missing: 'kind'\",\n });\n return;\n }\n if (kindKv.value.kind !== \"literal\" || kindKv.value.type !== \"string\") {\n this.errors.push({\n kind: \"error\",\n segment: kindKv.value.firstToken,\n message: \"Expected: string\",\n });\n return;\n }\n const kind: string = JSON.parse(kindKv.value.jsonCode);\n const isLowercase = kind === kind.toLowerCase();\n const isUppercase = kind === kind.toUpperCase();\n if (!isLowercase && !isUppercase) {\n this.errors.push({\n kind: \"error\",\n segment: kindKv.value.segment,\n message: \"Expected: lowercase or uppercase variant name\",\n });\n return;\n }\n const variantDef = nameToVariantDef[kind];\n if (!variantDef) {\n this.errors.push({\n kind: \"error\",\n segment: kindKv.value.segment,\n message: \"Unknown variant\",\n });\n return;\n }\n const valueKv = object.keyValues[\"value\"];\n if (!valueKv) {\n this.errors.push({\n kind: \"error\",\n segment: object.segment,\n message: \"Missing: 'value'\",\n });\n return;\n }\n for (const key of object.allKeys) {\n if (key.key !== \"kind\" && key.key !== \"value\") {\n this.errors.push({\n kind: \"error\",\n segment: key.keySegment,\n message: \"Unexpected entry\",\n });\n }\n }\n const path: Path = {\n kind: \"variant-value\",\n variantName: variantDef.name,\n enumPath: enumPath,\n };\n this.validate(valueKv.value, path, variantDef.type!);\n }\n\n private validateTimestamp(value: JsonValue): boolean {\n if (value.kind !== \"object\") {\n this.errors.push({\n kind: \"error\",\n segment: value.firstToken,\n message: \"Expected: timestamp\",\n });\n return false;\n }\n const unixMillisKv = value.keyValues[\"unix_millis\"];\n if (!unixMillisKv) {\n this.errors.push({\n kind: \"error\",\n segment: value.firstToken,\n message: \"Missing: 'unix_millis'\",\n });\n return true;\n }\n if (\n unixMillisKv.value.kind !== \"literal\" ||\n unixMillisKv.value.type !== \"number\"\n ) {\n this.errors.push({\n kind: \"error\",\n segment: unixMillisKv.value.firstToken,\n message: \"Expected: number\",\n });\n return true;\n }\n const unixMillis = toJson(unixMillisKv.value) as number;\n if (unixMillis < -8640000000000000 || 8640000000000000 < unixMillis) {\n this.errors.push({\n kind: \"error\",\n segment: unixMillisKv.value.firstToken,\n message: \"Timestamp out of range\",\n });\n return true;\n }\n // At this point: the timestamp is technically valid.\n const formatted = value.keyValues[\"formatted\"];\n if (!formatted) {\n return true;\n }\n if (\n formatted.value.kind !== \"literal\" ||\n formatted.value.type !== \"string\"\n ) {\n this.errors.push({\n kind: \"error\",\n segment: formatted.value.firstToken,\n message: \"Expected: string\",\n });\n return true;\n }\n const formattedStr = toJson(formatted.value) as string;\n if (formattedStr === \"n/a\") {\n return true;\n }\n const parsedMillis = Date.parse(formattedStr);\n if (Number.isNaN(parsedMillis)) {\n this.errors.push({\n kind: \"error\",\n segment: formatted.value.firstToken,\n message: \"Invalid ISO 8601 date string\",\n });\n return true;\n }\n if (parsedMillis !== unixMillis) {\n this.errors.push({\n kind: \"error\",\n segment: formatted.value.firstToken,\n message: \"Does not match 'unix_millis'\",\n });\n }\n for (const key of value.allKeys) {\n if (key.key !== \"unix_millis\" && key.key !== \"formatted\") {\n this.errors.push({\n kind: \"error\",\n segment: key.keySegment,\n message: \"Unexpected entry\",\n });\n }\n }\n return true;\n }\n}\n\nfunction extractItemKey(\n item: JsonValue,\n keyExtractor: string | undefined,\n): string | null {\n if (keyExtractor === undefined) {\n return null;\n }\n const pieces = keyExtractor.split(\".\");\n let value = item;\n for (const piece of pieces) {\n if (value.kind !== \"object\") {\n // Error\n return null;\n }\n const kv = value.keyValues[piece];\n if (!kv) {\n // Error\n return null;\n }\n value = kv.value;\n }\n switch (value.kind) {\n case \"literal\": {\n switch (value.type) {\n case \"string\":\n case \"number\":\n case \"boolean\":\n return value.jsonCode;\n }\n // Error\n return null;\n }\n case \"object\": {\n const kv = value.keyValues[\"unix_millis\"];\n if (kv && kv.value.kind === \"literal\" && kv.value.type === \"number\") {\n return kv.value.jsonCode;\n } else {\n // Error\n return null;\n }\n }\n case \"array\": {\n // Error\n return null;\n }\n }\n}\n\nfunction hasPrimitiveType(\n value: JsonValue,\n expectedType: PrimitiveType,\n): boolean {\n switch (expectedType) {\n case \"bool\":\n return value.kind === \"literal\" && value.type === \"boolean\";\n case \"int32\": {\n return isInteger(value, -2147483648n, 2147483647n);\n }\n case \"int64\": {\n return isInteger(value, -9223372036854775808n, 9223372036854775807n);\n }\n case \"hash64\": {\n return isInteger(value, 0n, 18446744073709551615n);\n }\n case \"float32\":\n case \"float64\": {\n return isFloat(value);\n }\n case \"string\": {\n return value.kind === \"literal\" && value.type === \"string\";\n }\n case \"bytes\": {\n if (value.kind !== \"literal\") {\n return false;\n }\n try {\n primitiveSerializer(\"bytes\").fromJsonCode(value.jsonCode);\n return true;\n } catch {\n return false;\n }\n }\n case \"timestamp\": {\n // Case handled separately in validate()\n throw new Error();\n }\n }\n}\n\nfunction isInteger(value: JsonValue, min: bigint, max: bigint): boolean {\n if (value.kind !== \"literal\") {\n return false;\n }\n let decimalRep: string;\n if (value.type === \"string\") {\n decimalRep = JSON.parse(value.jsonCode);\n } else if (value.type === \"number\") {\n decimalRep = value.jsonCode;\n } else {\n return false;\n }\n let int: bigint;\n try {\n int = BigInt(decimalRep);\n } catch {\n return false;\n }\n return min <= int && int <= max;\n}\n\nfunction isFloat(value: JsonValue): boolean {\n if (value.kind !== \"literal\") {\n return false;\n }\n if (value.type === \"number\") {\n return true;\n } else if (\n value.type === \"string\" &&\n (value.jsonCode === '\"NaN\"' ||\n value.jsonCode === '\"Infinity\"' ||\n value.jsonCode === '\"-Infinity\"')\n ) {\n return true;\n } else {\n return false;\n }\n}\n\nfunction getTypeDesc(type: TypeSignature): string {\n function getTypePart(type: TypeSignature): string {\n switch (type.kind) {\n case \"primitive\":\n return type.value;\n case \"array\":\n return `[${getTypePart(type.value.item)}]`;\n case \"optional\":\n return `${getTypePart(type.value)}?`;\n case \"record\": {\n const recordId = type.value;\n return recordId.split(\":\")[1];\n }\n }\n }\n function getModulePart(type: TypeSignature): string | null {\n switch (type.kind) {\n case \"primitive\":\n return null;\n case \"array\":\n return getModulePart(type.value.item);\n case \"optional\":\n return getModulePart(type.value);\n case \"record\": {\n const recordId = type.value;\n return recordId.split(\":\")[0];\n }\n }\n }\n const typePart = getTypePart(type);\n const modulePart = getModulePart(type);\n return modulePart ? `${typePart} (${modulePart})` : typePart;\n}\n\nfunction getTypeDoc(\n type: TypeSignature,\n idToRecordDef: Readonly<{ [id: string]: RecordDefinition }>,\n): string | undefined {\n switch (type.kind) {\n case \"primitive\":\n return undefined;\n case \"array\":\n return getTypeDoc(type.value.item, idToRecordDef);\n case \"optional\":\n return getTypeDoc(type.value, idToRecordDef);\n case \"record\": {\n const recordId = type.value;\n const recordDef = idToRecordDef[recordId]!;\n return recordDef.doc;\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"schema_validator.js","sourceRoot":"","sources":["../../src/json/schema_validator.ts"],"names":[],"mappings":"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","sourcesContent":["import { primitiveSerializer } from \"skir-client\";\nimport { toJson } from \"./to_json\";\nimport type {\n EnumDefinition,\n FieldDefinition,\n Hint,\n JsonError,\n JsonObject,\n JsonValue,\n MutableTypeHint,\n Path,\n PrimitiveType,\n RecordDefinition,\n TypeDefinition,\n TypeHint,\n TypeSignature,\n ValidationResult,\n VariantDefinition,\n} from \"./types\";\n\nexport function validateSchema(\n value: JsonValue,\n schema: TypeDefinition,\n): ValidationResult {\n const idToRecordDef: { [id: string]: RecordDefinition } = {};\n for (const record of schema.records) {\n idToRecordDef[record.id] = record;\n }\n\n const validator = new SchemaValidator(idToRecordDef);\n const root: Path = { kind: \"root\" };\n validator.validate(value, root, schema.type);\n const pathToTypeHint = new Map<Path, TypeHint>();\n for (const hint of validator.hints) {\n const { valueContext } = hint;\n if (valueContext) {\n pathToTypeHint.set(valueContext.path, hint);\n }\n }\n return {\n errors: validator.errors,\n hints: validator.hints,\n rootTypeHint: validator.rootTypeHint,\n pathToTypeHint: pathToTypeHint,\n };\n}\n\nclass SchemaValidator {\n constructor(readonly idToRecordDef: { [id: string]: RecordDefinition }) {}\n readonly errors: JsonError[] = [];\n readonly hints: Hint[] = [];\n private readonly typeHintStack: MutableTypeHint[] = [];\n rootTypeHint: TypeHint | undefined;\n\n validate(\n value: JsonValue,\n path: Path,\n schema: TypeSignature,\n optionalSchema?: TypeSignature,\n ): void {\n const { idToRecordDef, typeHintStack } = this;\n value.expectedType = schema;\n // For every call to pushTypeHint() there emust be one call to typeHintStack.pop()\n const pushTypeHint = (options?: {\n enumDefinition?: EnumDefinition;\n }): void => {\n const typeDesc = getTypeDesc(optionalSchema ?? schema);\n const typeDoc = getTypeDoc(schema, idToRecordDef);\n const message = [typeDesc];\n if (typeDoc) {\n message.push(typeDoc);\n }\n if (value.kind === \"array\") {\n const { length } = value.values;\n if (length) {\n message.push(`Length: ${length}`);\n }\n }\n const hint: MutableTypeHint = {\n segment: value.firstToken,\n message: message.length === 1 ? message[0] : message,\n valueContext: { value, path },\n childHints: [],\n enumDefinition: options?.enumDefinition,\n };\n if (typeHintStack.length) {\n const topOfStack = typeHintStack[typeHintStack.length - 1];\n topOfStack.childHints.push(hint);\n } else {\n this.rootTypeHint = hint;\n }\n this.hints.push(hint);\n typeHintStack.push(hint);\n };\n switch (schema.kind) {\n case \"array\": {\n if (value.kind === \"array\") {\n pushTypeHint();\n for (const [index, item] of value.values.entries()) {\n const { key_extractor: keyExtractor, item: itemSchema } =\n schema.value;\n const itemKey = extractItemKey(item, keyExtractor);\n const itemPath: Path = {\n kind: \"array-item\",\n index: index,\n key: itemKey,\n arrayPath: path,\n };\n this.validate(item, itemPath, itemSchema);\n }\n typeHintStack.pop();\n } else {\n this.errors.push({\n kind: \"error\",\n segment: value.segment,\n message: \"Expected: array\",\n });\n }\n break;\n }\n case \"optional\": {\n if (value.kind === \"literal\" && value.jsonCode === \"null\") {\n pushTypeHint();\n typeHintStack.pop();\n } else {\n this.validate(value, path, schema.value, schema);\n }\n break;\n }\n case \"primitive\": {\n const primitiveType = schema.value;\n if (primitiveType === \"timestamp\") {\n if (this.validateTimestamp(value)) {\n pushTypeHint();\n typeHintStack.pop();\n }\n } else if (hasPrimitiveType(value, primitiveType)) {\n pushTypeHint();\n typeHintStack.pop();\n } else {\n this.errors.push({\n kind: \"error\",\n segment: value.firstToken,\n message: `Expected: ${primitiveType}`,\n });\n }\n break;\n }\n case \"record\": {\n const recordDef = idToRecordDef[schema.value];\n if (recordDef.kind === \"struct\") {\n const nameToFieldDef: { [name: string]: FieldDefinition } = {};\n recordDef.fields.forEach((field) => {\n nameToFieldDef[field.name] = field;\n });\n if (value.kind === \"object\") {\n pushTypeHint();\n for (const keyValue of Object.values(value.keyValues)) {\n const { key, value } = keyValue;\n const fieldDef = nameToFieldDef[key];\n if (fieldDef) {\n if (fieldDef.doc) {\n this.hints.push({\n segment: keyValue.keySegment,\n message: fieldDef.doc,\n });\n }\n const valuePath: Path = {\n kind: \"field-value\",\n fieldName: key,\n structPath: path,\n };\n this.validate(value, valuePath, fieldDef.type!);\n } else {\n this.errors.push({\n kind: \"error\",\n segment: keyValue.keySegment,\n message: \"Unknown field\",\n });\n }\n }\n typeHintStack.pop();\n } else {\n this.errors.push({\n kind: \"error\",\n segment: value.firstToken,\n message: \"Expected: object\",\n });\n }\n } else {\n // Enum\n const nameToVariantDef: { [name: string]: VariantDefinition } = {};\n recordDef.variants.forEach((variant) => {\n nameToVariantDef[variant.name.toLowerCase()] = variant;\n nameToVariantDef[variant.name.toUpperCase()] = variant;\n });\n if (value.kind === \"object\") {\n pushTypeHint();\n this.validateEnumObject(value, path, nameToVariantDef);\n typeHintStack.pop();\n } else if (value.kind === \"literal\" && value.type === \"string\") {\n const name = JSON.parse(value.jsonCode);\n const fieldDef = nameToVariantDef[name];\n if (fieldDef && fieldDef.type) {\n this.errors.push({\n kind: \"error\",\n segment: value.segment,\n message: \"Expected: constant variant\",\n });\n } else if (name === \"unknown\" || name === \"UNKNOWN\" || fieldDef) {\n pushTypeHint({ enumDefinition: recordDef });\n typeHintStack.pop();\n } else {\n this.errors.push({\n kind: \"error\",\n segment: value.segment,\n message: \"Unknown variant\",\n });\n }\n } else {\n this.errors.push({\n kind: \"error\",\n segment: value.firstToken,\n message: \"Expected: object or string\",\n });\n }\n }\n break;\n }\n default: {\n const _: never = schema;\n throw new Error(_);\n }\n }\n }\n\n validateEnumObject(\n object: JsonObject,\n enumPath: Path,\n nameToVariantDef: { [name: string]: VariantDefinition },\n ): void {\n const kindKv = object.keyValues[\"kind\"];\n if (!kindKv) {\n this.errors.push({\n kind: \"error\",\n segment: object.segment,\n message: \"Missing: 'kind'\",\n });\n return;\n }\n if (kindKv.value.kind !== \"literal\" || kindKv.value.type !== \"string\") {\n this.errors.push({\n kind: \"error\",\n segment: kindKv.value.firstToken,\n message: \"Expected: string\",\n });\n return;\n }\n const kind: string = JSON.parse(kindKv.value.jsonCode);\n const variantDef = nameToVariantDef[kind];\n if (!variantDef) {\n this.errors.push({\n kind: \"error\",\n segment: kindKv.value.segment,\n message: \"Unknown variant\",\n });\n return;\n } else if (variantDef.type === undefined) {\n this.errors.push({\n kind: \"error\",\n segment: kindKv.value.segment,\n message: \"Expected: wrapper variant\",\n });\n }\n const valueKv = object.keyValues[\"value\"];\n if (!valueKv) {\n this.errors.push({\n kind: \"error\",\n segment: object.segment,\n message: \"Missing: 'value'\",\n });\n return;\n }\n for (const key of object.allKeys) {\n if (key.key !== \"kind\" && key.key !== \"value\") {\n this.errors.push({\n kind: \"error\",\n segment: key.keySegment,\n message: \"Unexpected entry\",\n });\n }\n }\n const path: Path = {\n kind: \"variant-value\",\n variantName: variantDef.name,\n enumPath: enumPath,\n };\n this.validate(valueKv.value, path, variantDef.type!);\n }\n\n private validateTimestamp(value: JsonValue): boolean {\n if (value.kind !== \"object\") {\n this.errors.push({\n kind: \"error\",\n segment: value.firstToken,\n message: \"Expected: timestamp\",\n });\n return false;\n }\n const unixMillisKv = value.keyValues[\"unix_millis\"];\n if (!unixMillisKv) {\n this.errors.push({\n kind: \"error\",\n segment: value.firstToken,\n message: \"Missing: 'unix_millis'\",\n });\n return true;\n }\n if (\n unixMillisKv.value.kind !== \"literal\" ||\n unixMillisKv.value.type !== \"number\"\n ) {\n this.errors.push({\n kind: \"error\",\n segment: unixMillisKv.value.firstToken,\n message: \"Expected: number\",\n });\n return true;\n }\n const unixMillis = toJson(unixMillisKv.value) as number;\n if (unixMillis < -8640000000000000 || 8640000000000000 < unixMillis) {\n this.errors.push({\n kind: \"error\",\n segment: unixMillisKv.value.firstToken,\n message: \"Timestamp out of range\",\n });\n return true;\n }\n // At this point: the timestamp is technically valid.\n const formatted = value.keyValues[\"formatted\"];\n if (!formatted) {\n return true;\n }\n if (\n formatted.value.kind !== \"literal\" ||\n formatted.value.type !== \"string\"\n ) {\n this.errors.push({\n kind: \"error\",\n segment: formatted.value.firstToken,\n message: \"Expected: string\",\n });\n return true;\n }\n const formattedStr = toJson(formatted.value) as string;\n if (formattedStr === \"n/a\") {\n return true;\n }\n const parsedMillis = Date.parse(formattedStr);\n if (Number.isNaN(parsedMillis)) {\n this.errors.push({\n kind: \"error\",\n segment: formatted.value.firstToken,\n message: \"Invalid ISO 8601 date string\",\n });\n return true;\n }\n if (parsedMillis !== unixMillis) {\n this.errors.push({\n kind: \"error\",\n segment: formatted.value.firstToken,\n message: \"Does not match 'unix_millis'\",\n });\n }\n for (const key of value.allKeys) {\n if (key.key !== \"unix_millis\" && key.key !== \"formatted\") {\n this.errors.push({\n kind: \"error\",\n segment: key.keySegment,\n message: \"Unexpected entry\",\n });\n }\n }\n return true;\n }\n}\n\nfunction extractItemKey(\n item: JsonValue,\n keyExtractor: string | undefined,\n): string | null {\n if (keyExtractor === undefined) {\n return null;\n }\n const pieces = keyExtractor.split(\".\");\n let value = item;\n for (const piece of pieces) {\n if (value.kind !== \"object\") {\n // Error\n return null;\n }\n const kv = value.keyValues[piece];\n if (!kv) {\n // Error\n return null;\n }\n value = kv.value;\n }\n switch (value.kind) {\n case \"literal\": {\n switch (value.type) {\n case \"string\":\n case \"number\":\n case \"boolean\":\n return value.jsonCode;\n }\n // Error\n return null;\n }\n case \"object\": {\n const kv = value.keyValues[\"unix_millis\"];\n if (kv && kv.value.kind === \"literal\" && kv.value.type === \"number\") {\n return kv.value.jsonCode;\n } else {\n // Error\n return null;\n }\n }\n case \"array\": {\n // Error\n return null;\n }\n }\n}\n\nfunction hasPrimitiveType(\n value: JsonValue,\n expectedType: PrimitiveType,\n): boolean {\n switch (expectedType) {\n case \"bool\":\n return value.kind === \"literal\" && value.type === \"boolean\";\n case \"int32\": {\n return isInteger(value, -2147483648n, 2147483647n);\n }\n case \"int64\": {\n return isInteger(value, -9223372036854775808n, 9223372036854775807n);\n }\n case \"hash64\": {\n return isInteger(value, 0n, 18446744073709551615n);\n }\n case \"float32\":\n case \"float64\": {\n return isFloat(value);\n }\n case \"string\": {\n return value.kind === \"literal\" && value.type === \"string\";\n }\n case \"bytes\": {\n if (value.kind !== \"literal\") {\n return false;\n }\n try {\n primitiveSerializer(\"bytes\").fromJsonCode(value.jsonCode);\n return true;\n } catch {\n return false;\n }\n }\n case \"timestamp\": {\n // Case handled separately in validate()\n throw new Error();\n }\n }\n}\n\nfunction isInteger(value: JsonValue, min: bigint, max: bigint): boolean {\n if (value.kind !== \"literal\") {\n return false;\n }\n let decimalRep: string;\n if (value.type === \"string\") {\n decimalRep = JSON.parse(value.jsonCode);\n } else if (value.type === \"number\") {\n decimalRep = value.jsonCode;\n } else {\n return false;\n }\n let int: bigint;\n try {\n int = BigInt(decimalRep);\n } catch {\n return false;\n }\n return min <= int && int <= max;\n}\n\nfunction isFloat(value: JsonValue): boolean {\n if (value.kind !== \"literal\") {\n return false;\n }\n if (value.type === \"number\") {\n return true;\n } else if (\n value.type === \"string\" &&\n (value.jsonCode === '\"NaN\"' ||\n value.jsonCode === '\"Infinity\"' ||\n value.jsonCode === '\"-Infinity\"')\n ) {\n return true;\n } else {\n return false;\n }\n}\n\nfunction getTypeDesc(type: TypeSignature): string {\n function getTypePart(type: TypeSignature): string {\n switch (type.kind) {\n case \"primitive\":\n return type.value;\n case \"array\":\n return `[${getTypePart(type.value.item)}]`;\n case \"optional\":\n return `${getTypePart(type.value)}?`;\n case \"record\": {\n const recordId = type.value;\n return recordId.split(\":\")[1];\n }\n }\n }\n function getModulePart(type: TypeSignature): string | null {\n switch (type.kind) {\n case \"primitive\":\n return null;\n case \"array\":\n return getModulePart(type.value.item);\n case \"optional\":\n return getModulePart(type.value);\n case \"record\": {\n const recordId = type.value;\n return recordId.split(\":\")[0];\n }\n }\n }\n const typePart = getTypePart(type);\n const modulePart = getModulePart(type);\n return modulePart ? `${typePart} (${modulePart})` : typePart;\n}\n\nfunction getTypeDoc(\n type: TypeSignature,\n idToRecordDef: Readonly<{ [id: string]: RecordDefinition }>,\n): string | undefined {\n switch (type.kind) {\n case \"primitive\":\n return undefined;\n case \"array\":\n return getTypeDoc(type.value.item, idToRecordDef);\n case \"optional\":\n return getTypeDoc(type.value, idToRecordDef);\n case \"record\": {\n const recordId = type.value;\n const recordDef = idToRecordDef[recordId]!;\n return recordDef.doc;\n }\n }\n}\n"]}
|
|
@@ -223,7 +223,7 @@ describe("schema_validator", () => {
|
|
|
223
223
|
const mixedCaseResult = validateSchema(parse('{"kind": "Complex", "value": 123}'), schema);
|
|
224
224
|
expect(mixedCaseResult.errors).toMatch([
|
|
225
225
|
{
|
|
226
|
-
message: "
|
|
226
|
+
message: "Unknown variant",
|
|
227
227
|
},
|
|
228
228
|
]);
|
|
229
229
|
});
|
|
@@ -245,6 +245,51 @@ describe("schema_validator", () => {
|
|
|
245
245
|
},
|
|
246
246
|
]);
|
|
247
247
|
});
|
|
248
|
+
it("reports error when typed enum variant is provided as string", () => {
|
|
249
|
+
const schema = {
|
|
250
|
+
type: { kind: "record", value: "MyEnum" },
|
|
251
|
+
records: [
|
|
252
|
+
{
|
|
253
|
+
kind: "enum",
|
|
254
|
+
id: "MyEnum",
|
|
255
|
+
variants: [
|
|
256
|
+
{
|
|
257
|
+
name: "COMPLEX",
|
|
258
|
+
number: 1,
|
|
259
|
+
type: { kind: "primitive", value: "int32" },
|
|
260
|
+
},
|
|
261
|
+
],
|
|
262
|
+
},
|
|
263
|
+
],
|
|
264
|
+
};
|
|
265
|
+
const result = validateSchema(parse('"COMPLEX"'), schema);
|
|
266
|
+
expect(result.errors).toMatch([
|
|
267
|
+
{
|
|
268
|
+
message: "Expected: constant variant",
|
|
269
|
+
},
|
|
270
|
+
]);
|
|
271
|
+
});
|
|
272
|
+
it("reports error when constant enum variant is provided as object", () => {
|
|
273
|
+
const schema = {
|
|
274
|
+
type: { kind: "record", value: "MyEnum" },
|
|
275
|
+
records: [
|
|
276
|
+
{
|
|
277
|
+
kind: "enum",
|
|
278
|
+
id: "MyEnum",
|
|
279
|
+
variants: [{ name: "SIMPLE", number: 1 }],
|
|
280
|
+
},
|
|
281
|
+
],
|
|
282
|
+
};
|
|
283
|
+
const result = validateSchema(parse('{"kind": "SIMPLE"}'), schema);
|
|
284
|
+
expect(result.errors).toMatch([
|
|
285
|
+
{
|
|
286
|
+
message: "Expected: wrapper variant",
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
message: "Missing: 'value'",
|
|
290
|
+
},
|
|
291
|
+
]);
|
|
292
|
+
});
|
|
248
293
|
it("stores enum definition in type hint for UNKNOWN enum literal", () => {
|
|
249
294
|
const schema = {
|
|
250
295
|
type: { kind: "record", value: "MyEnum" },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema_validator.test.js","sourceRoot":"","sources":["../../src/json/schema_validator.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect } from \"buckwheat\";\nimport { describe, it } from \"mocha\";\nimport { parseJsonValue } from \"./json_parser.js\";\nimport { validateSchema } from \"./schema_validator.js\";\nimport { JsonValue, TypeDefinition } from \"./types.js\";\n\nfunction parse(json: string): JsonValue {\n const result = parseJsonValue(json);\n if (!result.value) {\n throw new Error(`JSON parse error: ${JSON.stringify(result.errors)}`);\n }\n return result.value;\n}\n\ndescribe(\"schema_validator\", () => {\n it(\"validates primitive int32\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"primitive\", value: \"int32\" },\n records: [],\n };\n const result = validateSchema(parse(\"123\"), schema);\n expect(result).toMatch({ errors: [] });\n if (result.hints.length === 0) {\n throw new Error(\"Expected type hints\");\n }\n });\n\n it(\"validates primitive string\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"primitive\", value: \"string\" },\n records: [],\n };\n const result = validateSchema(parse('\"hello\"'), schema);\n expect(result).toMatch({ errors: [] });\n });\n\n it(\"reports error for type mismatch (int32 vs string)\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"primitive\", value: \"int32\" },\n records: [],\n };\n const result = validateSchema(parse('\"hello\"'), schema);\n expect(result.errors).toMatch([\n {\n message: \"Expected: int32\",\n },\n ]);\n });\n\n it(\"validates array of primitives\", () => {\n const schema: TypeDefinition = {\n type: {\n kind: \"array\",\n value: { item: { kind: \"primitive\", value: \"int32\" } },\n },\n records: [],\n };\n const result = validateSchema(parse(\"[1, 2, 3]\"), schema);\n expect(result).toMatch({ errors: [] });\n });\n\n it(\"reports error for invalid array item\", () => {\n const schema: TypeDefinition = {\n type: {\n kind: \"array\",\n value: { item: { kind: \"primitive\", value: \"int32\" } },\n },\n records: [],\n };\n const result = validateSchema(parse('[1, \"bad\", 3]'), schema);\n expect(result.errors).toMatch([\n {\n message: \"Expected: int32\",\n segment: {\n start: 4,\n end: 9,\n },\n },\n ]);\n });\n\n it(\"validates optional field (present)\", () => {\n const schema: TypeDefinition = {\n type: {\n kind: \"optional\",\n value: { kind: \"primitive\", value: \"int32\" },\n },\n records: [],\n };\n const result = validateSchema(parse(\"123\"), schema);\n expect(result).toMatch({ errors: [] });\n });\n\n it(\"validates optional field (null)\", () => {\n const schema: TypeDefinition = {\n type: {\n kind: \"optional\",\n value: { kind: \"primitive\", value: \"int32\" },\n },\n records: [],\n };\n const result = validateSchema(parse(\"null\"), schema);\n expect(result).toMatch({ errors: [] });\n });\n\n it(\"validates struct\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"record\", value: \"MyStruct\" },\n records: [\n {\n kind: \"struct\",\n id: \"MyStruct\",\n fields: [\n {\n name: \"foo\",\n number: 1,\n type: { kind: \"primitive\", value: \"string\" },\n },\n {\n name: \"bar\",\n number: 2,\n type: { kind: \"primitive\", value: \"int32\" },\n },\n ],\n },\n ],\n };\n const result = validateSchema(parse('{\"foo\": \"hi\", \"bar\": 123}'), schema);\n expect(result).toMatch({ errors: [] });\n });\n\n it(\"reports unknown field in struct\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"record\", value: \"MyStruct\" },\n records: [\n {\n kind: \"struct\",\n id: \"MyStruct\",\n fields: [],\n },\n ],\n };\n const result = validateSchema(parse('{\"unknown\": 1}'), schema);\n expect(result.errors).toMatch([\n {\n message: \"Unknown field\",\n segment: {\n start: 1,\n end: 10,\n },\n },\n ]);\n });\n\n it(\"validates enum (string literal accepts lower and upper)\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"record\", value: \"MyEnum\" },\n records: [\n {\n kind: \"enum\",\n id: \"MyEnum\",\n variants: [\n { name: \"FOO\", number: 1 },\n { name: \"BAR\", number: 2 },\n ],\n },\n ],\n };\n const lowerResult = validateSchema(parse('\"foo\"'), schema);\n expect(lowerResult).toMatch({ errors: [] });\n\n const upperResult = validateSchema(parse('\"FOO\"'), schema);\n expect(upperResult).toMatch({ errors: [] });\n });\n\n it(\"rejects mixed-case enum string literal\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"record\", value: \"MyEnum\" },\n records: [\n {\n kind: \"enum\",\n id: \"MyEnum\",\n variants: [{ name: \"FOO\", number: 1 }],\n },\n ],\n };\n\n const result = validateSchema(parse('\"Foo\"'), schema);\n expect(result.errors).toMatch([\n {\n message: \"Unknown variant\",\n },\n ]);\n });\n\n it(\"accepts UNKNOWN and unknown enum literals\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"record\", value: \"MyEnum\" },\n records: [\n {\n kind: \"enum\",\n id: \"MyEnum\",\n variants: [{ name: \"FOO\", number: 1 }],\n },\n ],\n };\n\n expect(validateSchema(parse('\"UNKNOWN\"'), schema)).toMatch({ errors: [] });\n expect(validateSchema(parse('\"unknown\"'), schema)).toMatch({ errors: [] });\n\n const mixedCaseResult = validateSchema(parse('\"Unknown\"'), schema);\n expect(mixedCaseResult.errors).toMatch([\n {\n message: \"Unknown variant\",\n },\n ]);\n });\n\n it(\"validates enum object kind in lower and upper\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"record\", value: \"MyEnum\" },\n records: [\n {\n kind: \"enum\",\n id: \"MyEnum\",\n variants: [\n {\n name: \"COMPLEX\",\n number: 1,\n type: { kind: \"primitive\", value: \"int32\" },\n },\n ],\n },\n ],\n };\n\n expect(\n validateSchema(parse('{\"kind\": \"complex\", \"value\": 123}'), schema),\n ).toMatch({\n errors: [],\n });\n expect(\n validateSchema(parse('{\"kind\": \"COMPLEX\", \"value\": 123}'), schema),\n ).toMatch({\n errors: [],\n });\n\n const mixedCaseResult = validateSchema(\n parse('{\"kind\": \"Complex\", \"value\": 123}'),\n schema,\n );\n expect(mixedCaseResult.errors).toMatch([\n {\n message: \"Expected: lowercase or uppercase variant name\",\n },\n ]);\n });\n\n it(\"reports unknown enum variant\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"record\", value: \"MyEnum\" },\n records: [\n {\n kind: \"enum\",\n id: \"MyEnum\",\n variants: [{ name: \"First\", number: 1 }],\n },\n ],\n };\n const result = validateSchema(parse('\"Unknown\"'), schema);\n expect(result.errors).toMatch([\n {\n message: \"Unknown variant\",\n },\n ]);\n });\n\n it(\"stores enum definition in type hint for UNKNOWN enum literal\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"record\", value: \"MyEnum\" },\n records: [\n {\n kind: \"enum\",\n id: \"MyEnum\",\n variants: [\n { name: \"First\", number: 1 },\n { name: \"Second\", number: 2 },\n ],\n },\n ],\n };\n\n const result = validateSchema(parse('\"UNKNOWN\"'), schema);\n expect(result.errors).toMatch([]);\n if (!result.rootTypeHint) {\n throw new Error(\"Expected root type hint\");\n }\n expect(result.rootTypeHint.enumDefinition).toMatch({\n kind: \"enum\",\n id: \"MyEnum\",\n variants: [\n { name: \"First\", number: 1 },\n { name: \"Second\", number: 2 },\n ],\n });\n });\n\n it(\"stores enum definition in nested UNKNOWN enum field hint\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"record\", value: \"MyStruct\" },\n records: [\n {\n kind: \"struct\",\n id: \"MyStruct\",\n fields: [\n {\n name: \"status\",\n number: 1,\n type: { kind: \"record\", value: \"MyEnum\" },\n },\n ],\n },\n {\n kind: \"enum\",\n id: \"MyEnum\",\n variants: [\n { name: \"First\", number: 1 },\n { name: \"Second\", number: 2 },\n ],\n },\n ],\n };\n\n const result = validateSchema(parse('{\"status\": \"UNKNOWN\"}'), schema);\n expect(result.errors).toMatch([]);\n if (!result.rootTypeHint) {\n throw new Error(\"Expected root type hint\");\n }\n if (result.rootTypeHint.childHints.length !== 1) {\n throw new Error(\"Expected one child type hint\");\n }\n const statusHint = result.rootTypeHint.childHints[0];\n expect(statusHint.enumDefinition).toMatch({\n kind: \"enum\",\n id: \"MyEnum\",\n variants: [\n { name: \"First\", number: 1 },\n { name: \"Second\", number: 2 },\n ],\n });\n });\n\n it(\"validates enum (object with kind)\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"record\", value: \"MyEnum\" },\n records: [\n {\n kind: \"enum\",\n id: \"MyEnum\",\n variants: [\n {\n name: \"complex\",\n number: 1,\n type: { kind: \"primitive\", value: \"int32\" },\n },\n ],\n },\n ],\n };\n\n expect(\n validateSchema(parse('{\"kind\": \"complex\", \"value\": 123}'), schema),\n ).toMatch({ errors: [] });\n expect(\n validateSchema(parse('{\"kind\": \"complex\", \"value\": \"foo\"}'), schema),\n ).toMatch({\n errors: [\n {\n message: \"Expected: int32\",\n },\n ],\n });\n expect(validateSchema(parse('{\"kind\": \"complex\"}'), schema)).toMatch({\n errors: [\n {\n message: \"Missing: 'value'\",\n },\n ],\n });\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"schema_validator.test.js","sourceRoot":"","sources":["../../src/json/schema_validator.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect } from \"buckwheat\";\nimport { describe, it } from \"mocha\";\nimport { parseJsonValue } from \"./json_parser.js\";\nimport { validateSchema } from \"./schema_validator.js\";\nimport { JsonValue, TypeDefinition } from \"./types.js\";\n\nfunction parse(json: string): JsonValue {\n const result = parseJsonValue(json);\n if (!result.value) {\n throw new Error(`JSON parse error: ${JSON.stringify(result.errors)}`);\n }\n return result.value;\n}\n\ndescribe(\"schema_validator\", () => {\n it(\"validates primitive int32\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"primitive\", value: \"int32\" },\n records: [],\n };\n const result = validateSchema(parse(\"123\"), schema);\n expect(result).toMatch({ errors: [] });\n if (result.hints.length === 0) {\n throw new Error(\"Expected type hints\");\n }\n });\n\n it(\"validates primitive string\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"primitive\", value: \"string\" },\n records: [],\n };\n const result = validateSchema(parse('\"hello\"'), schema);\n expect(result).toMatch({ errors: [] });\n });\n\n it(\"reports error for type mismatch (int32 vs string)\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"primitive\", value: \"int32\" },\n records: [],\n };\n const result = validateSchema(parse('\"hello\"'), schema);\n expect(result.errors).toMatch([\n {\n message: \"Expected: int32\",\n },\n ]);\n });\n\n it(\"validates array of primitives\", () => {\n const schema: TypeDefinition = {\n type: {\n kind: \"array\",\n value: { item: { kind: \"primitive\", value: \"int32\" } },\n },\n records: [],\n };\n const result = validateSchema(parse(\"[1, 2, 3]\"), schema);\n expect(result).toMatch({ errors: [] });\n });\n\n it(\"reports error for invalid array item\", () => {\n const schema: TypeDefinition = {\n type: {\n kind: \"array\",\n value: { item: { kind: \"primitive\", value: \"int32\" } },\n },\n records: [],\n };\n const result = validateSchema(parse('[1, \"bad\", 3]'), schema);\n expect(result.errors).toMatch([\n {\n message: \"Expected: int32\",\n segment: {\n start: 4,\n end: 9,\n },\n },\n ]);\n });\n\n it(\"validates optional field (present)\", () => {\n const schema: TypeDefinition = {\n type: {\n kind: \"optional\",\n value: { kind: \"primitive\", value: \"int32\" },\n },\n records: [],\n };\n const result = validateSchema(parse(\"123\"), schema);\n expect(result).toMatch({ errors: [] });\n });\n\n it(\"validates optional field (null)\", () => {\n const schema: TypeDefinition = {\n type: {\n kind: \"optional\",\n value: { kind: \"primitive\", value: \"int32\" },\n },\n records: [],\n };\n const result = validateSchema(parse(\"null\"), schema);\n expect(result).toMatch({ errors: [] });\n });\n\n it(\"validates struct\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"record\", value: \"MyStruct\" },\n records: [\n {\n kind: \"struct\",\n id: \"MyStruct\",\n fields: [\n {\n name: \"foo\",\n number: 1,\n type: { kind: \"primitive\", value: \"string\" },\n },\n {\n name: \"bar\",\n number: 2,\n type: { kind: \"primitive\", value: \"int32\" },\n },\n ],\n },\n ],\n };\n const result = validateSchema(parse('{\"foo\": \"hi\", \"bar\": 123}'), schema);\n expect(result).toMatch({ errors: [] });\n });\n\n it(\"reports unknown field in struct\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"record\", value: \"MyStruct\" },\n records: [\n {\n kind: \"struct\",\n id: \"MyStruct\",\n fields: [],\n },\n ],\n };\n const result = validateSchema(parse('{\"unknown\": 1}'), schema);\n expect(result.errors).toMatch([\n {\n message: \"Unknown field\",\n segment: {\n start: 1,\n end: 10,\n },\n },\n ]);\n });\n\n it(\"validates enum (string literal accepts lower and upper)\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"record\", value: \"MyEnum\" },\n records: [\n {\n kind: \"enum\",\n id: \"MyEnum\",\n variants: [\n { name: \"FOO\", number: 1 },\n { name: \"BAR\", number: 2 },\n ],\n },\n ],\n };\n const lowerResult = validateSchema(parse('\"foo\"'), schema);\n expect(lowerResult).toMatch({ errors: [] });\n\n const upperResult = validateSchema(parse('\"FOO\"'), schema);\n expect(upperResult).toMatch({ errors: [] });\n });\n\n it(\"rejects mixed-case enum string literal\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"record\", value: \"MyEnum\" },\n records: [\n {\n kind: \"enum\",\n id: \"MyEnum\",\n variants: [{ name: \"FOO\", number: 1 }],\n },\n ],\n };\n\n const result = validateSchema(parse('\"Foo\"'), schema);\n expect(result.errors).toMatch([\n {\n message: \"Unknown variant\",\n },\n ]);\n });\n\n it(\"accepts UNKNOWN and unknown enum literals\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"record\", value: \"MyEnum\" },\n records: [\n {\n kind: \"enum\",\n id: \"MyEnum\",\n variants: [{ name: \"FOO\", number: 1 }],\n },\n ],\n };\n\n expect(validateSchema(parse('\"UNKNOWN\"'), schema)).toMatch({ errors: [] });\n expect(validateSchema(parse('\"unknown\"'), schema)).toMatch({ errors: [] });\n\n const mixedCaseResult = validateSchema(parse('\"Unknown\"'), schema);\n expect(mixedCaseResult.errors).toMatch([\n {\n message: \"Unknown variant\",\n },\n ]);\n });\n\n it(\"validates enum object kind in lower and upper\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"record\", value: \"MyEnum\" },\n records: [\n {\n kind: \"enum\",\n id: \"MyEnum\",\n variants: [\n {\n name: \"COMPLEX\",\n number: 1,\n type: { kind: \"primitive\", value: \"int32\" },\n },\n ],\n },\n ],\n };\n\n expect(\n validateSchema(parse('{\"kind\": \"complex\", \"value\": 123}'), schema),\n ).toMatch({\n errors: [],\n });\n expect(\n validateSchema(parse('{\"kind\": \"COMPLEX\", \"value\": 123}'), schema),\n ).toMatch({\n errors: [],\n });\n\n const mixedCaseResult = validateSchema(\n parse('{\"kind\": \"Complex\", \"value\": 123}'),\n schema,\n );\n expect(mixedCaseResult.errors).toMatch([\n {\n message: \"Unknown variant\",\n },\n ]);\n });\n\n it(\"reports unknown enum variant\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"record\", value: \"MyEnum\" },\n records: [\n {\n kind: \"enum\",\n id: \"MyEnum\",\n variants: [{ name: \"First\", number: 1 }],\n },\n ],\n };\n const result = validateSchema(parse('\"Unknown\"'), schema);\n expect(result.errors).toMatch([\n {\n message: \"Unknown variant\",\n },\n ]);\n });\n\n it(\"reports error when typed enum variant is provided as string\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"record\", value: \"MyEnum\" },\n records: [\n {\n kind: \"enum\",\n id: \"MyEnum\",\n variants: [\n {\n name: \"COMPLEX\",\n number: 1,\n type: { kind: \"primitive\", value: \"int32\" },\n },\n ],\n },\n ],\n };\n\n const result = validateSchema(parse('\"COMPLEX\"'), schema);\n expect(result.errors).toMatch([\n {\n message: \"Expected: constant variant\",\n },\n ]);\n });\n\n it(\"reports error when constant enum variant is provided as object\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"record\", value: \"MyEnum\" },\n records: [\n {\n kind: \"enum\",\n id: \"MyEnum\",\n variants: [{ name: \"SIMPLE\", number: 1 }],\n },\n ],\n };\n\n const result = validateSchema(parse('{\"kind\": \"SIMPLE\"}'), schema);\n expect(result.errors).toMatch([\n {\n message: \"Expected: wrapper variant\",\n },\n {\n message: \"Missing: 'value'\",\n },\n ]);\n });\n\n it(\"stores enum definition in type hint for UNKNOWN enum literal\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"record\", value: \"MyEnum\" },\n records: [\n {\n kind: \"enum\",\n id: \"MyEnum\",\n variants: [\n { name: \"First\", number: 1 },\n { name: \"Second\", number: 2 },\n ],\n },\n ],\n };\n\n const result = validateSchema(parse('\"UNKNOWN\"'), schema);\n expect(result.errors).toMatch([]);\n if (!result.rootTypeHint) {\n throw new Error(\"Expected root type hint\");\n }\n expect(result.rootTypeHint.enumDefinition).toMatch({\n kind: \"enum\",\n id: \"MyEnum\",\n variants: [\n { name: \"First\", number: 1 },\n { name: \"Second\", number: 2 },\n ],\n });\n });\n\n it(\"stores enum definition in nested UNKNOWN enum field hint\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"record\", value: \"MyStruct\" },\n records: [\n {\n kind: \"struct\",\n id: \"MyStruct\",\n fields: [\n {\n name: \"status\",\n number: 1,\n type: { kind: \"record\", value: \"MyEnum\" },\n },\n ],\n },\n {\n kind: \"enum\",\n id: \"MyEnum\",\n variants: [\n { name: \"First\", number: 1 },\n { name: \"Second\", number: 2 },\n ],\n },\n ],\n };\n\n const result = validateSchema(parse('{\"status\": \"UNKNOWN\"}'), schema);\n expect(result.errors).toMatch([]);\n if (!result.rootTypeHint) {\n throw new Error(\"Expected root type hint\");\n }\n if (result.rootTypeHint.childHints.length !== 1) {\n throw new Error(\"Expected one child type hint\");\n }\n const statusHint = result.rootTypeHint.childHints[0];\n expect(statusHint.enumDefinition).toMatch({\n kind: \"enum\",\n id: \"MyEnum\",\n variants: [\n { name: \"First\", number: 1 },\n { name: \"Second\", number: 2 },\n ],\n });\n });\n\n it(\"validates enum (object with kind)\", () => {\n const schema: TypeDefinition = {\n type: { kind: \"record\", value: \"MyEnum\" },\n records: [\n {\n kind: \"enum\",\n id: \"MyEnum\",\n variants: [\n {\n name: \"complex\",\n number: 1,\n type: { kind: \"primitive\", value: \"int32\" },\n },\n ],\n },\n ],\n };\n\n expect(\n validateSchema(parse('{\"kind\": \"complex\", \"value\": 123}'), schema),\n ).toMatch({ errors: [] });\n expect(\n validateSchema(parse('{\"kind\": \"complex\", \"value\": \"foo\"}'), schema),\n ).toMatch({\n errors: [\n {\n message: \"Expected: int32\",\n },\n ],\n });\n expect(validateSchema(parse('{\"kind\": \"complex\"}'), schema)).toMatch({\n errors: [\n {\n message: \"Missing: 'value'\",\n },\n ],\n });\n });\n});\n"]}
|
package/package.json
CHANGED
|
@@ -251,7 +251,7 @@ describe("schema_validator", () => {
|
|
|
251
251
|
);
|
|
252
252
|
expect(mixedCaseResult.errors).toMatch([
|
|
253
253
|
{
|
|
254
|
-
message: "
|
|
254
|
+
message: "Unknown variant",
|
|
255
255
|
},
|
|
256
256
|
]);
|
|
257
257
|
});
|
|
@@ -275,6 +275,55 @@ describe("schema_validator", () => {
|
|
|
275
275
|
]);
|
|
276
276
|
});
|
|
277
277
|
|
|
278
|
+
it("reports error when typed enum variant is provided as string", () => {
|
|
279
|
+
const schema: TypeDefinition = {
|
|
280
|
+
type: { kind: "record", value: "MyEnum" },
|
|
281
|
+
records: [
|
|
282
|
+
{
|
|
283
|
+
kind: "enum",
|
|
284
|
+
id: "MyEnum",
|
|
285
|
+
variants: [
|
|
286
|
+
{
|
|
287
|
+
name: "COMPLEX",
|
|
288
|
+
number: 1,
|
|
289
|
+
type: { kind: "primitive", value: "int32" },
|
|
290
|
+
},
|
|
291
|
+
],
|
|
292
|
+
},
|
|
293
|
+
],
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
const result = validateSchema(parse('"COMPLEX"'), schema);
|
|
297
|
+
expect(result.errors).toMatch([
|
|
298
|
+
{
|
|
299
|
+
message: "Expected: constant variant",
|
|
300
|
+
},
|
|
301
|
+
]);
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
it("reports error when constant enum variant is provided as object", () => {
|
|
305
|
+
const schema: TypeDefinition = {
|
|
306
|
+
type: { kind: "record", value: "MyEnum" },
|
|
307
|
+
records: [
|
|
308
|
+
{
|
|
309
|
+
kind: "enum",
|
|
310
|
+
id: "MyEnum",
|
|
311
|
+
variants: [{ name: "SIMPLE", number: 1 }],
|
|
312
|
+
},
|
|
313
|
+
],
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
const result = validateSchema(parse('{"kind": "SIMPLE"}'), schema);
|
|
317
|
+
expect(result.errors).toMatch([
|
|
318
|
+
{
|
|
319
|
+
message: "Expected: wrapper variant",
|
|
320
|
+
},
|
|
321
|
+
{
|
|
322
|
+
message: "Missing: 'value'",
|
|
323
|
+
},
|
|
324
|
+
]);
|
|
325
|
+
});
|
|
326
|
+
|
|
278
327
|
it("stores enum definition in type hint for UNKNOWN enum literal", () => {
|
|
279
328
|
const schema: TypeDefinition = {
|
|
280
329
|
type: { kind: "record", value: "MyEnum" },
|
|
@@ -205,7 +205,7 @@ class SchemaValidator {
|
|
|
205
205
|
this.errors.push({
|
|
206
206
|
kind: "error",
|
|
207
207
|
segment: value.segment,
|
|
208
|
-
message: "Expected:
|
|
208
|
+
message: "Expected: constant variant",
|
|
209
209
|
});
|
|
210
210
|
} else if (name === "unknown" || name === "UNKNOWN" || fieldDef) {
|
|
211
211
|
pushTypeHint({ enumDefinition: recordDef });
|
|
@@ -257,24 +257,20 @@ class SchemaValidator {
|
|
|
257
257
|
return;
|
|
258
258
|
}
|
|
259
259
|
const kind: string = JSON.parse(kindKv.value.jsonCode);
|
|
260
|
-
const
|
|
261
|
-
|
|
262
|
-
if (!isLowercase && !isUppercase) {
|
|
260
|
+
const variantDef = nameToVariantDef[kind];
|
|
261
|
+
if (!variantDef) {
|
|
263
262
|
this.errors.push({
|
|
264
263
|
kind: "error",
|
|
265
264
|
segment: kindKv.value.segment,
|
|
266
|
-
message: "
|
|
265
|
+
message: "Unknown variant",
|
|
267
266
|
});
|
|
268
267
|
return;
|
|
269
|
-
}
|
|
270
|
-
const variantDef = nameToVariantDef[kind];
|
|
271
|
-
if (!variantDef) {
|
|
268
|
+
} else if (variantDef.type === undefined) {
|
|
272
269
|
this.errors.push({
|
|
273
270
|
kind: "error",
|
|
274
271
|
segment: kindKv.value.segment,
|
|
275
|
-
message: "
|
|
272
|
+
message: "Expected: wrapper variant",
|
|
276
273
|
});
|
|
277
|
-
return;
|
|
278
274
|
}
|
|
279
275
|
const valueKv = object.keyValues["value"];
|
|
280
276
|
if (!valueKv) {
|