Validate fact requirements through briefing vocabulary
This commit is contained in:
@@ -31,7 +31,7 @@ func TestDefaultModuleRegistryValidatesReportDefaults(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestFactRequirementVocabularyMatchesModuleDefinitions(t *testing.T) {
|
||||
vocabulary := make(map[string]factRequirement, len(factRequirementVocabulary))
|
||||
vocabulary := make(map[string]*factRequirement, len(factRequirementVocabulary))
|
||||
for _, requirement := range factRequirementVocabulary {
|
||||
if requirement.identity == "" {
|
||||
t.Fatal("fact requirement identity is empty")
|
||||
@@ -42,10 +42,13 @@ func TestFactRequirementVocabularyMatchesModuleDefinitions(t *testing.T) {
|
||||
if _, exists := vocabulary[requirement.identity]; exists {
|
||||
t.Fatalf("duplicate fact requirement %q", requirement.identity)
|
||||
}
|
||||
if requirement.available == nil {
|
||||
t.Fatalf("fact requirement %q has no availability predicate", requirement.identity)
|
||||
}
|
||||
vocabulary[requirement.identity] = requirement
|
||||
}
|
||||
|
||||
used := map[factRequirement]struct{}{}
|
||||
used := map[*factRequirement]struct{}{}
|
||||
for _, definition := range defaultModuleDefinitions() {
|
||||
for _, requirement := range definition.RequiredCollected {
|
||||
assertFactRequirementCategory(t, vocabulary, used, definition.ID, requirement, collectedFactRequirement)
|
||||
@@ -61,7 +64,7 @@ func TestFactRequirementVocabularyMatchesModuleDefinitions(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func assertFactRequirementCategory(t *testing.T, vocabulary map[string]factRequirement, used map[factRequirement]struct{}, moduleID module.ID, requirement factRequirement, want factRequirementCategory) {
|
||||
func assertFactRequirementCategory(t *testing.T, vocabulary map[string]*factRequirement, used map[*factRequirement]struct{}, moduleID module.ID, requirement *factRequirement, want factRequirementCategory) {
|
||||
t.Helper()
|
||||
descriptor, ok := vocabulary[requirement.identity]
|
||||
if !ok {
|
||||
@@ -480,6 +483,52 @@ func TestModuleRegistryRejectsDefinitionsWithoutBuilders(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestModuleRegistryRejectsInvalidFactRequirements(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
configure func(*ModuleDefinition)
|
||||
wantErr string
|
||||
}{
|
||||
{
|
||||
name: "Unknown",
|
||||
configure: func(definition *ModuleDefinition) {
|
||||
definition.RequiredCollected = []*factRequirement{{identity: "collected.unknown", category: collectedFactRequirement}}
|
||||
},
|
||||
wantErr: `module "metadata" uses unknown collected fact requirement "collected.unknown"`,
|
||||
},
|
||||
{
|
||||
name: "DerivedListedAsCollected",
|
||||
configure: func(definition *ModuleDefinition) {
|
||||
definition.RequiredCollected = []*factRequirement{dailySummariesRequirement}
|
||||
},
|
||||
wantErr: `module "metadata" lists derived fact requirement "derived.daily_summaries" as collected`,
|
||||
},
|
||||
{
|
||||
name: "CollectedListedAsDerived",
|
||||
configure: func(definition *ModuleDefinition) {
|
||||
definition.RequiredDerived = []*factRequirement{currentConditionsRequirement}
|
||||
},
|
||||
wantErr: `module "metadata" lists collected fact requirement "collected.current_conditions" as derived`,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
definition := ModuleDefinition{
|
||||
ID: module.Metadata,
|
||||
StanzaName: "metadata",
|
||||
DefaultOptions: module.MetadataOptions{},
|
||||
Builder: noopModuleBuilder,
|
||||
}
|
||||
tt.configure(&definition)
|
||||
_, err := NewModuleRegistry([]ModuleDefinition{definition})
|
||||
if err == nil || err.Error() != tt.wantErr {
|
||||
t.Fatalf("error = %v, want %q", err, tt.wantErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestModuleRegistryRejectsUnsupportedMissingDataWarn(t *testing.T) {
|
||||
_, err := NewModuleRegistry([]ModuleDefinition{
|
||||
{ID: module.Metadata, StanzaName: "metadata", DefaultOptions: module.MetadataOptions{}, MissingData: module.MissingDataWarn, Builder: noopModuleBuilder},
|
||||
@@ -513,25 +562,25 @@ func TestModuleRegistryAcceptsTypedOptions(t *testing.T) {
|
||||
|
||||
func TestSPCConvectiveOutlookCollectedRequirementAvailability(t *testing.T) {
|
||||
ctx := ModuleContext{}
|
||||
if collectedFactAvailable(spcOutlooksRequirement, ctx) {
|
||||
t.Fatal("collectedFactAvailable() = true, want false without source")
|
||||
if spcOutlooksRequirement.available(ctx) {
|
||||
t.Fatal("SPC outlook requirement is available, want false without source")
|
||||
}
|
||||
|
||||
ctx.Collected = facts.CollectedFacts{SPCConvectiveOutlooks: &weatherdata.ConvectiveOutlookRun{}}
|
||||
if !collectedFactAvailable(spcOutlooksRequirement, ctx) {
|
||||
t.Fatal("collectedFactAvailable() = false, want true with checked source")
|
||||
if !spcOutlooksRequirement.available(ctx) {
|
||||
t.Fatal("SPC outlook requirement is unavailable, want true with checked source")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSPCConvectiveOutlookDerivedRequirementAvailability(t *testing.T) {
|
||||
ctx := ModuleContext{}
|
||||
if derivedFactAvailable(spcDerivedOutlooksRequirement, ctx) {
|
||||
t.Fatal("derivedFactAvailable() = true, want false without derived outlooks")
|
||||
if spcDerivedOutlooksRequirement.available(ctx) {
|
||||
t.Fatal("derived SPC outlook requirement is available, want false without derived outlooks")
|
||||
}
|
||||
|
||||
ctx.Derived = facts.DerivedFacts{SPCConvectiveOutlooks: []weatherdata.ConvectiveOutlook{}}
|
||||
if !derivedFactAvailable(spcDerivedOutlooksRequirement, ctx) {
|
||||
t.Fatal("derivedFactAvailable() = false, want true for checked empty derived outlooks")
|
||||
if !spcDerivedOutlooksRequirement.available(ctx) {
|
||||
t.Fatal("derived SPC outlook requirement is unavailable, want true for checked empty derived outlooks")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user