-
Notifications
You must be signed in to change notification settings - Fork 6
Handle date/time conversion in runtime #258
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
to handle converting to ICU Calendar
plugin/src/main/java/app/cash/paraphrase/plugin/ResourceWriter.kt
Outdated
Show resolved
Hide resolved
| private val Iso8601Locale by lazy(LazyThreadSafetyMode.NONE) { | ||
| ULocale.Builder() | ||
| .setExtension('u', "ca-iso8601") | ||
| .build() | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since AndroidDateTimeConverter is an object, this ULocale instantiation was happening immediately when FormattedResources was accessed, causing the JVM test to (still) crash. Loading it lazily avoids this.
sample/library/src/test/kotlin/app/cash/paraphrase/sample/library/JvmDateTimeConverter.kt
Show resolved
Hide resolved
This prevents the ULocale from being instantiated at class-loading time, which would crash JVM tests due to the missing Android implementation.
7fa0ec6 to
83c9523
Compare
JakeWharton
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Definitely not sure how I feel about this. It's basically Dispatchers.setMain which is my mortal enemy.
plugin/src/main/java/app/cash/paraphrase/plugin/ResourceWriter.kt
Outdated
Show resolved
Hide resolved
| @Before fun substituteDateTimeConverter() { | ||
| FormattedResources.dateTimeConverter = JvmDateTimeConverter |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Painful 🙈
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep. Nothing better came to mind quickly but I can stew on it a bit longer.
sample/library/src/test/kotlin/app/cash/paraphrase/sample/library/JvmDateTimeConverter.kt
Show resolved
Hide resolved
|
I just realized I never responded to this, so sorry about that! I think that in practice this approach probably would work fine (at least for our setup at Cash), even if we're leaking state across tests. Definitely agree that swapping out the static reference is painful though and it would be great to avoid it. We could potentially limit the API surface a bit by hiding the assignment behind a JUnit Another thing we could explore is making the resources themselves injectable. Something like: val FormattedResources = BaseFormattedResources(dateConverter = AndroidDateConverter)
class BaseFormattedResources(private val dateConverter : DateConverter<*>) {
fun my_string(date: LocalDate): FormattedResource { ... }
}People could still reference the default resources statically, but they could also pass in an instance if they need to for testing: class MyPresenter(private val formattedResources: BaseFormattedResources = FormattedResources) { ... }
class MyPresenterTest {
private val presenter = MyPresenter(BaseFormattedResources(JvmDateConverter))
}Lots of options here in terms of naming, the exact configuration, how much we encourage static use vs injecting instances, etc. |
|
Makes sense. I'll give this a try. |
Closes #230.
This implements the first solution I proposed in #230. I'm not overly attached to this approach, just wanted to prove it out.
This pulls all
android.icuimports out of generated code and into the runtime, allowing substitution of non-Android ICU dependencies in JVM unit tests.Generated code now uses a generic
DateTimeConverterinterface to format date/time parameters. The defaultAndroidDateTimeConverterimplementation instantiatesandroid.icu.util.Calendars. JVM tests can substitute aJvmDateTimeConverterinto theirFormattedResourcesobject to instantiatecom.ibm.icu.util.Calendars, avoiding the need for Robolectric to format date/time strings.