sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1405499 - in /sis/branches/JDK7/sis-utility/src: main/java/org/apache/sis/measure/AngleFormat.java main/java/org/apache/sis/measure/FormattedCharacterIterator.java test/java/org/apache/sis/measure/FormattedCharacterIteratorTest.java
Date Sun, 04 Nov 2012 04:49:09 GMT
Author: desruisseaux
Date: Sun Nov  4 04:49:08 2012
New Revision: 1405499

URL: http://svn.apache.org/viewvc?rev=1405499&view=rev
Log:
AngleFormat now includes all NumberFormat attributes when formatting AttributedCharacterIterator.
This commit also makes our AttributedCharacterIterator more compliant with the java.text contract,
since we also need to check for run limits when the current character does *not* contain the
requested
attribute.

Modified:
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/measure/AngleFormat.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/measure/FormattedCharacterIterator.java
    sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/measure/FormattedCharacterIteratorTest.java

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/measure/AngleFormat.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/measure/AngleFormat.java?rev=1405499&r1=1405498&r2=1405499&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/measure/AngleFormat.java (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/measure/AngleFormat.java Sun
Nov  4 04:49:08 2012
@@ -292,12 +292,12 @@ public class AngleFormat extends Format 
     private transient NumberFormat numberFormat;
 
     /**
-     * Object to give to {@code DecimalFormat.format} methods in order to get the position
-     * of the integer part. Cached in order to avoid recreating this object too often.
+     * Object to give to {@code DecimalFormat.format} methods,
+     * cached in order to avoid recreating this object too often.
      *
-     * @see #integerFieldPosition()
+     * @see #dummyFieldPosition()
      */
-    private transient FieldPosition integerFieldPosition;
+    private transient FieldPosition dummyFieldPosition;
 
     /**
      * A temporary variable which may be set to the character iterator for which the
@@ -320,13 +320,13 @@ public class AngleFormat extends Format 
     }
 
     /**
-     * Returns the field position for the integer part of numeric values.
+     * Returns the dummy field position.
      */
-    private FieldPosition integerFieldPosition() {
-        if (integerFieldPosition == null) {
-            integerFieldPosition = new FieldPosition(NumberFormat.INTEGER_FIELD);
+    private FieldPosition dummyFieldPosition() {
+        if (dummyFieldPosition == null) {
+            dummyFieldPosition = new FieldPosition(NumberFormat.INTEGER_FIELD);
         }
-        return integerFieldPosition;
+        return dummyFieldPosition;
     }
 
     /**
@@ -803,7 +803,7 @@ scan:   for (int i=0; i<length;) {
         final int offset = toAppendTo.length();
         final int fieldPos = getField(pos);
         if (isNaN(angle) || isInfinite(angle)) {
-            toAppendTo = numberFormat().format(angle, toAppendTo, integerFieldPosition());
+            toAppendTo = numberFormat().format(angle, toAppendTo, dummyFieldPosition());
             if (fieldPos >= DEGREES_FIELD && fieldPos <= SECONDS_FIELD) {
                 pos.setBeginIndex(offset);
                 pos.setEndIndex(toAppendTo.length());
@@ -855,6 +855,8 @@ scan:   for (int i=0; i<length;) {
         }
         /*
          * Formats fields in a loop from DEGREES_FIELD to SECONDS_FIELD inclusive.
+         * The first part of the loop will configure the NumberFormat, but without
+         * writing anything yet (ignoring the prefix written before the loop).
          */
         int field = DEGREES_FIELD;
         if (prefix != null) {
@@ -872,11 +874,9 @@ scan:   for (int i=0; i<length;) {
                 case SECONDS_FIELD: value=seconds; width=secondsFieldWidth; suffix=secondsSuffix;
hasMore=false; break;
                 default: throw new AssertionError(field);
             }
-            final int startPosition = toAppendTo.length();
             if (hasMore) {
                 numberFormat.setMinimumIntegerDigits(width);
                 numberFormat.setMaximumFractionDigits(0);
-                toAppendTo = numberFormat.format(value, toAppendTo, integerFieldPosition());
             } else if (useDecimalSeparator) {
                 numberFormat.setMinimumIntegerDigits(width);
                 if (maximumTotalWidth != 0) {
@@ -899,26 +899,35 @@ scan:   for (int i=0; i<length;) {
                 }
                 numberFormat.setMinimumFractionDigits(minimumFractionDigits);
                 numberFormat.setMaximumFractionDigits(maximumFractionDigits);
-                toAppendTo = numberFormat.format(value, toAppendTo, integerFieldPosition());
             } else {
                 value *= pow10(fractionFieldWidth);
                 numberFormat.setMaximumFractionDigits(0);
                 numberFormat.setMinimumIntegerDigits(width + fractionFieldWidth);
-                toAppendTo = numberFormat.format(value, toAppendTo, integerFieldPosition());
             }
-            if (suffix != null) {
-                toAppendTo.append(suffix);
+            /*
+             * At this point, we known the value to format and the NumberFormat instance
has been
+             * configured. If the user asked for an attributed character iterator and assuming
that
+             * we want also the attributes produced by the NumberFormat, then we have to
invoke the
+             * heavy formatToCharacterIterator(…). Otherwise the usual format(…)
method fits well.
+             */
+            final int startPosition = toAppendTo.length();
+            if (characterIterator instanceof FormattedCharacterIterator) {
+                final FormattedCharacterIterator it = (FormattedCharacterIterator) characterIterator;
+                it.append(numberFormat.formatToCharacterIterator(value), toAppendTo);
+                if (suffix != null) {
+                    toAppendTo.append(suffix);
+                }
+                it.addFieldLimit(Field.forCode(field), Integer.valueOf((int) value), startPosition);
+            } else {
+                toAppendTo = numberFormat.format(value, toAppendTo, dummyFieldPosition());
+                if (suffix != null) {
+                    toAppendTo.append(suffix);
+                }
             }
             if (field == fieldPos) {
                 pos.setBeginIndex(startPosition);
                 pos.setEndIndex(toAppendTo.length());
             }
-            if (characterIterator instanceof FormattedCharacterIterator) {
-                final Integer integerPart = Integer.valueOf((int) value);
-                final FormattedCharacterIterator it = (FormattedCharacterIterator) characterIterator;
-                it.addField(Field.forCode(field), integerPart, startPosition, toAppendTo.length());
-                it.addField(NumberFormat.Field.INTEGER, integerPart, integerFieldPosition);
-            }
             field++;
         } while (hasMore);
         return toAppendTo;
@@ -988,8 +997,8 @@ scan:   for (int i=0; i<length;) {
             pos.setEndIndex(toAppendTo.length());
         }
         if (characterIterator instanceof FormattedCharacterIterator) {
-            ((FormattedCharacterIterator) characterIterator).addField(
-                    Field.HEMISPHERE, suffix, startPosition, toAppendTo.length());
+            ((FormattedCharacterIterator) characterIterator).addFieldLimit(
+                    Field.HEMISPHERE, suffix, startPosition);
         }
         return toAppendTo;
     }
@@ -1010,6 +1019,27 @@ scan:   for (int i=0; i<length;) {
      *     }
      * }
      *
+     * Alternatively, if the current {@linkplain AttributedCharacterIterator#getIndex() iterator
+     * index} is before the start of the minutes field, then the starting position of that
field
+     * can be obtained directly by {@code it.getRunLimit(MINUTES)}. If the current iterator
index
+     * is inside the minutes field, then the above method call will rather returns the end
of that
+     * field. The same strategy works for other all fields too.
+     *
+     * <p>The returned character iterator contains all {@link java.text.NumberFormat.Field}
+     * attributes in addition to the {@link Field} ones. Consequently the same character
may
+     * have more than one attribute. For example when formatting 45°30′15.0″N,
then:</p>
+     *
+     * <ul>
+     *   <li>The {@code 45°}   part has the {@link Field#DEGREES} attribute.</li>
+     *   <li>The {@code 30′}   part has the {@link Field#MINUTES} attribute.</li>
+     *   <li>The {@code 15.0″} part has the {@link Field#SECONDS} attribute.</li>
+     *   <li>The {@code N}     part has the {@link Field#HEMISPHERE} attribute.</li>
+     *   <li>The {@code 45}, {@code 30} and {@code 15} parts have the
+     *       {@link java.text.NumberFormat.Field#INTEGER} attribute.</li>
+     *   <li>The {@code .} part has the {@link java.text.NumberFormat.Field#DECIMAL_SEPARATOR}
attribute.</li>
+     *   <li>The last {@code 0} part has the {@link java.text.NumberFormat.Field#FRACTION}
attribute.</li>
+     * </ul>
+     *
      * In Apache SIS implementation, the returned character iterator also implements the
      * {@link CharSequence} interface for convenience.
      *
@@ -1583,7 +1613,7 @@ BigBoss:    switch (skipSuffix(source, p
     public AngleFormat clone() {
         final AngleFormat clone = (AngleFormat) super.clone();
         clone.numberFormat = null;
-        clone.integerFieldPosition = null;
+        clone.dummyFieldPosition = null;
         return clone;
     }
 

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/measure/FormattedCharacterIterator.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/measure/FormattedCharacterIterator.java?rev=1405499&r1=1405498&r2=1405499&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/measure/FormattedCharacterIterator.java
(original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/measure/FormattedCharacterIterator.java
Sun Nov  4 04:49:08 2012
@@ -24,7 +24,6 @@ import java.util.IdentityHashMap;
 import java.util.Map;
 import java.util.Set;
 import java.text.Format;
-import java.text.FieldPosition;
 import java.text.AttributedCharacterIterator;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.internal.util.SurjectiveConverter;
@@ -161,26 +160,40 @@ final class FormattedCharacterIterator e
     }
 
     /**
-     * Adds the run range, together with the value, for a given field in the formatted text.
-     * Callers shall avoid adding the same (<var>field</var>, <var>value</var>)
pair in two
-     * or more juxtaposed fields if possible, since it may cause a violation of the
-     * {@link java.text.AttributedCharacterIterator} contract in current implementation.
-     * See the class javadoc for details.
-     */
-    final void addField(final Attribute field, final Object value, final int start, final
int limit) {
-        upper = text.length(); // Update for new charaters added in the StringBuffer since
last call.
-        assert (start >= lower) && (limit >= start) && (limit <=
upper) : limit;
-        Entry e = new Entry(field, value, start, limit, attributes); // Constructor adds
itself to the map.
+     * Invoked by {@code Format} implementations when a field ended. This method stores the
+     * given attribute value for the run ranging from {@code start} inclusive to the current
+     * {@linkplain #text} length, exclusive.
+     */
+    final void addFieldLimit(final Attribute field, final Object value, final int start)
{
+        // The Entry constructor adds itself to the attributes map.
+        // The returned intance is used only for assertions checks.
+        Entry e = new Entry(field, value, start, upper = text.length(), attributes);
         assert ((e = e.previous) == null) || (start >= e.limit); // Check for non-overlapping
fields.
     }
 
     /**
-     * Same as {@link #addField(Attribute, Object, int, int)}, but extracting the {@code
start} and
-     * {@code limit} values from the given {@link FieldPosition}. This is a convenience method
for
-     * the formatters which delegate part of their work to another formatter.
+     * Appends all characters and attributes from the given iterator.
+     *
+     * @param toAppendTo Shall be the same instance than {@link #text}.
      */
-    final void addField(final Attribute field, final Object value, final FieldPosition pos)
{
-        addField(field, value, pos.getBeginIndex(), pos.getEndIndex());
+    final void append(final AttributedCharacterIterator it, final StringBuffer toAppendTo)
{
+        final int offset = toAppendTo.length();
+        int currentRunLimit = 0; // Next index where to check for attributes.
+        for (char c=it.first(); c!=DONE; c=it.next()) {
+            toAppendTo.append(c);
+            if (it.getIndex() == currentRunLimit) {
+                currentRunLimit = it.getRunLimit();
+                for (final Map.Entry<Attribute,Object> entry : it.getAttributes().entrySet())
{
+                    final Attribute attribute = entry.getKey();
+                    if (it.getRunLimit(attribute) == currentRunLimit) {
+                        new Entry(attribute, entry.getValue(), // Constructeur adds itself
to the map.
+                                offset + it.getRunStart(attribute),
+                                offset + currentRunLimit, attributes);
+                    }
+                }
+            }
+        }
+        upper = toAppendTo.length();
     }
 
     /**
@@ -206,13 +219,25 @@ final class FormattedCharacterIterator e
                 }
             }
             for (Entry entry : entries) {
+                Entry notFound = entry;
                 while (entry != null) {
                     if (index >= entry.start && index < entry.limit) {
                         if (entry.start > start) start = entry.start;
                         if (entry.limit < limit) limit = entry.limit;
+                        notFound = null; // Found the attribute.
                     }
                     entry = entry.previous;
                 }
+                /*
+                 * If the attribute has not been found for the current character position,
+                 * then we need to reverse the condition: if the attribute become defined
+                 * in another position, we must stop the run at that position.
+                 */
+                while (notFound != null) {
+                    if (notFound.start >  index && notFound.start < limit)
limit = notFound.start;
+                    if (notFound.limit <= index && notFound.limit > start)
start = notFound.limit;
+                    notFound = notFound.previous;
+                }
             }
         }
     }

Modified: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/measure/FormattedCharacterIteratorTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/measure/FormattedCharacterIteratorTest.java?rev=1405499&r1=1405498&r2=1405499&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/measure/FormattedCharacterIteratorTest.java
(original)
+++ sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/measure/FormattedCharacterIteratorTest.java
Sun Nov  4 04:49:08 2012
@@ -22,9 +22,14 @@ import java.util.HashSet;
 import java.text.AttributedCharacterIterator;
 import org.apache.sis.test.TestCase;
 import org.apache.sis.test.DependsOnMethod;
+import org.apache.sis.internal.simple.SimpleCharacterIterator;
 import org.junit.Test;
 
+import static java.lang.StrictMath.min;
+import static java.lang.StrictMath.max;
 import static java.text.NumberFormat.Field.INTEGER;
+import static java.text.NumberFormat.Field.FRACTION;
+import static java.text.NumberFormat.Field.DECIMAL_SEPARATOR;
 import static java.text.AttributedCharacterIterator.DONE;
 import static java.text.AttributedCharacterIterator.Attribute;
 import static org.apache.sis.measure.AngleFormat.Field.*;
@@ -87,7 +92,7 @@ public final strictfp class FormattedCha
      */
     @Test
     public void testNonOverlappingAttributes() {
-        testAttributes(false);
+        testAttributes(new LatitudeString().iterator(false), false);
     }
 
     /**
@@ -98,7 +103,7 @@ public final strictfp class FormattedCha
     @Test
     @DependsOnMethod("testNonOverlappingAttributes")
     public void testOverlappingAttributes() {
-        testAttributes(true);
+        testAttributes(new LatitudeString().iterator(true), true);
     }
 
     /**
@@ -114,26 +119,41 @@ public final strictfp class FormattedCha
         assertTrue(keys.add(HEMISPHERE));
         if (overlapping) {
             assertTrue(keys.add(INTEGER));
+            assertTrue(keys.add(FRACTION));
+            assertTrue(keys.add(DECIMAL_SEPARATOR));
         }
         return keys;
     }
 
     /**
-     * Tests an iteration with attributes, optionally having {@code INTEGER} attributes
-     * overlapping the {@code DEGREES}/{@code MINUTES}/{@code SECONDS} ones.
-     */
-    private static void testAttributes(final boolean overlapping) {
-        final FormattedCharacterIterator it = new FormattedCharacterIterator(LATITUDE_STRING);
-        it.addField(DEGREES,     45,  0,  3);
-        it.addField(MINUTES,     30,  3,  6);
-        it.addField(SECONDS,     15,  6, 11);
-        it.addField(HEMISPHERE, 'N', 11, 12);
-        if (overlapping) {
-            it.addField(INTEGER, 45,  0,  2);
-            it.addField(INTEGER, 30,  3,  5);
-            it.addField(INTEGER, 15,  6,  8);
+     * The {@value FormattedCharacterIteratorTest#LATITUDE_STRING} character string
+     * with attributes. Built in a sub-class of {@link SimpleCharacterIterator} in
+     * order to have access to the protected {@link #upper} field.
+     */
+    @SuppressWarnings("serial")
+    private static class LatitudeString extends SimpleCharacterIterator {
+        LatitudeString() {
+            super(LATITUDE_STRING);
+        }
+
+        /**
+         * Creates and returns an attributed {@link FormattedCharacterIterator}
+         * with the attributes.
+         */
+        FormattedCharacterIterator iterator(final boolean o) {
+            final FormattedCharacterIterator it = new FormattedCharacterIterator(this);
+            int start=0; upper= 2; if (o) it.addFieldLimit(INTEGER,            45, start);
+                         upper= 3;        it.addFieldLimit(DEGREES,            45, start);
+            start=upper; upper= 5; if (o) it.addFieldLimit(INTEGER,            30, start);
+                         upper= 6;        it.addFieldLimit(MINUTES,            30, start);
+            start=upper; upper= 8; if (o) it.addFieldLimit(INTEGER,            15, start);
+            start=upper; upper= 9; if (o) it.addFieldLimit(DECIMAL_SEPARATOR, '.', start);
+            start=upper; upper=10; if (o) it.addFieldLimit(FRACTION,            0, start);
+            start=6;     upper=11;        it.addFieldLimit(SECONDS,            15, start);
+            start=upper; upper=12;        it.addFieldLimit(HEMISPHERE,        'N', start);
+            assertEquals(text.length(), upper);
+            return it;
         }
-        testAttributes(it, overlapping);
     }
 
     /**
@@ -146,37 +166,85 @@ public final strictfp class FormattedCha
     @SuppressWarnings("fallthrough")
     static void testAttributes(final AttributedCharacterIterator it, final boolean overlapping)
{
         assertEquals(getAllAttributeKeys(overlapping), it.getAllAttributeKeys());
+        assertEquals(0, it.getIndex());
+        assertEquals(3, it.getRunLimit(MINUTES));
+        assertEquals(6, it.getRunLimit(SECONDS));
+
         for (char c=it.first(); c!=DONE; c=it.next()) {
+            final int index = it.getIndex();
             final AngleFormat.Field key;
             final Comparable<?> value;
             final int start, limit;
-            int oi = 0; // How many characters to remove for having the limit of the integer
field.
-            switch (it.getIndex()) {
-                case  0: assertEquals('4', c); // Beginning of 45°
-                case  1: oi = overlapping ? 1 : 0;
-                case  2: key=DEGREES;    value= 45; start=0; limit= 3; break;
-                case  3: assertEquals('3', c); // Beginning of 30′
-                case  4: oi = overlapping ? 1 : 0;
-                case  5: key=MINUTES;    value= 30; start=3; limit= 6; break;
-                case  6: assertEquals('1', c); // Beginning of 15.0″
-                case  7: oi = overlapping ? 3 : 0;
-                case  8:
-                case  9:
-                case 10: key=SECONDS;    value= 15; start= 6; limit=11; break;
-                case 11: key=HEMISPHERE; value='N'; start=11; limit=12; break;
-                default: throw new AssertionError();
+                 if (index <  3) {key=DEGREES;    value= 45; start= 0; limit= 3;}
+            else if (index <  6) {key=MINUTES;    value= 30; start= 3; limit= 6;}
+            else if (index < 11) {key=SECONDS;    value= 15; start= 6; limit=11;}
+            else                 {key=HEMISPHERE; value='N'; start=11; limit=12;}
+            /*
+             * Expected values when asking for a NumberFormat field.
+             * Initialized to the values when no such field exists,
+             * then updated if overlapping fields are allowed.
+             */
+            boolean isInteger      = false;
+            boolean isSeparator    = false;
+            boolean isFraction     = false;
+            int     startInteger   =  0;
+            int     limitInteger   = 12;
+            int     startSeparator =  0;
+            int     limitSeparator = 12;
+            int     startFraction  =  0;
+            int     limitFraction  = 12;
+            int     numAttributes  =  1;
+            if (overlapping) {
+                /*
+                 * Update the above expected values when the current position
+                 * is inside a NumberFormat field.
+                 */
+                switch (index) {
+                    case 0: case 1: // Degrees
+                    case 3: case 4: // Minutes
+                    case 6: case 7: isInteger   = true; numAttributes = 2; startInteger =
start; limitInteger   =  2+start; break;
+                    case 8:         isSeparator = true; numAttributes = 2; startSeparator
= 8;   limitSeparator =  9; break;
+                    case 9:         isFraction  = true; numAttributes = 2; startFraction
 = 9;   limitFraction  = 10; break;
+                }
+                /*
+                 * Update the expected values for fields which are not at the current position.
+                 * A search for a field should give the position where the next field start,
or
+                 * where the previous field ended.
+                 */
+                if (!isInteger) {
+                    if (index < 7) {
+                        startInteger = index;   // End of previous integer field.
+                        limitInteger = index+1; // Start of next integer field.
+                    } else {
+                        startInteger = 8;       // End of last integer field.
+                    }
+                }
+                if (!isSeparator) {
+                    if (index < 8) limitSeparator = 8; // Start of next separator field.
+                    else           startSeparator = 9; // End of previous separator field.
+                }
+                if (!isFraction) {
+                    if (index < 9) limitFraction =  9; // Start of next fraction field.
+                    else           startFraction = 10; // End of previous fraction field.
+                }
             }
             final Map<Attribute,Object> attributes = it.getAttributes();
-            assertEquals("attributes.size", (oi!=0) ? 2     : 1,    attributes.size());
-            assertEquals("attributes.get",            value,        attributes.get(key));
-            assertEquals("attributes.get",  (oi!=0) ? value : null, attributes.get(INTEGER));
-
-            assertEquals("getRunStart",           start,         it.getRunStart());
-            assertEquals("getRunLimit",           limit-oi,      it.getRunLimit());
-            assertEquals("getRunStart",           start,         it.getRunStart(key));
-            assertEquals("getRunLimit",           limit,         it.getRunLimit(key));
-            assertEquals("getRunStart", (oi!=0) ? start    :  0, it.getRunStart(INTEGER));
-            assertEquals("getRunLimit", (oi!=0) ? limit-oi : 12, it.getRunLimit(INTEGER));
+            assertEquals("attributes.size", numAttributes, attributes.size());
+            assertEquals("attributes.get",  value,         attributes.get(key));
+            assertEquals("attributes.get",  isInteger,     attributes.get(INTEGER) != null);
+            assertEquals("attributes.get",  isFraction,    attributes.get(FRACTION) != null);
+            assertEquals("attributes.get",  isSeparator,   attributes.get(DECIMAL_SEPARATOR)
!= null);
+
+            assertEquals("getRunStart", start,          it.getRunStart(key));
+            assertEquals("getRunLimit", limit,          it.getRunLimit(key));
+            assertEquals("getRunStart", startInteger,   it.getRunStart(INTEGER));
+            assertEquals("getRunLimit", limitInteger,   it.getRunLimit(INTEGER));
+            assertEquals("getRunStart", startFraction,  it.getRunStart(FRACTION));
+            assertEquals("getRunLimit", limitFraction,  it.getRunLimit(FRACTION));
+            assertEquals("getRunStart", startSeparator, it.getRunStart(DECIMAL_SEPARATOR));
+            assertEquals("getRunLimit", limitSeparator, it.getRunLimit(DECIMAL_SEPARATOR));
+            assertEquals("getRunStart", max(max(max(startInteger, startSeparator), startFraction),
start), it.getRunStart());
+            assertEquals("getRunLimit", min(min(min(limitInteger, limitSeparator), limitFraction),
limit), it.getRunLimit());
         }
     }
 }



Mime
View raw message