yq/pkg/yqlib/operator_first_test.go
2025-10-12 14:32:28 +11:00

187 lines
4.9 KiB
Go

package yqlib
import "testing"
var firstOperatorScenarios = []expressionScenario{
{
description: "First matching element from array",
document: "[{a: banana},{a: cat},{a: apple}]",
expression: `first(.a == "cat")`,
expected: []string{
"D0, P[1], (!!map)::{a: cat}\n",
},
},
{
description: "First matching element from array with multiple matches",
document: "[{a: banana},{a: cat, b: firstCat},{a: apple},{a: cat, b: secondCat}]",
expression: `first(.a == "cat")`,
expected: []string{
"D0, P[1], (!!map)::{a: cat, b: firstCat}\n",
},
},
{
description: "First matching element from array with numeric condition",
document: "[{a: 10},{a: 100},{a: 1},{a: 101}]",
expression: `first(.a > 50)`,
expected: []string{
"D0, P[1], (!!map)::{a: 100}\n",
},
},
{
description: "First matching element from array with boolean condition",
document: "[{a: false},{a: true, b: firstTrue},{a: false}, {a: true, b: secondTrue}]",
expression: `first(.a == true)`,
expected: []string{
"D0, P[1], (!!map)::{a: true, b: firstTrue}\n",
},
},
{
description: "First matching element from array with null values",
document: "[{a: null},{a: cat},{a: apple}]",
expression: `first(.a != null)`,
expected: []string{
"D0, P[1], (!!map)::{a: cat}\n",
},
},
{
description: "First matching element from array with complex condition",
document: "[{a: dog, b: 7},{a: cat, b: 3},{a: apple, b: 5}]",
expression: `first(.b > 4 and .b < 6)`,
expected: []string{
"D0, P[2], (!!map)::{a: apple, b: 5}\n",
},
},
{
description: "First matching element from map",
document: "x: {a: banana}\ny: {a: cat}\nz: {a: apple}",
expression: `first(.a == "cat")`,
expected: []string{
"D0, P[y], (!!map)::{a: cat}\n",
},
},
{
description: "First matching element from map with numeric condition",
document: "x: {a: 10}\ny: {a: 100}\nz: {a: 101}",
expression: `first(.a > 50)`,
expected: []string{
"D0, P[y], (!!map)::{a: 100}\n",
},
},
{
description: "First matching element from nested structure",
document: "items: [{a: banana},{a: cat},{a: apple}]",
expression: `.items | first(.a == "cat")`,
expected: []string{
"D0, P[items 1], (!!map)::{a: cat}\n",
},
},
{
description: "First matching element with no matches",
document: "[{a: banana},{a: cat},{a: apple}]",
expression: `first(.a == "dog")`,
expected: []string{
// No output expected when no matches
},
},
{
description: "First matching element from empty array",
document: "[]",
expression: `first(.a == "cat")`,
expected: []string{
// No output expected when array is empty
},
},
{
description: "First matching element from scalar node",
document: "hello",
expression: `first(. == "hello")`,
expected: []string{
// No output expected when node is scalar (no content to splat)
},
},
{
description: "First matching element from null node",
document: "null",
expression: `first(. == "hello")`,
expected: []string{
// No output expected when node is null (no content to splat)
},
},
{
description: "First matching element with string condition",
document: "[{a: banana},{a: cat},{a: apple}]",
expression: `first(.a | test("^c"))`,
expected: []string{
"D0, P[1], (!!map)::{a: cat}\n",
},
},
{
description: "First matching element with length condition",
document: "[{a: hi},{a: hello},{a: world}]",
expression: `first(.a | length > 4)`,
expected: []string{
"D0, P[1], (!!map)::{a: hello}\n",
},
},
{
description: "First matching element from array of strings",
document: "[banana, cat, apple]",
expression: `first(. == "cat")`,
expected: []string{
"D0, P[1], (!!str)::cat\n",
},
},
{
description: "First matching element from array of numbers",
document: "[10, 100, 1]",
expression: `first(. > 50)`,
expected: []string{
"D0, P[1], (!!int)::100\n",
},
},
{
description: "First element with no filter from array",
document: "[10, 100, 1]",
expression: `first`,
expected: []string{
"D0, P[0], (!!int)::10\n",
},
},
{
description: "First element with no filter from array of maps",
document: "[{a: 10},{a: 100}]",
expression: `first`,
expected: []string{
"D0, P[0], (!!map)::{a: 10}\n",
},
},
{
description: "No filter on empty array returns nothing",
skipDoc: true,
document: "[]",
expression: `first`,
expected: []string{},
},
{
description: "No filter on scalar returns nothing",
skipDoc: true,
document: "hello",
expression: `first`,
expected: []string{},
},
{
description: "No filter on null returns nothing",
skipDoc: true,
document: "null",
expression: `first`,
expected: []string{},
},
}
func TestFirstOperatorScenarios(t *testing.T) {
for _, tt := range firstOperatorScenarios {
testScenario(t, &tt)
}
documentOperatorScenarios(t, "first", firstOperatorScenarios)
}