From 74908b390a442388266325e87580b7c4cc9403a9 Mon Sep 17 00:00:00 2001 From: Konrad Niemiec Date: Tue, 24 Oct 2023 19:16:07 -0700 Subject: [PATCH] negative numbers --- pkg/star/static/walk.go | 22 +++++++++++++++-- pkg/star/static/walk_test.go | 48 ++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 2 deletions(-) diff --git a/pkg/star/static/walk.go b/pkg/star/static/walk.go index 1eb43ea2..62ea2b44 100644 --- a/pkg/star/static/walk.go +++ b/pkg/star/static/walk.go @@ -147,7 +147,7 @@ func (w *walker) extractValue(vPtr *build.Expr, f *featurev1beta1.StaticFeature) return nil, featurev1beta1.FeatureType_FEATURE_TYPE_UNSPECIFIED, errors.Wrapf(ErrUnsupportedStaticParsing, "unknown identifier %s", t.Name) } case *build.LiteralExpr: - if strings.Contains(t.Token, ".") { + if strings.Contains(t.Token, ".") || strings.Contains(t.Token, "e") || strings.Contains(t.Token, "E") { if f, err := strconv.ParseFloat(t.Token, 64); err == nil { return wrapperspb.Double(f), featurev1beta1.FeatureType_FEATURE_TYPE_FLOAT, nil } @@ -170,8 +170,26 @@ func (w *walker) extractValue(vPtr *build.Expr, f *featurev1beta1.StaticFeature) case *build.DotExpr: // could be a proto enum return w.extractProtoValue(t, f) + case *build.UnaryExpr: + if t.Op == "-" { + wrapper, featureType, err := w.extractValue(&t.X, f) + if err != nil { + return nil, featurev1beta1.FeatureType_FEATURE_TYPE_UNSPECIFIED, err + } + if featureType == featurev1beta1.FeatureType_FEATURE_TYPE_FLOAT { + wrapperD, _ := wrapper.(*wrapperspb.DoubleValue) + wrapperD.Value = -wrapperD.Value + return wrapperD, featureType, nil + } else if featureType == featurev1beta1.FeatureType_FEATURE_TYPE_INT { + wrapperI, _ := wrapper.(*wrapperspb.Int64Value) + wrapperI.Value = -wrapperI.Value + return wrapperI, featureType, nil + } else { + return nil, featurev1beta1.FeatureType_FEATURE_TYPE_UNSPECIFIED, errors.Wrapf(ErrUnsupportedStaticParsing, "unsupported negative on type %T", wrapper) + } + } } - return nil, featurev1beta1.FeatureType_FEATURE_TYPE_UNSPECIFIED, errors.Wrapf(ErrUnsupportedStaticParsing, "type %T", v) + return nil, featurev1beta1.FeatureType_FEATURE_TYPE_UNSPECIFIED, errors.Wrapf(ErrUnsupportedStaticParsing, "%v type %T", v, v) } func (w *walker) extractProtoValue(v build.Expr, f *featurev1beta1.StaticFeature) (proto.Message, featurev1beta1.FeatureType, error) { diff --git a/pkg/star/static/walk_test.go b/pkg/star/static/walk_test.go index 4f674244..d3f99d98 100644 --- a/pkg/star/static/walk_test.go +++ b/pkg/star/static/walk_test.go @@ -315,6 +315,54 @@ func TestWalkerMutateRemoveOnlyOverride(t *testing.T) { assert.NotContains(t, string(bytes), "age == 10") } +func TestWalkerNegativeNumber(t *testing.T) { + starBytes := []byte(` + export( + Config( + description = "this is a simple config", + default = -1, + rules = [ + ("age == 10", -2), + ], + ), + ) + `) + b := testWalker(t, starBytes) + f, err := b.Build() + require.NoError(t, err) + require.NotNil(t, f) + + f.FeatureOld.Tree.Constraints = nil + + bytes, err := b.Mutate(f) + require.NoError(t, err) + assert.NotContains(t, string(bytes), "age == 10") +} + +func TestWalkerNegativeFloat(t *testing.T) { + starBytes := []byte(` + export( + Config( + description = "this is a simple config", + default = -1e5, + rules = [ + ("age == 10", -2.0), + ], + ), + ) + `) + b := testWalker(t, starBytes) + f, err := b.Build() + require.NoError(t, err) + require.NotNil(t, f) + + f.FeatureOld.Tree.Constraints = nil + + bytes, err := b.Mutate(f) + require.NoError(t, err) + assert.NotContains(t, string(bytes), "age == 10") +} + func TestWalkerMutateDescription(t *testing.T) { for _, fType := range parsableFeatureTypes { t.Run(string(fType), func(t *testing.T) {