From c0fd3fe38b756eef3745db4019fce23a119bd6dc Mon Sep 17 00:00:00 2001 From: TJ Miller Date: Thu, 9 Mar 2023 15:59:12 -0800 Subject: [PATCH] Handle int modulo by 0 and add tests --- pkg/yqlib/doc/operators/modulo.md | 35 +++++++++++++++++++++++++++++++ pkg/yqlib/operator_modulo.go | 3 +++ pkg/yqlib/operator_modulo_test.go | 16 ++++++++++++++ 3 files changed, 54 insertions(+) diff --git a/pkg/yqlib/doc/operators/modulo.md b/pkg/yqlib/doc/operators/modulo.md index b26a39b2..b7ecd7e0 100644 --- a/pkg/yqlib/doc/operators/modulo.md +++ b/pkg/yqlib/doc/operators/modulo.md @@ -35,3 +35,38 @@ a: !!float 2 b: 2.5 ``` +## Number modulo - int by zero +If the lhs is an int and rhs is a 0 the result is an error. + +Given a sample.yml file of: +```yaml +a: 1 +b: 0 +``` +then +```bash +yq '.a = .a % .b' sample.yml +``` +will output +```bash +Error: cannot modulo by 0 +``` + +## Number modulo - float by zero +If the lhs is a float and rhs is a 0 the result is NaN. + +Given a sample.yml file of: +```yaml +a: 1.1 +b: 0 +``` +then +```bash +yq '.a = .a % .b' sample.yml +``` +will output +```yaml +a: !!float NaN +b: 0 +``` + diff --git a/pkg/yqlib/operator_modulo.go b/pkg/yqlib/operator_modulo.go index 116f614b..cc4e6860 100644 --- a/pkg/yqlib/operator_modulo.go +++ b/pkg/yqlib/operator_modulo.go @@ -68,6 +68,9 @@ func moduloScalars(context Context, target *CandidateNode, lhs *yaml.Node, rhs * if err != nil { return err } + if rhsNum == 0 { + return fmt.Errorf("cannot modulo by 0") + } remainder := lhsNum % rhsNum target.Node.Tag = lhs.Tag diff --git a/pkg/yqlib/operator_modulo_test.go b/pkg/yqlib/operator_modulo_test.go index ae94ed91..ee1c9101 100644 --- a/pkg/yqlib/operator_modulo_test.go +++ b/pkg/yqlib/operator_modulo_test.go @@ -40,6 +40,22 @@ var moduloOperatorScenarios = []expressionScenario{ "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",