Skip to content

Commit f01f59d

Browse files
authored
feat: imple function extract between positions (#557)
* feat: added file extract_between_positions.go * feat: add NewExtractBetweenPositionsAction constructor * feat: ExtractBetweenPositionsFunction with 4 error cases * test: add empty extract_between_positions_test.go * feat: EXTRACT_BETWEEN_POSITIONS with unit tests
1 parent cc592e3 commit f01f59d

3 files changed

Lines changed: 217 additions & 0 deletions

File tree

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// Copyright 2023 Linkall Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package strings
16+
17+
import (
18+
"fmt"
19+
20+
"github.com/vanus-labs/vanus/internal/primitive/transform/action"
21+
"github.com/vanus-labs/vanus/internal/primitive/transform/arg"
22+
"github.com/vanus-labs/vanus/internal/primitive/transform/common"
23+
"github.com/vanus-labs/vanus/internal/primitive/transform/context"
24+
)
25+
26+
type extractBetweenPositionsAction struct {
27+
action.CommonAction
28+
}
29+
30+
// NewExtractBetweenPositionsAction ["extract_between_positions",
31+
// "sourceJSONPath", "targetJsonPath", "startPosition", "endPosition"]
32+
func NewExtractBetweenPositionsAction() action.Action {
33+
return &extractBetweenPositionsAction{
34+
CommonAction: action.CommonAction{
35+
ActionName: "EXTRACT_BETWEEN_POSITIONS",
36+
FixedArgs: []arg.TypeList{arg.EventList, arg.EventList, arg.All, arg.All},
37+
},
38+
}
39+
}
40+
41+
func (a *extractBetweenPositionsAction) Init(args []arg.Arg) error {
42+
a.TargetArg = args[1]
43+
a.Args = []arg.Arg{args[0]}
44+
a.Args = append(a.Args, args[2:]...)
45+
a.ArgTypes = []common.Type{common.String, common.Int, common.Int}
46+
return nil
47+
}
48+
49+
func (a *extractBetweenPositionsAction) Execute(ceCtx *context.EventContext) error {
50+
args, err := a.RunArgs(ceCtx)
51+
if err != nil {
52+
return err
53+
}
54+
55+
sourceJSONPath, _ := args[0].(string)
56+
startPosition, _ := args[1].(int)
57+
endPosition, _ := args[2].(int)
58+
59+
if startPosition > len(sourceJSONPath) {
60+
return fmt.Errorf("start position must be equal or less than the length of the string")
61+
}
62+
if startPosition <= 0 {
63+
return fmt.Errorf("start position must be more than zero")
64+
}
65+
if endPosition > len(sourceJSONPath) {
66+
return fmt.Errorf("end position must be equal or less than the length of the string")
67+
}
68+
if startPosition > endPosition {
69+
return fmt.Errorf("start position must be be equal or less than end position")
70+
}
71+
return a.TargetArg.SetValue(ceCtx, sourceJSONPath[startPosition-1:endPosition])
72+
}
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
// Copyright 2023 Linkall Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package strings_test
16+
17+
import (
18+
"testing"
19+
20+
cetest "github.com/cloudevents/sdk-go/v2/test"
21+
. "github.com/smartystreets/goconvey/convey"
22+
23+
"github.com/vanus-labs/vanus/internal/primitive/transform/action/strings"
24+
"github.com/vanus-labs/vanus/internal/primitive/transform/context"
25+
"github.com/vanus-labs/vanus/internal/primitive/transform/runtime"
26+
)
27+
28+
func TestExtractBetweenPositionsAction(t *testing.T) {
29+
funcName := strings.NewExtractBetweenPositionsAction().Name()
30+
31+
Convey("test: Positive testcase", t, func() {
32+
a, err := runtime.NewAction([]interface{}{funcName, "$.data.appinfoA", "$.data.appinfoB", 2, 4})
33+
So(err, ShouldBeNil)
34+
e := cetest.MinEvent()
35+
data := map[string]interface{}{
36+
"appinfoA": "hello world!",
37+
}
38+
ceCtx := &context.EventContext{
39+
Event: &e,
40+
Data: data,
41+
}
42+
err = a.Execute(ceCtx)
43+
So(err, ShouldBeNil)
44+
res, ok := data["appinfoB"]
45+
So(ok, ShouldBeTrue)
46+
So(res, ShouldResemble, "ell")
47+
})
48+
49+
Convey("test: Positive testcase - extract positions on edges", t, func() {
50+
a, err := runtime.NewAction([]interface{}{funcName, "$.data.appinfoA", "$.data.appinfoB", 1, 12})
51+
So(err, ShouldBeNil)
52+
e := cetest.MinEvent()
53+
data := map[string]interface{}{
54+
"appinfoA": "hello world!",
55+
}
56+
ceCtx := &context.EventContext{
57+
Event: &e,
58+
Data: data,
59+
}
60+
err = a.Execute(ceCtx)
61+
So(err, ShouldBeNil)
62+
res, ok := data["appinfoB"]
63+
So(ok, ShouldBeTrue)
64+
So(res, ShouldResemble, "hello world!")
65+
})
66+
67+
Convey("test: Positive testcase - extract positions are equal", t, func() {
68+
a, err := runtime.NewAction([]interface{}{funcName, "$.data.appinfoA", "$.data.appinfoB", 1, 1})
69+
So(err, ShouldBeNil)
70+
e := cetest.MinEvent()
71+
data := map[string]interface{}{
72+
"appinfoA": "hello world!",
73+
}
74+
ceCtx := &context.EventContext{
75+
Event: &e,
76+
Data: data,
77+
}
78+
err = a.Execute(ceCtx)
79+
So(err, ShouldBeNil)
80+
res, ok := data["appinfoB"]
81+
So(ok, ShouldBeTrue)
82+
So(res, ShouldResemble, "h")
83+
})
84+
85+
Convey("test: Negative testcase - start position more than the length of the string", t, func() {
86+
a, err := runtime.NewAction([]interface{}{funcName, "$.data.appinfoA", "$.data.appinfoB", 13, 13})
87+
So(err, ShouldBeNil)
88+
e := cetest.MinEvent()
89+
data := map[string]interface{}{
90+
"appinfoA": "hello world!",
91+
}
92+
ceCtx := &context.EventContext{
93+
Event: &e,
94+
Data: data,
95+
}
96+
err = a.Execute(ceCtx)
97+
So(err.Error(), ShouldEqual, "start position must be equal or less than the length of the string")
98+
})
99+
100+
Convey("test: Negative testcase - start position less than one", t, func() {
101+
a, err := runtime.NewAction([]interface{}{funcName, "$.data.appinfoA", "$.data.appinfoB", 0, 13})
102+
So(err, ShouldBeNil)
103+
e := cetest.MinEvent()
104+
data := map[string]interface{}{
105+
"appinfoA": "hello world!",
106+
}
107+
ceCtx := &context.EventContext{
108+
Event: &e,
109+
Data: data,
110+
}
111+
err = a.Execute(ceCtx)
112+
So(err.Error(), ShouldEqual, "start position must be more than zero")
113+
})
114+
115+
Convey("test: Negative testcase - end position bigger than the length of the string", t, func() {
116+
a, err := runtime.NewAction([]interface{}{funcName, "$.data.appinfoA", "$.data.appinfoB", 5, 13})
117+
So(err, ShouldBeNil)
118+
e := cetest.MinEvent()
119+
data := map[string]interface{}{
120+
"appinfoA": "hello world!",
121+
}
122+
ceCtx := &context.EventContext{
123+
Event: &e,
124+
Data: data,
125+
}
126+
err = a.Execute(ceCtx)
127+
So(err.Error(), ShouldEqual, "end position must be equal or less than the length of the string")
128+
})
129+
130+
Convey("test: Negative testcase - start position bigger than end position", t, func() {
131+
a, err := runtime.NewAction([]interface{}{funcName, "$.data.appinfoA", "$.data.appinfoB", 5, 3})
132+
So(err, ShouldBeNil)
133+
e := cetest.MinEvent()
134+
data := map[string]interface{}{
135+
"appinfoA": "hello world!",
136+
}
137+
ceCtx := &context.EventContext{
138+
Event: &e,
139+
Data: data,
140+
}
141+
err = a.Execute(ceCtx)
142+
So(err.Error(), ShouldEqual, "start position must be be equal or less than end position")
143+
})
144+
}

internal/primitive/transform/runtime/init.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ func init() {
6060
strings.NewSplitWithDelimiterAction,
6161
strings.NewSplitBetweenPositionsAction,
6262
strings.NewSplitFromStartAction,
63+
strings.NewExtractBetweenPositionsAction,
6364
// condition
6465
condition.NewConditionIfAction,
6566
// array

0 commit comments

Comments
 (0)