Skip to content

Commit

Permalink
Introduce DSL for cleaner API SaveRequests
Browse files Browse the repository at this point in the history
  • Loading branch information
alexstyl committed Nov 23, 2021
1 parent 46a3d70 commit b984774
Show file tree
Hide file tree
Showing 6 changed files with 307 additions and 6 deletions.
2 changes: 2 additions & 0 deletions library/build.gradle
Expand Up @@ -50,4 +50,6 @@ dependencies {
androidTestImplementation "androidx.test:runner:$testRunnerVersion"
androidTestImplementation "androidx.test:rules:$testRulesVersion"
androidTestImplementation "androidx.test:core:$testCoreVersion"
testImplementation "junit:junit:$junitVersion"
testImplementation "org.assertj:assertj-core:$assertjVersion"
}
37 changes: 37 additions & 0 deletions library/src/main/java/com/alexstyl/contactstore/ContactStoreDSL.kt
@@ -0,0 +1,37 @@
package com.alexstyl.contactstore

suspend fun ContactStore.execute(request: SaveRequest.() -> Unit) {
execute(SaveRequest().apply(request))
}

fun SaveRequest.insert(builder: MutableContactBuilder.() -> Unit) {
val values = MutableContactBuilder().apply(builder)
insert(MutableContact().apply {
isStarred = values.isStarred
imageData = values.imageData

prefix = values.prefix
firstName = values.firstName
middleName = values.middleName
lastName = values.lastName
suffix = values.suffix

fullNameStyle = values.fullNameStyle
phoneticFirstName = values.phoneticFirstName
phoneticLastName = values.phoneticLastName
phoneticMiddleName = values.phoneticMiddleName

nickname = values.nickname
note = values.note?.let { Note(it) }

jobTitle = values.jobTitle
organization = values.organization

phones.addAll(values.phones)
mails.addAll(values.mails)
events.addAll(values.events)
postalAddresses.addAll(values.postalAddresses)
webAddresses.addAll(values.webAddresses)
groups.addAll(values.groupMemberships)
})
}
12 changes: 6 additions & 6 deletions library/src/main/java/com/alexstyl/contactstore/DataClasses.kt
Expand Up @@ -29,12 +29,12 @@ data class WebAddress(val raw: String)

data class PostalAddress(
val street: String,
val poBox: String,
val neighborhood: String,
val city: String,
val region: String,
val postCode: String,
val country: String
val poBox: String = "",
val neighborhood: String = "",
val city: String = "",
val region: String = "",
val postCode: String = "",
val country: String = "",
)

@Suppress("MagicNumber")
Expand Down
@@ -0,0 +1,111 @@
package com.alexstyl.contactstore

import android.provider.ContactsContract

data class MutableContactBuilder(
var prefix: String = "",
var firstName: String = "",
var middleName: String = "",
var lastName: String = "",
var suffix: String = "",
var fullNameStyle: Int = ContactsContract.FullNameStyle.UNDEFINED,
var phoneticNameStyle: Int = ContactsContract.PhoneticNameStyle.UNDEFINED,
var phoneticFirstName: String = "",
var phoneticMiddleName: String = "",
var phoneticLastName: String = "",
var nickname: String = "",
var note: String? = null,
var jobTitle: String = "",
var organization: String = "",
var imageData: ImageData? = null,
var isStarred: Boolean = false,
) {
private val _phones: MutableList<LabeledValue<PhoneNumber>> = mutableListOf()
val phones: List<LabeledValue<PhoneNumber>>
get() = _phones.toList()

private val _mails: MutableList<LabeledValue<MailAddress>> = mutableListOf()
val mails: List<LabeledValue<MailAddress>>
get() = _mails.toList()

private val _events: MutableList<LabeledValue<EventDate>> = mutableListOf()
val events: List<LabeledValue<EventDate>>
get() = _events.toList()

private val _postalAddresses: MutableList<LabeledValue<PostalAddress>> = mutableListOf()
val postalAddresses: List<LabeledValue<PostalAddress>>
get() = _postalAddresses.toList()

private val _webAddresses: MutableList<LabeledValue<WebAddress>> = mutableListOf()
val webAddresses: List<LabeledValue<WebAddress>>
get() = _webAddresses.toList()

private val _groups: MutableList<GroupMembership> = mutableListOf()
val groupMemberships: List<GroupMembership>
get() = _groups.toList()

fun phone(
number: String,
label: Label
) {
_phones.add(LabeledValue(PhoneNumber(number), label))
}

fun mail(
address: String,
label: Label
) {
_mails.add(LabeledValue(MailAddress(address), label))
}

fun event(dayOfMonth: Int, month: Int, year: Int? = null, label: Label) {
_events.add(
LabeledValue(EventDate(dayOfMonth = dayOfMonth, month = month, year = year), label)
)
}

fun postalAddress(
street: String,
poBox: String = "",
neighborhood: String = "",
city: String = "",
region: String = "",
postCode: String = "",
country: String = "",
label: Label
) {
_postalAddresses.add(
LabeledValue(
value = PostalAddress(
street = street,
poBox = poBox,
neighborhood = neighborhood,
city = city,
region = region,
postCode = postCode,
country = country,
),
label = label
)
)
}

fun postalAddress(fullAddress: String, label: Label) {
_postalAddresses.add(
LabeledValue(
value = PostalAddress(fullAddress),
label = label
)
)
}

fun webAddress(address: String, label: Label) {
_webAddresses.add(LabeledValue(WebAddress(address), label))
}

fun groupMembership(groupId: Long) {
_groups.add(
GroupMembership(groupId)
)
}
}
19 changes: 19 additions & 0 deletions library/src/main/java/com/alexstyl/contactstore/SaveRequest.kt
Expand Up @@ -35,4 +35,23 @@ class SaveRequest {
fun delete(contactId: Long) {
_requests.add(Delete(contactId))
}

override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false

other as SaveRequest

if (_requests != other._requests) return false

return true
}

