From eaa870d5c52a85d4508e9bb34860b040a312ec98 Mon Sep 17 00:00:00 2001 From: NikolaLohinski Date: Tue, 27 Feb 2024 21:23:44 +0100 Subject: [PATCH] feat(tests): add match test --- builtins/tests.md | 13 +++++++++++- docs/index.md | 11 ++++++++++ internal/provider/tests_test.go | 36 +++++++++++++++++++++++++++++++++ lib/tests.go | 24 ++++++++++++++++++++++ 4 files changed, 83 insertions(+), 1 deletion(-) diff --git a/builtins/tests.md b/builtins/tests.md index 8f8e059..125de99 100644 --- a/builtins/tests.md +++ b/builtins/tests.md @@ -1,2 +1,13 @@ ## The `empty` test -Check if the input is empty. Works on strings, lists and dictionaries. \ No newline at end of file + +Check if the input is empty. Works on strings, lists and dictionaries. + +## The `match` test + +Expects a string holding a regular expression to be passed as an argument to match against the input. Returns `true` if the input matches the expression and `false` otherwise. For example: + +``` +{{ "123" is match("^[0-9]+") }} +``` + +will evaluate to `True`. \ No newline at end of file diff --git a/docs/index.md b/docs/index.md index 21e9eff..31032da 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1467,8 +1467,19 @@ Classic type casting tests. ### The `empty` test + Check if the input is empty. Works on strings, lists and dictionaries. +### The `match` test + +Expects a string holding a regular expression to be passed as an argument to match against the input. Returns `true` if the input matches the expression and `false` otherwise. For example: + +``` +{{ "123" is match("^[0-9]+") }} +``` + +will evaluate to `True`. + ## Methods diff --git a/internal/provider/tests_test.go b/internal/provider/tests_test.go index d2976c5..cdc4e96 100644 --- a/internal/provider/tests_test.go +++ b/internal/provider/tests_test.go @@ -87,4 +87,40 @@ var _ = Context("tests", func() { itShouldFailToRender(terraformCode, "invalid call to test 'empty': True is neither a list, a dict nor a string") }) }) + Context("match", func() { + BeforeEach(func() { + *template = `{{- input is match("^f(o)+$") -}}` + }) + Context("when the input is a string that matches", func() { + BeforeEach(func() { + *context = `input = "foo"` + }) + itShouldSetTheExpectedResult(terraformCode, "True") + }) + Context("when the input is a string that does not matches", func() { + BeforeEach(func() { + *context = `input = "bar"` + }) + itShouldSetTheExpectedResult(terraformCode, "False") + }) + Context("when the argument is not a valid regex", func() { + BeforeEach(func() { + *context = `input = "foo"` + *template = `{{- input is match("{.*[") -}}` + }) + itShouldFailToRender(terraformCode, "failed to compile: {.*\\[: error parsing regexp") + }) + Context("when the input is an error", func() { + BeforeEach(func() { + *template = `{{- ("thrown" | fail) is match(".*") -}}` + }) + itShouldFailToRender(terraformCode, "thrown") + }) + Context("when the input is invalid", func() { + BeforeEach(func() { + *context = `input = true` + }) + itShouldFailToRender(terraformCode, "True is not a string") + }) + }) }) diff --git a/lib/tests.go b/lib/tests.go index 2cd44fd..6201e6c 100644 --- a/lib/tests.go +++ b/lib/tests.go @@ -10,6 +10,7 @@ import ( var Tests = exec.NewTestSet(map[string]exec.TestFunction{ "empty": testEmpty, + "match": testMatch, }) func testEmpty(ctx *exec.Context, in *exec.Value, params *exec.VarArgs) (bool, error) { @@ -22,3 +23,26 @@ func testEmpty(ctx *exec.Context, in *exec.Value, params *exec.VarArgs) (bool, e return in.Len() == 0, nil } } + +func testMatch(ctx *exec.Context, in *exec.Value, params *exec.VarArgs) (bool, error) { + if in.IsError() { + return false, errors.New(in.Error()) + } + var ( + regex string + ) + if err := params.Take( + exec.KeywordArgument("regex", exec.AsValue(2), exec.StringArgument(®ex)), + ); err != nil { + return false, exec.AsValue(exec.ErrInvalidCall(err)) + } + if !in.IsString() { + return false, exec.AsValue(exec.ErrInvalidCall(fmt.Errorf("%s is not a string", in.String()))) + } + matcher, err := regexp.Compile(regex) + if err != nil { + return false, exec.AsValue(exec.ErrInvalidCall(fmt.Errorf("failed to compile: %s: %s", regex, err))) + } + + return matcher.MatchString(in.String()), nil +}