...

Source file src/github.com/grpc-ecosystem/grpc-gateway/runtime/fieldmask_test.go

Documentation: github.com/grpc-ecosystem/grpc-gateway/runtime

     1  package runtime
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"testing"
     7  
     8  	"google.golang.org/genproto/protobuf/field_mask"
     9  )
    10  
    11  func fieldMasksEqual(fm1, fm2 *field_mask.FieldMask) bool {
    12  	if fm1 == nil && fm2 == nil {
    13  		return true
    14  	}
    15  	if fm1 == nil || fm2 == nil {
    16  		return false
    17  	}
    18  	if len(fm1.GetPaths()) != len(fm2.GetPaths()) {
    19  		return false
    20  	}
    21  
    22  	paths := make(map[string]bool)
    23  	for _, path := range fm1.GetPaths() {
    24  		paths[path] = true
    25  	}
    26  	for _, path := range fm2.GetPaths() {
    27  		if _, ok := paths[path]; !ok {
    28  			return false
    29  		}
    30  	}
    31  
    32  	return true
    33  }
    34  
    35  func newFieldMask(paths ...string) *field_mask.FieldMask {
    36  	return &field_mask.FieldMask{Paths: paths}
    37  }
    38  
    39  func fieldMaskString(fm *field_mask.FieldMask) string {
    40  	if fm == nil {
    41  		return ""
    42  	}
    43  	return fmt.Sprintf("%v", fm.GetPaths())
    44  }
    45  
    46  func TestFieldMaskFromRequestBody(t *testing.T) {
    47  	for _, tc := range []struct {
    48  		name        string
    49  		input       string
    50  		expected    *field_mask.FieldMask
    51  		expectedErr error
    52  	}{
    53  		{name: "empty", expected: newFieldMask()},
    54  		{name: "simple", input: `{"foo":1, "bar":"baz"}`, expected: newFieldMask("foo", "bar")},
    55  		{name: "nested", input: `{"foo": {"bar":1, "baz": 2}, "qux": 3}`, expected: newFieldMask("foo.bar", "foo.baz", "qux")},
    56  		{name: "canonical", input: `{"f": {"b": {"d": 1, "x": 2}, "c": 1}}`, expected: newFieldMask("f.b.d", "f.b.x", "f.c")},
    57  		{name: "deeply-nested", input: `{"foo": {"bar": {"baz": {"a": 1, "b": 2}}}}`, expected: newFieldMask("foo.bar.baz.a", "foo.bar.baz.b")},
    58  	} {
    59  		t.Run(tc.name, func(t *testing.T) {
    60  			actual, err := FieldMaskFromRequestBody(bytes.NewReader([]byte(tc.input)), nil)
    61  			if !fieldMasksEqual(actual, tc.expected) {
    62  				t.Errorf("want %v; got %v", fieldMaskString(tc.expected), fieldMaskString(actual))
    63  			}
    64  			if err != tc.expectedErr {
    65  				t.Errorf("want %v; got %v", tc.expectedErr, err)
    66  			}
    67  		})
    68  	}
    69  }
    70  
    71  // avoid compiler optimising benchmark away
    72  var result *field_mask.FieldMask
    73  
    74  func BenchmarkABEFieldMaskFromRequestBody(b *testing.B) {
    75  	input := `{` +
    76  		`"single_nested":				{"name": "bar",` +
    77  		`                           	 "amount": 10,` +
    78  		`                           	 "ok": "TRUE"},` +
    79  		`"uuid":						"6EC2446F-7E89-4127-B3E6-5C05E6BECBA7",` +
    80  		`"nested": 						[{"name": "bar",` +
    81  		`								  "amount": 10},` +
    82  		`								 {"name": "baz",` +
    83  		`								  "amount": 20}],` +
    84  		`"float_value":             	1.5,` +
    85  		`"double_value":            	2.5,` +
    86  		`"int64_value":             	4294967296,` +
    87  		`"uint64_value":            	9223372036854775807,` +
    88  		`"int32_value":             	-2147483648,` +
    89  		`"fixed64_value":           	9223372036854775807,` +
    90  		`"fixed32_value":           	4294967295,` +
    91  		`"bool_value":              	true,` +
    92  		`"string_value":            	"strprefix/foo",` +
    93  		`"bytes_value":					"132456",` +
    94  		`"uint32_value":            	4294967295,` +
    95  		`"enum_value":     		        "ONE",` +
    96  		`"path_enum_value":	    	    "DEF",` +
    97  		`"nested_path_enum_value":  	"JKL",` +
    98  		`"sfixed32_value":          	2147483647,` +
    99  		`"sfixed64_value":          	-4611686018427387904,` +
   100  		`"sint32_value":            	2147483647,` +
   101  		`"sint64_value":            	4611686018427387903,` +
   102  		`"repeated_string_value": 		["a", "b", "c"],` +
   103  		`"oneof_value":					{"oneof_string":"x"},` +
   104  		`"map_value": 					{"a": "ONE",` +
   105  		`								 "b": "ZERO"},` +
   106  		`"mapped_string_value": 		{"a": "x",` +
   107  		`								 "b": "y"},` +
   108  		`"mapped_nested_value": 		{"a": {"name": "x", "amount": 1},` +
   109  		`								 "b": {"name": "y", "amount": 2}},` +
   110  		`"nonConventionalNameValue":	"camelCase",` +
   111  		`"timestamp_value":				"2016-05-10T10:19:13.123Z",` +
   112  		`"repeated_enum_value":			["ONE", "ZERO"],` +
   113  		`"repeated_enum_annotation":	 ["ONE", "ZERO"],` +
   114  		`"enum_value_annotation": 		"ONE",` +
   115  		`"repeated_string_annotation":	["a", "b"],` +
   116  		`"repeated_nested_annotation": 	[{"name": "hoge",` +
   117  		`								  "amount": 10},` +
   118  		`								 {"name": "fuga",` +
   119  		`								  "amount": 20}],` +
   120  		`"nested_annotation": 			{"name": "hoge",` +
   121  		`								 "amount": 10},` +
   122  		`"int64_override_type":			12345` +
   123  		`}`
   124  	var r *field_mask.FieldMask
   125  	var err error
   126  	for i := 0; i < b.N; i++ {
   127  		r, err = FieldMaskFromRequestBody(bytes.NewReader([]byte(input)), nil)
   128  	}
   129  	if err != nil {
   130  		b.Error(err)
   131  	}
   132  	result = r
   133  }
   134  
   135  func BenchmarkNonStandardFieldMaskFromRequestBody(b *testing.B) {
   136  	input := `{` +
   137  		`"id":			"foo",` +
   138  		`"Num": 		2,` +
   139  		`"line_num": 	3,` +
   140  		`"langIdent":	"bar",` +
   141  		`"STATUS": 		"baz"` +
   142  		`}`
   143  	var r *field_mask.FieldMask
   144  	var err error
   145  	for i := 0; i < b.N; i++ {
   146  		r, err = FieldMaskFromRequestBody(bytes.NewReader([]byte(input)), nil)
   147  	}
   148  	if err != nil {
   149  		b.Error(err)
   150  	}
   151  	result = r
   152  }
   153  

View as plain text