override fun hashCode(): Int {
return _requests.hashCode()
}

override fun toString(): String {
return "SaveRequest(_requests=$_requests)"
}
}
@@ -0,0 +1,132 @@
package com.alexstyl.contactstore

import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.runBlocking
import org.assertj.core.api.Assertions.assertThat
import org.junit.Test

class ContactStoreDSLKtTest {

@Test
fun insert(): Unit = runBlocking {
val store = contactStore()
store.execute {
insert {
prefix = "pref"
firstName = "Paolo"
middleName = "Mid"
lastName = "Melendez"
suffix = "Suf"
note = "Note to self"
jobTitle = "Job Title"
organization = "Org"

imageData = ImageData("image data".toByteArray())
isStarred = false
phone(
number = "555-11-23",
label = Label.LocationHome
)

mail(
address = "paolo@paolo.com",
label = Label.LocationWork
)
event(
dayOfMonth = 3,
month = 12,
year = 2021,
label = Label.DateBirthday
)

postalAddress(
street = "85 Somewhere Str",
label = Label.LocationHome
)

webAddress(
address = "www.paolo.com",
label = Label.LocationWork
)
groupMembership(groupId = 123)
}
}
assertThat(store.request).isEqualTo(
SaveRequest().apply {
insert(MutableContact().apply {
prefix = "pref"
firstName = "Paolo"
middleName = "Mid"
lastName = "Melendez"
suffix = "Suf"
note = Note("Note to self")
jobTitle = "Job Title"
organization = "Org"

imageData = ImageData("image data".toByteArray())
isStarred = false
phones.add(
LabeledValue(
value = PhoneNumber("555-11-23"),
label = Label.LocationHome
)
)
mails.add(
LabeledValue(
value = MailAddress("paolo@paolo.com"),
label = Label.LocationWork
)
)
events.add(
LabeledValue(
value = EventDate(
dayOfMonth = 3,
month = 12,
year = 2021,
),
label = Label.DateBirthday
)
)

postalAddresses.add(
LabeledValue(
PostalAddress(street = "85 Somewhere Str"),
Label.LocationHome
)
)

webAddresses.add(
LabeledValue(
value = WebAddress("www.paolo.com"),
label = Label.LocationWork
)
)
groups.add(
GroupMembership(123)
)
})
}
)
}

private fun contactStore(): TestContactStore {
return TestContactStore()
}

private class TestContactStore : ContactStore {

var request: SaveRequest? = null

override suspend fun execute(request: SaveRequest) {
this.request = request
}

override fun fetchContacts(
predicate: ContactPredicate?,
columnsToFetch: List<ContactColumn>
): Flow<List<Contact>> {
return emptyFlow()
}
}
}

0 comments on commit b984774

Please sign in to comment.