Skip to content

Commit

Permalink
fix rules to support blank as they should rely on required to check i…
Browse files Browse the repository at this point in the history
…f required
  • Loading branch information
chrisjenx committed Oct 8, 2024
1 parent ee412c1 commit b0dee8f
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.chrisjenx.yakcov

@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION)
actual annotation class IOSIgnore()
1 change: 1 addition & 0 deletions library/src/commonMain/composeResources/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<string name="ruleMinValue">Must be at least %1$s</string>
<string name="ruleMaxValue">Must be at most %1$s</string>
<string name="ruleMinLength">Must be at least %1$s characters</string>
<string name="ruleMinLengthNoWhitespace">Must be at least %1$s characters excluding whitespace</string>
<string name="ruleMaxLength">Must be at most %1$s characters</string>
<string name="ruleEmail">Invalid email address</string>
<string name="rulePhone">Invalid phone number</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import yakcov.library.generated.resources.ruleInvalidDate
import yakcov.library.generated.resources.ruleMaxLength
import yakcov.library.generated.resources.ruleMaxValue
import yakcov.library.generated.resources.ruleMinLength
import yakcov.library.generated.resources.ruleMinLengthNoWhitespace
import yakcov.library.generated.resources.ruleMinValue
import yakcov.library.generated.resources.ruleMonth
import yakcov.library.generated.resources.ruleNumeric
Expand All @@ -40,6 +41,7 @@ data object Required : ValueValidatorRule<String> {
@Stable
data object Numeric : ValueValidatorRule<String> {
override fun validate(value: String): ValidationResult {
if (value.isBlank()) return ResourceValidationResult.success()
return if (value.toLongOrNull() == null) {
ResourceValidationResult.error(Res.string.ruleNumeric)
} else {
Expand All @@ -52,6 +54,7 @@ data object Numeric : ValueValidatorRule<String> {
@Stable
data object Decimal : ValueValidatorRule<String> {
override fun validate(value: String): ValidationResult {
if (value.isBlank()) return ResourceValidationResult.success()
return if (value.toFloatOrNull() == null) {
ResourceValidationResult.error(Res.string.ruleDecimal)
} else {
Expand All @@ -63,6 +66,7 @@ data object Decimal : ValueValidatorRule<String> {
@Stable
data class MinValue(val minValue: Number) : ValueValidatorRule<String> {
override fun validate(value: String): ValidationResult {
if (value.isBlank()) return ResourceValidationResult.success()
val number = value.toDoubleOrNull()
return if (number == null || number < minValue.toDouble()) {
ResourceValidationResult.error(Res.string.ruleMinValue, minValue)
Expand All @@ -75,6 +79,7 @@ data class MinValue(val minValue: Number) : ValueValidatorRule<String> {
@Stable
data class MaxValue(val maxValue: Float) : ValueValidatorRule<String> {
override fun validate(value: String): ValidationResult {
if (value.isBlank()) return ResourceValidationResult.success()
val number = value.toFloatOrNull()
return if (value.isNotBlank() && (number == null || number > maxValue)) {
ResourceValidationResult.error(Res.string.ruleMaxValue, maxValue)
Expand All @@ -84,13 +89,29 @@ data class MaxValue(val maxValue: Float) : ValueValidatorRule<String> {
}
}

/**
* @param trim if true will trim the start and end before checking the length
* @param includeWhiteSpace if false will not count white space chars in this string.
* As defined by [Char.isWhitespace]
*/
@Stable
data class MinLength(val minLength: Int) : ValueValidatorRule<String> {
data class MinLength(
val minLength: Int,
val trim: Boolean = true,
val includeWhiteSpace: Boolean = true,
) : ValueValidatorRule<String> {
override fun validate(value: String): ValidationResult {
return if (value.length < minLength) {
ResourceValidationResult.error(Res.string.ruleMinLength, minLength)
} else {
ResourceValidationResult.success()
val trimmed = value.let { if (trim) it.trim() else it }
return when {
includeWhiteSpace && trimmed.length < minLength -> {
ResourceValidationResult.error(Res.string.ruleMinLength, minLength)
}

!includeWhiteSpace && trimmed.count { !it.isWhitespace() } < minLength -> {
ResourceValidationResult.error(Res.string.ruleMinLengthNoWhitespace, minLength)
}

else -> ResourceValidationResult.success()
}
}
}
Expand All @@ -111,6 +132,7 @@ data class MaxLength(val maxLength: Int) : ValueValidatorRule<String> {
data object Email : ValueValidatorRule<String> {
override fun validate(value: String): ValidationResult {
// only validate if not empty as Required will check if not empty
if (value.isBlank()) return ResourceValidationResult.success()
return if (!value.isEmail()) {
ResourceValidationResult.error(Res.string.ruleEmail)
} else {
Expand All @@ -127,6 +149,7 @@ data object Email : ValueValidatorRule<String> {
data class Phone(val defaultRegion: String = "US") : ValueValidatorRule<String> {
override fun validate(value: String): ValidationResult {
// only validate if not empty as Required will check if not empty
if (value.isBlank()) return ResourceValidationResult.success()
return if (!value.isPhoneNumber(defaultRegion)) {
ResourceValidationResult.error(Res.string.rulePhone)
} else {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.chrisjenx.yakcov.strings

import com.chrisjenx.yakcov.IOSIgnore
import com.chrisjenx.yakcov.ValidationResult.Outcome
import com.chrisjenx.yakcov.initPhoneNumberUtil
import kotlin.test.BeforeTest
import kotlin.test.Test
import kotlin.test.assertEquals

class EmailRuleTest {

@Test
fun email_empty_success() {
assertEquals(Outcome.SUCCESS, Email.validate("").outcome())
}

@Test
fun email_invalid_error() {
assertEquals(Outcome.ERROR, Email.validate("43435").outcome())
}

@Test
fun email_valid_success() {
assertEquals(Outcome.SUCCESS, Email.validate("[email protected]").outcome())
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@ class PhoneRuleTest {
}

@Test
fun phoneNumber_invalid() {
fun phoneNumber_empty_success() {
assertEquals(Outcome.SUCCESS, Phone().validate("").outcome())
}

@Test
fun phoneNumber_invalid_error() {
assertEquals(Outcome.ERROR, Phone().validate("43435").outcome())
}

Expand All @@ -25,7 +30,7 @@ class PhoneRuleTest {
}

@Test
@IOSIgnore
@IOSIgnore // FIXME: This is failing on iOS, get cocoapods working so we can use libphonenumber on iOS.
fun phoneNumber_wrongRegion() {
// This is a UK number should error for US
assertEquals(Outcome.ERROR, Phone("US").validate("07745973912").outcome())
Expand Down

0 comments on commit b0dee8f

Please sign in to comment.