diff --git a/ucl/builtins/strs.go b/ucl/builtins/strs.go index ff30cd4..4b813ca 100644 --- a/ucl/builtins/strs.go +++ b/ucl/builtins/strs.go @@ -10,10 +10,11 @@ func Strs() ucl.Module { return ucl.Module{ Name: "strs", Builtins: map[string]ucl.BuiltinHandler{ - "to-upper": toUpper, - "to-lower": toLower, - "trim": trim, - "join": join, + "to-upper": toUpper, + "to-lower": toLower, + "trim": trim, + "join": join, + "has-suffix": hasSuffix, }, } } @@ -70,3 +71,15 @@ func join(ctx context.Context, args ucl.CallArgs) (any, error) { return sb.String(), nil } + +func hasSuffix(ctx context.Context, args ucl.CallArgs) (any, error) { + var ( + s string + suffix string + ) + if err := args.Bind(&s, &suffix); err != nil { + return nil, err + } + + return strings.HasSuffix(s, suffix), nil +} diff --git a/ucl/builtins/strs_test.go b/ucl/builtins/strs_test.go index de97d7d..9aef92d 100644 --- a/ucl/builtins/strs_test.go +++ b/ucl/builtins/strs_test.go @@ -101,6 +101,34 @@ func TestStrs_Trim(t *testing.T) { } } +func TestStrs_HasSuffix(t *testing.T) { + tests := []struct { + desc string + eval string + want any + wantErr bool + }{ + {desc: "suffix 1", eval: `strs:has-suffix "hello" "lo"`, want: true}, + {desc: "suffix 2", eval: `strs:has-suffix "bellow" "low"`, want: true}, + {desc: "suffix 3", eval: `strs:has-suffix "goodbye" "lo"`, want: false}, + } + + for _, tt := range tests { + t.Run(tt.desc, func(t *testing.T) { + inst := ucl.New( + ucl.WithModule(builtins.Strs()), + ) + res, err := inst.Eval(context.Background(), tt.eval) + if tt.wantErr { + assert.Error(t, err) + } else { + assert.NoError(t, err) + assert.Equal(t, tt.want, res) + } + }) + } +} + func TestStrs_Join(t *testing.T) { tests := []struct { desc string