HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaModerate

Align Strings for Output

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
outputstringsforalign

Problem

I wrote a class which can format input so that it is properly aligned.

I'm interested in all suggestions (regarding structure, usability, style, naming, comments, etc).

I'm especially wondering about:

  • Is there a better way to write the tests? I want to first test the Content class, and then test the Align class (so that when an error is thrown, I can see right away where it is). Right now, I'm basically just copy-pasting the Content tests (the add and set tests), and adding align.output((String s) -> nothing());. This doesn't seem like the right way to do it.



Example Usage:

public static void main(String[] args) {
       Align align = new Align();
       // header
       align.addLine("Name", "Age", "Address", "Phone");

       // data
       align.addLine("Alice", "32", "United States", "555-123456");
       align.addLine("Bob", "12", "nowhere", "555-123456");
       align.addLine("Carol", "78", "1080 Maple Court Cape Girardeau, MO 63701", "555-123456");
       align.addLine("Ed", "159", "Fake Stree, Fakesville");

       // output
        align.output((String s) -> System.out.println(s));

       // add a forgotten column
       align.addColumn(3, "Hair Color", "Red", "Brown", "Blue", "Purple", "Orange");
       align.output((String s) -> System.out.println(s));
    }


Output:

`Name Age Address Phone
Alice 32 United States 555-123456
Bob 12 nowhere 555-123456
Carol 78 1080 Maple Court Cape Girardeau, MO 63701 555-123456
Ed 159 Fake Stree, Fakesville -

Name Age Address Hair Color Phone
Alice 32 United States Red 555-123456
Bob 12 nowhere Brown 555-123456
Carol 78 1080 Maple Court

Solution

You can simplify this:

align.output((String s) -> nothing(s));


to the shorter form:

align.output(this::nothing);


But, the important thing is, as you guessed, that printing from unit tests is not the right thing to do. You should convert the printing to assertions, for example:

@Test()
public void outputAddShortLineOutsideField() {
    Align align = getAlign(2, 3);
    align.addLine(5, "new");
    assertEquals(
            "00     01     \n" +
            "10     11     \n" +
            "20     21     \n" +
            "-      -      \n" +
            "-      -      \n" +
            "new    -      \n", align.toString());
}

@Test()
public void outputAddLongColumn() {
    Align align = getAlign(2, 3);
    align.addColumn(1, "new", "new", "new", "new", "new");
    assertEquals(
            "00     new     01     \n" +
            "10     new     11     \n" +
            "20     new     21     \n" +
            "-      new     -      \n" +
            "-      new     -      \n", align.toString());
}


I recommend to replace all the align.output(this::nothing); lines with this:

assertEquals("", align.toString());


Run it (lots of failures), your IDE should print (somewhere) an error message with the expected and actual values. If the actual values look what you expected, copy-paste into the unit test. Repeat for all tests and you're done. (... or go ahead and refactor some more ;-)

Btw, I think it's not a good idea to use toString for formatting purposes. It would be better to move the formatting logic to a different method (.format() ?), and make .toString() more "technical".

Also, I think Align is not a great name. Something like TabularTextBuilder or just TableBuilder would be better. And it might make sense to borrow ideas from the Builder pattern, making addLine return this instead of void, so that you can chain all the .addLine(...) (and other) calls, ending in a .format() call that returns the formatted text.

Code Snippets

align.output((String s) -> nothing(s));
align.output(this::nothing);
@Test()
public void outputAddShortLineOutsideField() {
    Align align = getAlign(2, 3);
    align.addLine(5, "new");
    assertEquals(
            "00     01     \n" +
            "10     11     \n" +
            "20     21     \n" +
            "-      -      \n" +
            "-      -      \n" +
            "new    -      \n", align.toString());
}

@Test()
public void outputAddLongColumn() {
    Align align = getAlign(2, 3);
    align.addColumn(1, "new", "new", "new", "new", "new");
    assertEquals(
            "00     new     01     \n" +
            "10     new     11     \n" +
            "20     new     21     \n" +
            "-      new     -      \n" +
            "-      new     -      \n", align.toString());
}
assertEquals("", align.toString());

Context

StackExchange Code Review Q#64407, answer score: 10

Revisions (0)

No revisions yet.