diff --git a/internal/primitive/transform/action/strings/replace_between_positions.go b/internal/primitive/transform/action/strings/replace_between_positions.go new file mode 100644 index 000000000..892227c39 --- /dev/null +++ b/internal/primitive/transform/action/strings/replace_between_positions.go @@ -0,0 +1,32 @@ +// Copyright 2023 Linkall Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package strings + +import ( + "github.com/linkall-labs/vanus/internal/primitive/transform/action" + "github.com/linkall-labs/vanus/internal/primitive/transform/arg" + "github.com/linkall-labs/vanus/internal/primitive/transform/function" +) + +// NewReplaceBetweenPositionsAction ["path","startPosition","endPosition","targetValue"]. +func NewReplaceBetweenPositionsAction() action.Action { + a := &action.SourceTargetSameAction{} + a.CommonAction = action.CommonAction{ + ActionName: "REPLACE_BETWEEN_POSITIONS", + FixedArgs: []arg.TypeList{arg.EventList, arg.All, arg.All, arg.All}, + Fn: function.ReplaceBetweenPositionsFunction, + } + return a +} diff --git a/internal/primitive/transform/action/strings/replace_between_positions_test.go b/internal/primitive/transform/action/strings/replace_between_positions_test.go new file mode 100644 index 000000000..b6faf0f64 --- /dev/null +++ b/internal/primitive/transform/action/strings/replace_between_positions_test.go @@ -0,0 +1,81 @@ +// Copyright 2023 Linkall Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package strings_test + +import ( + "testing" + + cetest "github.com/cloudevents/sdk-go/v2/test" + "github.com/linkall-labs/vanus/internal/primitive/transform/action/strings" + "github.com/linkall-labs/vanus/internal/primitive/transform/context" + "github.com/linkall-labs/vanus/internal/primitive/transform/runtime" + . "github.com/smartystreets/goconvey/convey" +) + +func TestReplaceBetweenPositionsAction(t *testing.T) { + funcName := strings.NewReplaceBetweenPositionsAction().Name() + + Convey("test Positive testcase", t, func() { + a, err := runtime.NewAction([]interface{}{funcName, "$.test", 7, 12, "Vanus"}) + So(err, ShouldBeNil) + e := cetest.MinEvent() + e.SetExtension("test", "Hello, World!") + ceCtx := &context.EventContext{ + Event: &e, + } + err = a.Execute(ceCtx) + So(err, ShouldBeNil) + So(e.Extensions()["test"], ShouldEqual, "Hello, Vanus!") + }) + + Convey("test Negative testcase: startPosition greater than string length", t, func() { + a, err := runtime.NewAction([]interface{}{funcName, "$.test", 100, 8, "Dan"}) + So(err, ShouldBeNil) + e := cetest.MinEvent() + e.SetExtension("test", "Start position must be less than the length of the string") + ceCtx := &context.EventContext{ + Event: &e, + } + err = a.Execute(ceCtx) + So(err, ShouldNotBeNil) + So(e.Extensions()["test"], ShouldEqual, "Start position must be less than the length of the string") + }) + + Convey("test Negative testcase: endPosition greater than string length", t, func() { + a, err := runtime.NewAction([]interface{}{funcName, "$.test", 8, 60, "free to use"}) + So(err, ShouldBeNil) + e := cetest.MinEvent() + e.SetExtension("test", "End position must be less than the length of the string") + ceCtx := &context.EventContext{ + Event: &e, + } + err = a.Execute(ceCtx) + So(err, ShouldNotBeNil) + So(e.Extensions()["test"], ShouldEqual, "End position must be less than the length of the string") + }) + + Convey("test Negative testcase: startPosition greater than endPosition", t, func() { + a, err := runtime.NewAction([]interface{}{funcName, "$.test", 12, 5, "Python"}) + So(err, ShouldBeNil) + e := cetest.MinEvent() + e.SetExtension("test", "Start position must be less than end position") + ceCtx := &context.EventContext{ + Event: &e, + } + err = a.Execute(ceCtx) + So(err, ShouldNotBeNil) + So(e.Extensions()["test"], ShouldEqual, "Start position must be less than end position") + }) +} diff --git a/internal/primitive/transform/common/cast.go b/internal/primitive/transform/common/cast.go index 89f1b0973..7218e8395 100644 --- a/internal/primitive/transform/common/cast.go +++ b/internal/primitive/transform/common/cast.go @@ -50,6 +50,8 @@ func Cast(val interface{}, target Type) (interface{}, error) { return float64(value), nil case int64: return float64(value), nil + case int: + return float64(value), nil } return 0, fmt.Errorf("undefined cast from %v to %v", TypeFromVal(val), target) case Bool: diff --git a/internal/primitive/transform/function/strings_functions.go b/internal/primitive/transform/function/strings_functions.go index 590430980..386a42db6 100644 --- a/internal/primitive/transform/function/strings_functions.go +++ b/internal/primitive/transform/function/strings_functions.go @@ -15,6 +15,7 @@ package function import ( + "fmt" "strings" "github.com/linkall-labs/vanus/internal/primitive/transform/common" @@ -81,3 +82,24 @@ var SplitWithSepFunction = function{ return strings.SplitN(s, sep, int(args[2].(float64))), nil }, } + +var ReplaceBetweenPositionsFunction = function{ + name: "REPLACE_BETWEEN_POSITIONS", + fixedArgs: []common.Type{common.String, common.Number, common.Number, common.String}, + fn: func(args []interface{}) (interface{}, error) { + path, _ := args[0].(string) + startPosition := int(args[1].(float64)) + endPosition := int(args[2].(float64)) + targetValue, _ := args[3].(string) + if startPosition >= len(path) { + return nil, fmt.Errorf("start position must be less than the length of the string") + } + if endPosition >= len(path) { + return nil, fmt.Errorf("end position must be less than the length of the string") + } + if startPosition >= endPosition { + return nil, fmt.Errorf("start position must be less than end position") + } + return path[:startPosition] + targetValue + path[endPosition:], nil + }, +} diff --git a/internal/primitive/transform/runtime/init.go b/internal/primitive/transform/runtime/init.go index 48987e5b8..27bf52286 100644 --- a/internal/primitive/transform/runtime/init.go +++ b/internal/primitive/transform/runtime/init.go @@ -50,6 +50,7 @@ func init() { strings.NewAddSuffixAction, strings.NewReplaceWithRegexAction, strings.NewReplaceStringAction, + strings.NewReplaceBetweenPositionsAction, // condition condition.NewConditionIfAction, // render