Skip to content

Commit fea7c91

Browse files
authored
Merge pull request beego#4607 from jimashi/develop
add template functions eq,lt to support uint and int compare.
2 parents 2207201 + 92b520d commit fea7c91

3 files changed

Lines changed: 244 additions & 18 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# developing
22

3+
- Add template functions eq,lt to support uint and int compare. [4607](https://github.com/beego/beego/pull/4607)
34
- Migrate tests to GitHub Actions. [4663](https://github.com/beego/beego/issues/4663)
45
- Add http client and option func. [4455](https://github.com/beego/beego/issues/4455)
56
- Add: Convenient way to generate mock object [4620](https://github.com/beego/beego/issues/4620)

server/web/templatefunc.go

Lines changed: 40 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -606,10 +606,23 @@ func eq(arg1 interface{}, arg2 ...interface{}) (bool, error) {
606606
if err != nil {
607607
return false, err
608608
}
609+
truth := false
609610
if k1 != k2 {
610-
return false, errBadComparison
611+
// Special case: Can compare integer values regardless of type's sign.
612+
switch {
613+
case k1 == intKind && k2 == uintKind:
614+
truth = v1.Int() >= 0 && uint64(v1.Int()) == v2.Uint()
615+
case k1 == uintKind && k2 == intKind:
616+
truth = v2.Int() >= 0 && v1.Uint() == uint64(v2.Int())
617+
default:
618+
return false, errBadComparison
619+
}
620+
if truth {
621+
return true, nil
622+
} else {
623+
return false, nil
624+
}
611625
}
612-
truth := false
613626
switch k1 {
614627
case boolKind:
615628
truth = v1.Bool() == v2.Bool()
@@ -652,23 +665,32 @@ func lt(arg1, arg2 interface{}) (bool, error) {
652665
if err != nil {
653666
return false, err
654667
}
655-
if k1 != k2 {
656-
return false, errBadComparison
657-
}
658668
truth := false
659-
switch k1 {
660-
case boolKind, complexKind:
661-
return false, errBadComparisonType
662-
case floatKind:
663-
truth = v1.Float() < v2.Float()
664-
case intKind:
665-
truth = v1.Int() < v2.Int()
666-
case stringKind:
667-
truth = v1.String() < v2.String()
668-
case uintKind:
669-
truth = v1.Uint() < v2.Uint()
670-
default:
671-
panic("invalid kind")
669+
if k1 != k2 {
670+
// Special case: Can compare integer values regardless of type's sign.
671+
switch {
672+
case k1 == intKind && k2 == uintKind:
673+
truth = v1.Int() < 0 || uint64(v1.Int()) < v2.Uint()
674+
case k1 == uintKind && k2 == intKind:
675+
truth = v2.Int() >= 0 && v1.Uint() < uint64(v2.Int())
676+
default:
677+
return false, errBadComparison
678+
}
679+
} else {
680+
switch k1 {
681+
case boolKind, complexKind:
682+
return false, errBadComparisonType
683+
case floatKind:
684+
truth = v1.Float() < v2.Float()
685+
case intKind:
686+
truth = v1.Int() < v2.Int()
687+
case stringKind:
688+
truth = v1.String() < v2.String()
689+
case uintKind:
690+
truth = v1.Uint() < v2.Uint()
691+
default:
692+
return false, errBadComparisonType
693+
}
672694
}
673695
return truth, nil
674696
}

server/web/templatefunc_test.go

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,3 +377,206 @@ func TestMapGet(t *testing.T) {
377377
t.Errorf("Error happens %v", err)
378378
}
379379
}
380+
381+
func Test_eq(t *testing.T) {
382+
tests := []struct {
383+
a interface{}
384+
b interface{}
385+
result bool
386+
}{
387+
{uint8(1), int(1), true},
388+
{uint8(3), int(1), false},
389+
{uint16(1), int(1), true},
390+
{uint16(3), int(1), false},
391+
{uint32(1), int(1), true},
392+
{uint32(3), int(1), false},
393+
{uint(1), int(1), true},
394+
{uint(3), int(1), false},
395+
{uint64(1), int(1), true},
396+
{uint64(3), int(1), false},
397+
{int8(-1), uint(1), false},
398+
{int16(-2), uint(1), false},
399+
{int32(-3), uint(1), false},
400+
{int64(-4), uint(1), false},
401+
{int8(1), uint(1), true},
402+
{int16(1), uint(1), true},
403+
{int32(1), uint(1), true},
404+
{int64(1), uint(1), true},
405+
{int8(-1), uint8(1), false},
406+
{int16(-2), uint8(1), false},
407+
{int32(-3), uint8(1), false},
408+
{int64(-4), uint8(1), false},
409+
{int8(1), uint8(1), true},
410+
{int16(1), uint8(1), true},
411+
{int32(1), uint8(1), true},
412+
{int64(1), uint8(1), true},
413+
{int8(-1), uint16(1), false},
414+
{int16(-2), uint16(1), false},
415+
{int32(-3), uint16(1), false},
416+
{int64(-4), uint16(1), false},
417+
{int8(1), uint16(1), true},
418+
{int16(1), uint16(1), true},
419+
{int32(1), uint16(1), true},
420+
{int64(1), uint16(1), true},
421+
{int8(-1), uint32(1), false},
422+
{int16(-2), uint32(1), false},
423+
{int32(-3), uint32(1), false},
424+
{int64(-4), uint32(1), false},
425+
{int8(1), uint32(1), true},
426+
{int16(1), uint32(1), true},
427+
{int32(1), uint32(1), true},
428+
{int64(1), uint32(1), true},
429+
{int8(-1), uint64(1), false},
430+
{int16(-2), uint64(1), false},
431+
{int32(-3), uint64(1), false},
432+
{int64(-4), uint64(1), false},
433+
{int8(1), uint64(1), true},
434+
{int16(1), uint64(1), true},
435+
{int32(1), uint64(1), true},
436+
{int64(1), uint64(1), true},
437+
}
438+
439+
for _, test := range tests {
440+
if res, err := eq(test.a, test.b); err != nil {
441+
if res != test.result {
442+
t.Errorf("a:%v(%T) equals b:%v(%T) should be %v", test.a, test.a, test.b, test.b, test.result)
443+
}
444+
}
445+
}
446+
}
447+
448+
func Test_lt(t *testing.T) {
449+
tests := []struct {
450+
a interface{}
451+
b interface{}
452+
result bool
453+
}{
454+
{uint8(1), int(3), true},
455+
{uint8(1), int(1), false},
456+
{uint8(3), int(1), false},
457+
{uint16(1), int(3), true},
458+
{uint16(1), int(1), false},
459+
{uint16(3), int(1), false},
460+
{uint32(1), int(3), true},
461+
{uint32(1), int(1), false},
462+
{uint32(3), int(1), false},
463+
{uint(1), int(3), true},
464+
{uint(1), int(1), false},
465+
{uint(3), int(1), false},
466+
{uint64(1), int(3), true},
467+
{uint64(1), int(1), false},
468+
{uint64(3), int(1), false},
469+
{int(-1), int(1), true},
470+
{int(1), int(1), false},
471+
{int(1), int(3), true},
472+
{int(3), int(1), false},
473+
{int8(-1), uint(1), true},
474+
{int8(1), uint(1), false},
475+
{int8(1), uint(3), true},
476+
{int8(3), uint(1), false},
477+
{int16(-1), uint(1), true},
478+
{int16(1), uint(1), false},
479+
{int16(1), uint(3), true},
480+
{int16(3), uint(1), false},
481+
{int32(-1), uint(1), true},
482+
{int32(1), uint(1), false},
483+
{int32(1), uint(3), true},
484+
{int32(3), uint(1), false},
485+
{int64(-1), uint(1), true},
486+
{int64(1), uint(1), false},
487+
{int64(1), uint(3), true},
488+
{int64(3), uint(1), false},
489+
{int(-1), uint(1), true},
490+
{int(1), uint(1), false},
491+
{int(1), uint(3), true},
492+
{int(3), uint(1), false},
493+
{int8(-1), uint8(1), true},
494+
{int8(1), uint8(1), false},
495+
{int8(1), uint8(3), true},
496+
{int8(3), uint8(1), false},
497+
{int16(-1), uint8(1), true},
498+
{int16(1), uint8(1), false},
499+
{int16(1), uint8(3), true},
500+
{int16(3), uint8(1), false},
501+
{int32(-1), uint8(1), true},
502+
{int32(1), uint8(1), false},
503+
{int32(1), uint8(3), true},
504+
{int32(3), uint8(1), false},
505+
{int64(-1), uint8(1), true},
506+
{int64(1), uint8(1), false},
507+
{int64(1), uint8(3), true},
508+
{int64(3), uint8(1), false},
509+
{int(-1), uint8(1), true},
510+
{int(1), uint8(1), false},
511+
{int(1), uint8(3), true},
512+
{int(3), uint8(1), false},
513+
{int8(-1), uint16(1), true},
514+
{int8(1), uint16(1), false},
515+
{int8(1), uint16(3), true},
516+
{int8(3), uint16(1), false},
517+
{int16(-1), uint16(1), true},
518+
{int16(1), uint16(1), false},
519+
{int16(1), uint16(3), true},
520+
{int16(3), uint16(1), false},
521+
{int32(-1), uint16(1), true},
522+
{int32(1), uint16(1), false},
523+
{int32(1), uint16(3), true},
524+
{int32(3), uint16(1), false},
525+
{int64(-1), uint16(1), true},
526+
{int64(1), uint16(1), false},
527+
{int64(1), uint16(3), true},
528+
{int64(3), uint16(1), false},
529+
{int(-1), uint16(1), true},
530+
{int(1), uint16(1), false},
531+
{int(1), uint16(3), true},
532+
{int(3), uint16(1), false},
533+
{int8(-1), uint32(1), true},
534+
{int8(1), uint32(1), false},
535+
{int8(1), uint32(3), true},
536+
{int8(3), uint32(1), false},
537+
{int16(-1), uint32(1), true},
538+
{int16(1), uint32(1), false},
539+
{int16(1), uint32(3), true},
540+
{int16(3), uint32(1), false},
541+
{int32(-1), uint32(1), true},
542+
{int32(1), uint32(1), false},
543+
{int32(1), uint32(3), true},
544+
{int32(3), uint32(1), false},
545+
{int64(-1), uint32(1), true},
546+
{int64(1), uint32(1), false},
547+
{int64(1), uint32(3), true},
548+
{int64(3), uint32(1), false},
549+
{int(-1), uint32(1), true},
550+
{int(1), uint32(1), false},
551+
{int(1), uint32(3), true},
552+
{int(3), uint32(1), false},
553+
{int8(-1), uint64(1), true},
554+
{int8(1), uint64(1), false},
555+
{int8(1), uint64(3), true},
556+
{int8(3), uint64(1), false},
557+
{int16(-1), uint64(1), true},
558+
{int16(1), uint64(1), false},
559+
{int16(1), uint64(3), true},
560+
{int16(3), uint64(1), false},
561+
{int32(-1), uint64(1), true},
562+
{int32(1), uint64(1), false},
563+
{int32(1), uint64(3), true},
564+
{int32(3), uint64(1), false},
565+
{int64(-1), uint64(1), true},
566+
{int64(1), uint64(1), false},
567+
{int64(1), uint64(3), true},
568+
{int64(3), uint64(1), false},
569+
{int(-1), uint64(1), true},
570+
{int(1), uint64(1), false},
571+
{int(1), uint64(3), true},
572+
{int(3), uint64(1), false},
573+
}
574+
575+
for _, test := range tests {
576+
if res, err := lt(test.a, test.b); err != nil {
577+
if res != test.result {
578+
t.Errorf("a:%v(%T) lt b:%v(%T) should be %v", test.a, test.a, test.b, test.b, test.result)
579+
}
580+
}
581+
}
582+
}

0 commit comments

Comments
 (0)