Skip to content

Commit

Permalink
sibling and child checks, unit test streamlining
Browse files Browse the repository at this point in the history
  • Loading branch information
Jesse Coretta authored and Jesse Coretta committed Sep 29, 2024
1 parent 19e9a49 commit f63f665
Show file tree
Hide file tree
Showing 5 changed files with 248 additions and 85 deletions.
72 changes: 57 additions & 15 deletions asn.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ func (r ASN1Notation) Index(idx int) (nanf NameAndNumberForm, ok bool) {
}
} else if idx > L {
nanf = r[L-1]
} else {
} else if idx < L {
nanf = r[idx]
}
}
Expand Down Expand Up @@ -242,40 +242,82 @@ is an ancestor of the input value, which can be string or [ASN1Notation].
*/
func (r ASN1Notation) AncestorOf(asn any) (anc bool) {
if !r.IsZero() {
var A *ASN1Notation

switch tv := asn.(type) {
case string:
A, _ = NewASN1Notation(tv)
case *ASN1Notation:
if tv != nil {
A = tv
if A := assertASN1Notation(asn); !A.IsZero() {
if A.Len() > r.Len() {
anc = r.matchASN1(A, 0)
}
case ASN1Notation:
if tv.Len() >= 0 {
A = &tv
}
}

return
}

/*
ChildOf returns a Boolean value indicative of whether the receiver is
a direct superior (parent) of the input value, which can be string or
[ASN1Notation].
*/
func (r ASN1Notation) ChildOf(asn any) (cof bool) {
if !r.IsZero() {
if A := assertASN1Notation(asn); !A.IsZero() {
if A.Len()-1 == r.Len() {
cof = r.matchASN1(A, 0)
}
}
}

return
}

if A.Len() > r.Len() {
anc = r.matchASN1(A)
/*
SiblingOf returns a Boolean value indicative of whether the receiver is
a sibling of the input value, which can be string or [ASN1Notation].
*/
func (r ASN1Notation) SiblingOf(asn any) (sof bool) {
if !r.IsZero() {
if A := assertASN1Notation(asn); !A.IsZero() {
if A.Len() == r.Len() && !A.Leaf().Equal(r.Leaf()) {
sof = r.matchASN1(A, -1)
}
}
}

return
}

func (r ASN1Notation) matchASN1(asn *ASN1Notation) (matched bool) {
func (r ASN1Notation) matchASN1(asn *ASN1Notation, off int) (matched bool) {
L := r.Len()
ct := 0
for i := 0; i < L; i++ {
x, _ := r.Index(i)
if y, ok := asn.Index(i); ok {
if x.Equal(y) {
ct++
} else if off == -1 && L-1 == i {
// sibling check should end in
// a FAILED match for the final
// arcs.
ct++
}
}
}

return ct == L
}

func assertASN1Notation(asn any) (A *ASN1Notation) {
switch tv := asn.(type) {
case string:
A, _ = NewASN1Notation(tv)
case *ASN1Notation:
if tv != nil {
A = tv
}
case ASN1Notation:
if tv.Len() >= 0 {
A = &tv
}
}

return
}
67 changes: 51 additions & 16 deletions asn_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -254,33 +254,68 @@ func TestASN1Notation_IsZero(t *testing.T) {
}
}

func TestASN1Notation_AncestorOf(t *testing.T) {
asn, err := NewASN1Notation(`{joint-iso-itu-t(2) asn1(1)}`)
func TestASN1Notation_AncestorChildOf(t *testing.T) {
asn, _ := NewASN1Notation(`{iso(1)}`)
chstr := `{iso(1) identified-organization(3)}`
child, err := NewASN1Notation(chstr)
if err != nil {
t.Errorf("%s failed: %v", t.Name(), err)
t.Errorf(err.Error())
return
}

child, err := NewASN1Notation(`{iso(1) identified-organization(3) dod(6) internet(1)}`)
for _, d := range []any{
chstr,
child,
*child,
} {
if !asn.AncestorOf(d) {
t.Errorf("%s failed: ancestor check returned bogus result",
t.Name())
return
}
}
}

func TestASN1Notation_ChildOf(t *testing.T) {
asn, _ := NewASN1Notation(`{iso(1)}`)
chstr := `{iso(1) identified-organization(3)}`
child, err := NewASN1Notation(chstr)
if err != nil {
t.Errorf("%s failed: %v", t.Name(), err)
t.Errorf(err.Error())
return
}
if asn.AncestorOf(child) {
t.Errorf("%s failed: ancestry check returned bogus result",
t.Name())
return

for _, d := range []any{
chstr,
child,
*child,
} {
if !asn.ChildOf(d) {
t.Errorf("%s failed: child check returned bogus result",
t.Name())
return
}
}
}

if asn.AncestorOf(*child) {
t.Errorf("%s failed: ancestry check returned bogus result",
t.Name())
func TestASN1Notation_SiblingOf(t *testing.T) {
asn, _ := NewASN1Notation(`{joint-iso-itu-t(2) uuid(25)}`)
sibstr := `{joint-iso-itu-t(2) asn1(1)}`
sib, err := NewASN1Notation(sibstr)
if err != nil {
t.Errorf(err.Error())
return
}

if asn.AncestorOf(child.String()) {
t.Errorf("%s failed: ancestry check returned bogus result",
t.Name())
return
for _, d := range []any{
sibstr,
sib,
*sib,
} {
if !asn.SiblingOf(d) {
t.Errorf("%s failed: sibling check returned bogus result",
t.Name())
return
}
}
}
74 changes: 58 additions & 16 deletions dot.go
Original file line number Diff line number Diff line change
Expand Up @@ -339,10 +339,10 @@ func (r DotNotation) Index(idx int) (a NumberForm, ok bool) {
}
} else if idx > L {
a = r[L-1]
} else {
} else if idx < L {
a = r[idx]
}
ok = true
ok = !a.IsZero()
}

return
Expand Down Expand Up @@ -371,37 +371,79 @@ is an ancestor of the input value, which can be string or [DotNotation].
*/
func (r DotNotation) AncestorOf(dot any) (is bool) {
if !r.IsZero() {
var D *DotNotation

switch tv := dot.(type) {
case string:
D, _ = NewDotNotation(tv)
case *DotNotation:
if tv != nil {
D = tv
if D := assertDotNot(dot); !D.IsZero() {
if D.Len() > r.Len() {
is = r.matchDotNot(D, 0)
}
case DotNotation:
if tv.Len() >= 0 {
D = &tv
}
}

return
}

/*
ChildOf returns a Boolean value indicative of whether the receiver is
a direct superior (parent) of the input value, which can be string or
[ASN1Notation].
*/
func (r DotNotation) ChildOf(asn any) (cof bool) {
if !r.IsZero() {
if D := assertDotNot(asn); !D.IsZero() {
if D.Len()-1 == r.Len() {
cof = r.matchDotNot(D, 0)
}
}
}

return
}

/*
SiblingOf returns a Boolean value indicative of whether the receiver is
a sibling of the input value, which can be string or [ASN1Notation].
*/
func (r DotNotation) SiblingOf(dot any) (sof bool) {
if !r.IsZero() {
if D := assertDotNot(dot); !D.IsZero() {
if D.Len() == r.Len() && !D.Leaf().Equal(r.Leaf()) {
sof = r.matchDotNot(D, -1)
}
}
}

return
}

if D.Len() > r.Len() {
is = r.matchDotNot(D)
func assertDotNot(dot any) (D *DotNotation) {
switch tv := dot.(type) {
case string:
D, _ = NewDotNotation(tv)
case *DotNotation:
if tv != nil {
D = tv
}
case DotNotation:
if tv.Len() >= 0 {
D = &tv
}
}

return
}

func (r DotNotation) matchDotNot(dot *DotNotation) bool {
func (r DotNotation) matchDotNot(dot *DotNotation, off int) bool {
L := r.Len()
ct := 0
for i := 0; i < L; i++ {
x, _ := r.Index(i)
if y, ok := dot.Index(i); ok {
if x.Equal(y) {
ct++
} else if off == -1 && L-1 == i {
// sibling check should end in
// a FAILED match for the final
// arcs.
ct++
}
}
}
Expand Down
44 changes: 44 additions & 0 deletions dot_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,50 @@ func TestDotNotation_AncestorOf(t *testing.T) {
}
}

func TestDotNotation_ChildOf(t *testing.T) {
dot, _ := NewDotNotation(`1.3.6`)
chstr := `1.3.6.1`
child, err := NewDotNotation(chstr)
if err != nil {
t.Errorf(err.Error())
return
}

for _, d := range []any{
chstr,
child,
*child,
} {
if !dot.ChildOf(d) {
t.Errorf("%s failed: child check returned bogus result",
t.Name())
return
}
}
}

func TestDotNotation_SiblingOf(t *testing.T) {
dot, _ := NewDotNotation(`1.3.6.1.2.1`)
chstr := `1.3.6.1.2.2`
child, err := NewDotNotation(chstr)
if err != nil {
t.Errorf(err.Error())
return
}

for _, d := range []any{
chstr,
child,
*child,
} {
if !dot.SiblingOf(d) {
t.Errorf("%s failed: sibling check returned bogus result",
t.Name())
return
}
}
}

func TestDotNotation_codecov(t *testing.T) {
_, err := NewDotNotation(``)
if err == nil {
Expand Down
Loading

0 comments on commit f63f665

Please sign in to comment.