feat: implement case function (#16)

Follow GitHub Actions

* added unit tests

Closes #15

Reviewed-on: https://gitea.com/actions-oss/act-cli/pulls/16
Co-authored-by: ChristopherHX <christopher.homberger@web.de>
Co-committed-by: ChristopherHX <christopher.homberger@web.de>
This commit is contained in:
ChristopherHX
2025-12-18 19:27:30 +00:00
committed by ChristopherHX
parent 83cbf1f2b8
commit ee2e0135d5
6 changed files with 164 additions and 14 deletions

View File

@@ -97,6 +97,12 @@ func TestEvaluator_Raw(t *testing.T) {
{"contains(fromjson('[[3,5],[5,6]]').*[1], 6)", true},
{"contains(fromjson('[[3,5],[5,6]]').*[1], 3)", false},
{"contains(fromjson('[[3,5],[5,6]]').*[1], '6')", true},
{"case(6 == 6, 0, 1)", 0.0},
{"case(6 != 6, 0, 1)", 1.0},
{"case(6 != 6, 0, 'test')", "test"},
{"case(contains(fromjson('[\"ac\"]'), 'a'), 0, 'test')", "test"},
{"case(0 == 1, 0, 2 == 2, 1, 0)", 1.0},
{"case(0 == 1, 0, 2 != 2, 1, 0)", 0.0},
}
for _, tt := range tests {

View File

@@ -2,6 +2,7 @@ package v2
import (
"encoding/json"
"errors"
"strings"
"github.com/actions-oss/act-cli/internal/eval/functions"
@@ -163,6 +164,30 @@ func (Join) Evaluate(eval *Evaluator, args []exprparser.Node) (*EvaluationResult
return CreateIntermediateResult(eval.Context(), ""), nil
}
type Case struct {
}
func (Case) Evaluate(eval *Evaluator, args []exprparser.Node) (*EvaluationResult, error) {
if len(args)%2 == 0 {
return nil, errors.New("case function requires an odd number of arguments")
}
for i := 0; i < len(args)-1; i += 2 {
condition, err := eval.Evaluate(args[i])
if err != nil {
return nil, err
}
if condition.kind != ValueKindBoolean {
return nil, errors.New("case function conditions must evaluate to boolean")
}
if condition.IsTruthy() {
return eval.Evaluate(args[i+1])
}
}
return eval.Evaluate(args[len(args)-1])
}
func GetFunctions() CaseInsensitiveObject[Function] {
return CaseInsensitiveObject[Function](map[string]Function{
"fromjson": &FromJSON{},
@@ -172,5 +197,6 @@ func GetFunctions() CaseInsensitiveObject[Function] {
"endswith": &EndsWith{},
"format": &Format{},
"join": &Join{},
"case": &Case{},
})
}

View File

@@ -64,7 +64,7 @@ func (ee ExpressionEvaluator) canEvaluate(parsed exprparser.Node, snode *schema.
canEvaluate = canEvaluate && ee.EvaluationContext.Variables.Get(v) != nil
}
for _, v := range snode.GetFunctions() {
canEvaluate = canEvaluate && ee.EvaluationContext.Functions.Get(v.Name) != nil
canEvaluate = canEvaluate && ee.EvaluationContext.Functions.Get(v.GetName()) != nil
}
exprparser.VisitNode(parsed, func(node exprparser.Node) {
switch el := node.(type) {