URL Parts

Level: Intermediate 30–60 min

Concepts: ParsingStrings

Solutions: C# | TypeScript | Python


Decomposes a given URL into its parts.

For example when the URL https://www.tddbuddy.com is decomposed into its parts.

PartValue
Protocolhttp
Subdomainwww
Domaintddbuddy.com
Port80 (Default for HTTP)
Path” (Empty in our case)

Please be sure to handle the following:

  • Only top level domains like .com or .net.
    • Do not worry second level domains like .co.uk or co.za
  • Only the protocols specified in the default ports section below.
  • Be sure to deal with local network hostname only cases. E.g. http://localhost

Do not use built-in classes like Uri to solve this.

Default Ports

http: 80, https: 443, ftp: 21, sftp: 22

Examples

Examples
URL: http://foo.bar.com/foobar.html
Protocol: http
Subdomain: foo
Domain name: bar.com
Port: 80
Path: foobar.html
URL: https://www.foobar.com:8080/download/install.exe
Protocol: https
Subdomain: www
Domain name: foobar.com
Port: 8080
Path: download/installer.exe
URL: ftp://foo.com:9000/files
Protocol: ftp
Subdomain: '' (empty string)
Domain name: foo.com
Port: 9000
Path: files
URL: https://localhost/index.html#footer
Protocol: https
Subdomain: '' (empty string)
Domain name: localhost
Port: 443
Path: index.html

Hints

Exclude the leading / when handling path. E.g. /download becomes download.

URL Grammar

Below is a EBNF like grammar for a URL as per this kata.

url = protocol ”://” [subdomain] host [top-level-domain] [”:” port] [path] [”?” parameters] [”#” anchor]

protocol = “http” | “https” | “ftp” | “sftp”

subdomain = alphanumeric string starting with alpha

host = alphanumeric string

top-level-domain = “.com” | “.net” | “.org” | “.int” | “.edu” | “.gov” | “.mil”

port = numeric

path = alphanumeric string

parameters = alphanumeric string

anchor = alphanumeric string

Reference Walkthrough

Reference implementations in C#, TypeScript, and Python live at tddbuddy-reference-katas/url-parts. Ten shared scenarios cover the four protocols (http, https, ftp, sftp) with their default ports, explicit ports, paths with and without query strings, fragments, and the bare localhost host — satisfied identically across all three languages.

This kata ships in Agent Full-Bake mode at high gear (F1 tier): the algorithm is small enough to land as one commit per language. There are no builders — the parse returns a typed UrlParts record (C# record, TS interface, Python @dataclass(frozen=True)) which is a data shape, not a fluent construction API. No regex and no built-in URL classes (System.Uri, new URL, urllib.parse) per the prompt: each language hand-rolls a left-to-right peel — anchor, then parameters, then path, then port, then host — so the order of operations stays visible in the code. See the repo’s Gears section for when high gear is the right call.


  • 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.
  • Test Deletion Is a Privileged Operation
    The cheapest way for an agent to make a failing test pass is to delete it. That is logical for the agent and catastrophic for the codebase. Tests are append-only by default. Deletion needs a human author, a separate commit, and a separate review.
  • Refactor Was Always Where Compounding Lived
    Red and green were the visible two thirds of TDD. Refactor was the optional polish. Codebases that compound did the refactor pass; codebases that accrete did not. Agents skip refactor by default because it has no green-bar reward, and a year of skipped refactors is how a codebase loses its shape.