github.com/tomwright/dasel@v1.27.3/node_query_multiple_internal_test.go (about)

     1  package dasel
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  	"testing"
     7  )
     8  
     9  func assertQueryMultipleResult(t *testing.T, exp []reflect.Value, expErr error, got []*Node, gotErr error) bool {
    10  	if !assertErrResult(t, expErr, gotErr) {
    11  		return false
    12  	}
    13  	gotVals := make([]interface{}, len(got))
    14  	if len(got) > 0 {
    15  		for i, n := range got {
    16  			if !n.Value.IsValid() {
    17  				gotVals[i] = nil
    18  				continue
    19  			}
    20  			gotVals[i] = n.Value.Interface()
    21  		}
    22  	}
    23  	expVals := make([]interface{}, len(exp))
    24  	if len(exp) > 0 {
    25  		for i, n := range exp {
    26  			if !n.IsValid() {
    27  				expVals[i] = nil
    28  				continue
    29  			}
    30  			expVals[i] = n.Interface()
    31  		}
    32  	}
    33  	if !reflect.DeepEqual(expVals, gotVals) {
    34  		t.Errorf("expected result %v, got %v", expVals, gotVals)
    35  		return false
    36  	}
    37  	return true
    38  }
    39  
    40  func assertQueryMultipleResultOneOf(t *testing.T, exp [][]reflect.Value, expErr error, got []*Node, gotErr error) bool {
    41  	if !assertErrResult(t, expErr, gotErr) {
    42  		return false
    43  	}
    44  	gotVals := make([]interface{}, len(got))
    45  	if len(got) > 0 {
    46  		for i, n := range got {
    47  			if !n.Value.IsValid() {
    48  				gotVals[i] = nil
    49  				continue
    50  			}
    51  			gotVals[i] = n.Value.Interface()
    52  		}
    53  	}
    54  
    55  	for _, exp := range exp {
    56  		expVals := make([]interface{}, len(exp))
    57  		if len(exp) > 0 {
    58  			for i, n := range exp {
    59  				if !n.IsValid() {
    60  					expVals[i] = nil
    61  					continue
    62  				}
    63  				expVals[i] = n.Interface()
    64  			}
    65  		}
    66  
    67  		if reflect.DeepEqual(expVals, gotVals) {
    68  			return true
    69  		}
    70  	}
    71  
    72  	t.Errorf("unexpected result: %v", gotVals)
    73  	return false
    74  }
    75  
    76  func TestFindNodesProperty(t *testing.T) {
    77  	t.Run("NilValue", func(t *testing.T) {
    78  		selector := Selector{Current: ".", Raw: "."}
    79  		got, err := findNodesProperty(selector, nilValue(), false)
    80  		assertQueryMultipleResult(t, []reflect.Value{}, &UnexpectedPreviousNilValue{Selector: "."}, got, err)
    81  	})
    82  	t.Run("NotFound", func(t *testing.T) {
    83  		previousValue := reflect.ValueOf(map[string]interface{}{})
    84  		selector := Selector{Current: "x"}
    85  		got, err := findNodesProperty(selector, previousValue, false)
    86  		assertQueryMultipleResult(t, []reflect.Value{}, &ValueNotFound{Selector: selector.Current, PreviousValue: previousValue}, got, err)
    87  	})
    88  	t.Run("UnsupportedType", func(t *testing.T) {
    89  		previousValue := reflect.ValueOf(0)
    90  		selector := Selector{Current: "x"}
    91  		got, err := findNodesProperty(selector, previousValue, false)
    92  		assertQueryMultipleResult(t, []reflect.Value{}, &UnsupportedTypeForSelector{Selector: selector, Value: previousValue}, got, err)
    93  	})
    94  }
    95  
    96  func TestFindNodesLength(t *testing.T) {
    97  	t.Run("NilValue", func(t *testing.T) {
    98  		selector := Selector{Current: ".[#]", Raw: ".[#]"}
    99  		got, err := findNodesLength(selector, nilValue())
   100  		assertQueryMultipleResult(t, []reflect.Value{}, &UnexpectedPreviousNilValue{Selector: ".[#]"}, got, err)
   101  	})
   102  	t.Run("UnsupportedTypeInt", func(t *testing.T) {
   103  		selector := Selector{Current: ".[#]", Raw: ".[#]"}
   104  		val := 0
   105  		got, err := findNodesLength(selector, reflect.ValueOf(val))
   106  		assertQueryMultipleResult(t, []reflect.Value{}, &UnsupportedTypeForSelector{Selector: selector, Value: reflect.ValueOf(val)}, got, err)
   107  	})
   108  	t.Run("UnsupportedTypeBool", func(t *testing.T) {
   109  		selector := Selector{Current: ".[#]", Raw: ".[#]"}
   110  		val := false
   111  		got, err := findNodesLength(selector, reflect.ValueOf(val))
   112  		assertQueryMultipleResult(t, []reflect.Value{}, &UnsupportedTypeForSelector{Selector: selector, Value: reflect.ValueOf(val)}, got, err)
   113  	})
   114  	t.Run("SliceType", func(t *testing.T) {
   115  		selector := Selector{Current: ".[#]", Raw: ".[#]"}
   116  		got, err := findNodesLength(selector, reflect.ValueOf([]interface{}{"x", "y"}))
   117  		assertQueryMultipleResult(t, []reflect.Value{reflect.ValueOf(2)}, nil, got, err)
   118  	})
   119  	t.Run("MapType", func(t *testing.T) {
   120  		selector := Selector{Current: ".[#]", Raw: ".[#]"}
   121  		got, err := findNodesLength(selector, reflect.ValueOf(map[string]interface{}{
   122  			"x": 1,
   123  			"y": 2,
   124  		}))
   125  		assertQueryMultipleResult(t, []reflect.Value{reflect.ValueOf(2)}, nil, got, err)
   126  	})
   127  	t.Run("StringType", func(t *testing.T) {
   128  		selector := Selector{Current: ".[#]", Raw: ".[#]"}
   129  		got, err := findNodesLength(selector, reflect.ValueOf("hello"))
   130  		assertQueryMultipleResult(t, []reflect.Value{reflect.ValueOf(5)}, nil, got, err)
   131  	})
   132  }
   133  
   134  func TestFindNodesType(t *testing.T) {
   135  	t.Run("NilValue", func(t *testing.T) {
   136  		selector := Selector{Current: ".[#]", Raw: ".[#]"}
   137  		got, err := findNodesType(selector, nilValue())
   138  		assertQueryMultipleResult(t, []reflect.Value{}, &UnexpectedPreviousNilValue{Selector: ".[#]"}, got, err)
   139  	})
   140  	t.Run("Int", func(t *testing.T) {
   141  		selector := Selector{Current: ".[#]", Raw: ".[#]"}
   142  		val := 0
   143  		got, err := findNodesType(selector, reflect.ValueOf(val))
   144  		assertQueryMultipleResult(t, []reflect.Value{reflect.ValueOf("int")}, nil, got, err)
   145  	})
   146  	t.Run("Float", func(t *testing.T) {
   147  		selector := Selector{Current: ".[#]", Raw: ".[#]"}
   148  		val := 1.1
   149  		got, err := findNodesType(selector, reflect.ValueOf(val))
   150  		assertQueryMultipleResult(t, []reflect.Value{reflect.ValueOf("float")}, nil, got, err)
   151  	})
   152  	t.Run("Bool", func(t *testing.T) {
   153  		selector := Selector{Current: ".[#]", Raw: ".[#]"}
   154  		val := true
   155  		got, err := findNodesType(selector, reflect.ValueOf(val))
   156  		assertQueryMultipleResult(t, []reflect.Value{reflect.ValueOf("bool")}, nil, got, err)
   157  	})
   158  	t.Run("String", func(t *testing.T) {
   159  		selector := Selector{Current: ".[#]", Raw: ".[#]"}
   160  		val := "a"
   161  		got, err := findNodesType(selector, reflect.ValueOf(val))
   162  		assertQueryMultipleResult(t, []reflect.Value{reflect.ValueOf("string")}, nil, got, err)
   163  	})
   164  	t.Run("Map", func(t *testing.T) {
   165  		selector := Selector{Current: ".[#]", Raw: ".[#]"}
   166  		val := map[string]interface{}{"x": 1}
   167  		got, err := findNodesType(selector, reflect.ValueOf(val))
   168  		assertQueryMultipleResult(t, []reflect.Value{reflect.ValueOf("map")}, nil, got, err)
   169  	})
   170  	t.Run("Array", func(t *testing.T) {
   171  		selector := Selector{Current: ".[#]", Raw: ".[#]"}
   172  		val := []interface{}{"x"}
   173  		got, err := findNodesType(selector, reflect.ValueOf(val))
   174  		assertQueryMultipleResult(t, []reflect.Value{reflect.ValueOf("array")}, nil, got, err)
   175  	})
   176  }
   177  
   178  func TestFindNodesPropertyKeys(t *testing.T) {
   179  	t.Run("NilValue", func(t *testing.T) {
   180  		selector := Selector{Current: ".", Raw: "."}
   181  		got, err := findNodesPropertyKeys(selector, nilValue(), false)
   182  		assertQueryMultipleResult(t, []reflect.Value{}, &UnexpectedPreviousNilValue{Selector: "."}, got, err)
   183  	})
   184  	t.Run("UnsupportedCreate", func(t *testing.T) {
   185  		selector := Selector{Current: ".", Raw: "."}
   186  		got, err := findNodesPropertyKeys(selector, reflect.ValueOf(map[string]interface{}{}), true)
   187  		assertQueryMultipleResult(t, []reflect.Value{}, &UnsupportedSelector{Selector: selector.Raw}, got, err)
   188  	})
   189  	t.Run("UnsupportedType", func(t *testing.T) {
   190  		previousValue := reflect.ValueOf(0)
   191  		selector := Selector{Current: "x"}
   192  		got, err := findNodesPropertyKeys(selector, previousValue, false)
   193  		assertQueryMultipleResult(t, []reflect.Value{}, &UnsupportedTypeForSelector{Selector: selector, Value: previousValue}, got, err)
   194  	})
   195  	t.Run("SliceValue", func(t *testing.T) {
   196  		previousValue := reflect.ValueOf([]interface{}{"a", "b", "c"})
   197  		selector := Selector{Current: "-"}
   198  		got, err := findNodesPropertyKeys(selector, previousValue, false)
   199  
   200  		assertQueryMultipleResult(t, []reflect.Value{
   201  			reflect.ValueOf("0"),
   202  			reflect.ValueOf("1"),
   203  			reflect.ValueOf("2"),
   204  		}, nil, got, err)
   205  	})
   206  	t.Run("MapValue", func(t *testing.T) {
   207  		previousValue := reflect.ValueOf(map[string]interface{}{"name": "Tom", "age": 27})
   208  		selector := Selector{Current: "-"}
   209  		got, err := findNodesPropertyKeys(selector, previousValue, false)
   210  
   211  		assertQueryMultipleResultOneOf(t, [][]reflect.Value{
   212  			{
   213  				reflect.ValueOf("name"),
   214  				reflect.ValueOf("age"),
   215  			},
   216  			{
   217  				reflect.ValueOf("age"),
   218  				reflect.ValueOf("name"),
   219  			},
   220  		}, nil, got, err)
   221  	})
   222  }
   223  
   224  func TestFindNodesIndex(t *testing.T) {
   225  	t.Run("NilValue", func(t *testing.T) {
   226  		selector := Selector{Current: ".", Raw: "."}
   227  		got, err := findNodesIndex(selector, nilValue(), false)
   228  		assertQueryMultipleResult(t, []reflect.Value{}, &UnexpectedPreviousNilValue{Selector: "."}, got, err)
   229  	})
   230  	t.Run("NotFound", func(t *testing.T) {
   231  		selector := Selector{Current: "[0]", Index: 0, Raw: ".[0]"}
   232  		previousValue := reflect.ValueOf([]interface{}{})
   233  		got, err := findNodesIndex(selector, previousValue, false)
   234  		assertQueryMultipleResult(t, []reflect.Value{}, &ValueNotFound{Selector: "[0]", PreviousValue: previousValue}, got, err)
   235  	})
   236  	t.Run("UnsupportedType", func(t *testing.T) {
   237  		selector := Selector{Current: "[0]", Index: 0, Raw: ".[0]"}
   238  		previousValue := reflect.ValueOf(map[string]interface{}{})
   239  		got, err := findNodesIndex(selector, previousValue, false)
   240  		assertQueryMultipleResult(t, []reflect.Value{}, &UnsupportedTypeForSelector{Selector: selector, Value: previousValue}, got, err)
   241  	})
   242  }
   243  
   244  func TestFindNodesAnyIndex(t *testing.T) {
   245  	t.Run("NilValue", func(t *testing.T) {
   246  		selector := Selector{Current: "[*]", Raw: ".[*]"}
   247  		got, err := findNodesAnyIndex(selector, nilValue())
   248  		assertQueryMultipleResult(t, []reflect.Value{}, &UnexpectedPreviousNilValue{Selector: ".[*]"}, got, err)
   249  	})
   250  	t.Run("NotFound", func(t *testing.T) {
   251  		selector := Selector{Current: "[*]", Raw: ".[*]"}
   252  		previousValue := reflect.ValueOf([]interface{}{})
   253  		got, err := findNodesAnyIndex(selector, previousValue)
   254  		assertQueryMultipleResult(t, []reflect.Value{}, &ValueNotFound{Selector: "[*]", PreviousValue: previousValue}, got, err)
   255  	})
   256  	t.Run("NotFoundMap", func(t *testing.T) {
   257  		selector := Selector{Current: "[*]", Raw: ".[*]"}
   258  		previousValue := reflect.ValueOf(map[string]interface{}{})
   259  		got, err := findNodesAnyIndex(selector, previousValue)
   260  		assertQueryMultipleResult(t, []reflect.Value{}, &ValueNotFound{Selector: "[*]", PreviousValue: previousValue}, got, err)
   261  	})
   262  	t.Run("UnsupportedType", func(t *testing.T) {
   263  		selector := Selector{Current: "[*]", Raw: ".[*]"}
   264  		previousValue := reflect.ValueOf(0)
   265  		got, err := findNodesAnyIndex(selector, previousValue)
   266  		assertQueryMultipleResult(t, []reflect.Value{}, &UnsupportedTypeForSelector{Selector: selector, Value: previousValue}, got, err)
   267  	})
   268  }
   269  
   270  func TestFindNextAvailableIndexNodes(t *testing.T) {
   271  	t.Run("NotFound", func(t *testing.T) {
   272  		previousValue := reflect.ValueOf([]interface{}{})
   273  		selector := Selector{Current: "[0]", Index: 0}
   274  		got, err := findNextAvailableIndexNodes(selector, previousValue, false)
   275  		assertQueryMultipleResult(t, []reflect.Value{}, &ValueNotFound{Selector: selector.Current, PreviousValue: previousValue}, got, err)
   276  	})
   277  }
   278  
   279  func TestFindNodesDynamic(t *testing.T) {
   280  	t.Run("NilValue", func(t *testing.T) {
   281  		previousValue := reflect.ValueOf(nil)
   282  		selector := Selector{Raw: "."}
   283  		got, err := findNodesDynamic(selector, previousValue, false)
   284  		assertQueryMultipleResult(t, []reflect.Value{}, &UnexpectedPreviousNilValue{Selector: "."}, got, err)
   285  	})
   286  	t.Run("NotFound", func(t *testing.T) {
   287  		previousValue := reflect.ValueOf([]interface{}{})
   288  		selector := Selector{
   289  			Current: "(name=x)",
   290  			Conditions: []Condition{
   291  				&EqualCondition{Key: "name", Value: "x"},
   292  			},
   293  		}
   294  		got, err := findNodesDynamic(selector, previousValue, false)
   295  		assertQueryMultipleResult(t, []reflect.Value{}, &ValueNotFound{Selector: selector.Current, PreviousValue: previousValue}, got, err)
   296  	})
   297  	t.Run("NotFoundMap", func(t *testing.T) {
   298  		previousValue := reflect.ValueOf(map[string]interface{}{})
   299  		selector := Selector{
   300  			Current: "(name=x)",
   301  			Conditions: []Condition{
   302  				&EqualCondition{Key: "name", Value: "x"},
   303  			},
   304  		}
   305  		got, err := findNodesDynamic(selector, previousValue, false)
   306  		assertQueryMultipleResult(t, []reflect.Value{}, &ValueNotFound{Selector: selector.Current, PreviousValue: previousValue}, got, err)
   307  	})
   308  	t.Run("NotFoundWithCreate", func(t *testing.T) {
   309  		previousValue := reflect.ValueOf([]interface{}{})
   310  		selector := Selector{
   311  			Type:    "NEXT_AVAILABLE_INDEX",
   312  			Current: "(name=x)",
   313  			Conditions: []Condition{
   314  				&EqualCondition{Key: "name", Value: "x"},
   315  			},
   316  		}
   317  		got, err := findNodesDynamic(selector, previousValue, true)
   318  		if !assertQueryMultipleResult(t, []reflect.Value{nilValue()}, nil, got, err) {
   319  			return
   320  		}
   321  		if exp, got := "NEXT_AVAILABLE_INDEX", selector.Type; exp != got {
   322  			t.Errorf("expected type of %s, got %s", exp, got)
   323  			return
   324  		}
   325  	})
   326  	t.Run("UnsupportedType", func(t *testing.T) {
   327  		previousValue := reflect.ValueOf(0)
   328  		selector := Selector{
   329  			Current: "(name=x)",
   330  			Conditions: []Condition{
   331  				&EqualCondition{Key: "name", Value: "x"},
   332  			},
   333  		}
   334  		got, err := findNodesDynamic(selector, previousValue, false)
   335  		assertQueryMultipleResult(t, []reflect.Value{}, &UnsupportedTypeForSelector{Selector: selector, Value: previousValue}, got, err)
   336  	})
   337  }
   338  
   339  func TestFindNodesSearch(t *testing.T) {
   340  	t.Run("NilValue", func(t *testing.T) {
   341  		previousNode := New(nil)
   342  		selector := Selector{Raw: "."}
   343  		got, err := findNodesSearch(selector, previousNode, false)
   344  		assertQueryMultipleResult(t, []reflect.Value{}, &UnexpectedPreviousNilValue{Selector: "."}, got, err)
   345  	})
   346  	t.Run("NestedNilValue", func(t *testing.T) {
   347  		previousNode := New(map[string]interface{}{
   348  			"x": nil,
   349  		})
   350  		selector := Selector{
   351  			Type:    "SEARCH",
   352  			Raw:     ".(?:name=x)",
   353  			Current: ".(?:name=x)",
   354  			Conditions: []Condition{
   355  				&EqualCondition{Key: "name", Value: "x"},
   356  			},
   357  		}
   358  		got, err := findNodesSearch(selector, previousNode, false)
   359  		assertQueryMultipleResult(t, []reflect.Value{}, fmt.Errorf("could not find nodes search recursive: %w", &UnexpectedPreviousNilValue{Selector: selector.Current}), got, err)
   360  	})
   361  	t.Run("NotFound", func(t *testing.T) {
   362  		previousNode := New(map[string]interface{}{})
   363  		selector := Selector{
   364  			Type:    "SEARCH",
   365  			Raw:     ".(?:name=x)",
   366  			Current: ".(?:name=x)",
   367  			Conditions: []Condition{
   368  				&EqualCondition{Key: "name", Value: "x"},
   369  			},
   370  		}
   371  		got, err := findNodesSearch(selector, previousNode, false)
   372  		assertQueryMultipleResult(t, []reflect.Value{}, &ValueNotFound{Selector: selector.Current, PreviousValue: previousNode.Value}, got, err)
   373  	})
   374  	t.Run("NotFoundOptional", func(t *testing.T) {
   375  		previousNode := New(map[string]interface{}{})
   376  		selector := Selector{
   377  			Type:    "SEARCH_OPTIONAL",
   378  			Raw:     ".(#:name=x)",
   379  			Current: ".(#:name=x)",
   380  			Conditions: []Condition{
   381  				&EqualCondition{Key: "name", Value: "x"},
   382  			},
   383  		}
   384  		got, err := findNodesSearch(selector, previousNode, false)
   385  		assertQueryMultipleResult(t, []reflect.Value{}, &ValueNotFound{Selector: selector.Current, PreviousValue: previousNode.Value}, got, err)
   386  	})
   387  	t.Run("FoundAllMatches", func(t *testing.T) {
   388  		users := []interface{}{
   389  			map[string]interface{}{
   390  				"id":   1,
   391  				"name": "Tom",
   392  			},
   393  			map[string]interface{}{
   394  				"id":   2,
   395  				"name": "Jim",
   396  			},
   397  			map[string]interface{}{
   398  				"id":   3,
   399  				"name": "Tom",
   400  			},
   401  		}
   402  		previousNode := New(users)
   403  		selector := Selector{
   404  			Type:    "SEARCH",
   405  			Raw:     ".(?:name=Tom).name",
   406  			Current: ".(?:name=Tom)",
   407  			Conditions: []Condition{
   408  				&EqualCondition{Key: "name", Value: "Tom"},
   409  			},
   410  		}
   411  		got, err := findNodesSearch(selector, previousNode, false)
   412  		if err != nil {
   413  			t.Errorf("unexpected error: %s", err)
   414  			return
   415  		}
   416  		exp := []interface{}{
   417  			users[0], users[2],
   418  		}
   419  		gotVals := make([]interface{}, len(got))
   420  		for i, val := range got {
   421  			gotVals[i] = val.Value.Interface()
   422  		}
   423  		if !reflect.DeepEqual(exp, gotVals) {
   424  			t.Errorf("expected %v, got %v", exp, gotVals)
   425  		}
   426  	})
   427  	t.Run("FoundAllMatchesOptional", func(t *testing.T) {
   428  		users := []interface{}{
   429  			map[string]interface{}{
   430  				"id":   1,
   431  				"name": "Tom",
   432  			},
   433  			map[string]interface{}{
   434  				"id":   2,
   435  				"name": "Jim",
   436  			},
   437  			map[string]interface{}{
   438  				"id":   3,
   439  				"name": "Tom",
   440  			},
   441  		}
   442  		previousNode := New(users)
   443  		selector := Selector{
   444  			Type:    "SEARCH_OPTIONAL",
   445  			Raw:     ".(#:name=Tom).name",
   446  			Current: ".(#:name=Tom)",
   447  			Conditions: []Condition{
   448  				&EqualCondition{Key: "name", Value: "Tom"},
   449  			},
   450  		}
   451  		got, err := findNodesSearch(selector, previousNode, false)
   452  		if err != nil {
   453  			t.Errorf("unexpected error: %s", err)
   454  			return
   455  		}
   456  		exp := []interface{}{
   457  			users[0], users[2],
   458  		}
   459  		gotVals := make([]interface{}, len(got))
   460  		for i, val := range got {
   461  			gotVals[i] = val.Value.Interface()
   462  		}
   463  		if !reflect.DeepEqual(exp, gotVals) {
   464  			t.Errorf("expected %v, got %v", exp, gotVals)
   465  		}
   466  	})
   467  }
   468  
   469  func TestFindNodes(t *testing.T) {
   470  	t.Run("UnsupportedSelector", func(t *testing.T) {
   471  		previousNode := &Node{Value: reflect.ValueOf([]interface{}{})}
   472  		selector := Selector{Raw: "BAD"}
   473  		got, err := findNodes(selector, previousNode, false)
   474  		assertQueryMultipleResult(t, []reflect.Value{}, &UnsupportedSelector{Selector: "BAD"}, got, err)
   475  	})
   476  }