mirror of
https://github.com/yairm210/Unciv.git
synced 2025-08-04 00:59:41 +07:00
125 lines
4.5 KiB
Kotlin
125 lines
4.5 KiB
Kotlin
package com.unciv.testing
|
|
|
|
import com.badlogic.gdx.Gdx
|
|
import com.unciv.UncivGame
|
|
import com.unciv.json.json
|
|
import com.unciv.logic.GameInfo
|
|
import com.unciv.logic.GameStarter
|
|
import com.unciv.logic.civilization.PlayerType
|
|
import com.unciv.logic.files.UncivFiles
|
|
import com.unciv.logic.map.MapParameters
|
|
import com.unciv.logic.map.MapSize
|
|
import com.unciv.logic.map.MapSizeNew
|
|
import com.unciv.models.metadata.GameParameters
|
|
import com.unciv.models.metadata.GameSettings
|
|
import com.unciv.models.metadata.GameSetupInfo
|
|
import com.unciv.models.metadata.Player
|
|
import com.unciv.models.ruleset.RulesetCache
|
|
import com.unciv.models.ruleset.unique.UniqueType
|
|
import com.unciv.utils.debug
|
|
import org.junit.After
|
|
import org.junit.Assert
|
|
import org.junit.Before
|
|
import org.junit.Test
|
|
import org.junit.runner.RunWith
|
|
|
|
|
|
@RunWith(GdxTestRunner::class)
|
|
class SerializationTests {
|
|
|
|
private var game = GameInfo()
|
|
private var settingsBackup = GameSettings()
|
|
|
|
/** A runtime Class object for [kotlin.SynchronizedLazyImpl] to enable helping Gdx.Json to
|
|
* not StackOverflow on them, as a direct compile time retrieval is forbidden */
|
|
private val classSynchronizedLazyImpl: Class<*> by lazy {
|
|
// I hope you get the irony...
|
|
@Suppress("unused") // No, test is not _directly_ used, only reflected on
|
|
class TestWithLazy { val test: Int by lazy { 0 } }
|
|
val badInstance = TestWithLazy()
|
|
val badField = badInstance::class.java.declaredFields[0]
|
|
badField.isAccessible = true
|
|
badField.get(badInstance)::class.java
|
|
}
|
|
|
|
@Before
|
|
fun prepareGame() {
|
|
RulesetCache.loadRulesets(noMods = true)
|
|
|
|
// Create a tiny game with just 1 human player and the barbarians
|
|
// Must be 1 human otherwise GameInfo.setTransients crashes on the `if (currentPlayer == "")` line
|
|
val param = GameParameters().apply {
|
|
numberOfCityStates = 0
|
|
players.clear()
|
|
players.add(Player("Rome").apply { playerType = PlayerType.Human })
|
|
players.add(Player("Greece"))
|
|
}
|
|
val mapParameters = MapParameters().apply {
|
|
mapSize = MapSizeNew(MapSize.Tiny)
|
|
seed = 42L
|
|
}
|
|
val setup = GameSetupInfo(param, mapParameters)
|
|
UncivGame.Current = UncivGame()
|
|
UncivGame.Current.files = UncivFiles(Gdx.files)
|
|
|
|
// Both startNewGame and makeCivilizationsMeet will cause a save to storage of our empty settings
|
|
settingsBackup = UncivGame.Current.files.getGeneralSettings()
|
|
|
|
UncivGame.Current.settings = GameSettings()
|
|
game = GameStarter.startNewGame(setup)
|
|
UncivGame.Current.startSimulation(game)
|
|
|
|
// Found a city otherwise too many classes have no instance and are not tested
|
|
val civ = game.getCurrentPlayerCivilization()
|
|
val unit = civ.units.getCivUnits().first { it.hasUnique(UniqueType.FoundCity) }
|
|
val tile = unit.getTile()
|
|
unit.civInfo.addCity(tile.position)
|
|
if (tile.ruleset.tileImprovements.containsKey("City center"))
|
|
tile.changeImprovement("City center")
|
|
unit.destroy()
|
|
|
|
// Ensure some diplomacy objects are instantiated
|
|
val otherCiv = game.getCivilization("Greece")
|
|
civ.diplomacyFunctions.makeCivilizationsMeet(otherCiv)
|
|
}
|
|
|
|
@Test
|
|
fun canSerializeGame() {
|
|
val json = try {
|
|
json().toJson(game)
|
|
} catch (ex: Exception) {
|
|
""
|
|
}
|
|
Assert.assertTrue("This test will only pass when a game can be serialized", json.isNotEmpty())
|
|
}
|
|
|
|
@Test
|
|
fun serializedLaziesTest() {
|
|
val jsonSerializer = com.badlogic.gdx.utils.Json().apply {
|
|
setIgnoreDeprecated(true)
|
|
setDeprecated(classSynchronizedLazyImpl, "initializer", true)
|
|
setDeprecated(classSynchronizedLazyImpl, "lock", true) // this is the culprit as kotlin initializes it to `this@SynchronizedLazyImpl`
|
|
}
|
|
|
|
val json = try {
|
|
jsonSerializer.toJson(game)
|
|
} catch (ex: Throwable) {
|
|
ex.printStackTrace()
|
|
return
|
|
}
|
|
|
|
val pattern = """\{(\w+)\\${'$'}delegate:\{class:kotlin.SynchronizedLazyImpl,"""
|
|
val matches = Regex(pattern).findAll(json)
|
|
matches.forEach {
|
|
debug("Lazy missing `@delegate:Transient` annotation: %s", it.groups[1]!!.value)
|
|
}
|
|
val result = matches.any()
|
|
Assert.assertFalse("This test will only pass when no serializable lazy fields are found", result)
|
|
}
|
|
|
|
@After
|
|
fun cleanup() {
|
|
settingsBackup.save()
|
|
}
|
|
}
|