xref: /aosp_15_r20/external/executorch/extension/benchmark/apple/Benchmark/TestUtils/ResourceTestCase.m (revision 523fa7a60841cd1ecfb9cc4201f1ca8b03ed023a)
1/*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 * All rights reserved.
4 *
5 * This source code is licensed under the BSD-style license found in the
6 * LICENSE file in the root directory of this source tree.
7 */
8
9#import "ResourceTestCase.h"
10
11static void generateCombinations(
12    NSDictionary<NSString *, NSArray<NSString *> *> *matchesByResource,
13    NSArray<NSString *> *keys,
14    NSMutableDictionary<NSString *, NSString *> *result,
15    NSUInteger index,
16    NSMutableSet<NSDictionary<NSString *, NSString *> *> *combinations) {
17  if (index == keys.count) {
18    if (result.count == keys.count) {
19      [combinations addObject:[result copy]];
20    }
21    return;
22  }
23  NSString *key = keys[index];
24  NSArray<NSString *> *matches = matchesByResource[key] ?: @[];
25  if (!matches.count) {
26    generateCombinations(
27        matchesByResource, keys, result, index + 1, combinations);
28    return;
29  }
30  for (NSString *match in matches) {
31    result[key] = match;
32    generateCombinations(
33        matchesByResource, keys, result, index + 1, combinations);
34    [result removeObjectForKey:key];
35  }
36}
37
38@implementation ResourceTestCase
39
40+ (NSArray<NSBundle *> *)bundles {
41  return @[ [NSBundle mainBundle], [NSBundle bundleForClass:self] ];
42}
43
44+ (NSArray<NSString *> *)directories {
45  return @[];
46}
47
48+ (NSDictionary<NSString *, BOOL (^)(NSString *)> *)predicates {
49  return @{};
50}
51
52+ (NSDictionary<NSString *, void (^)(XCTestCase *)> *)dynamicTestsForResources:
53    (NSDictionary<NSString *, NSString *> *)resources {
54  return @{};
55}
56
57+ (NSDictionary<NSString *, void (^)(XCTestCase *)> *)dynamicTests {
58  NSMutableDictionary<NSString *, void (^)(XCTestCase *)> *tests =
59      [NSMutableDictionary new];
60  NSMutableSet<NSDictionary<NSString *, NSString *> *> *combinations =
61      [NSMutableSet new];
62  NSDictionary<NSString *, BOOL (^)(NSString *)> *predicates =
63      [self predicates];
64  NSArray<NSString *> *sortedKeys =
65      [predicates.allKeys sortedArrayUsingSelector:@selector(compare:)];
66
67  if (predicates.count == 0)
68    return @{};
69
70  for (NSBundle *bundle in self.bundles) {
71    for (NSString *directory in self.directories) {
72      NSArray<NSURL *> *resourceURLs =
73          [bundle URLsForResourcesWithExtension:nil subdirectory:directory];
74      if (!resourceURLs.count) {
75        continue;
76      };
77      NSMutableDictionary<NSString *, NSMutableArray<NSString *> *>
78          *matchesByResource = [NSMutableDictionary new];
79
80      for (NSURL *url in resourceURLs) {
81        NSString *file = url.lastPathComponent;
82        NSString *fullPath = url.path;
83
84        for (NSString *key in sortedKeys) {
85          if (predicates[key](file)) {
86            matchesByResource[key] =
87                matchesByResource[key] ?: [NSMutableArray new];
88            [matchesByResource[key] addObject:fullPath];
89          }
90        }
91      }
92      NSMutableDictionary<NSString *, NSString *> *result =
93          [NSMutableDictionary new];
94      generateCombinations(
95          matchesByResource, sortedKeys, result, 0, combinations);
96    }
97  }
98  for (NSDictionary<NSString *, NSString *> *resources in combinations) {
99    NSMutableString *resourceString = [NSMutableString new];
100    NSCharacterSet *punctuationSet = [NSCharacterSet punctuationCharacterSet];
101    for (NSString *key in sortedKeys) {
102      NSString *lastComponent = [resources[key] lastPathComponent];
103      NSString *cleanedComponent =
104          [[lastComponent componentsSeparatedByCharactersInSet:punctuationSet]
105              componentsJoinedByString:@"_"];
106      [resourceString appendFormat:@"_%@", cleanedComponent];
107    }
108    NSDictionary<NSString *, void (^)(XCTestCase *)> *resourceTests =
109        [self dynamicTestsForResources:resources];
110    [resourceTests
111        enumerateKeysAndObjectsUsingBlock:^(
112            NSString *testName, void (^testBlock)(XCTestCase *), BOOL *stop) {
113          tests[[testName stringByAppendingString:resourceString]] = testBlock;
114        }];
115  }
116  return tests;
117}
118
119@end
120