github.com/Jeffail/benthos/v3@v3.65.0/lib/processor/jmespath_test.go (about)

     1  package processor
     2  
     3  import (
     4  	"strconv"
     5  	"testing"
     6  
     7  	"github.com/Jeffail/benthos/v3/lib/log"
     8  	"github.com/Jeffail/benthos/v3/lib/message"
     9  	"github.com/Jeffail/benthos/v3/lib/metrics"
    10  	"github.com/Jeffail/gabs/v2"
    11  )
    12  
    13  func TestJMESPathAllParts(t *testing.T) {
    14  	conf := NewConfig()
    15  	conf.JMESPath.Parts = []int{}
    16  	conf.JMESPath.Query = "foo.bar"
    17  
    18  	testLog := log.Noop()
    19  
    20  	jSet, err := NewJMESPath(conf, nil, testLog, metrics.Noop())
    21  	if err != nil {
    22  		t.Fatal(err)
    23  	}
    24  
    25  	msgIn := message.New([][]byte{
    26  		[]byte(`{"foo":{"bar":0}}`),
    27  		[]byte(`{"foo":{"bar":1}}`),
    28  		[]byte(`{"foo":{"bar":2}}`),
    29  	})
    30  	msgs, res := jSet.ProcessMessage(msgIn)
    31  	if len(msgs) != 1 {
    32  		t.Fatal("Wrong count of messages")
    33  	}
    34  	if res != nil {
    35  		t.Fatal("Non-nil result")
    36  	}
    37  	for i, part := range message.GetAllBytes(msgs[0]) {
    38  		if exp, act := strconv.Itoa(i), string(part); exp != act {
    39  			t.Errorf("Wrong output from json: %v != %v", act, exp)
    40  		}
    41  	}
    42  }
    43  
    44  func TestJMESPathValidation(t *testing.T) {
    45  	conf := NewConfig()
    46  	conf.JMESPath.Parts = []int{0}
    47  	conf.JMESPath.Query = "foo.bar"
    48  
    49  	testLog := log.Noop()
    50  
    51  	jSet, err := NewJMESPath(conf, nil, testLog, metrics.Noop())
    52  	if err != nil {
    53  		t.Fatal(err)
    54  	}
    55  
    56  	msgIn := message.New([][]byte{[]byte("this is bad json")})
    57  	msgs, res := jSet.ProcessMessage(msgIn)
    58  	if len(msgs) != 1 {
    59  		t.Fatal("No passthrough for bad input data")
    60  	}
    61  	if res != nil {
    62  		t.Fatal("Non-nil result")
    63  	}
    64  	if exp, act := "this is bad json", string(message.GetAllBytes(msgs[0])[0]); exp != act {
    65  		t.Errorf("Wrong output from bad json: %v != %v", act, exp)
    66  	}
    67  
    68  	conf.JMESPath.Parts = []int{5}
    69  
    70  	jSet, err = NewJMESPath(conf, nil, testLog, metrics.Noop())
    71  	if err != nil {
    72  		t.Fatal(err)
    73  	}
    74  
    75  	msgIn = message.New([][]byte{[]byte("{}")})
    76  	msgs, res = jSet.ProcessMessage(msgIn)
    77  	if len(msgs) != 1 {
    78  		t.Fatal("No passthrough for bad index")
    79  	}
    80  	if res != nil {
    81  		t.Fatal("Non-nil result")
    82  	}
    83  	if exp, act := "{}", string(message.GetAllBytes(msgs[0])[0]); exp != act {
    84  		t.Errorf("Wrong output from bad index: %v != %v", act, exp)
    85  	}
    86  }
    87  
    88  func TestJMESPathMutation(t *testing.T) {
    89  	conf := NewConfig()
    90  	conf.JMESPath.Query = "{foo: merge(foo, {bar:'baz'})}"
    91  
    92  	jSet, err := NewJMESPath(conf, nil, log.Noop(), metrics.Noop())
    93  	if err != nil {
    94  		t.Fatal(err)
    95  	}
    96  
    97  	ogObj := gabs.New()
    98  	ogObj.Set("is this", "foo", "original", "content")
    99  	ogExp := ogObj.String()
   100  
   101  	msgIn := message.New(make([][]byte, 1))
   102  	msgIn.Get(0).SetJSON(ogObj.Data())
   103  	msgs, res := jSet.ProcessMessage(msgIn)
   104  	if len(msgs) != 1 {
   105  		t.Fatal("No passthrough for bad input data")
   106  	}
   107  	if res != nil {
   108  		t.Fatal("Non-nil result")
   109  	}
   110  	if exp, act := `{"foo":{"bar":"baz","original":{"content":"is this"}}}`, string(message.GetAllBytes(msgs[0])[0]); exp != act {
   111  		t.Errorf("Wrong output: %v != %v", act, exp)
   112  	}
   113  
   114  	if exp, act := ogExp, ogObj.String(); exp != act {
   115  		t.Errorf("Original contents were mutated: %v != %v", act, exp)
   116  	}
   117  }
   118  
   119  func TestJMESPath(t *testing.T) {
   120  	tLog := log.Noop()
   121  	tStats := metrics.Noop()
   122  
   123  	type jTest struct {
   124  		name   string
   125  		path   string
   126  		input  string
   127  		output string
   128  	}
   129  
   130  	tests := []jTest{
   131  		{
   132  			name:   "select obj",
   133  			path:   "foo.bar",
   134  			input:  `{"foo":{"bar":{"baz":1}}}`,
   135  			output: `{"baz":1}`,
   136  		},
   137  		{
   138  			name:   "select array",
   139  			path:   "foo.bar",
   140  			input:  `{"foo":{"bar":["baz","qux"]}}`,
   141  			output: `["baz","qux"]`,
   142  		},
   143  		{
   144  			name:   "select obj as str",
   145  			path:   "foo.bar",
   146  			input:  `{"foo":{"bar":"{\"baz\":1}"}}`,
   147  			output: `"{\"baz\":1}"`,
   148  		},
   149  		{
   150  			name:   "select str",
   151  			path:   "foo.bar",
   152  			input:  `{"foo":{"bar":"hello world"}}`,
   153  			output: `"hello world"`,
   154  		},
   155  		{
   156  			name:   "select float",
   157  			path:   "foo.bar",
   158  			input:  `{"foo":{"bar":0.123}}`,
   159  			output: `0.123`,
   160  		},
   161  		{
   162  			name:   "select int",
   163  			path:   "foo.bar",
   164  			input:  `{"foo":{"bar":123}}`,
   165  			output: `123`,
   166  		},
   167  		{
   168  			name:   "select bool",
   169  			path:   "foo.bar",
   170  			input:  `{"foo":{"bar":true}}`,
   171  			output: `true`,
   172  		},
   173  		{
   174  			name:   "addition int",
   175  			path:   "sum([foo.bar, `6`])",
   176  			input:  `{"foo":{"bar":123}}`,
   177  			output: `129`,
   178  		},
   179  	}
   180  
   181  	for _, test := range tests {
   182  		conf := NewConfig()
   183  		conf.JMESPath.Parts = []int{0}
   184  		conf.JMESPath.Query = test.path
   185  
   186  		jSet, err := NewJMESPath(conf, nil, tLog, tStats)
   187  		if err != nil {
   188  			t.Fatalf("Error for test '%v': %v", test.name, err)
   189  		}
   190  
   191  		inMsg := message.New(
   192  			[][]byte{
   193  				[]byte(test.input),
   194  			},
   195  		)
   196  		msgs, _ := jSet.ProcessMessage(inMsg)
   197  		if len(msgs) != 1 {
   198  			t.Fatalf("Test '%v' did not succeed", test.name)
   199  		}
   200  
   201  		if exp, act := test.output, string(message.GetAllBytes(msgs[0])[0]); exp != act {
   202  			t.Errorf("Wrong result '%v': %v != %v", test.name, act, exp)
   203  		}
   204  	}
   205  }