1// Copyright 2020 Google Inc. All rights reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package proptools 16 17import ( 18 "reflect" 19 "testing" 20) 21 22func TestPropertyNameForField(t *testing.T) { 23 tests := []struct { 24 name string 25 input string 26 want string 27 }{ 28 { 29 name: "short", 30 input: "S", 31 want: "s", 32 }, 33 { 34 name: "long", 35 input: "String", 36 want: "string", 37 }, 38 { 39 name: "uppercase", 40 input: "STRING", 41 want: "STRING", 42 }, 43 { 44 name: "mixed", 45 input: "StRiNg", 46 want: "stRiNg", 47 }, 48 { 49 name: "underscore", 50 input: "Under_score", 51 want: "under_score", 52 }, 53 { 54 name: "uppercase underscore", 55 input: "UNDER_SCORE", 56 want: "UNDER_SCORE", 57 }, 58 { 59 name: "x86", 60 input: "X86", 61 want: "x86", 62 }, 63 { 64 name: "x86_64", 65 input: "X86_64", 66 want: "x86_64", 67 }, 68 } 69 for _, tt := range tests { 70 t.Run(tt.name, func(t *testing.T) { 71 if got := PropertyNameForField(tt.input); got != tt.want { 72 t.Errorf("PropertyNameForField(%v) = %v, want %v", tt.input, got, tt.want) 73 } 74 }) 75 } 76} 77 78func TestFieldNameForProperty(t *testing.T) { 79 tests := []struct { 80 name string 81 input string 82 want string 83 }{ 84 { 85 name: "short lowercase", 86 input: "s", 87 want: "S", 88 }, 89 { 90 name: "short uppercase", 91 input: "S", 92 want: "S", 93 }, 94 { 95 name: "long lowercase", 96 input: "string", 97 want: "String", 98 }, 99 { 100 name: "long uppercase", 101 input: "STRING", 102 want: "STRING", 103 }, 104 { 105 name: "mixed", 106 input: "StRiNg", 107 want: "StRiNg", 108 }, 109 } 110 for _, tt := range tests { 111 t.Run(tt.name, func(t *testing.T) { 112 if got := FieldNameForProperty(tt.input); got != tt.want { 113 t.Errorf("FieldNameForProperty(%v) = %v, want %v", tt.input, got, tt.want) 114 } 115 }) 116 } 117} 118 119func TestClearField(t *testing.T) { 120 props := struct { 121 i int 122 s string 123 ps *string 124 ss []string 125 c struct { 126 n int 127 } 128 }{} 129 130 props.i = 42 131 Clear(&props.i) 132 if props.i != 0 { 133 t.Error("int field is not cleared to zero.") 134 } 135 136 props.s = "foo" 137 Clear(&props.s) 138 if props.s != "" { 139 t.Error("string field is not cleared to zero.") 140 } 141 142 props.ps = StringPtr("foo") 143 Clear(&props.ps) 144 if props.ps != nil { 145 t.Error("string pointer field is not cleared to zero.") 146 } 147 148 props.ss = []string{"foo"} 149 Clear(&props.ss) 150 if props.ss != nil { 151 t.Error("string array field is not cleared to zero.") 152 } 153 154 props.c.n = 42 155 Clear(&props.c) 156 if props.c.n != 0 { 157 t.Error("struct field is not cleared to zero.") 158 } 159} 160 161func TestIsConfigurable(t *testing.T) { 162 testCases := []struct { 163 name string 164 value interface{} 165 expected bool 166 }{ 167 { 168 name: "Configurable string", 169 value: Configurable[string]{}, 170 expected: true, 171 }, 172 { 173 name: "Configurable string list", 174 value: Configurable[[]string]{}, 175 expected: true, 176 }, 177 { 178 name: "Configurable bool", 179 value: Configurable[bool]{}, 180 expected: true, 181 }, 182 { 183 name: "Other struct with a bool as the first field", 184 value: struct { 185 x bool 186 }{}, 187 expected: false, 188 }, 189 } 190 for _, tc := range testCases { 191 t.Run(tc.name, func(t *testing.T) { 192 value := reflect.ValueOf(tc.value) 193 if isConfigurable(value.Type()) != tc.expected { 194 t.Errorf("Expected isConfigurable to return %t", tc.expected) 195 } 196 }) 197 } 198} 199