diff --git a/utils/dataconverter.go b/utils/dataconverter.go index ab065d331..da1825964 100644 --- a/utils/dataconverter.go +++ b/utils/dataconverter.go @@ -591,15 +591,37 @@ func (jsnC JSONConverter) Convert(in any) (any, error) { // StripConverter strips the prefix, the suffix or both from a string. type StripConverter struct { - side string - substr string - amount int + side string // side represents which part of the string to strip: prefix, suffix, or both. + substr string // substr represents the substring to be removed from the string. + amount int // amount represents the number of characters to be removed from the string. } -// NewStripConverter creates a new StripConverter with the specified parameters. +// NewStripConverter initializes and returns a new StripConverter with configurations +// based on the provided parameters in the input string. Each parameter in the input +// string should be separated by ':'. +// +// The input string must follow one of the following formats: +// 1. "*strip::" +// 2. "*strip::[:]" +// 3. "*strip::*char:[:]" +// +// Explanation of placeholders: +// - : Specifies which part of the string to strip. Must be one of "*prefix", "*suffix", or "*both". +// - : Identifies the substring to remove. It can be a specific string, "*nil" for null characters, +// "*space" for spaces, or any other character. +// - (optional): Determines the number of characters to remove. If omitted, all instances of +// are removed. +// +// Examples: +// - "*strip:*prefix:5": Removes the first 5 characters from the string's prefix. +// - "*strip:*suffix:*nil": Eliminates all trailing null characters in the string. +// - "*strip:*both:*space:2": Clears 2 spaces from both the prefix and suffix of the string. +// - "*strip:*suffix:*char:abc": Removes the substring "abc" from the suffix of the string. +// - "*strip:*prefix:*char:abc:2": Strips the substring "abc" from the prefix of the string, repeated 2 times. func NewStripConverter(params string) (DataConverter, error) { paramSlice := strings.Split(params, InInFieldSep) - if len(paramSlice) < 3 || len(paramSlice) > 5 { + paramCount := len(paramSlice) + if paramCount < 3 || paramCount > 5 { return nil, errors.New("strip converter: invalid number of parameters (should have 3, 4 or 5)") } sc := StripConverter{ @@ -612,12 +634,15 @@ func NewStripConverter(params string) (DataConverter, error) { case EmptyString: return nil, errors.New("strip converter: substr parameter cannot be empty") case MetaNil, MetaSpace: + if paramCount == 5 { + return nil, errors.New("strip converter: cannot have 5 params in *nil/*space case") + } if sc.substr == MetaNil { sc.substr = "\u0000" } else { sc.substr = " " } - if len(paramSlice) == 4 { + if paramCount == 4 { sc.amount, err = strconv.Atoi(paramSlice[3]) if err != nil { return nil, fmt.Errorf("strip converter: invalid amount parameter (%w)", err) @@ -625,11 +650,11 @@ func NewStripConverter(params string) (DataConverter, error) { sc.substr = strings.Repeat(sc.substr, sc.amount) } case MetaChar: - if len(paramSlice) < 4 { - return nil, errors.New("strip converter: usage of *char implies the need of 4 or 5 params") + if paramCount < 4 || paramSlice[3] == EmptyString { + return nil, errors.New("strip converter: usage of *char implies the need of 4 or 5 non-empty params") } - sc.substr = paramSlice[3] // should probably return error if empty - if len(paramSlice) == 5 { + sc.substr = paramSlice[3] + if paramCount == 5 { sc.amount, err = strconv.Atoi(paramSlice[4]) if err != nil { return nil, fmt.Errorf("strip converter: invalid amount parameter (%w)", err) @@ -637,13 +662,15 @@ func NewStripConverter(params string) (DataConverter, error) { sc.substr = strings.Repeat(sc.substr, sc.amount) } default: + if paramCount > 3 { + return nil, errors.New("strip converter: just the amount specified, cannot have more than 3 params") + } sc.amount, err = strconv.Atoi(paramSlice[2]) if err != nil { return nil, fmt.Errorf("strip converter: invalid amount parameter (%w)", err) } sc.substr = "" } - return sc, nil } diff --git a/utils/dataconverter_test.go b/utils/dataconverter_test.go index 18b554c0b..d78c07641 100644 --- a/utils/dataconverter_test.go +++ b/utils/dataconverter_test.go @@ -1468,7 +1468,7 @@ func TestStripConverter(t *testing.T) { name: "Empty third parameter", params: "*strip:*prefix:", input: "TEST", - expected: "", + expected: "strip converter: substr parameter cannot be empty", constructorErr: true, convertErr: false, }, @@ -1476,15 +1476,15 @@ func TestStripConverter(t *testing.T) { name: "Invalid side parameter", params: "*strip:*invalid:*nil", input: "TEST", - expected: "", + expected: "strip converter: invalid side parameter", constructorErr: false, convertErr: true, }, { - name: "Invalid nr. of parameters", + name: "Invalid nr. of params *char", params: "*strip:*prefix:*char:*nil:abc:3", input: "TEST", - expected: "", + expected: "strip converter: invalid number of parameters (should have 3, 4 or 5)", constructorErr: true, convertErr: false, }, @@ -1492,7 +1492,7 @@ func TestStripConverter(t *testing.T) { name: "Invalid amount parameter", params: "*strip:*prefix:*char:0:three", input: "000TEST", - expected: "", + expected: "strip converter: invalid amount parameter (strconv.Atoi: parsing \"three\": invalid syntax)", constructorErr: true, convertErr: false, }, @@ -1520,25 +1520,82 @@ func TestStripConverter(t *testing.T) { constructorErr: false, convertErr: false, }, + { + name: "*char missing substring case 1", + params: "*strip:*prefix:*char", + input: "12345TEST", + expected: "strip converter: usage of *char implies the need of 4 or 5 non-empty params", + constructorErr: true, + convertErr: false, + }, + { + name: "*char missing substring case 2", + params: "*strip:*prefix:*char::2", + input: "12345TEST", + expected: "strip converter: usage of *char implies the need of 4 or 5 non-empty params", + constructorErr: true, + convertErr: false, + }, + { + name: "*char missing substring case 3", + params: "*strip:*prefix:*char:", + input: "12345TEST", + expected: "strip converter: usage of *char implies the need of 4 or 5 non-empty params", + constructorErr: true, + convertErr: false, + }, + { + name: "*nil/*space too many parameters", + params: "*strip:*prefix:*nil:5:12345", + input: "12345TEST", + expected: "strip converter: cannot have 5 params in *nil/*space case", + constructorErr: true, + convertErr: false, + }, + { + name: "third param numeric with too many params case 1", + params: "*strip:*prefix:1:1", + input: "12345TEST", + expected: "strip converter: just the amount specified, cannot have more than 3 params", + constructorErr: true, + convertErr: false, + }, + { + name: "third param numeric with too many params case 2", + params: "*strip:*prefix:1:12345:1", + input: "12345TEST", + expected: "strip converter: just the amount specified, cannot have more than 3 params", + constructorErr: true, + convertErr: false, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { sc, err := NewDataConverter(tt.params) if (err != nil) != tt.constructorErr { - t.Errorf("NewStripConverter error = %v, constructorErr %v", err, tt.constructorErr) + t.Errorf("NewStripConverter() error = %v, constructorErr %v", err, tt.constructorErr) return } if tt.constructorErr { + if err.Error() != tt.expected { + t.Errorf("expected error message: %v, received: %v", tt.expected, err.Error()) + } return } rcv, err := sc.Convert(tt.input) if (err != nil) != tt.convertErr { - t.Errorf("Convert error = %v, convertErr %v", err, tt.convertErr) + t.Errorf("Convert() error = %v, convertErr %v", err, tt.convertErr) + return + } + if tt.convertErr { + if err.Error() != tt.expected { + t.Errorf("expected error message: %s, received: %s", tt.expected, err.Error()) + } return } if rcv != tt.expected { - t.Errorf("expected: %s, received: %s", tt.expected, rcv) + t.Errorf("expected: %q, received: %q", tt.expected, rcv) } }) }