Skip to content

Commit 3309266

Browse files
authored
Fix failed builds (#2981)
#### Rationale computeIfAbsent cause NullPointerException. #### Related Pull Requests - <!-- list of links to related pull requests (replace this comment) --> #### Changes - <!-- list of descriptions of changes that are worth noting (replace this comment) -->
1 parent decb1b7 commit 3309266

1 file changed

Lines changed: 66 additions & 5 deletions

File tree

src/org/labkey/test/util/TestDataGenerator.java

Lines changed: 66 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,9 @@
6262
import java.util.List;
6363
import java.util.Map;
6464
import java.util.Objects;
65+
import java.util.Optional;
6566
import java.util.Set;
67+
import java.util.TreeSet;
6668
import java.util.concurrent.ThreadLocalRandom;
6769
import java.util.function.Function;
6870
import java.util.function.Supplier;
@@ -431,7 +433,10 @@ private Map<String, Object> generateRow()
431433
final Map<String, Object> newRow = new CaseInsensitiveHashMap<>();
432434
for (String columnName : _columns.keySet())
433435
{
434-
_dataSuppliers.computeIfAbsent(columnName, k -> getDefaultDataSupplier(_columns.get(k)));
436+
if (!_dataSuppliers.containsKey(columnName))
437+
{
438+
_dataSuppliers.put(columnName, getDefaultDataSupplier(_columns.get(columnName)));
439+
}
435440

436441
if (_autoGeneratedFields.contains(columnName))
437442
{
@@ -622,22 +627,78 @@ public static String randomDomainName(@Nullable String namePart, @Nullable Integ
622627
namePart = namePart == null ? "" : namePart;
623628
DomainKind _domainKind = domainKind == null ? DomainKind.SampleSet : domainKind;
624629
String charSet = ALPHANUMERIC_STRING + DOMAIN_SPECIAL_STRING;
630+
// Excluded characters for generation, spaces excluded for correct insertSpaces work
631+
String exclusion = " ";
625632
int currentTries = 0;
626-
RandomName randomName = randomName(namePart, getNumChars(numStartChars, 5), getNumChars(numEndChars, 50), charSet, null);
633+
RandomName randomName = randomName(namePart, getNumChars(numStartChars, 5), getNumChars(numEndChars, 50), charSet, exclusion);
627634
while (isDomainAndFieldNameInvalid(_domainKind, randomName, null))
628635
{
629-
randomName = randomName(namePart, getNumChars(numStartChars, 5), getNumChars(numEndChars, 50), charSet, null);
636+
randomName = randomName(namePart, getNumChars(numStartChars, 5), getNumChars(numEndChars, 50), charSet, exclusion);
630637
if (++currentTries >= MAX_RANDOM_TRIES)
631638
throw new IllegalStateException("Failed to generate a valid domain name after " + MAX_RANDOM_TRIES + " tries. Last generated name: " + randomName);
632639
}
633640

634-
// Multiple spaces in the UI are collapsed into a single space. If we need to test for handling of multiple spaces, we'll not use this generator
635-
String domainName = randomName.name().replaceAll("\\s+", " ");
641+
// Insert spaces every 8 chars (skipped for short names) and always one immediately before and after namePart.
642+
String domainName = insertSpaces(randomName.name(), namePart);
636643

637644
TestLogger.log("Generated random domain name for domainKind " + _domainKind + ": " + domainName);
638645
return domainName;
639646
}
640647

648+
/**
649+
* Insert single spaces around {@code namePart} and at every 8th char (when {@code base.length() > 6}),
650+
* snapping inside-namePart positions to the nearest boundary. Skips any insertion that would land at
651+
* an edge, create a double space, or form a "space-dash-non-space" pattern.
652+
*/
653+
private static String insertSpaces(String base, String namePart)
654+
{
655+
int npStart = namePart.isEmpty() ? -1 : base.indexOf(namePart);
656+
int npEnd = npStart < 0 ? -1 : npStart + namePart.length();
657+
658+
// Indices in base before which a single space will be inserted. TreeSet auto-sorts and dedupes.
659+
Set<Integer> positions = new TreeSet<>();
660+
661+
// Mandatory: immediately before and after namePart.
662+
addIfSafe(positions, base, npStart);
663+
addIfSafe(positions, base, npEnd);
664+
665+
// Every-8-chars step; positions strictly inside namePart snap to the nearest boundary.
666+
if (base.length() > 6)
667+
{
668+
for (int p = 8; p < base.length(); p += 8)
669+
{
670+
int snapped = p;
671+
if (npStart >= 0 && p > npStart && p < npEnd)
672+
snapped = (npEnd - p) <= (p - npStart) ? npEnd : npStart;
673+
addIfSafe(positions, base, snapped);
674+
}
675+
}
676+
677+
// Drop positions that would form " -X" (space, dash, non-space). A dash followed by another
678+
// inserted space — or by end of string — is fine.
679+
positions.removeIf(p -> base.charAt(p) == '-'
680+
&& p + 1 < base.length()
681+
&& !positions.contains(p + 1)
682+
&& base.charAt(p + 1) != ' ');
683+
684+
StringBuilder sb = new StringBuilder(base.length() + positions.size());
685+
for (int i = 0; i < base.length(); i++)
686+
{
687+
if (positions.contains(i))
688+
sb.append(' ');
689+
sb.append(base.charAt(i));
690+
}
691+
return sb.toString();
692+
}
693+
694+
/** Add {@code p} to {@code positions} only if inserting a space at {@code p} won't be at an edge of
695+
* {@code base} or sit next to an already-existing space (which would form a double space). */
696+
private static void addIfSafe(Set<Integer> positions, String base, int p)
697+
{
698+
if (p > 0 && p < base.length() && base.charAt(p - 1) != ' ' && base.charAt(p) != ' ')
699+
positions.add(p);
700+
}
701+
641702
private static int getNumChars(Integer val, int max)
642703
{
643704
return val != null ? val : randomInt(0, max);

0 commit comments

Comments
 (0)