Skip to content

Commit

Permalink
feat(template): add random function
Browse files Browse the repository at this point in the history
  • Loading branch information
oliviaBahr authored Sep 20, 2024
1 parent 324e105 commit 9cf42b5
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/template/func_map.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ func funcMap() template.FuncMap {
"replaceP": replaceP,
"gt": gt,
"lt": lt,
"random": random,
"reason": GetReasonFromStatus,
"hresult": hresult,
"trunc": trunc,
Expand Down
22 changes: 22 additions & 0 deletions src/template/random.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package template

import (
"errors"
"fmt"
"math/rand"
"reflect"
)

func random(list interface{}) (string, error) {
v := reflect.ValueOf(list)

if v.Kind() != reflect.Slice && v.Kind() != reflect.Array {
return "", errors.New("input must be a slice or array")
}

if v.Len() == 0 {
return "", errors.New("input slice or array is empty")
}

return fmt.Sprintf("%v", v.Index(rand.Intn(v.Len()))), nil
}
65 changes: 65 additions & 0 deletions src/template/random_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package template

import (
"fmt"
"testing"

"github.com/stretchr/testify/assert"
)

func TestRandom(t *testing.T) {
cases := []struct {
Case string
Input interface{}
ShouldError bool
}{
{
Case: "valid slice",
Input: []int{1, 2, 3, 4, 5},
},
{
Case: "valid array",
Input: [5]int{1, 2, 3, 4, 5},
},
{
Case: "empty slice",
Input: []int{},
ShouldError: true,
},
{
Case: "not a slice or array",
Input: "not a slice",
ShouldError: true,
},
{
Case: "valid string slice",
Input: []string{"a", "b", "c"},
},
{
Case: "valid float slice",
Input: []float64{1.1, 2.2, 3.3},
},
{
Case: "interface with multiple types",
Input: []interface{}{
"a",
1,
true,
},
},
{
Case: "valid struct slice",
Input: []struct{ Name string }{{Name: "Alice"}, {Name: "Bob"}},
},
}

for _, tc := range cases {
result, err := random(tc.Input)
if tc.ShouldError {
assert.Error(t, err, tc.Case)
} else {
assert.NoError(t, err, tc.Case)
assert.Contains(t, fmt.Sprintf("%v", tc.Input), result, tc.Case)
}
}
}
1 change: 1 addition & 0 deletions website/docs/configuration/templates.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ use them.
| `{{ replaceP "c.t" "cut code cat" "dog" }}` | Exposes [regexp.ReplaceAllString][regexpra] as a string template function. |
| <code>\{\{ .Code &vert; hresult \}\}</code> | Transform a status code to its HRESULT value for easy troubleshooting. For example `-1978335212` becomes `0x8A150014`. |
| `{{ readFile ".version.json" }}` | Read a file in the current directory. Returns a string. |
| `{{ random (list \"a\" 2 .MyThirdItem) }}` | Selects a random element from a list. The list can be an array or slice containing any types (use sprig's `list`). |

<!-- markdownlint-enable MD013 -->

Expand Down

0 comments on commit 9cf42b5

Please sign in to comment.