Skip to content

Commit

Permalink
feat: invoke AString format args
Browse files Browse the repository at this point in the history
  • Loading branch information
tynn committed Dec 3, 2023
1 parent ed62b7c commit aa328d3
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 41 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: gradle/wrapper-validation-action@v1
- uses: actions/setup-java@v3
- uses: actions/setup-java@v4
with:
distribution: adopt
java-version: 17
Expand All @@ -29,7 +29,7 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: gradle/wrapper-validation-action@v1
- uses: actions/setup-java@v3
- uses: actions/setup-java@v4
with:
distribution: adopt
java-version: 17
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: gradle/wrapper-validation-action@v1
- uses: actions/setup-java@v3
- uses: actions/setup-java@v4
with:
distribution: adopt
java-version: 17
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public class ParcelableAStringTest {
private static final int RES_ID = 123;
private static final int QUANTITY = 456;
private static final AString FORMAT = new Format();
private static final Object[] FORMAT_ARGS = {"arg1", 2, 3L, 4.5, 6F, new Date()};
private static final Object[] FORMAT_ARGS = {"arg1", 2, 3L, 4.5, 6F, new Date(), Wrapper.wrap("test-string")};

@Test
public void Wrapper_should_implement_parcelable() {
Expand Down Expand Up @@ -115,7 +115,7 @@ private static class Format implements AString {
@Nullable
@Override
public String invoke(@NonNull Context context) {
return "%s%d%d%f%f%s";
return "%s%d%d%f%f%s%s";
}

@Override
Expand Down
28 changes: 25 additions & 3 deletions astring/src/main/java/xyz/tynn/astring/ToString.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import static androidx.core.os.ParcelCompat.readParcelable;
import static androidx.core.os.ParcelCompat.readSerializable;
import static java.lang.String.format;
import static java.util.Arrays.copyOf;
import static xyz.tynn.astring.Wrapper.NULL;

import android.content.Context;
Expand All @@ -28,12 +29,20 @@ final class ToString implements AString {

private final AString delegate;
private final Locale locale;
private final Object[] formatArgs;
private final Object[] formatArgs, aStringArgs;

private ToString(AString delegate, Locale locale, Object[] formatArgs) {
this.delegate = delegate;
this.locale = locale;
this.formatArgs = formatArgs;
this.aStringArgs = maybeCopyFormatArgs(formatArgs);
}

private static Object[] maybeCopyFormatArgs(Object[] formatArgs) {
if (formatArgs != null) for (Object arg : formatArgs)
if (arg instanceof AString)
return copyOf(formatArgs, formatArgs.length, Object[].class);
return null;
}

static AString wrap(AString delegate, Locale locale, Object[] formatArgs) {
Expand All @@ -53,8 +62,21 @@ static AString wrap(AString delegate, Locale locale, Object[] formatArgs) {
@Override
public String invoke(@NonNull Context context) {
CharSequence formatString = delegate.invoke(context);
return formatString == null ? null : formatArgs == null ? formatString.toString()
: format(getLocale(context), formatString.toString(), formatArgs);
if (formatString == null) return null;
Object[] formatArgs = getFormatArgs(context);
if (formatArgs == null) return formatString.toString();
return format(getLocale(context), formatString.toString(), formatArgs);
}

private Object[] getFormatArgs(Context context) {
Object[] formatArgs = this.formatArgs;
if (formatArgs == null) return null;
Object[] aStringArgs = this.aStringArgs;
if (aStringArgs == null) return formatArgs;
for (int i = 0; i < formatArgs.length; i++)
if (formatArgs[i] instanceof AString)
aStringArgs[i] = ((AString) formatArgs[i]).invoke(context);
return aStringArgs;
}

@SuppressWarnings("deprecation")
Expand Down
70 changes: 40 additions & 30 deletions astring/src/test/kotlin/xyz/tynn/astring/ToStringTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ internal class ToStringTest {

private val locale = Locale.CANADA
private val format = Format()
private val formatArgs = arrayOf('1', 2, "3")

@Test
fun `invoke should return string without locale`() {
Expand All @@ -28,17 +29,24 @@ internal class ToStringTest {
}

assertEquals(
"23",
ToString.wrap(format, null, arrayOf(2, "3")).invoke(context),
"123",
ToString.wrap(format, null, formatArgs).invoke(context),
)
}

@Test
fun `invoke should return string with locale`() {
assertEquals(
"23",
ToString.wrap(format, locale, arrayOf(2, "3"))
.invoke(mockk()),
"123",
ToString.wrap(format, locale, formatArgs).invoke(mockk()),
)
}

@Test
fun `invoke should invoke AString args`() {
assertEquals(
"123",
ToString.wrap(format, locale, arrayOf("1".asAString(), 2, "3")).invoke(mockk()),
)
}

Expand All @@ -65,20 +73,20 @@ internal class ToStringTest {
ToString.wrap(format, locale, arrayOf())
}
assertTrue {
ToString.wrap(format, null, arrayOf(2, "3")) ==
ToString.wrap(format, null, arrayOf(2, "3"))
ToString.wrap(format, null, formatArgs) ==
ToString.wrap(format, null, formatArgs)
}
assertTrue {
ToString.wrap(format, locale, arrayOf(2, "3")) ==
ToString.wrap(format, locale, arrayOf(2, "3"))
ToString.wrap(format, locale, formatArgs) ==
ToString.wrap(format, locale, formatArgs)
}
}

@Test
fun `equals should be false for non matching locales`() {
assertFalse {
ToString.wrap(format, Locale.GERMAN, arrayOf(2, "3")) ==
ToString.wrap(format, locale, arrayOf(2, "3"))
ToString.wrap(format, Locale.GERMAN, formatArgs) ==
ToString.wrap(format, locale, formatArgs)
}
}

Expand All @@ -89,28 +97,28 @@ internal class ToStringTest {
ToString.wrap(TextResource(1), null, arrayOf())
}
assertFalse {
ToString.wrap(format, null, arrayOf(2, "3")) ==
ToString.wrap(TextResource(1), null, arrayOf(2, "3"))
ToString.wrap(format, null, formatArgs) ==
ToString.wrap(TextResource(1), null, formatArgs)
}
}

@Test
fun `equals should be false for non matching format args`() {
assertFalse {
ToString.wrap(format, null, arrayOf(2, 3)) ==
ToString.wrap(format, null, arrayOf("2", "3"))
ToString.wrap(format, null, arrayOf(1, 2, 3)) ==
ToString.wrap(format, null, formatArgs)
}
assertFalse {
ToString.wrap(format, locale, arrayOf(2, 3)) ==
ToString.wrap(format, locale, arrayOf("2", "3"))
ToString.wrap(format, locale, arrayOf(1, 2, 3)) ==
ToString.wrap(format, locale, formatArgs)
}
assertFalse {
ToString.wrap(format, null, arrayOf()) ==
ToString.wrap(format, null, arrayOf(2, "3"))
ToString.wrap(format, null, formatArgs)
}
assertFalse {
ToString.wrap(format, locale, arrayOf()) ==
ToString.wrap(format, locale, arrayOf(2, "3"))
ToString.wrap(format, locale, formatArgs)
}
}

Expand Down Expand Up @@ -152,13 +160,12 @@ internal class ToStringTest {
ToString.wrap(format, locale, arrayOf()).hashCode(),
)
assertEquals(
41436,
ToString.wrap(format, null, arrayOf(2, "3")).hashCode(),
117355,
ToString.wrap(format, null, formatArgs).hashCode(),
)
assertEquals(
-1299735837,
ToString.wrap(format, locale, arrayOf(2, "3"))
.hashCode(),
-1299659918,
ToString.wrap(format, locale, formatArgs).hashCode(),
)
}

Expand All @@ -169,18 +176,21 @@ internal class ToStringTest {
ToString.wrap(format, null, arrayOf()).toString(),
)
assertEquals(
"AString(Format($format,2,3))",
ToString.wrap(format, null, arrayOf(2, "3")).toString(),
"AString(Format($format,AString(CharSequence(1))))",
ToString.wrap(format, null, arrayOf("1".asAString())).toString(),
)
assertEquals(
"AString(Format($format,1,2,3))",
ToString.wrap(format, null, formatArgs).toString(),
)
assertEquals(
"AString(Format($locale,$format,2,3))",
ToString.wrap(format, locale, arrayOf(2, "3"))
.toString(),
"AString(Format($locale,$format,1,2,3))",
ToString.wrap(format, locale, formatArgs).toString(),
)
}

private class Format : AString {
override fun invoke(context: Context) = "%d%s"
override fun invoke(context: Context) = "%s%d%s"
override fun writeToParcel(dest: Parcel, flags: Int) = Unit
override fun equals(other: Any?) = other is Format
override fun hashCode() = 11
Expand Down
4 changes: 2 additions & 2 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[versions]
android = "8.1.4"
compose-compiler = "1.5.4"
android = "8.2.0"
compose-compiler = "1.5.5"
kotlin = "1.9.21"

[plugins]
Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-all.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down

0 comments on commit aa328d3

Please sign in to comment.