Skip to content

Commit

Permalink
[#41] Formatting-Options like lowercase, uppercase, capitalize
Browse files Browse the repository at this point in the history
  • Loading branch information
comahe-de committed Nov 16, 2023
1 parent ae7cd84 commit 945eee8
Show file tree
Hide file tree
Showing 5 changed files with 199 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import de.comahe.i18n4k.Locale
import de.comahe.i18n4k.messages.formatter.parsing.MessageFormatContext
import de.comahe.i18n4k.messages.formatter.parsing.MessageParser
import de.comahe.i18n4k.messages.formatter.parsing.MessagePart
import de.comahe.i18n4k.strings.LocalizedString
import de.comahe.i18n4k.messages.formatter.types.MessageNumberFormatters
import de.comahe.i18n4k.messages.formatter.types.MessageTransformFormatters
import kotlinx.atomicfu.atomic
import kotlinx.atomicfu.update
import kotlinx.collections.immutable.persistentMapOf
Expand Down Expand Up @@ -77,7 +78,9 @@ object MessageFormatterDefault : MessageFormatter {

private val messageFormatContext = atomic(
MessageFormatContext(
MessageNumberFormatters.all.associateBy({ it.typeId }, { it }).toPersistentMap()
(MessageNumberFormatters.all
+ MessageTransformFormatters.all)
.associateBy({ it.typeId }, { it }).toPersistentMap()
)
)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package de.comahe.i18n4k.messages.formatter
package de.comahe.i18n4k.messages.formatter.types

import de.comahe.i18n4k.Locale
import de.comahe.i18n4k.messages.formatter.MessageValueFormatter
import de.comahe.i18n4k.messages.formatter.parsing.MessageFormatContext
import de.comahe.i18n4k.messages.formatter.parsing.StylePart
import de.comahe.i18n4k.messages.formatter.parsing.toSimple
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package de.comahe.i18n4k.messages.formatter.types

import de.comahe.i18n4k.Locale
import de.comahe.i18n4k.messages.formatter.MessageValueFormatter
import de.comahe.i18n4k.messages.formatter.parsing.MessageFormatContext
import de.comahe.i18n4k.messages.formatter.parsing.StylePart
import de.comahe.i18n4k.messages.formatter.parsing.toSimple
import kotlinx.collections.immutable.persistentListOf

/**
* Provides the possibility to transform the letters to uppercase,
* lowercase or capitalize (uppercase the first letter, rest lowercase).
*
* Format:
*
* {~, FORMAT_OPTION, TEXT_WITH_PATTERNS}
* - FORMAT_OPTION
* - uppercase: transform all letters to uppercase
* - lowercase: transform all letters to lowercase
* - capitalize: transform the first letter to uppercase
* - TEXT_WITH_PATTERNS: Any text including patterns.
*
* Example:
*
* {~, capitalize, {0} } is the best!
*
* Result for "ice": Ice is the best!
*/
object MessageTransformFormatters {
val all = persistentListOf(
UppercaseFormatter, LowercaseFormatter, CapitalizeFormatter
)

abstract class TransformFormatter(override val typeId: String) : MessageValueFormatter {

override fun format(
result: StringBuilder,
value: Any?,
style: StylePart?,
parameters: List<Any>,
locale: Locale,
context: MessageFormatContext,
) {
val textToTransform = style?.toSimple()?.format(parameters, locale, context)
?: return
result.ensureCapacity(result.length + textToTransform.length)
formatString(result, textToTransform)
}

protected abstract fun formatString(
result: StringBuilder,
value: CharSequence,
)
}

object UppercaseFormatter : TransformFormatter("uppercase") {
override fun formatString(
result: StringBuilder,
value: CharSequence,
) {
for (c in value)
result.append(c.uppercaseChar())
}
}

object LowercaseFormatter : TransformFormatter("lowercase") {
override fun formatString(
result: StringBuilder,
value: CharSequence,
) {
for (c in value)
result.append(c.lowercaseChar())
}
}

object CapitalizeFormatter : TransformFormatter("capitalize") {
override fun formatString(
result: StringBuilder,
value: CharSequence,
) {
if (value.isEmpty())
return
result.append(value[0].uppercaseChar())
for (i in 1 until value.length)
result.append(value[i])
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package da.comahe.i18n4k

import de.comahe.i18n4k.Locale
import de.comahe.i18n4k.config.I18n4kConfigDefault
import de.comahe.i18n4k.i18n4k
import de.comahe.i18n4k.messages.formatter.MessageFormatterDefault.format
import kotlin.test.BeforeTest
import kotlin.test.Test
import kotlin.test.assertEquals

class MessageNumberFormattersTest {

private var i18n4kConfig = I18n4kConfigDefault()

@BeforeTest
fun init() {
i18n4k = i18n4kConfig
i18n4kConfig.restoreDefaultSettings()
}

/**
* Test formats of
* [de.comahe.i18n4k.messages.formatter.types.MessageNumberFormatters]
*/
@Test
fun format_parameterNumberTest() {
val locale = Locale("en")
val params = listOf(12345.6789)

assertEquals("12,345.6789 #", format("{0,number} #", params, locale))
assertEquals("12,345.68 #", format("{0,number, %.2} #", params, locale))
assertEquals("12,345.6789 #", format("{0,number, %.6} #", params, locale))
assertEquals("12,345.678900 #", format("{0,number, %.06} #", params, locale))
assertEquals("12.3456789 km #", format("{0,length} #", params, locale))
assertEquals("12.35 km #", format("{0,length, %.2} #", params, locale))
assertEquals("12.3456789 km #", format("{0,length, %.9} #", params, locale))
assertEquals("12.345678900 km #", format("{0,length, %.09} #", params, locale))
assertEquals("12,345.6789 m² #", format("{0,area} #", params, locale))
assertEquals("12,345.68 m² #", format("{0,area, %.2} #", params, locale))
assertEquals("12,345.6789 m² #", format("{0,area, %.6} #", params, locale))
assertEquals("12,345.678900 m² #", format("{0,area, %.06} #", params, locale))
assertEquals("12.3456789 kg #", format("{0,weight} #", params, locale))
assertEquals("12.35 kg #", format("{0,weight, %.2} #", params, locale))
assertEquals("12.3456789 kg #", format("{0,weight, %.9} #", params, locale))
assertEquals("12.345678900 kg #", format("{0,weight, %.09} #", params, locale))
assertEquals("3:25:46 h #", format("{0,timespan} #", params, locale))


}

@Test
fun format_parameterNumberTest_de() {
val locale = Locale("de")
val params = listOf(12345.6789)

assertEquals("12.345,6789 #", format("{0,number} #", params, locale))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package da.comahe.i18n4k

import de.comahe.i18n4k.Locale
import de.comahe.i18n4k.config.I18n4kConfigDefault
import de.comahe.i18n4k.i18n4k
import de.comahe.i18n4k.messages.formatter.MessageFormatterDefault.format
import kotlin.test.BeforeTest
import kotlin.test.Test
import kotlin.test.assertEquals

class MessageTransformFormattersTest {

private var i18n4kConfig = I18n4kConfigDefault()

@BeforeTest
fun init() {
i18n4k = i18n4kConfig
i18n4kConfig.restoreDefaultSettings()
}

/**
* Test formats of
* [de.comahe.i18n4k.messages.formatter.types.MessageTransformFormatters]
*/
@Test
fun test_transform() {
val locale = Locale("en")
val params = listOf("hello WORLD")

assertEquals("HELLO WORLD!", format("{~, uppercase, {0} }!", params, locale))
assertEquals("hello world!", format("{~, lowercase, {0} }!", params, locale))
assertEquals("Hello WORLD!", format("{~, capitalize, {0} }!", params, locale))

assertEquals("@hello WORLD!", format("{~, capitalize, @{0} }!", params, locale))
}

@Test
fun test_invalid() {
val locale = Locale("en")
val params = listOf("hello WORLD")

assertEquals("!", format("{~, uppercase }!", params, locale))
assertEquals("{1}!", format("{~, lowercase, {1} }!", params, locale))
assertEquals("{1}!", format("{~, capitalize, {1} | {0} }!", params, locale))
}
}

0 comments on commit 945eee8

Please sign in to comment.