Skip to content

Commit

Permalink
added tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ascandone committed Nov 12, 2024
1 parent 8279b97 commit 08f979a
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 2 deletions.
9 changes: 7 additions & 2 deletions internal/interpreter/interpreter.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ func parseVar(type_ string, rawValue string, r parser.Range) (Value, Interpreter
case analysis.TypeAccount:
return AccountAddress(rawValue), nil
case analysis.TypePortion:
bi, err := parsePortionSpecific(rawValue)
bi, err := ParsePortionSpecific(rawValue)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -861,7 +861,7 @@ func (st *programState) evaluateSentAmt(sentValue parser.SentValue) (*string, *b
// slightly edited copy-paste from:
// https://github.com/formancehq/ledger/blob/b188d0c80eadaab5024d74edc967c7005e155f7c/internal/machine/portion.go#L57

func parsePortionSpecific(input string) (*big.Rat, InterpreterError) {
func ParsePortionSpecific(input string) (*big.Rat, InterpreterError) {
var res *big.Rat
var ok bool

Expand Down Expand Up @@ -890,5 +890,10 @@ func parsePortionSpecific(input string) (*big.Rat, InterpreterError) {
if res == nil {
return nil, BadPortionParsingErr{Reason: "invalid format", Source: input}
}

if res.Cmp(big.NewRat(0, 1)) == -1 || res.Cmp(big.NewRat(1, 1)) == 1 {
return nil, BadPortionParsingErr{Reason: "portion must be between 0% and 100% inclusive", Source: input}
}

return res, nil
}
131 changes: 131 additions & 0 deletions internal/interpreter/portion_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package interpreter_test

import (
"math/big"
"strings"
"testing"

"github.com/formancehq/numscript/internal/interpreter"
)

func TestBetween0And1Inclusive(t *testing.T) {
tests := []struct {
in string
want *big.Rat
wantErr bool
}{
{
in: "0%",
want: big.NewRat(0, 1),
},
{
in: "0.0%",
want: big.NewRat(0, 1),
},
{
in: "0/1",
want: big.NewRat(0, 1),
},
{
in: "0/25",
want: big.NewRat(0, 1),
},
{
in: "0/100",
want: big.NewRat(0, 1),
},
{
in: "1%",
want: big.NewRat(1, 100),
},
{
in: "1/100",
want: big.NewRat(1, 100),
},
{
in: "10/1000",
want: big.NewRat(1, 100),
},
{
in: "50/100",
want: big.NewRat(50, 100),
},
{
in: "50%",
want: big.NewRat(50, 100),
},
{
in: "50.0%",
want: big.NewRat(50, 100),
},
{
in: "1/1",
want: big.NewRat(1, 1),
},
{
in: "100/100",
want: big.NewRat(1, 1),
},
{
in: "100.0%",
want: big.NewRat(1, 1),
},
{
in: "100%",
want: big.NewRat(1, 1),
},
// Now for the failures. We don't check negative numbers in this test because
// those are a parsing failure, not a range failure.
{
in: "100.1%",
wantErr: true,
},
{
in: "101%",
wantErr: true,
},
{
in: "101/100",
wantErr: true,
},
{
in: "2/1",
wantErr: true,
},
{
in: "3/2",
wantErr: true,
},
}

for _, test := range tests {
t.Run(test.in, func(t *testing.T) {
got, err := interpreter.ParsePortionSpecific(test.in)
if test.wantErr {
if err == nil {
t.Fatal("should have errored")
}
if !strings.Contains(err.Error(), "between") {
t.Fatal("wrong error")
}
return
}
if err != nil {
t.Fatalf("ParsePortionSpecific(%q): %v", test.in, err)
}
if test.want.Cmp(got) != 0 {
t.Fatalf("ParsePortionSpecific(%q) = %q, want %q", test.in, got, test.want)
}
})
}
}

func TestInvalidFormat(t *testing.T) {
_, err := interpreter.ParsePortionSpecific("this is not a portion")
if err == nil {
t.Fatal("should have errored")
}
if !strings.Contains(err.Error(), "format") {
t.Fatal("wrong error")
}
}

0 comments on commit 08f979a

Please sign in to comment.