sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1782918 - in /sis/branches/JDK8/core: sis-referencing/src/main/java/org/apache/sis/referencing/gazetteer/ sis-referencing/src/test/java/org/apache/sis/referencing/gazetteer/ sis-utility/src/main/java/org/apache/sis/util/ sis-utility/src/te...
Date Tue, 14 Feb 2017 07:23:33 GMT
Author: desruisseaux
Date: Tue Feb 14 07:23:33 2017
New Revision: 1782918

URL: http://svn.apache.org/viewvc?rev=1782918&view=rev
Log:
First working version of Military Grid Reference System encoding, UTM part only (not yet polar
part).

Modified:
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/gazetteer/MGRSEncoder.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystem.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/gazetteer/MGRSEncoderTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystemTest.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/StringBuilders.java
    sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/util/StringBuildersTest.java

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/gazetteer/MGRSEncoder.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/gazetteer/MGRSEncoder.java?rev=1782918&r1=1782917&r2=1782918&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/gazetteer/MGRSEncoder.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/gazetteer/MGRSEncoder.java
[UTF-8] Tue Feb 14 07:23:33 2017
@@ -30,7 +30,9 @@ import org.apache.sis.referencing.crs.De
 import org.apache.sis.referencing.cs.AxesConvention;
 import org.apache.sis.referencing.IdentifiedObjects;
 import org.apache.sis.referencing.CRS;
+import org.apache.sis.math.MathFunctions;
 import org.apache.sis.util.resources.Errors;
+import org.apache.sis.util.StringBuilders;
 
 
 /**
@@ -69,7 +71,41 @@ final class MGRSEncoder {
     /**
      * Size of the 100,000-meter squares.
      */
