-
-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: allow functions aliasing 🌱 (#3)
This pull request introduces the aliasing feature in the update allows for backward compatibility by mapping old function names to their updated versions. This ensures legacy code remains functional while encouraging the adoption of new naming conventions without breaking existing projects.
- Loading branch information
Showing
6 changed files
with
182 additions
and
42 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,5 @@ | ||
.env | ||
.vscode/ | ||
|
||
vendor/ | ||
/.glide |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
package sprout | ||
|
||
// BACKWARDS COMPATIBILITY | ||
// The following functions are provided for backwards compatibility with the | ||
// original sprig methods. They are not recommended for use in new code. | ||
var bc_registerSprigFuncs = map[string][]string{ | ||
"dateModify": {"date_modify"}, //! Deprecated: Should use dateModify instead | ||
"dateInZone": {"date_in_zone"}, //! Deprecated: Should use dateInZone instead | ||
"mustDateModify": {"must_date_modify"}, //! Deprecated: Should use mustDateModify instead | ||
"ellipsis": {"abbrev"}, //! Deprecated: Should use ellipsis instead | ||
"ellipsisBoth": {"abbrevboth"}, //! Deprecated: Should use ellipsisBoth instead | ||
"trimAll": {"trimall"}, //! Deprecated: Should use trimAll instead | ||
"int": {"atoi"}, //! Deprecated: Should use toInt instead | ||
"append": {"push"}, //! Deprecated: Should use append instead | ||
"mustAppend": {"mustPush"}, //! Deprecated: Should use mustAppend instead | ||
"list": {"tuple"}, // FIXME: with the addition of append/prepend these are no longer immutable. | ||
"max": {"biggest"}, | ||
} | ||
|
||
//\ BACKWARDS COMPATIBILITY | ||
|
||
// WithAlias returns a FunctionHandlerOption that associates one or more alias | ||
// names with an original function name. | ||
// This allows the function to be called by any of its aliases. | ||
// | ||
// originalFunction specifies the original function name to which aliases will | ||
// be added. aliases is a variadic parameter that takes one or more strings as | ||
// aliases for the original function. | ||
// | ||
// The function does nothing if no aliases are provided. | ||
// If the original function name does not already have associated aliases in | ||
// the FunctionHandler, a new slice of strings is created to hold its aliases. | ||
// Each provided alias is then appended to this slice. | ||
// | ||
// This option must be applied to a FunctionHandler using the FunctionHandler's | ||
// options mechanism for the aliases to take effect. | ||
func WithAlias(originalFunction string, aliases ...string) FunctionHandlerOption { | ||
return func(p *FunctionHandler) { | ||
if len(aliases) == 0 { | ||
return | ||
} | ||
|
||
if _, ok := p.funcsAlias[originalFunction]; !ok { | ||
p.funcsAlias[originalFunction] = make([]string, 0) | ||
} | ||
|
||
p.funcsAlias[originalFunction] = append(p.funcsAlias[originalFunction], aliases...) | ||
} | ||
} | ||
|
||
// registerAliases allows the aliases to be used as references to the original | ||
// functions. | ||
// | ||
// It should be called after all aliases have been added through the WithAlias | ||
// option and before the function map is used to ensure all aliases are properly | ||
// registered. | ||
func (p *FunctionHandler) registerAliases() { | ||
// BACKWARDS COMPATIBILITY | ||
// Register the sprig function aliases | ||
for originalFunction, aliases := range bc_registerSprigFuncs { | ||
for _, alias := range aliases { | ||
p.funcMap[alias] = p.funcMap[originalFunction] | ||
} | ||
} | ||
//\ BACKWARDS COMPATIBILITY | ||
|
||
for originalFunction, aliases := range p.funcsAlias { | ||
for _, alias := range aliases { | ||
p.funcMap[alias] = p.funcMap[originalFunction] | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package sprout | ||
|
||
import ( | ||
"reflect" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
// TestWithAlias checks that aliases are correctly added to a function. | ||
func TestWithAlias(t *testing.T) { | ||
handler := NewFunctionHandler() | ||
originalFunc := "originalFunc" | ||
alias1 := "alias1" | ||
alias2 := "alias2" | ||
|
||
// Apply the WithAlias option with two aliases. | ||
WithAlias(originalFunc, alias1, alias2)(handler) | ||
|
||
// Check that the aliases were added. | ||
assert.Contains(t, handler.funcsAlias, originalFunc) | ||
assert.Contains(t, handler.funcsAlias[originalFunc], alias1) | ||
assert.Contains(t, handler.funcsAlias[originalFunc], alias2) | ||
assert.Len(t, handler.funcsAlias[originalFunc], 2, "there should be exactly 2 aliases") | ||
} | ||
|
||
func TestWithAlias_Empty(t *testing.T) { | ||
handler := NewFunctionHandler() | ||
originalFunc := "originalFunc" | ||
|
||
// Apply the WithAlias option with no aliases. | ||
WithAlias(originalFunc)(handler) | ||
|
||
// Check that no aliases were added. | ||
assert.NotContains(t, handler.funcsAlias, originalFunc) | ||
} | ||
|
||
// TestRegisterAliases checks that aliases are correctly registered in the function map. | ||
func TestRegisterAliases(t *testing.T) { | ||
handler := NewFunctionHandler() | ||
originalFunc := "originalFunc" | ||
alias1 := "alias1" | ||
alias2 := "alias2" | ||
|
||
// Mock a function for originalFunc and add it to funcMap. | ||
mockFunc := func() {} | ||
handler.funcMap[originalFunc] = mockFunc | ||
|
||
// Apply the WithAlias option and then register the aliases. | ||
WithAlias(originalFunc, alias1, alias2)(handler) | ||
handler.registerAliases() | ||
|
||
// Check that the aliases are mapped to the same function as the original function in funcMap. | ||
assert.True(t, reflect.ValueOf(handler.funcMap[originalFunc]).Pointer() == reflect.ValueOf(handler.funcMap[alias1]).Pointer()) | ||
assert.True(t, reflect.ValueOf(handler.funcMap[originalFunc]).Pointer() == reflect.ValueOf(handler.funcMap[alias2]).Pointer()) | ||
} | ||
|
||
func TestAliasesInTemplate(t *testing.T) { | ||
handler := NewFunctionHandler() | ||
originalFuncName := "originalFunc" | ||
alias1 := "alias1" | ||
alias2 := "alias2" | ||
|
||
// Mock a function for originalFunc and add it to funcMap. | ||
mockFunc := func() string { return "cheese" } | ||
handler.funcMap[originalFuncName] = mockFunc | ||
|
||
// Apply the WithAlias option and then register the aliases. | ||
WithAlias(originalFuncName, alias1, alias2)(handler) | ||
|
||
// Create a template with the aliases. | ||
result, err := runTemplate(t, handler, `{{originalFunc}} {{alias1}} {{alias2}}`) | ||
assert.NoError(t, err) | ||
assert.Equal(t, "cheese cheese cheese", result) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters