From e54ddfebec031d51b2b6f597cee861b0cf0ea0b1 Mon Sep 17 00:00:00 2001 From: debugtalk Date: Wed, 29 Sep 2021 11:07:40 +0800 Subject: [PATCH] fix: parse variables --- parser.go | 40 ++++++++++++++++++---------------------- parser_test.go | 27 +++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 22 deletions(-) diff --git a/parser.go b/parser.go index c64d2c8a..73491576 100644 --- a/parser.go +++ b/parser.go @@ -47,13 +47,24 @@ var ( // parseString parse string with variables func parseString(raw string, variablesMapping map[string]interface{}) interface{} { - matchStartPosition := strings.Index(raw, "$") - if matchStartPosition == -1 { // no $ found - return raw - } - parsedString := raw[0:matchStartPosition] + matchStartPosition := 0 + parsedString := "" + remainedString := raw for matchStartPosition < len(raw) { + // locate $ char position + startPosition := strings.Index(remainedString, "$") + if startPosition == -1 { // no $ found + // append remained string + parsedString += remainedString + break + } + + // found $, check if variable or function + matchStartPosition += startPosition + parsedString += remainedString[0:startPosition] + remainedString = remainedString[startPosition:] + // search variable like ${var} or $var varMatched := regexCompileVariable.FindStringSubmatch(raw[matchStartPosition:]) if len(varMatched) == 3 { @@ -70,27 +81,12 @@ func parseString(raw string, variablesMapping map[string]interface{}) interface{ return varValue } - parsedString += fmt.Sprintf("%v", varValue) matchStartPosition += len(varMatched[0]) + parsedString += fmt.Sprintf("%v", varValue) + remainedString = raw[matchStartPosition:] log.Printf("[parseString] parsedString: %v, matchStartPosition: %v", parsedString, matchStartPosition) continue } - - currentPosition := matchStartPosition - var remainedString string - // find next $ location - nextStartPosition := strings.Index(raw[currentPosition+1:], "$") - if nextStartPosition == -1 { // no $ found - remainedString = raw[currentPosition:] - // break loop - matchStartPosition = len(raw) - } else { // found next $ - matchStartPosition = nextStartPosition - remainedString = raw[currentPosition:nextStartPosition] - } - - // append remained string - parsedString += remainedString } return parsedString diff --git a/parser_test.go b/parser_test.go index c6ff2576..bf239b3b 100644 --- a/parser_test.go +++ b/parser_test.go @@ -55,4 +55,31 @@ func TestParseDataStringWithVariables(t *testing.T) { if !assert.Equal(t, "abc#XYZ", parseData("${var_1}#XYZ", variablesMapping)) { t.Fail() } + if !assert.Equal(t, "/abc/def/var3", parseData("/$var_1/$var_2/var3", variablesMapping)) { + t.Fail() + } + if !assert.Equal(t, 123, parseData("$var_3", variablesMapping)) { + t.Fail() + } + if !assert.Equal(t, map[string]interface{}{"a": 1}, parseData("$var_4", variablesMapping)) { + t.Fail() + } + if !assert.Equal(t, true, parseData("$var_5", variablesMapping)) { + t.Fail() + } + if !assert.Equal(t, nil, parseData("$var_6", variablesMapping)) { + t.Fail() + } + // TODO: fix compatibility with python version, "abc{'a': 1}" + if !assert.Equal(t, "abcmap[a:1]", parseData("abc$var_4", variablesMapping)) { + t.Fail() + } + // TODO: fix compatibility with python version, "abcTrue" + if !assert.Equal(t, "abctrue", parseData("abc$var_5", variablesMapping)) { + t.Fail() + } + // TODO: fix compatibility with python version, raise exception + if !assert.Equal(t, "/api/", parseData("/api/$SECRET_KEY", variablesMapping)) { + t.Fail() + } }