auditRegistrationBundle function
RegistrationBundleAudit
auditRegistrationBundle(
- RegistrationBundle bundle, {
- bool includeUnknownShapeWarnings = false,
Audits bundle for duplicate types, duplicate keys, canonical drift, and
missing shape data.
Implementation
RegistrationBundleAudit auditRegistrationBundle(
RegistrationBundle bundle, {
bool includeUnknownShapeWarnings = false,
}) {
final issues = <RegistrationAuditIssue>[];
final typeOwners = <ChartType, ChartRegistration>{};
final canonicalTypeOwners = <ChartType, ChartRegistration>{};
final keyOwners = <String, ChartRegistration>{};
final normalizedKeyOwners = <String, _RegistrationKeyOwner>{};
for (final reg in bundle.registrations) {
final canonicalType = canonicalChartType(reg.type);
if (canonicalType != reg.type) {
issues.add(
RegistrationAuditIssue(
severity: RegistrationAuditSeverity.error,
code: 'LEGACY_REGISTRATION_TYPE',
message:
'Registration ${reg.type.name} in ${bundle.name} should use '
'canonical chart type ${canonicalType.name}.',
firstType: canonicalType,
secondType: reg.type,
),
);
}
final existingType = typeOwners[reg.type];
if (existingType != null) {
issues.add(
RegistrationAuditIssue(
severity: RegistrationAuditSeverity.error,
code: 'DUPLICATE_TYPE',
message:
'Chart type ${chartTypeToString(reg.type)} is registered more than once in ${bundle.name}.',
firstType: existingType.type,
secondType: reg.type,
),
);
} else {
typeOwners[reg.type] = reg;
}
final existingCanonicalType = canonicalTypeOwners[canonicalType];
if (existingCanonicalType != null &&
existingCanonicalType.type != reg.type) {
issues.add(
RegistrationAuditIssue(
severity: RegistrationAuditSeverity.error,
code: 'DUPLICATE_CANONICAL_TYPE',
message:
'Canonical chart type ${chartTypeToString(canonicalType)} is '
'owned by both ${existingCanonicalType.type.name} and '
'${reg.type.name} in ${bundle.name}.',
firstType: existingCanonicalType.type,
secondType: reg.type,
),
);
} else {
canonicalTypeOwners[canonicalType] = reg;
}
final typeStringKey = normalizeChartTypeKey(reg.typeString);
final canonicalTypeStringKey = normalizeChartTypeKey(
chartTypeToString(canonicalType),
);
if (typeStringKey.isEmpty) {
issues.add(
RegistrationAuditIssue(
severity: RegistrationAuditSeverity.error,
code: 'EMPTY_TYPE_STRING',
message:
'Chart type ${chartTypeToString(canonicalType)} in '
'${bundle.name} has an empty registration typeString.',
secondType: reg.type,
),
);
} else if (typeStringKey != canonicalTypeStringKey) {
issues.add(
RegistrationAuditIssue(
severity: RegistrationAuditSeverity.error,
code: 'TYPE_STRING_MISMATCH',
message:
'Registration typeString "${reg.typeString}" does not match '
'canonical chart type ${chartTypeToString(canonicalType)}.',
key: reg.typeString,
secondType: reg.type,
),
);
}
for (final entry in _registrationKeyEntries(reg)) {
final key = entry.rawKey;
final existingKeyOwner = keyOwners[key];
if (existingKeyOwner != null) {
final severity = existingKeyOwner.type == reg.type
? RegistrationAuditSeverity.error
: RegistrationAuditSeverity.warning;
issues.add(
RegistrationAuditIssue(
severity: severity,
code: existingKeyOwner.type == reg.type
? 'DUPLICATE_KEY'
: 'KEY_COLLISION',
message:
'Registration key "$key" is used by ${chartTypeToString(existingKeyOwner.type)} and ${chartTypeToString(reg.type)}.',
key: key,
firstType: existingKeyOwner.type,
secondType: reg.type,
),
);
} else {
keyOwners[key] = reg;
}
final existingNormalizedOwner = normalizedKeyOwners[entry.normalizedKey];
if (existingNormalizedOwner != null &&
existingNormalizedOwner.rawKey != entry.rawKey) {
final sameType = existingNormalizedOwner.registration.type == reg.type;
issues.add(
RegistrationAuditIssue(
severity: RegistrationAuditSeverity.warning,
code: sameType
? 'REDUNDANT_NORMALIZED_ALIAS'
: 'NORMALIZED_KEY_COLLISION',
message: sameType
? 'Registration key "${entry.rawKey}" normalizes to the same '
'lookup key as "${existingNormalizedOwner.rawKey}" for '
'${chartTypeToString(reg.type)}.'
: 'Registration key "${entry.rawKey}" normalizes to the same '
'lookup key as "${existingNormalizedOwner.rawKey}", used '
'by ${chartTypeToString(existingNormalizedOwner.registration.type)} '
'and ${chartTypeToString(reg.type)}.',
key: entry.normalizedKey,
firstType: existingNormalizedOwner.registration.type,
secondType: reg.type,
),
);
} else {
normalizedKeyOwners[entry.normalizedKey] = _RegistrationKeyOwner(
registration: reg,
rawKey: entry.rawKey,
);
}
}
if (includeUnknownShapeWarnings &&
targetSeriesDataShape(reg.type) == ChartSeriesDataShape.unknown) {
issues.add(
RegistrationAuditIssue(
severity: RegistrationAuditSeverity.warning,
code: 'UNKNOWN_DATA_SHAPE',
message:
'Chart type ${chartTypeToString(reg.type)} has no data-shape capability mapping.',
secondType: reg.type,
),
);
}
}
return RegistrationBundleAudit(
bundleName: bundle.name,
registrationCount: bundle.registrations.length,
issues: issues,
);
}