TableTest Formatter Features

March 8, 2026 · View on GitHub

This document describes the features provided by the TableTest Formatter.

Key features:

  • Consistent, readable tables – Vertically aligned columns and rows with normalized spacing
  • Context-aware – Works in standalone .table files, Java/Kotlin text blocks, and Java string arrays
  • Smart collection formatting – Normalizes spacing in lists, sets, and maps while preserving your quote choices
  • Preserves structure – Comments and blank lines maintained exactly as written
  • Unicode support – Accurate width calculation for CJK characters, emojis, and special characters
  • Safe by default – Never breaks builds; returns input unchanged on parse errors
  • Flexible integration – Spotless plugin (Gradle and Maven) or CLI tool

Table of Contents

Supported Contexts

The formatter provides TableTest formatting support in three contexts:

ContextDescription
Native filesStandalone .table files
Java/Kotlin text blocksTableTest content inside @TableTest("""...""") text blocks
Java string arraysTableTest content inside @TableTest({"row1", "row2"}) arrays

All formatting features work identically across these contexts.

Integration Methods

TableTest Formatter is available through three integration methods:

MethodDescriptionBest For
Spotless (Gradle)Build-integrated formatting via Spotless pluginGradle projects, automated formatting
Spotless (Maven)Build-integrated formatting via Spotless pluginMaven projects, automated formatting
CLIStandalone command-line toolCI/CD, manual formatting, scripting

Features

Column Alignment

Aligns columns vertically by padding cells to match the widest value in each column. Pipe delimiters (|) line up across all rows, creating visually consistent tables.

Before:

Scenario|Input|Expected
Basic case|5|10
Edge case at zero|0|0

After:

Scenario          | Input | Expected
Basic case        | 5     | 10
Edge case at zero | 0     | 0

Width calculation:

  • Uses wcwidth algorithm (IEEE Std 1002.1-2001) for accurate Unicode width
  • Correctly handles CJK characters (Chinese, Japanese, Korean)
  • Supports emojis including complex ones with flags and skin tones
  • Note: IDE fonts may not render with true monospace widths; verify output in terminals

Row Alignment

Creates a straight left edge – all rows start at the same column position.

Before:

    a | b | c
longer value | d | e
        x | y | z

After:

a            | b | c
longer value | d | e
x            | y | z

Pipe Spacing

Applies consistent spacing around pipe delimiters: | (space-pipe-space). This creates clear visual separation between columns.

Format: Each pipe has exactly one space before and one space after (except at line boundaries).

Collection Formatting

Normalises spacing inside collection literals while preserving user quote choices:

Spacing rules:

  • Space after comma: [1,2,3][1, 2, 3]
  • Space after colon in maps: [a:b,c:d][a: b, c: d]
  • Remove extra spaces inside brackets/braces: [ [] ][[]], { [ ] }{[]}
  • Nested structures formatted recursively: [a:[1,2],b:[3,4]][a: [1, 2], b: [3, 4]]

Applies to:

  • Lists: [...]
  • Sets: {...}
  • Maps: [key: value, ...]

Important: Spacing rules only apply to collection literals. Plain values like a,b,c remain unchanged.

Quote Preservation

Preserves the user's original quote choices ('single' vs "double"). The formatter does not change which quote type is used, only normalizes spacing and alignment.

Example:

  • Input: '1' stays '1'
  • Input: "2" stays "2"
  • Input: 'He said "hello"' stays 'He said "hello"'

Indentation

Positions the table appropriately within its context:

Standalone .table files:

  • Tables start at the left margin (no indentation)

Java and Kotlin files:

  • Tables are indented relative to their @TableTest annotation position
  • Base indentation from source files is preserved (tabs stay tabs, spaces stay spaces)
  • Additional indentation is added using the configured indentStyle (default: 4 spaces)
  • Configurable via indentSize parameter (0 = align with annotation, N = add N indent characters)

Text block – before/after:

    @TableTest("""
Scenario|Input|Expected
Basic case|5|10
        """)
    @TableTest("""
        Scenario   | Input | Expected
        Basic case | 5     | 10
        """)

Java string array – before/after:

    @TableTest({"Scenario|Input|Expected","Basic case|5|10"})
    @TableTest({
        "Scenario   | Input | Expected",
        "Basic case | 5     | 10      "
    })

String array entries are padded with trailing spaces so all closing " align vertically.

Comments and Blank Lines

Preserves comments and blank lines exactly as-is, including their indentation. Comments (lines starting with //) and blank lines are formatted along with the rest of the table.

Example:

Scenario   | Input | Expected
Basic case | 5     | 10
// This comment is preserved
Edge case  | 0     | 0

// Blank lines are preserved too

Empty Cell Handling

Empty cells are padded with spaces to maintain column alignment. This ensures that pipes line up vertically even when some cells have no content.

Before:

a|b|c
||
x|y|

After:

a | b | c
  |   |
x | y |

Error Handling (Graceful Degradation)

The formatter follows a fail-safe policy to ensure it never breaks your build:

Returns input unchanged for:

  • Malformed tables (mismatched columns, corrupted structure)
  • Unparseable content (invalid syntax, unbalanced quotes)
  • Empty or whitespace-only input

Propagates to caller:

  • NullPointerException - if required parameters are null
  • IllegalArgumentException - if indent/tab size parameters are negative

Benefits:

  • Formatting never causes compilation errors
  • Syntax errors in tables don't block builds
  • Gradual fixing of table syntax issues without breaking CI
  • Safe to apply in any codebase state

Configuration Options

TableTest Formatter reads configuration from .editorconfig files following the EditorConfig specification.

Supported EditorConfig properties:

PropertyValuesDefaultDescription
indent_stylespace, tabspaceType of indentation for additional indent
indent_size0-N4Number of indent characters to add beyond base

How it works:

  • Place .editorconfig in your project root or source directories
  • The formatter searches up the directory tree to find applicable configuration
  • If no .editorconfig is found, defaults to 4 spaces
  • Base indentation from source files is always preserved

Indent behavior:

  • indent_style = space - Additional indentation uses spaces
  • indent_style = tab - Additional indentation uses tabs
  • indent_size = 0 - Tables align exactly with their @TableTest annotation
  • indent_size = N - Adds N indent characters beyond the base level

Example Configuration

Basic example:

# .editorconfig in project root

[*.java]
indent_style = space
indent_size = 4

[*.kt]
indent_style = space
indent_size = 4

[*.table]
indent_style = space
indent_size = 0

Advanced example with directory-specific settings:

# .editorconfig in project root

# Default for Java files
[*.java]
indent_style = space
indent_size = 4

# Tighter indentation for tests
[src/test/java/**/*.java]
indent_style = space
indent_size = 2

# No indentation for standalone table files
[*.table]
indent_style = space
indent_size = 0

Feature Summary

FeatureDescription
Column AlignmentAligns pipes and pads cells based on widest value per column
Row AlignmentCreates straight left edge across all rows
Pipe SpacingConsistent | format around all pipes
Collection FormattingNormalises spacing in lists, sets, and maps
Quote PreservationMaintains user's choice of single vs double quotes
IndentationContext-aware indentation (file type and annotation position)
Comments & Blank LinesPreserves exactly as-is with proper indentation
Empty Cell HandlingPads empty cells to maintain alignment
Error HandlingGraceful degradation – never breaks builds
Unicode WidthAccurate width calculation for CJK, emojis, special characters

Platform Support

The formatter runs on any platform with Java 21+:

  • Linux
  • macOS
  • Windows

All features work identically across platforms.