Fix text justification and linked tests
authorNiki Roo <niki@nikiroo.be>
Wed, 14 Mar 2018 06:45:49 +0000 (07:45 +0100)
committerNiki Roo <niki@nikiroo.be>
Wed, 14 Mar 2018 06:45:49 +0000 (07:45 +0100)
src/be/nikiroo/utils/StringJustifier.java
src/be/nikiroo/utils/test/StringUtilsTest.java
src/be/nikiroo/utils/test/Test.java
src/be/nikiroo/utils/test/TestCase.java

index 174c7e910d431dc11c79b3af720e553a28b411e2..9ea0b7259282f6f4d8ab7a934fe039970aa47daf 100644 (file)
@@ -49,77 +49,7 @@ class StringJustifier {
         * @return the list of justified lines
         */
        static List<String> left(final String data, final int width) {
-               List<String> lines = new LinkedList<String>();
-
-               for (String dataLine : data.split("\n")) {
-                       String line = rightTrim(dataLine.replace("\t", "    "));
-
-                       if (width > 0 && line.length() > width) {
-                               while (line.length() > 0) {
-                                       int i = Math.min(line.length(), width - 1); // -1 for "-"
-
-                                       boolean needDash = true;
-                                       // find the best space if any and if needed
-                                       int prevSpace = 0;
-                                       if (i < line.length()) {
-                                               prevSpace = -1;
-                                               int space = line.indexOf(' ');
-
-                                               while (space > -1 && space <= i) {
-                                                       prevSpace = space;
-                                                       space = line.indexOf(' ', space + 1);
-                                               }
-
-                                               if (prevSpace > 0) {
-                                                       i = prevSpace;
-                                                       needDash = false;
-                                               }
-                                       }
-                                       //
-
-                                       // no dash before space/dash
-                                       if ((i + 1) < line.length()) {
-                                               char car = line.charAt(i);
-                                               char nextCar = line.charAt(i + 1);
-                                               if (nextCar == ' ' || car == '-' || nextCar == '-') {
-                                                       needDash = false;
-                                               }
-                                       }
-
-                                       // if the space freed by the removed dash allows it, or if
-                                       // it is the last char, add the next char
-                                       if (!needDash || i >= line.length() - 1) {
-                                               int checkI = Math.min(i + 1, line.length());
-                                               if (checkI == i || checkI <= width) {
-                                                       needDash = false;
-                                                       i = checkI;
-                                               }
-                                       }
-
-                                       // no dash before parenthesis (but cannot add one more
-                                       // after)
-                                       if ((i + 1) < line.length()) {
-                                               char car = line.charAt(i + 1);
-                                               if (car == '(' || car == ')') {
-                                                       needDash = false;
-                                               }
-                                       }
-
-                                       if (needDash) {
-                                               lines.add(rightTrim(line.substring(0, i)) + "-");
-                                       } else {
-                                               lines.add(rightTrim(line.substring(0, i)));
-                                       }
-
-                                       // full trim (remove spaces when cutting)
-                                       line = line.substring(i).trim();
-                               }
-                       } else {
-                               lines.add(line);
-                       }
-               }
-
-               return lines;
+               return left(data, width, false);
        }
 
        /**
@@ -198,11 +128,11 @@ class StringJustifier {
                List<String> result = new LinkedList<String>();
 
                /*
-                * Same as left(), but insert spaces between words to make each line n
-                * chars long. The "algorithm" here is pretty dumb: it performs a split
-                * on space and then re-inserts multiples of n between words.
+                * Same as left(true), but insert spaces between words to make each line
+                * n chars long. The "algorithm" here is pretty dumb: it performs a
+                * split on space and then re-inserts multiples of n between words.
                 */
-               List<String> lines = left(str, n);
+               List<String> lines = left(str, n, true);
                for (int lineI = 0; lineI < lines.size() - 1; lineI++) {
                        String line = lines.get(lineI);
                        String[] words = line.split(" ");
@@ -241,6 +171,96 @@ class StringJustifier {
                return result;
        }
 
+       /**
+        * Process the given text into a list of left-justified lines of a given
+        * max-width.
+        * 
+        * @param data
+        *            the text to justify
+        * @param width
+        *            the maximum width of a line
+        * @param minTwoWords
+        *            use 2 words per line minimum if the text allows it
+        * 
+        * @return the list of justified lines
+        */
+       static private List<String> left(final String data, final int width,
+                       boolean minTwoWords) {
+               List<String> lines = new LinkedList<String>();
+
+               for (String dataLine : data.split("\n")) {
+                       String line = rightTrim(dataLine.replace("\t", "    "));
+
+                       if (width > 0 && line.length() > width) {
+                               while (line.length() > 0) {
+                                       int i = Math.min(line.length(), width - 1); // -1 for "-"
+
+                                       boolean needDash = true;
+                                       // find the best space if any and if needed
+                                       int prevSpace = 0;
+                                       if (i < line.length()) {
+                                               prevSpace = -1;
+                                               int space = line.indexOf(' ');
+                                               int numOfSpaces = 0;
+
+                                               while (space > -1 && space <= i) {
+                                                       prevSpace = space;
+                                                       space = line.indexOf(' ', space + 1);
+                                                       numOfSpaces++;
+                                               }
+
+                                               if (prevSpace > 0 && (!minTwoWords || numOfSpaces >= 2)) {
+                                                       i = prevSpace;
+                                                       needDash = false;
+                                               }
+                                       }
+                                       //
+
+                                       // no dash before space/dash
+                                       if ((i + 1) < line.length()) {
+                                               char car = line.charAt(i);
+                                               char nextCar = line.charAt(i + 1);
+                                               if (nextCar == ' ' || car == '-' || nextCar == '-') {
+                                                       needDash = false;
+                                               }
+                                       }
+
+                                       // if the space freed by the removed dash allows it, or if
+                                       // it is the last char, add the next char
+                                       if (!needDash || i >= line.length() - 1) {
+                                               int checkI = Math.min(i + 1, line.length());
+                                               if (checkI == i || checkI <= width) {
+                                                       needDash = false;
+                                                       i = checkI;
+                                               }
+                                       }
+
+                                       // no dash before parenthesis (but cannot add one more
+                                       // after)
+                                       if ((i + 1) < line.length()) {
+                                               char car = line.charAt(i + 1);
+                                               if (car == '(' || car == ')') {
+                                                       needDash = false;
+                                               }
+                                       }
+
+                                       if (needDash) {
+                                               lines.add(rightTrim(line.substring(0, i)) + "-");
+                                       } else {
+                                               lines.add(rightTrim(line.substring(0, i)));
+                                       }
+
+                                       // full trim (remove spaces when cutting)
+                                       line = line.substring(i).trim();
+                               }
+                       } else {
+                               lines.add(line);
+                       }
+               }
+
+               return lines;
+       }
+
        /**
         * Trim the given {@link String} on the right only.
         * 
index 4be75040b9966106beb932b825f60d2e53a8adeb..6ebf43ef019a0d2d2760892cd0ea2465888e7c2c 100644 (file)
@@ -144,6 +144,10 @@ class StringUtilsTest extends TestLauncher {
                        @Override
                        public void test() throws Exception {
                                Map<String, Map<Integer, Entry<Alignment, List<String>>>> source = new HashMap<String, Map<Integer, Entry<Alignment, List<String>>>>();
+                               addValue(source, Alignment.LEFT, "testy", -1, "testy");
+                               addValue(source, Alignment.RIGHT, "testy", -1, "testy");
+                               addValue(source, Alignment.CENTER, "testy", -1, "testy");
+                               addValue(source, Alignment.JUSTIFY, "testy", -1, "testy");
                                addValue(source, Alignment.LEFT, "testy", 5, "testy");
                                addValue(source, Alignment.LEFT, "testy", 3, "te-", "sty");
                                addValue(source, Alignment.LEFT,
@@ -164,14 +168,13 @@ class StringUtilsTest extends TestLauncher {
                                                "  sur  ", "plusie-", "  urs  ", "lignes ");
                                addValue(source, Alignment.JUSTIFY,
                                                "Un petit texte qui se mettra sur plusieurs lignes", 7,
-                                               "Un", "petit", "texte", "qui  se", "mettra", "sur",
-                                               "plusie-", "urs", "lignes");
+                                               "Un pet-", "it tex-", "te  qui", "se met-", "tra sur",
+                                               "plusie-", "urs li-", "gnes");
                                addValue(source, Alignment.JUSTIFY,
                                                "Un petit texte qui se mettra sur plusieurs lignes",
                                                14, "Un       petit", "texte  qui  se",
                                                "mettra     sur", "plusieurs lig-", "nes");
 
-                               System.out.println();
                                for (String data : source.keySet()) {
                                        for (int size : source.get(data).keySet()) {
                                                Alignment align = source.get(data).get(size).getKey();
@@ -181,21 +184,17 @@ class StringUtilsTest extends TestLauncher {
                                                List<String> result = StringUtils.justifyText(data,
                                                                size, align);
 
-                                               System.out.println("[" + data + " (" + size + ")"
-                                                               + "] -> [");
-                                               for (int i = 0; i < result.size(); i++) {
-                                                       String resultLine = result.get(i);
-                                                       System.out.println(i + ": " + resultLine);
-                                               }
-                                               System.out.println("]");
+                                               // System.out.println("[" + data + " (" + size + ")" +
+                                               // "] -> [");
+                                               // for (int i = 0; i < result.size(); i++) {
+                                               // String resultLine = result.get(i);
+                                               // System.out.println(i + ": " + resultLine);
+                                               // }
+                                               // System.out.println("]");
 
-                                               for (int i = 0; i < result.size() && i < values.size(); i++) {
-                                                       assertEquals("The line " + i + " is not correct",
-                                                                       values.get(i), result.get(i));
-                                               }
+                                               assertEquals(values, result);
                                        }
                                }
-                               System.out.println();
                        }
                });
 
index bb08e2b4c19ac94e0b103647ed03e28e18713855..dd6bf611792c302fc239082c8557583fff111271 100644 (file)
@@ -19,15 +19,14 @@ public class Test extends TestLauncher {
        public Test(String[] args) {
                super("Nikiroo-utils", args);
 
-               /*
                addSeries(new ProgressTest(args));
                addSeries(new BundleTest(args));
                addSeries(new IOUtilsTest(args));
                addSeries(new VersionTest(args));
                addSeries(new SerialTest(args));
                addSeries(new SerialServerTest(args));
-               */addSeries(new StringUtilsTest(args));
-               //addSeries(new TempFilesTest(args));
+               addSeries(new StringUtilsTest(args));
+               addSeries(new TempFilesTest(args));
 
                // TODO: test cache and downloader
                Cache cache = null;
index a62cb0b79646752fb9b37ffca7c4173dc795cac7..5cff3630a725aa1e5fb67301ff1518875589a96c 100644 (file)
@@ -1,5 +1,7 @@
 package be.nikiroo.utils.test;
 
+import java.util.List;
+
 /**
  * A {@link TestCase} that can be run with {@link TestLauncher}.
  * 
@@ -140,7 +142,7 @@ abstract public class TestCase {
        }
 
        /**
-        * Check that 2 {@link Object}s are equals.
+        * Check that 2 longs are equals.
         * 
         * @param expected
         *            the expected value
@@ -155,7 +157,7 @@ abstract public class TestCase {
        }
 
        /**
-        * Check that 2 {@link Object}s are equals.
+        * Check that 2 longs are equals.
         * 
         * @param errorMessage
         *            the error message to display if they differ
@@ -173,7 +175,7 @@ abstract public class TestCase {
        }
 
        /**
-        * Check that 2 {@link Object}s are equals.
+        * Check that 2 booleans are equals.
         * 
         * @param expected
         *            the expected value
@@ -189,7 +191,7 @@ abstract public class TestCase {
        }
 
        /**
-        * Check that 2 {@link Object}s are equals.
+        * Check that 2 booleans are equals.
         * 
         * @param errorMessage
         *            the error message to display if they differ
@@ -208,7 +210,7 @@ abstract public class TestCase {
        }
 
        /**
-        * Check that 2 {@link Object}s are equals.
+        * Check that 2 doubles are equals.
         * 
         * @param expected
         *            the expected value
@@ -224,7 +226,7 @@ abstract public class TestCase {
        }
 
        /**
-        * Check that 2 {@link Object}s are equals.
+        * Check that 2 doubles are equals.
         * 
         * @param errorMessage
         *            the error message to display if they differ
@@ -242,6 +244,32 @@ abstract public class TestCase {
                                Double.valueOf(actual));
        }
 
+       /**
+        * Check that 2 {@link List}s are equals.
+        * 
+        * @param errorMessage
+        *            the error message to display if they differ
+        * @param expected
+        *            the expected value
+        * @param actual
+        *            the actual value
+        * 
+        * @throws AssertException
+        *             in case they differ
+        */
+       public void assertEquals(List<?> expected, List<?> actual)
+                       throws AssertException {
+
+               assertEquals("The 2 lists don't contain the same number of items",
+                               expected.size(), actual.size());
+
+               int size = expected.size();
+               for (int i = 0; i < size; i++) {
+                       assertEquals("Line " + i + " (0-based) is not correct",
+                                       expected.get(i), actual.get(i));
+               }
+       }
+
        /**
         * Check that given {@link Object} is not NULL.
         *