|
59 | 59 | import java.util.List; |
60 | 60 | import java.util.Locale; |
61 | 61 | import java.util.Map; |
| 62 | +import java.util.Optional; |
62 | 63 | import java.util.regex.Pattern; |
63 | 64 |
|
64 | 65 | import static org.hamcrest.CoreMatchers.hasItems; |
@@ -786,24 +787,45 @@ private void createSampleTypeForNameValidation(String sampleTypeName, String nam |
786 | 787 |
|
787 | 788 | } |
788 | 789 |
|
| 790 | + /** |
| 791 | + * <p> |
| 792 | + * Validate that every name in {@code actualNames} matches one of the regex patterns in |
| 793 | + * {@code expectedNames}, using a multiset diff: every expected pattern must match at least |
| 794 | + * one actual name, every actual name must be matched by some expected pattern, and the |
| 795 | + * counts must be equal. Order is intentionally NOT verified. |
| 796 | + * </p> |
| 797 | + * <p> |
| 798 | + * On a mismatch the failure reports both the patterns that found no match and the actual |
| 799 | + * names that found no pattern, so a "missing row" or "extra row" failure is immediately |
| 800 | + * diagnosable instead of just a "wrong count" error. |
| 801 | + * </p> |
| 802 | + * <p> |
| 803 | + * This method was generated by Claude. |
| 804 | + * </p> |
| 805 | + */ |
789 | 806 | private void validateNamesGenerated(List<String> actualNames, List<String> expectedNames) |
790 | 807 | { |
| 808 | + checker().verifyEquals("Number of samples not as expected.", |
| 809 | + expectedNames.size(), actualNames.size()); |
791 | 810 |
|
792 | | - if (checker().verifyEquals("Number of samples not as expected.", |
793 | | - expectedNames.size(), actualNames.size())) |
| 811 | + List<String> unmatchedActuals = new ArrayList<>(actualNames); |
| 812 | + List<String> unmatchedPatterns = new ArrayList<>(); |
| 813 | + for (String pattern : expectedNames) |
794 | 814 | { |
795 | | - for (int i = 0; i < expectedNames.size(); i++) |
796 | | - { |
797 | | - String expectedPattern = expectedNames.get(i); |
798 | | - String actual = actualNames.get(i); |
799 | | - |
800 | | - checker().verifyTrue(String.format( |
801 | | - "Name at index %d did not match. Expected pattern: [%s] Actual: [%s]", |
802 | | - i, expectedPattern, actual), |
803 | | - Pattern.matches(expectedPattern, actual)); |
804 | | - } |
| 815 | + Optional<String> match = unmatchedActuals.stream() |
| 816 | + .filter(a -> Pattern.matches(pattern, a)) |
| 817 | + .findFirst(); |
| 818 | + if (match.isPresent()) |
| 819 | + unmatchedActuals.remove(match.get()); |
| 820 | + else |
| 821 | + unmatchedPatterns.add(pattern); |
805 | 822 | } |
806 | 823 |
|
| 824 | + checker().verifyTrue("Expected patterns with no matching actual name: " + unmatchedPatterns, |
| 825 | + unmatchedPatterns.isEmpty()); |
| 826 | + checker().verifyTrue("Actual names not matching any expected pattern (extras): " + unmatchedActuals, |
| 827 | + unmatchedActuals.isEmpty()); |
| 828 | + |
807 | 829 | checker().screenShotIfNewError("Generated_Names_Error"); |
808 | 830 | } |
809 | 831 |
|
|
0 commit comments