return start + (Math.abs(rand.nextInt())%(limit-start)) ;
}
public void styleTest() {
MText text = new StyledText("0123456789", AttributeMap.EMPTY_ATTRIBUTE_MAP);
AttributeMap[] styles = new AttributeMap[text.length()];
for (int i=0; i < styles.length; i++) {
styles[i] = AttributeMap.EMPTY_ATTRIBUTE_MAP;
}
AttributeMap[] oldStyles = new AttributeMap[styles.length];
System.arraycopy(styles, 0, oldStyles, 0, styles.length);
AttributeMap bigStyle = new AttributeMap(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON).
addAttribute(TextAttribute.SIZE, new Float(23.0f));
StyleModifier[] modifiers = {
StyleModifier.createReplaceModifier(new AttributeMap(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD)),
StyleModifier.createAddModifier(new AttributeMap(TextAttribute.WEIGHT, new Float(1.0f))),
createMinusModifier(TextAttribute.WEIGHT),
StyleModifier.createAddModifier(new AttributeMap(TextAttribute.POSTURE, new Float(0.0f))),
StyleModifier.createReplaceModifier(new AttributeMap(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE)),
createMinusModifier(TextAttribute.POSTURE),
StyleModifier.createAddModifier(bigStyle),
StyleModifier.createReplaceModifier(bigStyle),
createMinusModifier(bigStyle.getKeySet())
};
Random rand = new Random(RAND_SEED);
final int stopAt = 4;
for (int testItr=0; testItr < STYLE_TEST_ITERATIONS + 1; testItr++) {
System.arraycopy(styles, 0, oldStyles, 0, styles.length);
int startingAt = Integer.MAX_VALUE;
int endingAt = Integer.MIN_VALUE;
int oldTs = text.getTimeStamp();
// hack way to do an invariant check before starting...
if (testItr != 0) {
// modify styles
text.resetDamagedRange();
startingAt = randInt(rand, styles.length+1);
endingAt = randInt(rand, startingAt, styles.length+1);
StyleModifier modifier = modifiers[randInt(rand, modifiers.length)];
if (testItr == stopAt) {
testItr = stopAt;
}
text.modifyCharacterStyles(startingAt, endingAt, modifier);
for (int j=startingAt; j < endingAt; j++) {
styles[j] = modifier.modifyStyle(styles[j]);
}
}
// check invariants
AttributeMap oldStyle = null;
int textLength = text.length();
for (int runStart = 0; runStart < textLength;) {
AttributeMap currentStyle = text.characterStyleAt(runStart);
int runLimit = text.characterStyleLimit(runStart);
if (runStart >= runLimit) {
errln("Run length is not positive");
}
if (currentStyle.equals(oldStyle)) {
errln("Styles didn't merge");
}
for (int pos=runStart; pos < runLimit; pos++) {
AttributeMap charStyleAtPos = text.characterStyleAt(pos);
if (currentStyle != charStyleAtPos) {
errln("Iterator style is not equal to text style at " + pos + ".");
}
AttributeMap expected = styles[pos];
if (!currentStyle.equals(expected)) {
errln("Iterator style doesn't match expected style at " + pos + ".");
}
if (!(text.characterStyleStart(pos) == runStart) ||
!(text.characterStyleLimit(pos) == runLimit)) {
errln("style run start / limit is not consistent");
}
}
runStart = runLimit;
}
if (textLength > 0) {
if (text.characterStyleAt(textLength) !=
text.characterStyleAt(textLength-1)) {
errln("Character styles at end aren't the same");
}
}
// check damaged range:
int damageStart = Integer.MAX_VALUE;
int damageLimit = Integer.MIN_VALUE;
for (int i=0; i < textLength; i++) {
if (!styles[i].equals(oldStyles[i])) {
damageStart = Math.min(i, damageStart);
damageLimit = Math.max(i+1, damageLimit);
}
}
if (damageStart != text.damagedRangeStart() ||
damageLimit != text.damagedRangeLimit()) {
logln("Test iteration: " + testItr);
logln("startingAt: " + startingAt + "; endingAt: " + endingAt);
logln("damageStart: " + damageStart + "; damageLimit: " + damageLimit);
logln("text.rangeStart: " + text.damagedRangeStart() +
"text.rangeLimit: " + text.damagedRangeLimit());
errln("Damage range start or limit is not expected value");
}
if ((damageLimit == Integer.MIN_VALUE) != (oldTs == text.getTimeStamp())) {
errln("timeStamp is incorrect");
}
}
}