mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-07 00:41:39 +07:00
Unit test catching un-annotated lazies (#4886)
This commit is contained in:
@ -444,7 +444,7 @@ class Ruleset {
|
|||||||
* save all of the loaded rulesets somewhere for later use
|
* save all of the loaded rulesets somewhere for later use
|
||||||
* */
|
* */
|
||||||
object RulesetCache : HashMap<String,Ruleset>() {
|
object RulesetCache : HashMap<String,Ruleset>() {
|
||||||
fun loadRulesets(consoleMode: Boolean = false, printOutput: Boolean = false) {
|
fun loadRulesets(consoleMode: Boolean = false, printOutput: Boolean = false, noMods: Boolean = true) {
|
||||||
clear()
|
clear()
|
||||||
for (ruleset in BaseRuleset.values()) {
|
for (ruleset in BaseRuleset.values()) {
|
||||||
val fileName = "jsons/${ruleset.fullName}"
|
val fileName = "jsons/${ruleset.fullName}"
|
||||||
@ -453,6 +453,8 @@ object RulesetCache : HashMap<String,Ruleset>() {
|
|||||||
this[ruleset.fullName] = Ruleset().apply { load(fileHandle, printOutput) }
|
this[ruleset.fullName] = Ruleset().apply { load(fileHandle, printOutput) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (noMods) return
|
||||||
|
|
||||||
val modsHandles = if (consoleMode) FileHandle("mods").list()
|
val modsHandles = if (consoleMode) FileHandle("mods").list()
|
||||||
else Gdx.files.local("mods").list()
|
else Gdx.files.local("mods").list()
|
||||||
|
|
||||||
|
110
tests/src/com/unciv/testing/SerializationTests.kt
Normal file
110
tests/src/com/unciv/testing/SerializationTests.kt
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
package com.unciv.testing
|
||||||
|
|
||||||
|
import com.unciv.Constants
|
||||||
|
import com.unciv.UncivGame
|
||||||
|
import com.unciv.logic.GameInfo
|
||||||
|
import com.unciv.logic.GameSaver
|
||||||
|
import com.unciv.logic.GameStarter
|
||||||
|
import com.unciv.logic.civilization.PlayerType
|
||||||
|
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.Player
|
||||||
|
import com.unciv.models.ruleset.RulesetCache
|
||||||
|
import com.unciv.ui.newgamescreen.GameSetupInfo
|
||||||
|
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()
|
||||||
|
|
||||||
|
/** 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"))
|
||||||
|
religionEnabled = true
|
||||||
|
}
|
||||||
|
val mapParameters = MapParameters().apply {
|
||||||
|
mapSize = MapSizeNew(MapSize.Tiny)
|
||||||
|
seed = 42L
|
||||||
|
}
|
||||||
|
val setup = GameSetupInfo(param, mapParameters)
|
||||||
|
UncivGame.Current = UncivGame("")
|
||||||
|
UncivGame.Current.settings = GameSettings()
|
||||||
|
game = GameStarter.startNewGame(setup)
|
||||||
|
UncivGame.Current.gameInfo = game
|
||||||
|
|
||||||
|
// Found a city otherwise too many classes have no instance and are not tested
|
||||||
|
val civ = game.getCurrentPlayerCivilization()
|
||||||
|
val unit = civ.getCivUnits().first { it.hasUnique(Constants.settlerUnique) }
|
||||||
|
val tile = unit.getTile()
|
||||||
|
unit.civInfo.addCity(tile.position)
|
||||||
|
if (tile.ruleset.tileImprovements.containsKey("City center"))
|
||||||
|
tile.improvement = "City center"
|
||||||
|
unit.destroy()
|
||||||
|
|
||||||
|
// Ensure some diplomacy objects are instantiated
|
||||||
|
val otherCiv = game.getCivilization("Greece")
|
||||||
|
civ.makeCivilizationsMeet(otherCiv)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun canSerializeGame() {
|
||||||
|
val json = try {
|
||||||
|
GameSaver.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 {
|
||||||
|
println("Lazy missing `@delegate:Transient` annotation: " + it.groups[1]!!.value)
|
||||||
|
}
|
||||||
|
val result = matches.any()
|
||||||
|
Assert.assertFalse("This test will only pass when no serializable lazy fields are found", result)
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user