Skip to content
This repository was archived by the owner on Dec 21, 2024. It is now read-only.

Commit f63f665

Browse files
Jesse CorettaJesse Coretta
Jesse Coretta
authored and
Jesse Coretta
committed
sibling and child checks, unit test streamlining
1 parent 19e9a49 commit f63f665

File tree

5 files changed

+248
-85
lines changed

5 files changed

+248
-85
lines changed

asn.go

+57-15
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ func (r ASN1Notation) Index(idx int) (nanf NameAndNumberForm, ok bool) {
100100
}
101101
} else if idx > L {
102102
nanf = r[L-1]
103-
} else {
103+
} else if idx < L {
104104
nanf = r[idx]
105105
}
106106
}
@@ -242,40 +242,82 @@ is an ancestor of the input value, which can be string or [ASN1Notation].
242242
*/
243243
func (r ASN1Notation) AncestorOf(asn any) (anc bool) {
244244
if !r.IsZero() {
245-
var A *ASN1Notation
246-
247-
switch tv := asn.(type) {
248-
case string:
249-
A, _ = NewASN1Notation(tv)
250-
case *ASN1Notation:
251-
if tv != nil {
252-
A = tv
245+
if A := assertASN1Notation(asn); !A.IsZero() {
246+
if A.Len() > r.Len() {
247+
anc = r.matchASN1(A, 0)
253248
}
254-
case ASN1Notation:
255-
if tv.Len() >= 0 {
256-
A = &tv
249+
}
250+
}
251+
252+
return
253+
}
254+
255+
/*
256+
ChildOf returns a Boolean value indicative of whether the receiver is
257+
a direct superior (parent) of the input value, which can be string or
258+
[ASN1Notation].
259+
*/
260+
func (r ASN1Notation) ChildOf(asn any) (cof bool) {
261+
if !r.IsZero() {
262+
if A := assertASN1Notation(asn); !A.IsZero() {
263+
if A.Len()-1 == r.Len() {
264+
cof = r.matchASN1(A, 0)
257265
}
258266
}
267+
}
268+
269+
return
270+
}
259271

260-
if A.Len() > r.Len() {
261-
anc = r.matchASN1(A)
272+
/*
273+
SiblingOf returns a Boolean value indicative of whether the receiver is
274+
a sibling of the input value, which can be string or [ASN1Notation].
275+
*/
276+
func (r ASN1Notation) SiblingOf(asn any) (sof bool) {
277+
if !r.IsZero() {
278+
if A := assertASN1Notation(asn); !A.IsZero() {
279+
if A.Len() == r.Len() && !A.Leaf().Equal(r.Leaf()) {
280+
sof = r.matchASN1(A, -1)
281+
}
262282
}
263283
}
264284

265285
return
266286
}
267287

268-
func (r ASN1Notation) matchASN1(asn *ASN1Notation) (matched bool) {
288+
func (r ASN1Notation) matchASN1(asn *ASN1Notation, off int) (matched bool) {
269289
L := r.Len()
270290
ct := 0
271291
for i := 0; i < L; i++ {
272292
x, _ := r.Index(i)
273293
if y, ok := asn.Index(i); ok {
274294
if x.Equal(y) {
275295
ct++
296+
} else if off == -1 && L-1 == i {
297+
// sibling check should end in
298+
// a FAILED match for the final
299+
// arcs.
300+
ct++
276301
}
277302
}
278303
}
279304

280305
return ct == L
281306
}
307+
308+
func assertASN1Notation(asn any) (A *ASN1Notation) {
309+
switch tv := asn.(type) {
310+
case string:
311+
A, _ = NewASN1Notation(tv)
312+
case *ASN1Notation:
313+
if tv != nil {
314+
A = tv
315+
}
316+
case ASN1Notation:
317+
if tv.Len() >= 0 {
318+
A = &tv
319+
}
320+
}
321+
322+
return
323+
}

asn_test.go

+51-16
Original file line numberDiff line numberDiff line change
@@ -254,33 +254,68 @@ func TestASN1Notation_IsZero(t *testing.T) {
254254
}
255255
}
256256

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

264-
child, err := NewASN1Notation(`{iso(1) identified-organization(3) dod(6) internet(1)}`)
266+
for _, d := range []any{
267+
chstr,
268+
child,
269+
*child,
270+
} {
271+
if !asn.AncestorOf(d) {
272+
t.Errorf("%s failed: ancestor check returned bogus result",
273+
t.Name())
274+
return
275+
}
276+
}
277+
}
278+
279+
func TestASN1Notation_ChildOf(t *testing.T) {
280+
asn, _ := NewASN1Notation(`{iso(1)}`)
281+
chstr := `{iso(1) identified-organization(3)}`
282+
child, err := NewASN1Notation(chstr)
265283
if err != nil {
266-
t.Errorf("%s failed: %v", t.Name(), err)
284+
t.Errorf(err.Error())
267285
return
268286
}
269-
if asn.AncestorOf(child) {
270-
t.Errorf("%s failed: ancestry check returned bogus result",
271-
t.Name())
272-
return
287+
288+
for _, d := range []any{
289+
chstr,
290+
child,
291+
*child,
292+
} {
293+
if !asn.ChildOf(d) {
294+
t.Errorf("%s failed: child check returned bogus result",
295+
t.Name())
296+
return
297+
}
273298
}
299+
}
274300

275-
if asn.AncestorOf(*child) {
276-
t.Errorf("%s failed: ancestry check returned bogus result",
277-
t.Name())
301+
func TestASN1Notation_SiblingOf(t *testing.T) {
302+
asn, _ := NewASN1Notation(`{joint-iso-itu-t(2) uuid(25)}`)
303+
sibstr := `{joint-iso-itu-t(2) asn1(1)}`
304+
sib, err := NewASN1Notation(sibstr)
305+
if err != nil {
306+
t.Errorf(err.Error())
278307
return
279308
}
280309

281-
if asn.AncestorOf(child.String()) {
282-
t.Errorf("%s failed: ancestry check returned bogus result",
283-
t.Name())
284-
return
310+
for _, d := range []any{
311+
sibstr,
312+
sib,
313+
*sib,
314+
} {
315+
if !asn.SiblingOf(d) {
316+
t.Errorf("%s failed: sibling check returned bogus result",
317+
t.Name())
318+
return
319+
}
285320
}
286321
}

dot.go

+58-16
Original file line numberDiff line numberDiff line change
@@ -339,10 +339,10 @@ func (r DotNotation) Index(idx int) (a NumberForm, ok bool) {
339339
}
340340
} else if idx > L {
341341
a = r[L-1]
342-
} else {
342+
} else if idx < L {
343343
a = r[idx]
344344
}
345-
ok = true
345+
ok = !a.IsZero()
346346
}
347347

348348
return
@@ -371,37 +371,79 @@ is an ancestor of the input value, which can be string or [DotNotation].
371371
*/
372372
func (r DotNotation) AncestorOf(dot any) (is bool) {
373373
if !r.IsZero() {
374-
var D *DotNotation
375-
376-
switch tv := dot.(type) {
377-
case string:
378-
D, _ = NewDotNotation(tv)
379-
case *DotNotation:
380-
if tv != nil {
381-
D = tv
374+
if D := assertDotNot(dot); !D.IsZero() {
375+
if D.Len() > r.Len() {
376+
is = r.matchDotNot(D, 0)
382377
}
383-
case DotNotation:
384-
if tv.Len() >= 0 {
385-
D = &tv
378+
}
379+
}
380+
381+
return
382+
}
383+
384+
/*
385+
ChildOf returns a Boolean value indicative of whether the receiver is
386+
a direct superior (parent) of the input value, which can be string or
387+
[ASN1Notation].
388+
*/
389+
func (r DotNotation) ChildOf(asn any) (cof bool) {
390+
if !r.IsZero() {
391+
if D := assertDotNot(asn); !D.IsZero() {
392+
if D.Len()-1 == r.Len() {
393+
cof = r.matchDotNot(D, 0)
394+
}
395+
}
396+
}
397+
398+
return
399+
}
400+
401+
/*
402+
SiblingOf returns a Boolean value indicative of whether the receiver is
403+
a sibling of the input value, which can be string or [ASN1Notation].
404+
*/
405+
func (r DotNotation) SiblingOf(dot any) (sof bool) {
406+
if !r.IsZero() {
407+
if D := assertDotNot(dot); !D.IsZero() {
408+
if D.Len() == r.Len() && !D.Leaf().Equal(r.Leaf()) {
409+
sof = r.matchDotNot(D, -1)
386410
}
387411
}
412+
}
413+
414+
return
415+
}
388416

389-
if D.Len() > r.Len() {
390-
is = r.matchDotNot(D)
417+
func assertDotNot(dot any) (D *DotNotation) {
418+
switch tv := dot.(type) {
419+
case string:
420+
D, _ = NewDotNotation(tv)
421+
case *DotNotation:
422+
if tv != nil {
423+
D = tv
424+
}
425+
case DotNotation:
426+
if tv.Len() >= 0 {
427+
D = &tv
391428
}
392429
}
393430

394431
return
395432
}
396433

397-
func (r DotNotation) matchDotNot(dot *DotNotation) bool {
434+
func (r DotNotation) matchDotNot(dot *DotNotation, off int) bool {
398435
L := r.Len()
399436
ct := 0
400437
for i := 0; i < L; i++ {
401438
x, _ := r.Index(i)
402439
if y, ok := dot.Index(i); ok {
403440
if x.Equal(y) {
404441
ct++
442+
} else if off == -1 && L-1 == i {
443+
// sibling check should end in
444+
// a FAILED match for the final
445+
// arcs.
446+
ct++
405447
}
406448
}
407449
}

dot_test.go

+44
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,50 @@ func TestDotNotation_AncestorOf(t *testing.T) {
239239
}
240240
}
241241

242+
func TestDotNotation_ChildOf(t *testing.T) {
243+
dot, _ := NewDotNotation(`1.3.6`)
244+
chstr := `1.3.6.1`
245+
child, err := NewDotNotation(chstr)
246+
if err != nil {
247+
t.Errorf(err.Error())
248+
return
249+
}
250+
251+
for _, d := range []any{
252+
chstr,
253+
child,
254+
*child,
255+
} {
256+
if !dot.ChildOf(d) {
257+
t.Errorf("%s failed: child check returned bogus result",
258+
t.Name())
259+
return
260+
}
261+
}
262+
}
263+
264+
func TestDotNotation_SiblingOf(t *testing.T) {
265+
dot, _ := NewDotNotation(`1.3.6.1.2.1`)
266+
chstr := `1.3.6.1.2.2`
267+
child, err := NewDotNotation(chstr)
268+
if err != nil {
269+
t.Errorf(err.Error())
270+
return
271+
}
272+
273+
for _, d := range []any{
274+
chstr,
275+
child,
276+
*child,
277+
} {
278+
if !dot.SiblingOf(d) {
279+
t.Errorf("%s failed: sibling check returned bogus result",
280+
t.Name())
281+
return
282+
}
283+
}
284+
}
285+
242286
func TestDotNotation_codecov(t *testing.T) {
243287
_, err := NewDotNotation(``)
244288
if err == nil {

0 commit comments

Comments
 (0)