...

Source file src/github.com/jmespath/go-jmespath/interpreter_test.go

Documentation: github.com/jmespath/go-jmespath

     1  package jmespath
     2  
     3  import (
     4  	"encoding/json"
     5  	"testing"
     6  
     7  	"github.com/jmespath/go-jmespath/internal/testify/assert"
     8  )
     9  
    10  type scalars struct {
    11  	Foo string
    12  	Bar string
    13  }
    14  
    15  type sliceType struct {
    16  	A string
    17  	B []scalars
    18  	C []*scalars
    19  }
    20  
    21  type benchmarkStruct struct {
    22  	Fooasdfasdfasdfasdf string
    23  }
    24  
    25  type benchmarkNested struct {
    26  	Fooasdfasdfasdfasdf nestedA
    27  }
    28  
    29  type nestedA struct {
    30  	Fooasdfasdfasdfasdf nestedB
    31  }
    32  
    33  type nestedB struct {
    34  	Fooasdfasdfasdfasdf nestedC
    35  }
    36  
    37  type nestedC struct {
    38  	Fooasdfasdfasdfasdf string
    39  }
    40  
    41  type nestedSlice struct {
    42  	A []sliceType
    43  }
    44  
    45  func TestCanSupportEmptyInterface(t *testing.T) {
    46  	assert := assert.New(t)
    47  	data := make(map[string]interface{})
    48  	data["foo"] = "bar"
    49  	result, err := Search("foo", data)
    50  	assert.Nil(err)
    51  	assert.Equal("bar", result)
    52  }
    53  
    54  func TestCanSupportUserDefinedStructsValue(t *testing.T) {
    55  	assert := assert.New(t)
    56  	s := scalars{Foo: "one", Bar: "bar"}
    57  	result, err := Search("Foo", s)
    58  	assert.Nil(err)
    59  	assert.Equal("one", result)
    60  }
    61  
    62  func TestCanSupportUserDefinedStructsRef(t *testing.T) {
    63  	assert := assert.New(t)
    64  	s := scalars{Foo: "one", Bar: "bar"}
    65  	result, err := Search("Foo", &s)
    66  	assert.Nil(err)
    67  	assert.Equal("one", result)
    68  }
    69  
    70  func TestCanSupportStructWithSliceAll(t *testing.T) {
    71  	assert := assert.New(t)
    72  	data := sliceType{A: "foo", B: []scalars{{"f1", "b1"}, {"correct", "b2"}}}
    73  	result, err := Search("B[].Foo", data)
    74  	assert.Nil(err)
    75  	assert.Equal([]interface{}{"f1", "correct"}, result)
    76  }
    77  
    78  func TestCanSupportStructWithSlicingExpression(t *testing.T) {
    79  	assert := assert.New(t)
    80  	data := sliceType{A: "foo", B: []scalars{{"f1", "b1"}, {"correct", "b2"}}}
    81  	result, err := Search("B[:].Foo", data)
    82  	assert.Nil(err)
    83  	assert.Equal([]interface{}{"f1", "correct"}, result)
    84  }
    85  
    86  func TestCanSupportStructWithFilterProjection(t *testing.T) {
    87  	assert := assert.New(t)
    88  	data := sliceType{A: "foo", B: []scalars{{"f1", "b1"}, {"correct", "b2"}}}
    89  	result, err := Search("B[? `true` ].Foo", data)
    90  	assert.Nil(err)
    91  	assert.Equal([]interface{}{"f1", "correct"}, result)
    92  }
    93  
    94  func TestCanSupportStructWithSlice(t *testing.T) {
    95  	assert := assert.New(t)
    96  	data := sliceType{A: "foo", B: []scalars{{"f1", "b1"}, {"correct", "b2"}}}
    97  	result, err := Search("B[-1].Foo", data)
    98  	assert.Nil(err)
    99  	assert.Equal("correct", result)
   100  }
   101  
   102  func TestCanSupportStructWithOrExpressions(t *testing.T) {
   103  	assert := assert.New(t)
   104  	data := sliceType{A: "foo", C: nil}
   105  	result, err := Search("C || A", data)
   106  	assert.Nil(err)
   107  	assert.Equal("foo", result)
   108  }
   109  
   110  func TestCanSupportStructWithSlicePointer(t *testing.T) {
   111  	assert := assert.New(t)
   112  	data := sliceType{A: "foo", C: []*scalars{{"f1", "b1"}, {"correct", "b2"}}}
   113  	result, err := Search("C[-1].Foo", data)
   114  	assert.Nil(err)
   115  	assert.Equal("correct", result)
   116  }
   117  
   118  func TestWillAutomaticallyCapitalizeFieldNames(t *testing.T) {
   119  	assert := assert.New(t)
   120  	s := scalars{Foo: "one", Bar: "bar"}
   121  	// Note that there's a lower cased "foo" instead of "Foo",
   122  	// but it should still correspond to the Foo field in the
   123  	// scalars struct
   124  	result, err := Search("foo", &s)
   125  	assert.Nil(err)
   126  	assert.Equal("one", result)
   127  }
   128  
   129  func TestCanSupportStructWithSliceLowerCased(t *testing.T) {
   130  	assert := assert.New(t)
   131  	data := sliceType{A: "foo", B: []scalars{{"f1", "b1"}, {"correct", "b2"}}}
   132  	result, err := Search("b[-1].foo", data)
   133  	assert.Nil(err)
   134  	assert.Equal("correct", result)
   135  }
   136  
   137  func TestCanSupportStructWithNestedPointers(t *testing.T) {
   138  	assert := assert.New(t)
   139  	data := struct{ A *struct{ B int } }{}
   140  	result, err := Search("A.B", data)
   141  	assert.Nil(err)
   142  	assert.Nil(result)
   143  }
   144  
   145  func TestCanSupportFlattenNestedSlice(t *testing.T) {
   146  	assert := assert.New(t)
   147  	data := nestedSlice{A: []sliceType{
   148  		{B: []scalars{{Foo: "f1a"}, {Foo: "f1b"}}},
   149  		{B: []scalars{{Foo: "f2a"}, {Foo: "f2b"}}},
   150  	}}
   151  	result, err := Search("A[].B[].Foo", data)
   152  	assert.Nil(err)
   153  	assert.Equal([]interface{}{"f1a", "f1b", "f2a", "f2b"}, result)
   154  }
   155  
   156  func TestCanSupportFlattenNestedEmptySlice(t *testing.T) {
   157  	assert := assert.New(t)
   158  	data := nestedSlice{A: []sliceType{
   159  		{}, {B: []scalars{{Foo: "a"}}},
   160  	}}
   161  	result, err := Search("A[].B[].Foo", data)
   162  	assert.Nil(err)
   163  	assert.Equal([]interface{}{"a"}, result)
   164  }
   165  
   166  func TestCanSupportProjectionsWithStructs(t *testing.T) {
   167  	assert := assert.New(t)
   168  	data := nestedSlice{A: []sliceType{
   169  		{A: "first"}, {A: "second"}, {A: "third"},
   170  	}}
   171  	result, err := Search("A[*].A", data)
   172  	assert.Nil(err)
   173  	assert.Equal([]interface{}{"first", "second", "third"}, result)
   174  }
   175  
   176  func TestCanSupportSliceOfStructsWithFunctions(t *testing.T) {
   177  	assert := assert.New(t)
   178  	data := []scalars{scalars{"a1", "b1"}, scalars{"a2", "b2"}}
   179  	result, err := Search("length(@)", data)
   180  	assert.Nil(err)
   181  	assert.Equal(result.(float64), 2.0)
   182  }
   183  
   184  func BenchmarkInterpretSingleFieldStruct(b *testing.B) {
   185  	assert := assert.New(b)
   186  	intr := newInterpreter()
   187  	parser := NewParser()
   188  	ast, _ := parser.Parse("fooasdfasdfasdfasdf")
   189  	data := benchmarkStruct{"foobarbazqux"}
   190  	for i := 0; i < b.N; i++ {
   191  		_, err := intr.Execute(ast, data)
   192  		if err != nil {
   193  			assert.Fail("Received error from interpreter")
   194  		}
   195  	}
   196  }
   197  
   198  func BenchmarkInterpretNestedStruct(b *testing.B) {
   199  	assert := assert.New(b)
   200  	intr := newInterpreter()
   201  	parser := NewParser()
   202  	ast, _ := parser.Parse("fooasdfasdfasdfasdf.fooasdfasdfasdfasdf.fooasdfasdfasdfasdf.fooasdfasdfasdfasdf")
   203  	data := benchmarkNested{
   204  		nestedA{
   205  			nestedB{
   206  				nestedC{"foobarbazqux"},
   207  			},
   208  		},
   209  	}
   210  	for i := 0; i < b.N; i++ {
   211  		_, err := intr.Execute(ast, data)
   212  		if err != nil {
   213  			assert.Fail("Received error from interpreter")
   214  		}
   215  	}
   216  }
   217  
   218  func BenchmarkInterpretNestedMaps(b *testing.B) {
   219  	assert := assert.New(b)
   220  	jsonData := []byte(`{"fooasdfasdfasdfasdf": {"fooasdfasdfasdfasdf": {"fooasdfasdfasdfasdf": {"fooasdfasdfasdfasdf": "foobarbazqux"}}}}`)
   221  	var data interface{}
   222  	err := json.Unmarshal(jsonData, &data)
   223  	assert.Nil(err)
   224  
   225  	intr := newInterpreter()
   226  	parser := NewParser()
   227  	ast, _ := parser.Parse("fooasdfasdfasdfasdf.fooasdfasdfasdfasdf.fooasdfasdfasdfasdf.fooasdfasdfasdfasdf")
   228  	for i := 0; i < b.N; i++ {
   229  		_, err := intr.Execute(ast, data)
   230  		if err != nil {
   231  			assert.Fail("Received error from interpreter")
   232  		}
   233  	}
   234  }
   235  

View as plain text