String Transformer

Level: Advanced 60–90 min

Concepts: AlgorithmsDesign PatternsEdge CasesRefactoring

Solutions: C# | TypeScript | Python


Build a string transformer that supports chainable operations. Each operation transforms the input string and passes the result to the next operation.

Requirements

  1. Create a StringTransformer that takes an initial string
  2. Support the following operations, all chainable:
    • capitalise() — capitalise the first letter of each word
    • reverse() — reverse the entire string
    • removeWhitespace() — remove all whitespace
    • snakeCase() — convert to snake_case
    • camelCase() — convert to camelCase
    • truncate(n) — truncate to n characters, adding ”…” if truncated
    • repeat(n) — repeat the string n times with a space separator
    • replace(target, replacement) — replace all occurrences
  3. result() returns the final transformed string
  4. Operations are applied in order

Test Cases

InputOperationsResult
”hello world”capitalise()“Hello World"
"hello world”reverse()“dlrow olleh"
"hello world”removeWhitespace()“helloworld"
"hello world”snakeCase()“hello_world"
"Hello World”camelCase()“helloWorld"
"hello world”truncate(5)“hello…"
"hello world”truncate(50)“hello world"
"ha”repeat(3)“ha ha ha"
"hello world”capitalise().reverse()“dlroW olleH"
"hello world”snakeCase().capitalise()“Hello_World"
""capitalise()""
"HELLO WORLD”camelCase()“helloWorld"
"hello-world test”snakeCase()“hello_world_test”

Bonus

  • Add cipher(n) — apply a Caesar cipher shifting each letter by n positions
  • Add slug() — convert to URL-friendly slug (lowercase, hyphens, no special characters)
  • Add mask(n) — mask all but the last n characters with asterisks (useful for credit cards, emails)
  • Make the transformer immutable — each operation returns a new transformer, allowing branching transformations

Reference Walkthrough

Reference implementations in C#, TypeScript, and Python live at tddbuddy-reference-katas/string-transformer. This is an F2 (light builder) kata showcasing the Strategy pattern: every transformation (Capitalise, Reverse, SnakeCase, Truncate(n), Replace(target, replacement), …) is a self-contained class implementing a uniform apply(string) -> string; Pipeline runs them in order; a small test-folder PipelineBuilder makes each scenario a one-line fluent chain.

Scope note — eight required transformations only. The reference implements the eight chainable operations from the spec (capitalise, reverse, removeWhitespace, snakeCase, camelCase, truncate, repeat, replace). The four bonus ideas — cipher(n), slug(), mask(n), and immutable-branching pipelines — are out of scope and listed as stretch goals in the repo README.

This kata ships in Agent Full-Bake mode at middle gear, the F2 (light builder) tier. See the repo’s Gears section for why middle gear is the deliberate choice.


  • Katas Are Rehearsal, Not Performance
    You don't practice TDD on production code. You practice on katas and bring the muscle memory to production. The gap between knowing TDD and doing TDD is reps.
  • Agents Amplify Whatever Vocabulary They Find
    Agents do not bring vocabulary to your codebase. They mirror what's already there. Strong vocabulary gets agent contributions that read like the team. Weak vocabulary gets faster mediocrity. The work you did for craft reasons just became leverage.
  • The Hidden Output of TDD Was Never Code
    The visible artifact of TDD is a passing test suite. The actual artifact, the one that compounded value over the life of the codebase, was the vocabulary the team built while writing it. The dictionary, not the regression net.