From 2712ad22eb971d670c7146b962f1f6d266660cd6 Mon Sep 17 00:00:00 2001 From: Daria Bodiakova <70635654+DariaBod@users.noreply.github.com> Date: Tue, 31 Mar 2026 16:27:33 -0700 Subject: [PATCH 1/3] tests for multi ancestor fixes for mvtc values in other tests bitmaskSelect for selecting mvtc values --- .../labkey/test/util/TestDataGenerator.java | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/org/labkey/test/util/TestDataGenerator.java b/src/org/labkey/test/util/TestDataGenerator.java index 6f10582645..1df4ccea2a 100644 --- a/src/org/labkey/test/util/TestDataGenerator.java +++ b/src/org/labkey/test/util/TestDataGenerator.java @@ -52,6 +52,7 @@ import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; +import java.util.BitSet; import java.util.Calendar; import java.util.Collections; import java.util.Date; @@ -67,6 +68,7 @@ import java.util.function.Function; import java.util.function.Supplier; import java.util.regex.Pattern; +import java.util.stream.Collectors; import static org.labkey.test.BaseWebDriverTest.ALL_ILLEGAL_QUERY_KEY_CHARACTERS; import static org.labkey.test.util.data.TestDataUtils.REALISTIC_ASSAY_FIELDS; @@ -188,7 +190,10 @@ else if (fieldDefinition.getType().equals(FieldDefinition.ColumnType.MultiValueT { FieldDefinition.TextChoiceValidator validator = (FieldDefinition.TextChoiceValidator) fieldDefinition.getValidators().getFirst(); - List values = shuffleSelect(validator.getValues()); + // Use i + 1 as a bitmask so each row gets a deterministic, non-empty subset of choices, + // consistent with how other field types (Integer, Boolean, TextChoice) use i for predictable data. + // Salt with queryName hash so different entity types produce distinct MVTC values at the same row index. + List values = bitmaskSelect(validator.getValues(), i + 1, queryName.hashCode()); entityData.put(key, values); } } @@ -1000,6 +1005,23 @@ public static List shuffleSelect(List allFields, int selectCount) return shuffled.subList(0, selectCount); } + /** + * Selects elements by index using {@code bitmask}: bit N set → include element N. Supports up to 32 elements. + * XORs the bitmask with {@code salt} so that callers with the same bitmask (e.g. same row index) produce + * different selections. + */ + public static List bitmaskSelect(List allElements, int bitmask, int salt) + { + int n = allElements.size(); + int validMask = n < 32 ? (1 << n) - 1 : Integer.MAX_VALUE; + int effective = (bitmask ^ salt) & validMask; + if (effective == 0) + effective = bitmask & validMask; + return BitSet.valueOf(new long[]{effective}).stream() + .mapToObj(allElements::get) + .collect(Collectors.toList()); + } + public static List randomSelect(List allOptions, int selectCount) { List selected = new ArrayList<>(); From c71e9d3b4db6c98bfb2164e12429a5b4af81e78e Mon Sep 17 00:00:00 2001 From: Daria Bodiakova <70635654+DariaBod@users.noreply.github.com> Date: Tue, 7 Apr 2026 11:24:23 -0700 Subject: [PATCH 2/3] fix comments fix test --- src/org/labkey/test/params/FieldDefinition.java | 5 +++++ src/org/labkey/test/util/data/TestArrayDataUtils.java | 7 ++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/org/labkey/test/params/FieldDefinition.java b/src/org/labkey/test/params/FieldDefinition.java index 0336d68b51..9b7c94efe6 100644 --- a/src/org/labkey/test/params/FieldDefinition.java +++ b/src/org/labkey/test/params/FieldDefinition.java @@ -498,6 +498,11 @@ public void setNamePart(String namePart) _namePart = namePart; } + public String getNamePart() + { + return _namePart; + } + public boolean isNamePartMatch(String namePart) { return _namePart != null && _namePart.equals(namePart); diff --git a/src/org/labkey/test/util/data/TestArrayDataUtils.java b/src/org/labkey/test/util/data/TestArrayDataUtils.java index 7509828bdb..deaf7fa81b 100644 --- a/src/org/labkey/test/util/data/TestArrayDataUtils.java +++ b/src/org/labkey/test/util/data/TestArrayDataUtils.java @@ -62,6 +62,7 @@ public static List sortValues(List values) .sorted(Comparator .comparing((String s) -> s.substring(0, 1).toLowerCase()) .thenComparing(s -> s.substring(0, 1)) + .thenComparing(String.CASE_INSENSITIVE_ORDER) .thenComparing(s -> s)) .collect(Collectors.toList()); } @@ -90,7 +91,7 @@ public static Map filterAndPrepareMap(Map map, Li return prepareMapForCheck(filterMap(map, searchValues, filterType)); } - public static List parseMultiValueText(String multiValueString) throws IOException + public static List parseMultiValueText(String multiValueString) { CSVFormat format = CSVFormat.RFC4180.builder() .setIgnoreSurroundingSpaces(true).setTrim(true).get(); @@ -101,6 +102,10 @@ public static List parseMultiValueText(String multiValueString) throws I throw new IllegalArgumentException("Invalid multi-value text string: " + multiValueString); return records.getFirst().toList(); } + catch (IOException e) + { + throw new IllegalArgumentException(e); + } } public static String formatMultiValueText(List values) From c041958f57c044092634136805aed51809b9206c Mon Sep 17 00:00:00 2001 From: Daria Bodiakova <70635654+DariaBod@users.noreply.github.com> Date: Tue, 7 Apr 2026 16:09:01 -0700 Subject: [PATCH 3/3] fix comment --- src/org/labkey/test/params/FieldDefinition.java | 5 ----- src/org/labkey/test/params/FieldInfo.java | 6 ++++++ 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/org/labkey/test/params/FieldDefinition.java b/src/org/labkey/test/params/FieldDefinition.java index 9b7c94efe6..0336d68b51 100644 --- a/src/org/labkey/test/params/FieldDefinition.java +++ b/src/org/labkey/test/params/FieldDefinition.java @@ -498,11 +498,6 @@ public void setNamePart(String namePart) _namePart = namePart; } - public String getNamePart() - { - return _namePart; - } - public boolean isNamePartMatch(String namePart) { return _namePart != null && _namePart.equals(namePart); diff --git a/src/org/labkey/test/params/FieldInfo.java b/src/org/labkey/test/params/FieldInfo.java index 33b09edfd2..9ddcf15ddb 100644 --- a/src/org/labkey/test/params/FieldInfo.java +++ b/src/org/labkey/test/params/FieldInfo.java @@ -146,6 +146,12 @@ public String getName() return _fieldKey.getName(); } + @Contract(pure = true) + public String getNamePart() + { + return _namePart; + } + /** * Get column name quoted for use in queries and calculated field expressions */