mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
Update *strip converter implementation and its tests
Added in-depth comments to the constructor. Added test cases for most edge cases (if not all). Updated the test to verify not only if an error occurs, but to also check whether it matches the one we expect. Added 3 more sanity checks that were missed.
This commit is contained in:
committed by
Dan Christian Bogos
parent
36e43beca8
commit
6cfb934c9b
@@ -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:<side>:<amount>"
|
||||
// 2. "*strip:<side>:<substring>[:<amount>]"
|
||||
// 3. "*strip:<side>:*char:<substring>[:<amount>]"
|
||||
//
|
||||
// Explanation of placeholders:
|
||||
// - <side>: Specifies which part of the string to strip. Must be one of "*prefix", "*suffix", or "*both".
|
||||
// - <substring>: Identifies the substring to remove. It can be a specific string, "*nil" for null characters,
|
||||
// "*space" for spaces, or any other character.
|
||||
// - <amount> (optional): Determines the number of characters to remove. If omitted, all instances of <substring>
|
||||
// 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
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user