yq/pkg/yqlib/operator_modulo_test.go

121 lines
3.0 KiB
Go

package yqlib
import (
"testing"
)
var moduloOperatorScenarios = []expressionScenario{
{
skipDoc: true,
document: `[{a: 2.5, b: 2}, {a: 2, b: 0.75}]`,
expression: ".[] | .a % .b",
expected: []string{
"D0, P[0 a], (!!float)::0.5\n",
"D0, P[1 a], (!!float)::0.5\n",
},
},
{
skipDoc: true,
document: `{}`,
expression: "(.a / .b) as $x | .",
expected: []string{
"D0, P[], (doc)::{}\n",
},
},
{
description: "Number modulo - int",
subdescription: "If the lhs and rhs are ints then the expression will be calculated with ints.",
document: `{a: 13, b: 2}`,
expression: `.a = .a % .b`,
expected: []string{
"D0, P[], (doc)::{a: 1, b: 2}\n",
},
},
{
description: "Number modulo - float",
subdescription: "If the lhs or rhs are floats then the expression will be calculated with floats.",
document: `{a: 12, b: 2.5}`,
expression: `.a = .a % .b`,
expected: []string{
"D0, P[], (doc)::{a: !!float 2, b: 2.5}\n",
},
},
{
description: "Number modulo - int by zero",
subdescription: "If the lhs is an int and rhs is a 0 the result is an error.",
document: `{a: 1, b: 0}`,
expression: `.a = .a % .b`,
expectedError: "cannot modulo by 0",
},
{
description: "Number modulo - float by zero",
subdescription: "If the lhs is a float and rhs is a 0 the result is NaN.",
document: `{a: 1.1, b: 0}`,
expression: `.a = .a % .b`,
expected: []string{
"D0, P[], (doc)::{a: !!float NaN, b: 0}\n",
},
},
{
skipDoc: true,
description: "Custom types: that are really numbers",
document: "a: !horse 333.975\nb: !goat 299.2",
expression: `.a = .a % .b`,
expected: []string{
"D0, P[], (doc)::a: !horse 34.775000000000034\nb: !goat 299.2\n",
},
},
{
skipDoc: true,
document: "a: 2\nb: !goat 2.3",
expression: `.a = .a % .b`,
expected: []string{
"D0, P[], (doc)::a: !!float 2\nb: !goat 2.3\n",
},
},
{
skipDoc: true,
description: "Keep anchors",
document: "a: &horse [1]",
expression: `.a[1] = .a[0] % 2`,
expected: []string{
"D0, P[], (doc)::a: &horse [1, 1]\n",
},
},
{
skipDoc: true,
description: "Modulo int by string",
document: "a: 123\nb: '2'",
expression: `.a % .b`,
expectedError: "!!int cannot modulo by !!str",
},
{
skipDoc: true,
description: "Modulo string by int",
document: "a: 2\nb: '123'",
expression: `.b % .a`,
expectedError: "!!str cannot modulo by !!int",
},
{
skipDoc: true,
description: "Modulo map by int",
document: "a: {\"a\":1}\nb: 2",
expression: `.a % .b`,
expectedError: "!!map (a) cannot modulo by !!int (b)",
},
{
skipDoc: true,
description: "Modulo array by str",
document: "a: [1,2]\nb: '2'",
expression: `.a % .b`,
expectedError: "!!seq (a) cannot modulo by !!str (b)",
},
}
func TestModuloOperatorScenarios(t *testing.T) {
for _, tt := range moduloOperatorScenarios {
testScenario(t, &tt)
}
documentOperatorScenarios(t, "modulo", moduloOperatorScenarios)
}