Skip to content

Instantly share code, notes, and snippets.

@juan-medina
Created December 1, 2019 11:52
Show Gist options
  • Save juan-medina/7f865fa1a8eceb2d279f56260e75159c to your computer and use it in GitHub Desktop.
Save juan-medina/7f865fa1a8eceb2d279f56260e75159c to your computer and use it in GitHub Desktop.
kotlin-contacts-agenda
plugins {
kotlin("jvm") version "1.3.61"
}
group = "org.meda.juan"
version = "1.0-SNAPSHOT"
repositories {
mavenCentral()
}
dependencies {
implementation(kotlin("stdlib-jdk8"))
testImplementation("org.junit.jupiter:junit-jupiter-api:5.6.0-M1")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.6.0-M1")
testImplementation("com.timeular.nytta.prova:hamkrest:2.4.0")
}
tasks {
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
kotlinOptions.jvmTarget = "1.8"
}
test {
useJUnitPlatform()
}
}
import com.natpryce.hamkrest.assertion.assertThat
import com.natpryce.hamkrest.equalTo
import org.junit.jupiter.api.Test
import java.io.File
// Implement a Phone Directory
//
// Given a list of contacts which exist in a phone directory. The task is to implement search query for the phone directory.
// The search query on a string ‘str’ displays all the contacts which prefix as ‘str’.
// One special property of the search function is that, when a user searches for a contact from the contact list then
// suggestions (Contacts with prefix as the string entered so for) are shown after user enters each character.
//
// Note : Contacts in the list consist of only lower case alphabets.
class ContactsAgendaTests {
companion object {
fun generateTestFile(data: List<String>) : String = with(File.createTempFile("contacts", ".txt")) {
this.deleteOnExit()
this.outputStream().use { ost ->
ost.bufferedWriter().use { writer ->
data.forEach {
writer.appendln(it)
}
}
}
this.absolutePath
}
}
data class TestCase(val text: String, val expected: Int)
@Test
fun `we should search for contacts`() {
val testFile = generateTestFile(listOf(
"juan medina +44341",
"juan brena +78912",
"invalid"
))
val tests = arrayOf(
TestCase("juan", 2),
TestCase("brena", 1),
TestCase("medina", 1),
TestCase("pepe", 0),
TestCase("invalid", 0)
)
val phoneDirectory = PhoneDirectory(testFile)
tests.forEach {
var count = 0
phoneDirectory.search(it.text) {
count++
}
assertThat("case '${it.text}'", count, equalTo(it.expected))
}
}
@Test
fun `we should find a concrete contact`() {
val testFile = generateTestFile(listOf(
"juan medina +44341",
"juan brena +78912"
))
val phoneDirectory = PhoneDirectory(testFile)
var results = 0
phoneDirectory.search("medina") {
assertThat(it.name, equalTo("juan medina"))
assertThat(it.telephone, equalTo("+44341"))
results++
}
assertThat(results, equalTo(1))
}
}
kotlin.code.style=official
import java.io.BufferedReader
import java.io.File
data class Contact(val name: String, val telephone: String) {
companion object {
fun fromLine(line: String) = with(line.lastIndexOf(" ")) {
if (this != -1) {
Contact(line.substring(0, this), line.substring(this + 1))
} else {
null
}
}
}
}
class PhoneDirectory(private val fileName: String) {
private fun streamFile(streamer: (BufferedReader) -> Unit) {
with(File(fileName)) {
if (this.exists()) {
this.inputStream().use { ins ->
ins.bufferedReader().use {
streamer(it)
}
}
}
}
}
private fun forEachLine(matcher: (String) -> Unit) {
streamFile {
var line = it.readLine()
while (line != null) {
matcher(line)
line = it.readLine()
}
}
}
fun search(text: String, found: (contact: Contact) -> Unit) {
forEachLine {
val possible = Contact.fromLine(it)
if (possible != null) {
if (text in possible.name) {
found(possible)
}
}
}
}
}
rootProject.name = "kotlin-contacts-agenda"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment