Skip to content
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

Convert FallbackJSBundleLoaderTest to Kotlin #37750

Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.bridge

import com.facebook.common.logging.FLog
import com.facebook.common.logging.FakeLoggingDelegate
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.fail
import org.junit.Before
import org.junit.Test
import org.mockito.Mockito.*
import org.mockito.Mockito.`when` as whenever

class FallbackJSBundleLoaderTest {
private lateinit var mLoggingDelegate: FakeLoggingDelegate
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
private lateinit var mLoggingDelegate: FakeLoggingDelegate
private lateinit var loggingDelegate: FakeLoggingDelegate


@Before
fun setup() {
mLoggingDelegate = FakeLoggingDelegate()
FLog.setLoggingDelegate(mLoggingDelegate)
}

@Test
fun firstLoaderSucceeds() {
val delegates = arrayOf(successfulLoader("url1"), successfulLoader("url2"))

val fallbackLoader = FallbackJSBundleLoader(listOf(*delegates))

assertThat(fallbackLoader.loadScript(null)).isEqualTo("url1")

verify(delegates[0], times(1)).loadScript(null)
verify(delegates[1], never()).loadScript(null)

assertThat(
mLoggingDelegate.logContains(
FakeLoggingDelegate.WTF, FallbackJSBundleLoader.TAG, null
)
).isFalse
}

@Test
fun fallingBackSuccessfully() {
val delegates = arrayOf(
recoverableLoader("url1", "error1"), successfulLoader("url2"), successfulLoader("url3")
)

val fallbackLoader = FallbackJSBundleLoader(listOf(*delegates))

assertThat(fallbackLoader.loadScript(null)).isEqualTo("url2")

verify(delegates[0], times(1)).loadScript(null)
verify(delegates[1], times(1)).loadScript(null)
verify(delegates[2], never()).loadScript(null)

assertThat(
mLoggingDelegate.logContains(
FakeLoggingDelegate.WTF, FallbackJSBundleLoader.TAG, recoverableMsg("error1")
)
).isTrue
}

@Test
fun fallingbackUnsuccessfully() {
val delegates = arrayOf(
recoverableLoader("url1", "error1"), recoverableLoader("url2", "error2")
)

val fallbackLoader = FallbackJSBundleLoader(listOf(*delegates))

try {
fallbackLoader.loadScript(null)
fail("expect throw")
} catch (e: Exception) {
assertThat(e).isInstanceOf(RuntimeException::class.java)

var cause = e.cause
val msgs = ArrayList<String?>()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
val msgs = ArrayList<String?>()
val msgs = mutableListOf<String>()


while (cause != null) {
msgs.add(cause.message)
cause = cause.cause
}

assertThat(msgs).containsExactly(recoverableMsg("error1"), recoverableMsg("error2"))
}

verify(delegates[0], times(1)).loadScript(null)
verify(delegates[1], times(1)).loadScript(null)

assertThat(
mLoggingDelegate.logContains(
FakeLoggingDelegate.WTF, FallbackJSBundleLoader.TAG, recoverableMsg("error1")
)
).isTrue

assertThat(
mLoggingDelegate.logContains(
FakeLoggingDelegate.WTF, FallbackJSBundleLoader.TAG, recoverableMsg("error2")
)
).isTrue
}

@Test
fun unrecoverable() {
val delegates = arrayOf(fatalLoader("url1", "error1"), recoverableLoader("url2", "error2"))

val fallbackLoader = FallbackJSBundleLoader(listOf(*delegates))

try {
fallbackLoader.loadScript(null)
fail("expect throw")
} catch (e: Exception) {
assertThat(e.message).isEqualTo(fatalMsg("error1"))
}

verify(delegates[0], times(1)).loadScript(null)
verify(delegates[1], never()).loadScript(null)

assertThat(
mLoggingDelegate.logContains(
FakeLoggingDelegate.WTF, FallbackJSBundleLoader.TAG, null
)
).isFalse
}

companion object {
private val UNRECOVERABLE: String

init {
val prefix = FallbackJSBundleLoader.RECOVERABLE
val first = prefix[0]

UNRECOVERABLE = prefix.replace(first, (first.code + 1).toChar())
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is really not great and we should refactor it a bit.

Having tests rely on the init{} block of a companion object is really unpredictable.

Let's remove the companion object and let's move all the logic to private methods and initialize the stuff inside the setup method


private fun successfulLoader(url: String): JSBundleLoader {
val loader = mock(JSBundleLoader::class.java)
whenever(loader.loadScript(null)).thenReturn(url)

return loader
}

private fun recoverableMsg(errMsg: String): String {
return FallbackJSBundleLoader.RECOVERABLE + errMsg
}

private fun recoverableLoader(url: String, errMsg: String): JSBundleLoader {
val loader = mock(JSBundleLoader::class.java)
whenever(loader.loadScript(null)).thenThrow(RuntimeException(FallbackJSBundleLoader.RECOVERABLE + errMsg))

return loader
}

private fun fatalMsg(errMsg: String): String {
return UNRECOVERABLE + errMsg
}

private fun fatalLoader(url: String, errMsg: String): JSBundleLoader {
val loader = mock(JSBundleLoader::class.java)
whenever(loader.loadScript(null)).thenThrow(RuntimeException(UNRECOVERABLE + errMsg))

return loader
}
}
}