Solution: Creating user table row

private fun TableBuilder.userRow(user: User) { tr { td { +user.id } td { +user.name } td { +user.points.toString() } td { +user.category } } }

Example solution in playground

import org.junit.Test import kotlin.test.assertEquals data class User(val id: String, val name: String, val points: Int, val category: String) fun userTable(users: List<User>): TableBuilder = table { tr { td { +"Id" } td { +"Name" } td { +"Points" } td { +"Category" } } for (user in users) { userRow(user) } } private fun TableBuilder.userRow(user: User) { tr { td { +user.id } td { +user.name } td { +user.points.toString() } td { +user.category } } } fun main() { val users = listOf( User("1", "Randy", 2, "A"), User("4", "Andy", 4, "B"), User("3", "Mandy", 1, "C"), User("5", "Cindy", 5, "A"), User("2", "Lindy", 3, "B"), ) // val table = userTable(users) // println(table) // <table> // <tr><td>Id</td><td>Name</td> // <td>Points</td><td>Category</td></tr> // <tr><td>1</td><td>Randy</td><td>2</td><td>A</td></tr> // <tr><td>4</td><td>Andy</td><td>4</td><td>B</td></tr> // <tr><td>3</td><td>Mandy</td><td>1</td><td>C</td></tr> // <tr><td>5</td><td>Cindy</td><td>5</td><td>A</td></tr> // <tr><td>2</td><td>Lindy</td><td>3</td><td>B</td></tr> // </table> } fun table(init: TableBuilder.() -> Unit): TableBuilder = TableBuilder().apply(init) data class TableBuilder( var trs: List<TrBuilder> = emptyList() ) { fun tr(init: TrBuilder.() -> Unit) { trs += TrBuilder().apply(init) } override fun toString(): String = "<table>${trs.joinToString(separator = "")}</table>" } data class TrBuilder( var tds: List<TdBuilder> = emptyList() ) { fun td(init: TdBuilder.() -> Unit) { tds += TdBuilder().apply(init) } override fun toString(): String = "<tr>${tds.joinToString(separator = "")}</tr>" } data class TdBuilder(var text: String = "") { operator fun String.unaryPlus() { text += this } override fun toString(): String = "<td>$text</td>" } class StudentTableTest { @Test fun `should work for empty list`() { // when val result = userTable(listOf()) // then val expected = TableBuilder().apply { trs += TrBuilder().apply { tds += TdBuilder().apply { text = "Id" } tds += TdBuilder().apply { text = "Name" } tds += TdBuilder().apply { text = "Points" } tds += TdBuilder().apply { text = "Category" } } } assertEquals(expected, result) } @Test fun `should work for a list with a single element`() { // given val users = listOf( User("1", "Randy", 2, "A"), ) // when val result = userTable(users) // then val expected = TableBuilder().apply { trs += TrBuilder().apply { tds += TdBuilder().apply { text = "Id" } tds += TdBuilder().apply { text = "Name" } tds += TdBuilder().apply { text = "Points" } tds += TdBuilder().apply { text = "Category" } } trs += TrBuilder().apply { tds += TdBuilder().apply { text = "1" } tds += TdBuilder().apply { text = "Randy" } tds += TdBuilder().apply { text = "2" } tds += TdBuilder().apply { text = "A" } } } assertEquals(expected, result) } @Test fun `should work for a list with multiple users`() { // given val users = listOf( User("1", "Randy", 2, "A"), User("4", "Andy", 4, "B"), User("3", "Mandy", 1, "C"), User("5", "Cindy", 5, "A"), User("2", "Lindy", 3, "B"), ) // when val result = userTable(users) // then val expected = TableBuilder().apply { trs += TrBuilder().apply { tds += TdBuilder().apply { text = "Id" } tds += TdBuilder().apply { text = "Name" } tds += TdBuilder().apply { text = "Points" } tds += TdBuilder().apply { text = "Category" } } for (user in users) { trs += TrBuilder().apply { tds += TdBuilder().apply { text = user.id } tds += TdBuilder().apply { text = user.name } tds += TdBuilder().apply { text = user.points.toString() } tds += TdBuilder().apply { text = user.category } } } } assertEquals(expected, result) } }