Skip to content

Commit

Permalink
Move misplaced full path loop outside of the sameness check, and turn…
Browse files Browse the repository at this point in the history
… the check into a loop to avoid making a new but still conflicting name; add a test for that case
  • Loading branch information
zepheiryan committed May 12, 2022
1 parent fe23105 commit 479e55d
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 13 deletions.
33 changes: 20 additions & 13 deletions generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,34 +174,41 @@ func (g *Generator) processArray(name string, schema *Schema) (typeStr string, e
// schema: detail incl properties & child objects
// returns: generated type
func (g *Generator) processObject(name string, schema *Schema) (typ string, err error) {
sfp := schema.PathElement
nameCount := 1
finalName := name
sfp := schema.PathElement
sparent := schema.Parent
// Get the full path to root for each object, assuming there are
// no cycles.
for sparent != nil {
// Skip the root element for path comparison purposes, not
// everything has root as its ultimate ancestor.
if sparent.PathElement != "#" {
sfp = fmt.Sprintf("%s/%s", sparent.PathElement, sfp)
}
sparent = sparent.Parent
}
// Avoid quashing one or more types that share the same name.
// Generate the full path from root to compare whether the type
// Use the full path from root to compare whether the type
// is legitimately the same, as it would be due to references,
// or whether they're coming from different places in the tree.
if og, ok := g.Structs[name]; ok {
// Assuming there are no cycles.
for sparent != nil {
// Skip the root element for path comparison purposes, not
// everything has root as its ultimate ancestor.
if sparent.PathElement != "#" {
sfp = fmt.Sprintf("%s/%s", sparent.PathElement, sfp)
}
sparent = sparent.Parent
}
// This is a loop to check for whether the new name is also a
// conflicting name and to keep doing so until a unique name
// is found.
for og, ok := g.Structs[name]; ok; og, ok = g.Structs[name] {
if og.PathElement != sfp {
// Turn different Foos into Foo, Foo2, Foo3, etc.
// The original is the only name count that matters,
// the rest are unused.
og.NameCount += 1
g.Structs[name] = og
nameCount = og.NameCount
finalName = fmt.Sprintf("%v%v", name, og.NameCount)
name = finalName
} else {
break
}
}
name = finalName
strct := Struct{
ID: schema.ID(),
Name: name,
Expand Down
43 changes: 43 additions & 0 deletions generator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -811,6 +811,49 @@ func TestThatReusedNamesRemainDistinctTypes(t *testing.T) {
}
}

// Test that a generated name to avoid conflicts doesn't
// also conflict with another name (so if Foo2 already exists,
// and two Foos exist, you should have Foo, Foo2, and Foo22).
func TestReusedConflictingNames(t *testing.T) {
root := &Schema{}
root.Title = "RootElement"
root.Properties = map[string]*Schema{
"property1": {TypeValue: "object", Title: "foo2", Properties: map[string]*Schema{"sub": {TypeValue: "object", Properties: map[string]*Schema{"subproperty1": {TypeValue: "integer"}}}}},
"property2": {TypeValue: "object", Title: "foo", Properties: map[string]*Schema{"sub": {TypeValue: "object", Properties: map[string]*Schema{"subproperty1": {TypeValue: "string"}}}}},
"property3": {TypeValue: "object", Title: "foo", Properties: map[string]*Schema{"sub": {TypeValue: "object", Properties: map[string]*Schema{"subproperty1": {TypeValue: "string"}}}}},
}

root.Init()

g := New(root)
err := g.CreateTypes()
if err != nil {
t.Error(err)
}
results := g.Structs
if len(results) != 7 {
t.Errorf("Expected 7 results, but got %d results", len(results))
}
if _, ok := results["Foo"]; !ok {
t.Errorf("Expected type Foo, did not find it")
}
if _, ok := results["Foo2"]; !ok {
t.Errorf("Expected type Foo2, did not find it")
}
if _, ok := results["Foo22"]; !ok {
t.Errorf("Expected type Foo22, did not find it")
}
if _, ok := results["Sub"]; !ok {
t.Errorf("Expected type Sub, did not find it")
}
if _, ok := results["Sub2"]; !ok {
t.Errorf("Expected type Sub2, did not find it")
}
if _, ok := results["Sub3"]; !ok {
t.Errorf("Expected type Sub3, did not find it")
}
}

// Root is an example of a generated type.
type Root struct {
Name interface{} `json:"name,omitempty"`
Expand Down

0 comments on commit 479e55d

Please sign in to comment.