patternjavaModerate
Align Strings for Output
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:
Example Usage:
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
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
Contentclass, and then test theAlignclass (so that when an error is thrown, I can see right away where it is). Right now, I'm basically just copy-pasting theContenttests (theaddandsettests), and addingalign.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:
to the shorter form:
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:
I recommend to replace all the
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
Also, I think
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.