-    private static final double GRID_SQUARE_SIZE = 100_000;
+    static final double GRID_SQUARE_SIZE = 100_000;
+
+    /**
+     * The number of digits in a one-meter precision when formatting MGRS labels.
+     *
+     * <p><b>Invariant:</b> the following relationship must hold:
+     * {@code GRID_SQUARE_SIZE == Math.pow(10, METRE_PRECISION_DIGITS)}
+     */
+    static final int METRE_PRECISION_DIGITS = 5;
+
+    /**
+     * The first of the two letters ({@code 'I'} and {@code 'O'}) excluded in MGRS notation.
+     * This letter and all following letters shall be shifted by one character. Example:
+     *
+     * {@preformat java
+     *     char band = ...;
+     *     if (band >= EXCLUDE_I) {
+     *         band++;
+     *         if (band >= EXCLUDE_O) band++;
+     *     }
+     * }
+     *
+     * or equivalently:
+     *
+     * {@preformat java
+     *     char band = ...;
+     *     if (band >= EXCLUDE_I && ++band >= EXCLUDE_O) band++;
+     * }
+     */
+    private static final char EXCLUDE_I = 'I';
+
+    /**
+     * The second of the two letters ({@code 'I'} and {@code 'O'}) excluded in MGRS notation.
+     */
+    private static final char EXCLUDE_O = 'O';
 
     /**
      * UTM zone of position CRS (negative for South hemisphere), or 0 if that CRS is not
an UTM projection.
@@ -141,14 +177,8 @@ final class MGRSEncoder {
      */
     static char latitudeBand(final double φ) {
         int band = 'C' + (int) ((φ - UTM_SOUTH_BOUNDS) / LATITUDE_BAND_HEIGHT);
-        if (band >= 'N') {
-            if (band == 'W') {
-                band++;             // Because the last latitude band ('X') is 12° height
instead of 8°.
-            } else {
-                band += 2;
-            }
-        } else if (band >= 'I') {
-            band++;
+        if (band >= EXCLUDE_I && ++band >= EXCLUDE_O && ++band == 'Y')
{
+            band = 'X';         // Because the last latitude band ('X') is 12° height instead
of 8°.
         }
         return (char) band;
     }
@@ -194,11 +224,11 @@ final class MGRSEncoder {
      * Encodes the given position into a MGRS label. It is caller responsibility to ensure
that the
      * position CRS is the same than the CRS specified at this {@code MGRSEncoder} creation
time.
      *
-     * @param  position   the direct position to format as a MGRS label.
-     * @param  precision  the precision as a power of 10.
-     * @param  buffer     where to format the direct position.
+     * @param  position  the direct position to format as a MGRS label.
+     * @param  digits    number of digits to use for formatting the numerical part of a MGRS
label.
+     * @param  buffer    where to format the direct position.
      */
-    void encode(DirectPosition position, final double precision, final StringBuilder buffer)
throws TransformException {
+    void encode(DirectPosition position, final int digits, final StringBuilder buffer) throws
TransformException {
         if (toNormalized != null) {
             position = toNormalized.transform(position, null);
         }
@@ -216,43 +246,71 @@ final class MGRSEncoder {
                     throw new IllegalArgumentException();
                 }
                 buffer.append(zone).append(band);
-                /*
-                 * Columns in zone 1 are A-H, zone 2 are J-R (skipping O), zone 3 are S-Z,
-                 * then repeating every 3 zones. The zone number shall not take in account
-                 * the special cases done by the zone(…) method.
-                 */
-                final double x = position.getOrdinate(0);
-                final double y = position.getOrdinate(1);
-                final double cx = Math.floor(x / GRID_SQUARE_SIZE);
-                final double cy = Math.floor(y / GRID_SQUARE_SIZE);
-                int col = (int) cx;
-                if (col < 0 || col >= 8) {
-                    throw new IllegalArgumentException("UTM coordinates out of range"); 
   // TODO: localize
-                }
-                switch (utmZone % 3) {
-                    case 0: col += 'A'; break;
-                    case 1: col += 'J'; if (col >= 'O') col++; break;
-                    case 2: col += 'S'; break;
-                }
-                /*
-                 * Rows in even zones are ABCDEFGHJKLMNPQRSTUV
-                 * Rows in odd  zones are FGHJKLMNPQRSTUVABCDE
-                 * Those 20 letters are repeated in a cycle.
-                 */
-                int row = (int) cy;
-                if ((zone & 1) != 0) {
-                    row += ('F' - 'A');
+                if (digits >= 0) {
+                    /*
+                     * Specification said that 100,000-meters columns are lettered from A
through Z (omitting I and O)
+                     * starting at the 180° meridian, proceeding easterly for 18°, and
repeating for each 18° intervals.
+                     * Since a UTM zone is 6° width, a 18° interval is exactly 3 standard
UTM zones (not the zone number
+                     * modified by the zone(…) method). Columns in zone 1 are A-H, zone
2 are J-R (skipping O), zone 3
+                     * are S-Z, then repeating every 3 zones.
+                     */
+                    final double x = position.getOrdinate(0);
+                    final double y = position.getOrdinate(1);
+                    final double cx = Math.floor(x / GRID_SQUARE_SIZE);
+                    final double cy = Math.floor(y / GRID_SQUARE_SIZE);
+                    int col = (int) cx;
+                    if (col < 1 || col > 8) {
+                        /*
+                         * UTM northing values at the equator range from 166021 to 833979
meters approximatively
+                         * (WGS84 ellipsoid). Consequently 'cx' ranges from approximatively
1.66 to 8.34, so 'c'
+                         * should range from 1 to 8.
+                         */
+                        throw new TransformException(Errors.format(Errors.Keys.OutsideDomainOfValidity));
+                    }
+                    switch (utmZone % 3) {                          // First A-H sequence
starts at zone number 1.
+                        case 1: col += ('A' - 1); break;
+                        case 2: col += ('J' - 1); if (col >= EXCLUDE_O) col++; break;
+                        case 0: col += ('S' - 1); break;
+                    }
+                    /*
+                     * Rows in odd  zones are ABCDEFGHJKLMNPQRSTUV
+                     * Rows in even zones are FGHJKLMNPQRSTUVABCDE
+                     * Those 20 letters are repeated in a cycle.
+                     */
+                    int row = (int) cy;
+                    if ((zone & 1) == 0) {
+                        row += ('F' - 'A');
+                    }
+                    row = 'A' + (row % 20);
+                    if (row >= EXCLUDE_I && ++row >= EXCLUDE_O) row++;
+                    buffer.append((char) col).append((char) row);
+                    /*
+                     * Numerical location at the given precision.
+                     * The specification requires us to truncate the number, not to round
it.
+                     */
+                    if (digits > 0) {
+                        final double precision = MathFunctions.pow10(METRE_PRECISION_DIGITS
- digits);
+                        append(buffer, (int) ((x - cx * GRID_SQUARE_SIZE) / precision), digits);
+                        append(buffer, (int) ((y - cy * GRID_SQUARE_SIZE) / precision), digits);
+                    }
                 }
-                row = 'A' + (row % 20);
-                if (row >= 'N') row += 2;
-                else if (row >= 'I') row++;
-                buffer.append((char) col).append((char) row);
-                /*
-                 * Numerical location at the given precision.
-                 */
-                final int rx = (int) Math.floor((x - cx * GRID_SQUARE_SIZE) / precision);
-                final int ry = (int) Math.floor((y - cy * GRID_SQUARE_SIZE) / precision);
             }
         }
     }
+
+    /**
+     * Appends the given value in the given buffer, padding with zero digits in order to
get
+     * the specified total amount of digits.
+     */
+    private static void append(final StringBuilder buffer, final int value, int digits) throws
TransformException {
+        if (value >= 0) {
+            final int p = buffer.length();
+            digits -= (buffer.append(value).length() - p);
+            if (digits >= 0) {
+                StringBuilders.repeat(buffer, p, '0', digits);
+                return;
+            }
+        }
+        throw new TransformException(Errors.format(Errors.Keys.OutsideDomainOfValidity));
+    }
 }

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystem.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystem.java?rev=1782918&r1=1782917&r2=1782918&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystem.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystem.java
[UTF-8] Tue Feb 14 07:23:33 2017
@@ -25,6 +25,8 @@ import org.opengis.geometry.DirectPositi
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.opengis.referencing.operation.TransformException;
 import org.apache.sis.util.ArgumentChecks;
+import org.apache.sis.math.MathFunctions;
+import org.apache.sis.util.resources.Errors;
 
 
 /**
@@ -66,9 +68,9 @@ public class MilitaryGridReferenceSystem
      */
     public static class Coder {
         /**
-         * The precision as a power of 10.
+         * Number of digits to use for formatting the numerical part of a MGRS label.
          */
-        private double precision;
+        private byte digits;
 
         /**
          * Cached information needed for building a MGRS label from a direct position in
the given CRS.
@@ -84,12 +86,55 @@ public class MilitaryGridReferenceSystem
          * Creates a new coder initialized to the default precision.
          */
         public Coder() {
-            precision = 1;                          // 1 meter precision.
+            digits    = 5;                          // 1 meter precision.
             buffer    = new StringBuilder(12);      // Length of "4QFJ12345678" sample value.
             encoders  = new IdentityHashMap<>();
         }
 
         /**
+         * Returns the precision of the labels formatted by this coder.
+         * This method returns one of the following values:
+         *
+         * <table class="sis">
+         *   <caption>MGRS label precisions</caption>
+         *   <tr><th>Precision (m)</th>             <th>Label example</th></tr>
+         *   <tr><td style="text-align:right">1</td> <td>4QFJ 12345
67890</td></tr>
+         *   <tr><td style="text-align:right">10</td> <td>4QFJ 1234
6789</td></tr>
+         *   <tr><td style="text-align:right">100</td> <td>4QFJ 123
678</td></tr>
+         *   <tr><td style="text-align:right">1000</td> <td>4QFJ
12 67</td></tr>
+         *   <tr><td style="text-align:right">10 000</td> <td>4QFJ
1 6</td></tr>
+         *   <tr><td style="text-align:right">100 000</td> <td>4QFJ</td></tr>
+         *   <tr><td style="text-align:right">(approximative) 1 000 000</td>
<td>4Q</td></tr>
+         * </table>
+         *
+         * Values smaller than 1 (e.g. 0.01 for a centimetre precision) may also be returned
+         * if that value has been {@linkplain #setPrecision(double) explicitely set},
+         * but sub-metric precision are usually not used with MGRS.
+         *
+         * @return precision of formatted labels in metres.
+         */
+        public double getPrecision() {
+            return MathFunctions.pow10(MGRSEncoder.METRE_PRECISION_DIGITS - digits);
+        }
+
+        /**
+         * Sets the desired precision of the labels formatted by this coder.
+         * This method rounds the given precision to one of the power of 10
+         * documented in the {@link #getPrecision()} method.
+         *
+         * @param  precision  the desired precision in metres.
+         */
+        public void setPrecision(final double precision) {
+            final double p = Math.floor(Math.log10(precision));
+            if (!Double.isFinite(p)) {
+                throw new IllegalArgumentException(Errors.format(Errors.Keys.IllegalArgumentValue_2,
"precision", precision));
+            }
+            // The -3 is an arbitrary limit to millimetre precision.
+            int n = Math.max(-3, Math.min(MGRSEncoder.METRE_PRECISION_DIGITS + 1, (int) p));
+            digits = (byte) (MGRSEncoder.METRE_PRECISION_DIGITS - n);
+        }
+
+        /**
          * Encodes the given position into a MGRS label.
          * The given position must have a CRS associated to it.
          *
@@ -110,7 +155,7 @@ public class MilitaryGridReferenceSystem
                 throw new TransformException(e.toString(), e);
             }
             buffer.setLength(0);
-            encoder.encode(position, precision, buffer);
+            encoder.encode(position, digits, buffer);
             return buffer.toString();
         }
 

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/gazetteer/MGRSEncoderTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/gazetteer/MGRSEncoderTest.java?rev=1782918&r1=1782917&r2=1782918&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/gazetteer/MGRSEncoderTest.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/gazetteer/MGRSEncoderTest.java
[UTF-8] Tue Feb 14 07:23:33 2017
@@ -33,6 +33,16 @@ import static org.apache.sis.internal.re
  */
 public final strictfp class MGRSEncoderTest extends TestCase {
     /**
+     * Verifies relationship between static fields documented in {@link MGRSEncoder}.
+     */
+    @Test
+    public void verifyInvariants() {
+        assertEquals("GRID_SQUARE_SIZE",
+             StrictMath.pow(10, MGRSEncoder.METRE_PRECISION_DIGITS),
+                                MGRSEncoder.GRID_SQUARE_SIZE, STRICT);
+    }
+
+    /**
      * Tests {@link MGRSEncoder#latitudeBand(double)}.
      */
     @Test
@@ -52,7 +62,7 @@ public final strictfp class MGRSEncoderT
      */
     @Test
     public void testZone() {
-        assertEquals( "4°E band T", 31, MGRSEncoder.zone(UTM.zone( 4), 4, 'T'));
+        assertEquals( "4°E band T", 31, MGRSEncoder.zone(UTM.zone( 4),  4, 'T'));
         assertEquals( "4°E band V", 32, MGRSEncoder.zone(UTM.zone( 4),  4, 'V'));
         assertEquals("20°E band W", 34, MGRSEncoder.zone(UTM.zone(20), 20, 'W'));
         assertEquals("20°E band X", 33, MGRSEncoder.zone(UTM.zone(20), 20, 'X'));

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystemTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystemTest.java?rev=1782918&r1=1782917&r2=1782918&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystemTest.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/gazetteer/MilitaryGridReferenceSystemTest.java
[UTF-8] Tue Feb 14 07:23:33 2017
@@ -42,12 +42,30 @@ public final strictfp class MilitaryGrid
      * @throws TransformException if an error occurred while computing the MGRS label.
      */
     @Test
-    @org.junit.Ignore
     public void testEncoding() throws TransformException {
         final MilitaryGridReferenceSystem.Coder coder = new MilitaryGridReferenceSystem.Coder();
         final DirectPosition2D position = new DirectPosition2D(CommonCRS.WGS84.UTM(13, 103));
-        position.x = 377299;
+        position.x =  377299;
         position.y = 1483035;
-        assertEquals("48PUV7729883034", coder.encode(position));
+        assertEquals("precision", 1, coder.getPrecision(), STRICT);
+        assertEquals("48PUV7729983035", coder.encode(position));
+        coder.setPrecision(10);
+        assertEquals("precision", 10, coder.getPrecision(), STRICT);
+        assertEquals("48PUV77298303", coder.encode(position));
+        coder.setPrecision(304);
+        assertEquals("precision", 100, coder.getPrecision(), STRICT);
+        assertEquals("48PUV772830", coder.encode(position));
+        coder.setPrecision(1002);
+        assertEquals("precision", 1000, coder.getPrecision(), STRICT);
+        assertEquals("48PUV7783", coder.encode(position));
+        coder.setPrecision(10000);
+        assertEquals("precision", 10000, coder.getPrecision(), STRICT);
+        assertEquals("48PUV78", coder.encode(position));
+        coder.setPrecision(990004);
+        assertEquals("precision", 100000, coder.getPrecision(), STRICT);
+        assertEquals("48PUV", coder.encode(position));
+        coder.setPrecision(1000000);
+        assertEquals("precision", 1000000, coder.getPrecision(), STRICT);
+        assertEquals("48P", coder.encode(position));
     }
 }

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/StringBuilders.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/StringBuilders.java?rev=1782918&r1=1782917&r2=1782918&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/StringBuilders.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/StringBuilders.java
[UTF-8] Tue Feb 14 07:23:33 2017
@@ -161,6 +161,72 @@ public final class StringBuilders extend
     }
 
     /**
+     * Inserts the given character <var>n</var> time at the given position.
+     * This method does nothing if the given {@code count} is zero.
+     *
+     * @param  buffer  the buffer where to insert the character.
+     * @param  offset  position where to insert the characters.
+     * @param  c       the character to repeat.
+     * @param  count   number of time to repeat the given character.
+     * @throws NullPointerException if the given buffer is null.
+     * @throws IndexOutOfBoundsException if the given index is invalid.
+     * @throws IllegalArgumentException if the given count is negative.
+     *
+     * @since 0.8
+     */
+    public static void repeat(final StringBuilder buffer, final int offset, final char c,
final int count) {
+        ArgumentChecks.ensureNonNull("buffer", buffer);
+        switch (count) {
+            case 0:  break;
+            case 1:  buffer.insert(offset, c); break;
+            default: {
+                ArgumentChecks.ensurePositive("count", count);
+                final CharSequence r;
+                switch (c) {
+                    case ' ': r = CharSequences.spaces(count); break;
+                    case '0': r = Repeat.ZERO; break;
+                    default:  r = new Repeat(c, count); break;
+                }
+                buffer.insert(offset, r, 0, count);
+                break;
+            }
+        }
+    }
+
+    /**
+     * A sequence of a constant character. This implementation does not perform any argument
+     * check since it is for {@link StringBuilder#append(CharSequence, int, int)} usage only.
+     * The intend is to allow {@code StringBuilder} to append the characters in one operation
+     * instead than looping on {@link StringBuilder#insert(int, char)} (which would require
+     * memory move on each call).
+     */
+    private static final class Repeat implements CharSequence {
+        /** An infinite sequence of {@code '0'} character. */
+        static final Repeat ZERO = new Repeat('0', Integer.MAX_VALUE);
+
+        /** The character to repeat. */
+        private final char c;
+
+        /** Number of times the character is repeated. */
+        private final int n;
+
+        /** Creates a new sequence of constant character. */
+        Repeat(final char c, final int n) {
+            this.c = c;
+            this.n = n;
+        }
+
+        /** Returns the number of times the character is repeated. */
+        @Override public int length() {return n;}
+
+        /** Returns the constant character, regardless the index. */
+        @Override public char charAt(int i) {return c;}
+
+        /** Returns a sequence of the same constant character but different length. */
+        @Override public CharSequence subSequence(int start, int end) {return new Repeat(c,
end - start);}
+    }
+
+    /**
      * Trims the fractional part of the given formatted number, provided that it doesn't
change
      * the value. This method assumes that the number is formatted in the US locale, typically
      * by the {@link Double#toString(double)} method.
@@ -183,11 +249,9 @@ public final class StringBuilders extend
     public static void trimFractionalPart(final StringBuilder buffer) {
         ArgumentChecks.ensureNonNull ("buffer", buffer);
         for (int i=buffer.length(); i > 0;) {
-            final int c = buffer.codePointBefore(i);
-            i -= charCount(c);
-            switch (c) {
+            switch (buffer.charAt(--i)) {               // No need to use Unicode code points
here.
                 case '0': continue;
-                case '.': buffer.setLength(i); // Fall through
+                case '.': buffer.setLength(i);          // Fall through
                 default : return;
             }
         }

Modified: sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/util/StringBuildersTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/util/StringBuildersTest.java?rev=1782918&r1=1782917&r2=1782918&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/util/StringBuildersTest.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/util/StringBuildersTest.java
[UTF-8] Tue Feb 14 07:23:33 2017
@@ -80,6 +80,26 @@ public final strictfp class StringBuilde
     }
 
     /**
+     * Tests the {@link StringBuilders#repeat(StringBuilder, int, char, int)} method.
+     *
+     * @since 0.8
+     */
+    @Test
+    public void testRepeat() {
+        final StringBuilder buffer = new StringBuilder("AB12");
+        repeat(buffer, 2, 'C', 0);
+        assertEquals("AB12", buffer.toString());
+        repeat(buffer, 2, 'C', 1);
+        assertEquals("ABC12", buffer.toString());
+        repeat(buffer, 3, '0', 4);
+        assertEquals("ABC000012", buffer.toString());
+        repeat(buffer, 6, ' ', 2);
+        assertEquals("ABC000  012", buffer.toString());
+        repeat(buffer, 6, '.', 3);
+        assertEquals("ABC000...  012", buffer.toString());
+    }
+
+    /**
      * Tests the {@link StringBuilders#trimFractionalPart(StringBuilder)} method.
      */
     @Test



Mime
View raw message