Skip to content

Commit

Permalink
sort the spec in the test
Browse files Browse the repository at this point in the history
  • Loading branch information
Yarom Swisa authored and Yarom Swisa committed Nov 26, 2024
1 parent 6fff40e commit f14d741
Showing 1 changed file with 68 additions and 27 deletions.
95 changes: 68 additions & 27 deletions x/spec/keeper/spec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -819,48 +819,89 @@ func TestCookbookSpecs(t *testing.T) {
ts := newTester(t)

getToTopMostPath := "../../.././cookbook/specs/"
// base specs needs to be proposed first
baseSpecs := []string{"ibc.json", "tendermint.json", "ethermint.json", "cosmoswasm.json", "cosmossdk.json", "cosmossdk_45.json", "cosmossdk_full.json", "ethereum.json", "solana.json"}

Specs, err := getAllFilesInDirectory(getToTopMostPath)
SpecsFiles, err := getAllFilesInDirectory(getToTopMostPath)
require.NoError(t, err)

// remove the base specs so there wont be a duplicate
Specs = removeSetFromSet(baseSpecs, Specs)
Specs = append(baseSpecs, Specs...)
for _, fileName := range Specs {
proposal := utils.SpecAddProposalJSON{}
// Sort specs by hierarchy - specs that are imported by others should come first
specImports := make(map[string][]string)
specProposals := make(map[string]types.Spec)

// First read all spec contents
for _, fileName := range SpecsFiles {
contents, err := os.ReadFile(getToTopMostPath + fileName)
require.NoError(t, err)

// Parse imports from spec
var proposal utils.SpecAddProposalJSON
decoder := json.NewDecoder(bytes.NewReader(contents))
decoder.DisallowUnknownFields() // This will make the unmarshal fail if there are unused fields
err = decoder.Decode(&proposal)
require.NoError(t, err, fileName)

for _, sp := range proposal.Proposal.Specs {
ts.setSpec(sp)
fullspec, err := ts.expandSpec(sp)
require.NoError(t, err)
require.NotNil(t, fullspec)
verifications := []*types.Verification{}
for _, apiCol := range fullspec.ApiCollections {
for _, verification := range apiCol.Verifications {
require.NotNil(t, verification.ParseDirective)
if verification.ParseDirective.FunctionTag == types.FUNCTION_TAG_VERIFICATION {
require.NotEqual(t, "", verification.ParseDirective.ApiName)
}
}
verifications = append(verifications, apiCol.Verifications...)
imports := []string{}
for _, spec := range proposal.Proposal.Specs {
if spec.Imports != nil {
imports = append(imports, spec.Imports...)
}
if fullspec.Enabled {
// all specs need to have verifications
require.Greater(t, len(verifications), 0, fullspec.Index)
specImports[spec.Index] = imports
specProposals[spec.Index] = spec
}
}

// Topologically sort based on imports
var sortedSpecs []string
visited := make(map[string]bool)
visiting := make(map[string]bool)

var visit func(string)
visit = func(spec string) {
if visiting[spec] {
require.Fail(t, "Circular dependency detected")
}
if visited[spec] {
return
}
visiting[spec] = true
for _, imp := range specImports[spec] {
visit(imp)
}
visiting[spec] = false
visited[spec] = true
sortedSpecs = append(sortedSpecs, spec)
}

for spec := range specImports {
if !visited[spec] {
visit(spec)
}
}

SpecsFiles = sortedSpecs

for _, specName := range SpecsFiles {
sp := specProposals[specName]

ts.setSpec(sp)
fullspec, err := ts.expandSpec(sp)
require.NoError(t, err)
require.NotNil(t, fullspec)
verifications := []*types.Verification{}
for _, apiCol := range fullspec.ApiCollections {
for _, verification := range apiCol.Verifications {
require.NotNil(t, verification.ParseDirective)
if verification.ParseDirective.FunctionTag == types.FUNCTION_TAG_VERIFICATION {
require.NotEqual(t, "", verification.ParseDirective.ApiName)
}
}
_, err = fullspec.ValidateSpec(10000000)
require.NoError(t, err, sp.Name)
verifications = append(verifications, apiCol.Verifications...)
}
if fullspec.Enabled {
// all specs need to have verifications
require.Greater(t, len(verifications), 0, fullspec.Index)
}
_, err = fullspec.ValidateSpec(10000000)
require.NoError(t, err, sp.Name)
}
}

Expand Down

0 comments on commit f14d741

Please sign in to comment.