Skip to content

Commit

Permalink
cmd: adds a discard subcommand for format to discard the result Fixes:
Browse files Browse the repository at this point in the history
…#5863

Signed-off-by: 26tanishabanik <26tanishabanik@gmail.com>
  • Loading branch information
26tanishabanik authored and ashutosh-narkar committed Jul 19, 2023
1 parent 8fa5b02 commit 67159a6
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 0 deletions.
5 changes: 5 additions & 0 deletions cmd/eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ func newEvalCommandParams() evalCommandParams {
evalPrettyOutput,
evalSourceOutput,
evalRawOutput,
evalDiscardOutput,
}),
explain: newExplainFlag([]string{explainModeOff, explainModeFull, explainModeNotes, explainModeFails, explainModeDebug}),
target: util.NewEnumFlag(compile.TargetRego, []string{compile.TargetRego, compile.TargetWasm}),
Expand Down Expand Up @@ -142,6 +143,7 @@ const (
evalPrettyOutput = "pretty"
evalSourceOutput = "source"
evalRawOutput = "raw"
evalDiscardOutput = "discard"

// number of profile results to return by default
defaultProfileLimit = 10
Expand Down Expand Up @@ -232,6 +234,7 @@ Set the output format with the --format flag.
--format=pretty : output query results in a human-readable format
--format=source : output partial evaluation results in a source format
--format=raw : output the values from query results in a scripting friendly format
--format=discard : output the result field as "discarded" when non-nil
Schema
------
Expand Down Expand Up @@ -394,6 +397,8 @@ func eval(args []string, params evalCommandParams, w io.Writer) (bool, error) {
err = pr.Source(w, result)
case evalRawOutput:
err = pr.Raw(w, result)
case evalDiscardOutput:
err = pr.Discard(w, result)
default:
err = pr.JSON(w, result)
}
Expand Down
110 changes: 110 additions & 0 deletions cmd/eval_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1312,6 +1312,116 @@ time.clock(input.y, time.clock(input.x))
}
}

func TestEvalDiscardOutput(t *testing.T) {
tests := map[string]struct {
query, format, expected string
params evalCommandParams
}{
"success example": {
query: "1*2+3",
params: func() evalCommandParams {
params := newEvalCommandParams()
err := params.outputFormat.Set(evalDiscardOutput)
if err != nil {
t.Fatalf("unexpected error: %s", err)
}
return params
}(),
expected: `{
"result": "discarded"
}
`},
"error example": {
query: "1/0",
params: func() evalCommandParams {
params := newEvalCommandParams()
err := params.outputFormat.Set(evalDiscardOutput)
if err != nil {
t.Fatalf("unexpected error: %s", err)
}
return params
}(),
expected: `{}
`},
"error example show built-in-errors": {
query: "1/0",
params: func() evalCommandParams {
params := newEvalCommandParams()
err := params.outputFormat.Set(evalDiscardOutput)
if err != nil {
t.Fatalf("unexpected error: %s", err)
}
params.showBuiltinErrors = true
return params
}(),
expected: `{
"errors": [
{
"code": "eval_builtin_error",
"location": {
"col": 1,
"file": "",
"row": 1
},
"message": "div: divide by zero"
}
]
}
`},
}

for name, tc := range tests {
t.Run(name, func(t *testing.T) {
var buf bytes.Buffer
_, err := eval([]string{tc.query}, tc.params, &buf)
if err != nil {
t.Fatalf("unexpected error: %s", err)
}
if actual := buf.String(); actual != tc.expected {
t.Errorf("expected output %q\ngot %q", tc.expected, actual)
}
})
}
}

func TestEvalDiscardProfilerOutput(t *testing.T) {
params := newEvalCommandParams()
err := params.outputFormat.Set(evalDiscardOutput)
if err != nil {
t.Fatalf("unexpected error: %s", err)
}
params.profile = true

query := "1*2+3"

var buf bytes.Buffer
_, err = eval([]string{query}, params, &buf)
if err != nil {
t.Fatalf("unexpected error: %s", err)
}

var output map[string]interface{}
if err := util.NewJSONDecoder(&buf).Decode(&output); err != nil {
t.Fatal(err)
}

// assert that the result is set to discarded
result, ok := output["result"].(string)
if !ok {
t.Fatal("error extracting result as string from output")
}

if result != "discarded" {
t.Fatal("Expected result field to be set to 'discarded'")
}

// assert that profile is still set
_, ok = output["profile"]
if !ok {
t.Fatal("error in parsing profile output")
}
}

func TestPolicyWithStrictFlag(t *testing.T) {
testsShouldError := []struct {
note string
Expand Down
22 changes: 22 additions & 0 deletions internal/presentation/presentation.go
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,28 @@ func Raw(w io.Writer, r Output) error {
return nil
}

func Discard(w io.Writer, x interface{}) error {
encoder := json.NewEncoder(w)
encoder.SetIndent("", " ")
field, ok := x.(Output)
if !ok {
return fmt.Errorf("error in converting interface to type Output")
}
bs, err := json.Marshal(field)
if err != nil {
return err
}
var rawData map[string]interface{}
err = json.Unmarshal(bs, &rawData)
if err != nil {
return err
}
if rawData["result"] != nil {
rawData["result"] = "discarded"
}
return encoder.Encode(rawData)
}

func prettyError(w io.Writer, errs OutputErrors) error {
_, err := fmt.Fprintln(w, errs)
return err
Expand Down

0 comments on commit 67159a6

Please sign in to comment.