diff --git a/common/relationships.go b/common/relationships.go index 00625c75..4481559f 100644 --- a/common/relationships.go +++ b/common/relationships.go @@ -67,10 +67,16 @@ func (r Relationships) AddRelationship(target, ctype string) Relationship { } rel := relationships.NewRelationship() nextID := len(r.x.Relationship) + 1 + used := map[string]struct{}{} + + // identify IDs in use for _, exRel := range r.x.Relationship { - if exRel.IdAttr == fmt.Sprintf("rId%d", nextID) { - nextID++ - } + used[exRel.IdAttr] = struct{}{} + } + // find the next ID that is unused + for _, ok := used[fmt.Sprintf("rId%d", nextID)]; ok; _, ok = used[fmt.Sprintf("rId%d", nextID)] { + nextID++ + } rel.IdAttr = fmt.Sprintf("rId%d", nextID) rel.TargetAttr = target diff --git a/common/relationships_test.go b/common/relationships_test.go index 166c0fc6..93491c04 100644 --- a/common/relationships_test.go +++ b/common/relationships_test.go @@ -65,3 +65,27 @@ func TestRelationshipsCreation(t *testing.T) { t.Errorf("expected %s, got %s", exp, rel.ID()) } } + +func TestRelationshipsCreationUnordered(t *testing.T) { + r := common.NewRelationships() + r.AddRelationship("foo", "http://bar").X().IdAttr = "rId1" + r.AddRelationship("foo", "http://bar").X().IdAttr = "rId3" + r.AddRelationship("foo", "http://bar").X().IdAttr = "rId5" + r.AddRelationship("foo", "http://bar").X().IdAttr = "rId7" + + // len is 4, but id 5 is used, so we should get 6 next + rel := r.AddRelationship("foo", "http://bar") + + exp := "rId6" + if rel.ID() != exp { + t.Errorf("expected %s, got %s", exp, rel.ID()) + } + + // would get 7, but it's in use so we get 8 now + rel = r.AddRelationship("foo", "http://bar") + exp = "rId8" + if rel.ID() != exp { + t.Errorf("expected %s, got %s", exp, rel.ID()) + } + +}