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