| 237 | } |
| 238 | |
| 239 | func lintVectorTestGroups(vectorData []byte, path string) error { |
| 240 | var vector struct { |
| 241 | NumberOfTests int `json:"numberOfTests"` |
| 242 | TestGroups []struct { |
| 243 | Type string `json:"type"` |
| 244 | Tests []struct { |
| 245 | TcId int `json:"tcId"` |
| 246 | } `json:"tests"` |
| 247 | } `json:"testGroups"` |
| 248 | } |
| 249 | if err := json.Unmarshal(vectorData, &vector); err != nil { |
| 250 | return fmt.Errorf("error decoding vector JSON data for test groups: %w", err) |
| 251 | } |
| 252 | |
| 253 | // Within a vector file, all test groups must have the same type. |
| 254 | testGroupTypes := make(map[string]bool) |
| 255 | for _, tg := range vector.TestGroups { |
| 256 | if tg.Type != "" { |
| 257 | testGroupTypes[tg.Type] = true |
| 258 | } |
| 259 | } |
| 260 | |
| 261 | if len(testGroupTypes) > 1 { |
| 262 | var types []string |
| 263 | for t := range testGroupTypes { |
| 264 | types = append(types, t) |
| 265 | } |
| 266 | return fmt.Errorf("vector %q has multiple test group types: %v (expected only one type per file)", path, types) |
| 267 | } |
| 268 | |
| 269 | // Within a vector file, test case IDs must be unique. |
| 270 | testCaseIds := make(map[int]struct{}) |
| 271 | for _, tg := range vector.TestGroups { |
| 272 | for _, test := range tg.Tests { |
| 273 | if _, ok := testCaseIds[test.TcId]; ok { |
| 274 | return fmt.Errorf("vector %q has duplicate tcId %d", path, test.TcId) |
| 275 | } |
| 276 | testCaseIds[test.TcId] = struct{}{} |
| 277 | } |
| 278 | } |
| 279 | |
| 280 | if testCount := len(testCaseIds); testCount != vector.NumberOfTests { |
| 281 | return fmt.Errorf("vector %q declared %d tests in group, had %d", path, vector.NumberOfTests, testCount) |
| 282 | } |
| 283 | |
| 284 | return nil |
| 285 | } |
| 286 | |
| 287 | func lintVectorToSchema(schemaCompiler *jsonschema.Compiler, vectorData []byte, path string, results *schemaLintResults) error { |
| 288 | var vector struct { |