1// Copyright (C) 2024 The Android Open Source Project 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 templatefns 16 17import ( 18 "errors" 19 "testing" 20 21 pb "cts/test/mediapc/requirements/requirements_go_proto" 22 23 "google.golang.org/protobuf/proto" 24) 25 26var caseTests = []struct { 27 input, kebabCase, snakeCase, titleCase, upperCamelCase, lowerCamelCase, safeTestConfigID string 28}{ 29 { 30 input: "", 31 kebabCase: "", snakeCase: "", titleCase: "", upperCamelCase: "", lowerCamelCase: "", safeTestConfigID: ""}, 32 { 33 input: "f", 34 kebabCase: "f", snakeCase: "f", titleCase: "F", upperCamelCase: "F", lowerCamelCase: "f", safeTestConfigID: "__f"}, 35 { 36 input: "foo", 37 kebabCase: "foo", snakeCase: "foo", titleCase: "Foo", upperCamelCase: "Foo", lowerCamelCase: "foo", safeTestConfigID: "__foo"}, 38 { 39 input: " foo_bar", 40 kebabCase: "foo-bar", snakeCase: "foo_bar", titleCase: "Foo Bar", upperCamelCase: "FooBar", lowerCamelCase: "fooBar", safeTestConfigID: "__foo_bar"}, 41 { 42 input: " foo-bar", 43 kebabCase: "foo-bar", snakeCase: "foo_bar", titleCase: "Foo Bar", upperCamelCase: "FooBar", lowerCamelCase: "fooBar", safeTestConfigID: "__foo_bar"}, 44 { 45 input: " foo bar", 46 kebabCase: "foo-bar", snakeCase: "foo_bar", titleCase: "Foo Bar", upperCamelCase: "FooBar", lowerCamelCase: "fooBar", safeTestConfigID: "__foo_bar"}, 47 { 48 input: " Foo Bar", 49 kebabCase: "foo-bar", snakeCase: "foo_bar", titleCase: "Foo Bar", upperCamelCase: "FooBar", lowerCamelCase: "fooBar", safeTestConfigID: "__foo_bar"}, 50 { 51 input: "HTTP_status_code", 52 kebabCase: "http-status-code", snakeCase: "http_status_code", titleCase: "HTTP Status Code", upperCamelCase: "HTTPStatusCode", lowerCamelCase: "httpStatusCode", safeTestConfigID: "__http_status_code"}, 53 { 54 input: "foo many spaces", 55 kebabCase: "foo-many-spaces", snakeCase: "foo_many_spaces", titleCase: "Foo Many Spaces", upperCamelCase: "FooManySpaces", lowerCamelCase: "fooManySpaces", safeTestConfigID: "__foo_many_spaces"}, 56 { 57 input: "foo---many-dashes", 58 kebabCase: "foo-many-dashes", snakeCase: "foo_many_dashes", titleCase: "Foo Many Dashes", upperCamelCase: "FooManyDashes", lowerCamelCase: "fooManyDashes", safeTestConfigID: "__foo_many_dashes"}, 59 { 60 input: "foo___many_underline", 61 kebabCase: "foo-many-underline", snakeCase: "foo_many_underline", titleCase: "Foo Many Underline", upperCamelCase: "FooManyUnderline", lowerCamelCase: "fooManyUnderline", safeTestConfigID: "__foo_many_underline"}, 62 { 63 input: "UpperCamelCase", 64 kebabCase: "upper-camel-case", snakeCase: "upper_camel_case", titleCase: "Upper Camel Case", upperCamelCase: "UpperCamelCase", lowerCamelCase: "upperCamelCase", safeTestConfigID: "__upper_camel_case"}, 65 { 66 input: "ACRONYMInUpperCamelCase", 67 kebabCase: "acronym-in-upper-camel-case", snakeCase: "acronym_in_upper_camel_case", titleCase: "ACRONYM In Upper Camel Case", upperCamelCase: "ACRONYMInUpperCamelCase", lowerCamelCase: "acronymInUpperCamelCase", safeTestConfigID: "__acronym_in_upper_camel_case"}, 68 { 69 input: "FooGRPCHandler", 70 kebabCase: "foo-grpc-handler", snakeCase: "foo_grpc_handler", titleCase: "Foo GRPC Handler", upperCamelCase: "FooGRPCHandler", lowerCamelCase: "fooGRPCHandler", safeTestConfigID: "__foo_grpc_handler"}, 71 { 72 input: "GRPC1234Handler", 73 kebabCase: "grpc1234-handler", snakeCase: "grpc1234_handler", titleCase: "GRPC1234 Handler", upperCamelCase: "GRPC1234Handler", lowerCamelCase: "grpc1234Handler", safeTestConfigID: "__grpc1234_handler"}, 74 { 75 input: "tricky4567number", 76 kebabCase: "tricky4567-number", snakeCase: "tricky4567_number", titleCase: "Tricky4567 Number", upperCamelCase: "Tricky4567Number", lowerCamelCase: "tricky4567Number", safeTestConfigID: "__tricky4567_number"}, 77 { 78 input: "tricky 4567number", 79 kebabCase: "tricky-4567-number", snakeCase: "tricky_4567_number", titleCase: "Tricky 4567 Number", upperCamelCase: "Tricky4567Number", lowerCamelCase: "tricky4567Number", safeTestConfigID: "__tricky_4567_number"}, 80 { 81 input: "tricky 4567Number", 82 kebabCase: "tricky-4567-number", snakeCase: "tricky_4567_number", titleCase: "Tricky 4567 Number", upperCamelCase: "Tricky4567Number", lowerCamelCase: "tricky4567Number", safeTestConfigID: "__tricky_4567_number"}, 83 { 84 input: "tricky 4567 Number", 85 kebabCase: "tricky-4567-number", snakeCase: "tricky_4567_number", titleCase: "Tricky 4567 Number", upperCamelCase: "Tricky4567Number", lowerCamelCase: "tricky4567Number", safeTestConfigID: "__tricky_4567_number"}, 86 { 87 input: "lowerCamelCase", 88 kebabCase: "lower-camel-case", snakeCase: "lower_camel_case", titleCase: "Lower Camel Case", upperCamelCase: "LowerCamelCase", lowerCamelCase: "lowerCamelCase", safeTestConfigID: "__lower_camel_case"}, 89 { 90 input: "endInCapitalT", 91 kebabCase: "end-in-capital-t", snakeCase: "end_in_capital_t", titleCase: "End In Capital T", upperCamelCase: "EndInCapitalT", lowerCamelCase: "endInCapitalT", safeTestConfigID: "__end_in_capital_t"}, 92 { 93 input: "snake_case", 94 kebabCase: "snake-case", snakeCase: "snake_case", titleCase: "Snake Case", upperCamelCase: "SnakeCase", lowerCamelCase: "snakeCase", safeTestConfigID: "__snake_case"}, 95 { 96 input: "kebab-case", 97 kebabCase: "kebab-case", snakeCase: "kebab_case", titleCase: "Kebab Case", upperCamelCase: "KebabCase", lowerCamelCase: "kebabCase", safeTestConfigID: "__kebab_case"}, 98 { 99 input: "üñicödeCäse", 100 kebabCase: "üñicöde-cäse", snakeCase: "üñicöde_cäse", titleCase: "Üñicöde Cäse", upperCamelCase: "ÜñicödeCäse", lowerCamelCase: "üñicödeCäse", safeTestConfigID: "__üñicöde_cäse"}} 101 102func TestKebabCase(t *testing.T) { 103 for _, tt := range caseTests { 104 t.Run(tt.input, func(t *testing.T) { 105 if got := kebabCase(tt.input); got != tt.kebabCase { 106 t.Fatalf("KebabCase(%q) = %q, want %q", tt.input, got, tt.kebabCase) 107 } 108 }) 109 } 110} 111 112func TestSnakeCase(t *testing.T) { 113 for _, tt := range caseTests { 114 t.Run(tt.input, func(t *testing.T) { 115 if got := snakeCase(tt.input); got != tt.snakeCase { 116 t.Fatalf("SnakeCase(%q) = %q, want %q", tt.input, got, tt.snakeCase) 117 } 118 }) 119 } 120} 121 122func TestTitleCase(t *testing.T) { 123 for _, tt := range caseTests { 124 t.Run(tt.input, func(t *testing.T) { 125 if got := titleCase(tt.input); got != tt.titleCase { 126 t.Fatalf("TitleCase(%q) = %q, want %q", tt.input, got, tt.titleCase) 127 } 128 }) 129 } 130} 131 132func TestUpperCamelCase(t *testing.T) { 133 for _, tt := range caseTests { 134 t.Run(tt.input, func(t *testing.T) { 135 if got := upperCamelCase(tt.input); got != tt.upperCamelCase { 136 t.Fatalf("upperCamelCase(%q) = %q, want %q", tt.input, got, tt.upperCamelCase) 137 } 138 }) 139 } 140} 141 142func TestLowerCamelCase(t *testing.T) { 143 for _, tt := range caseTests { 144 t.Run(tt.input, func(t *testing.T) { 145 if got := lowerCamelCase(tt.input); got != tt.lowerCamelCase { 146 t.Fatalf("lowerCamelCase(%q) = %q, want %q", tt.input, got, tt.lowerCamelCase) 147 } 148 }) 149 } 150} 151 152func TestSafeTestConfigID(t *testing.T) { 153 for _, tt := range caseTests { 154 t.Run(tt.input, func(t *testing.T) { 155 if got := safeTestConfigID(tt.input); got != tt.safeTestConfigID { 156 t.Fatalf("safeTestConfigID(%q) = %q, want %q", tt.input, got, tt.safeTestConfigID) 157 } 158 }) 159 } 160} 161 162func TestDict(t *testing.T) { 163 errorValue := errors.New("error_value") 164 var dictTest = []struct { 165 values []any 166 want map[string]any 167 }{ 168 { 169 values: []any{1, 2, 3}, 170 want: map[string]any{ 171 "1": 2, 172 "3": nil, 173 }, 174 }, 175 { 176 values: []any{"foo", "bar"}, 177 want: map[string]any{"foo": "bar"}, 178 }, 179 { 180 values: []any{errors.New("error_key"), errorValue}, 181 want: map[string]any{"error_key": errorValue}, 182 }, 183 } 184 for _, tt := range dictTest { 185 got := dict(tt.values...) 186 for k, v := range tt.want { 187 if got[k] != v { 188 t.Fatalf("dict(%v)[%q] = %q, want %q", tt.values, k, got[k], v) 189 } 190 } 191 } 192} 193 194func TestHasConfigVariant(t *testing.T) { 195 testReq := pb.Requirement_builder{ 196 Specs: map[int64]*pb.RequirementSpec{ 197 30: pb.RequirementSpec_builder{ 198 TestConfigId: proto.String("720p"), 199 VariantSpecs: map[string]*pb.VariantSpec{ 200 "VP9": pb.VariantSpec_builder{}.Build(), 201 }, 202 }.Build(), 203 34: pb.RequirementSpec_builder{ 204 TestConfigId: proto.String("4k"), 205 VariantSpecs: make(map[string]*pb.VariantSpec), 206 }.Build(), 207 }, 208 }.Build() 209 210 tests := []struct { 211 r *pb.Requirement 212 configID string 213 variantID string 214 want bool 215 }{ 216 { 217 r: testReq, 218 configID: "720p", 219 variantID: "VP9", 220 want: true, 221 }, 222 { 223 r: testReq, 224 configID: "4k", 225 variantID: "VP9", 226 want: false, 227 }, 228 } 229 230 for _, tc := range tests { 231 got := HasConfigVariant(tc.r, tc.configID, tc.variantID) 232 if got != tc.want { 233 t.Errorf("HasConfigVariant(%v, %q, %q) = %v, want: %v", tc.r, tc.configID, tc.variantID, got, tc.want) 234 } 235 } 236} 237