Add MacMahon 3.9 import support
- Add MacMahon39.kt parser for MM39 tournament format - Auto-detect MM39 format in tournament import - Import players, games, bye players, and tournament parameters - Uses default values for time system and director since MM39 lacks those
This commit is contained in:
@@ -1,11 +1,13 @@
|
||||
package org.jeudego.pairgoth.test
|
||||
|
||||
import org.jeudego.pairgoth.ext.MacMahon39
|
||||
import org.jeudego.pairgoth.ext.OpenGotha
|
||||
import org.jeudego.pairgoth.model.toJson
|
||||
import org.jeudego.pairgoth.util.XmlUtils
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.nio.charset.StandardCharsets
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class ImportExportTests: TestBase() {
|
||||
|
||||
@@ -56,4 +58,73 @@ class ImportExportTests: TestBase() {
|
||||
assertEquals(jsonTournament, jsonTournament2)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `003 test macmahon39 import`() {
|
||||
getTestResources("macmahon39")?.forEach { file ->
|
||||
logger.info("===== Testing MacMahon 3.9 import: ${file.name} =====")
|
||||
val resource = file.readText(StandardCharsets.UTF_8)
|
||||
val root_xml = XmlUtils.parse(resource)
|
||||
|
||||
// Verify format detection
|
||||
assertTrue(MacMahon39.isFormat(root_xml), "File should be detected as MacMahon 3.9 format")
|
||||
|
||||
// Import tournament
|
||||
val tournament = MacMahon39.import(root_xml)
|
||||
|
||||
// Verify basic tournament data
|
||||
logger.info("Tournament name: ${tournament.name}")
|
||||
logger.info("Number of rounds: ${tournament.rounds}")
|
||||
logger.info("Number of players: ${tournament.pairables.size}")
|
||||
|
||||
assertEquals("Test MacMahon Tournament", tournament.name)
|
||||
assertEquals(3, tournament.rounds)
|
||||
assertEquals(4, tournament.pairables.size)
|
||||
|
||||
// Verify players
|
||||
val players = tournament.pairables.values.toList()
|
||||
val alice = players.find { it.name == "Smith" }
|
||||
val bob = players.find { it.name == "Jones" }
|
||||
val carol = players.find { it.name == "White" }
|
||||
val david = players.find { it.name == "Brown" }
|
||||
|
||||
assertTrue(alice != null, "Alice should exist")
|
||||
assertTrue(bob != null, "Bob should exist")
|
||||
assertTrue(carol != null, "Carol should exist")
|
||||
assertTrue(david != null, "David should exist")
|
||||
|
||||
assertEquals(2, alice!!.rank) // 3d = rank 2
|
||||
assertEquals(1, bob!!.rank) // 2d = rank 1
|
||||
assertEquals(0, carol!!.rank) // 1d = rank 0
|
||||
assertEquals(-1, david!!.rank) // 1k = rank -1
|
||||
|
||||
// Carol is super bar member
|
||||
assertEquals(1, carol.mmsCorrection)
|
||||
|
||||
// David skips round 2
|
||||
assertTrue(david.skip.contains(2), "David should skip round 2")
|
||||
|
||||
// Verify games
|
||||
val round1Games = tournament.games(1).values.toList()
|
||||
val round2Games = tournament.games(2).values.toList()
|
||||
|
||||
logger.info("Round 1 games: ${round1Games.size}")
|
||||
logger.info("Round 2 games: ${round2Games.size}")
|
||||
|
||||
assertEquals(2, round1Games.size)
|
||||
assertEquals(2, round2Games.size) // 1 regular game + 1 bye
|
||||
|
||||
// Test via API
|
||||
val resp = TestAPI.post("/api/tour", resource)
|
||||
val id = resp.asObject().getInt("id")
|
||||
logger.info("Imported tournament id: $id")
|
||||
|
||||
val apiTournament = TestAPI.get("/api/tour/$id").asObject()
|
||||
assertEquals("Test MacMahon Tournament", apiTournament.getString("name"))
|
||||
assertEquals(3, apiTournament.getInt("rounds"))
|
||||
|
||||
val apiPlayers = TestAPI.get("/api/tour/$id/part").asArray()
|
||||
assertEquals(4, apiPlayers.size)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
132
api-webapp/src/test/resources/macmahon39/sample-tournament.xml
Normal file
132
api-webapp/src/test/resources/macmahon39/sample-tournament.xml
Normal file
@@ -0,0 +1,132 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Sample MacMahon 3.9 format tournament file for testing -->
|
||||
<TournamentData typeversion="3.9">
|
||||
<Tournament typeversion="3.9">
|
||||
<Name>Test MacMahon Tournament</Name>
|
||||
<NumberOfRounds>3</NumberOfRounds>
|
||||
<UpperMacMahonBar>true</UpperMacMahonBar>
|
||||
<UpperMacMahonBarLevel>1d</UpperMacMahonBarLevel>
|
||||
<LowerMacMahonBar>true</LowerMacMahonBar>
|
||||
<LowerMacMahonBarLevel>20k</LowerMacMahonBarLevel>
|
||||
<RatingDeterminesRank>false</RatingDeterminesRank>
|
||||
<HandicapUsed>false</HandicapUsed>
|
||||
<HandicapBelow>true</HandicapBelow>
|
||||
<HandicapBelowLevel>30k</HandicapBelowLevel>
|
||||
<HandicapAdjustment>true</HandicapAdjustment>
|
||||
<HandicapAdjustmentValue>0</HandicapAdjustmentValue>
|
||||
<HandicapLimit>true</HandicapLimit>
|
||||
<HandicapLimitValue>9</HandicapLimitValue>
|
||||
<HandicapByLevel>false</HandicapByLevel>
|
||||
</Tournament>
|
||||
|
||||
<Walllist>
|
||||
<Criterion><ShortName>Score</ShortName></Criterion>
|
||||
<Criterion><ShortName>SOS</ShortName></Criterion>
|
||||
<Criterion><ShortName>SOSOS</ShortName></Criterion>
|
||||
</Walllist>
|
||||
|
||||
<Playerlist>
|
||||
<Player>
|
||||
<Id>1</Id>
|
||||
<PreliminaryRegistration>false</PreliminaryRegistration>
|
||||
<SuperBarMember>false</SuperBarMember>
|
||||
<GoPlayer>
|
||||
<FirstName>Alice</FirstName>
|
||||
<Surname>Smith</Surname>
|
||||
<Club>Paris</Club>
|
||||
<Country>FR</Country>
|
||||
<GoLevel>3d</GoLevel>
|
||||
<Rating>2200</Rating>
|
||||
<EgdPin>12345678</EgdPin>
|
||||
</GoPlayer>
|
||||
</Player>
|
||||
<Player>
|
||||
<Id>2</Id>
|
||||
<PreliminaryRegistration>false</PreliminaryRegistration>
|
||||
<SuperBarMember>false</SuperBarMember>
|
||||
<GoPlayer>
|
||||
<FirstName>Bob</FirstName>
|
||||
<Surname>Jones</Surname>
|
||||
<Club>Lyon</Club>
|
||||
<Country>FR</Country>
|
||||
<GoLevel>2d</GoLevel>
|
||||
<Rating>2100</Rating>
|
||||
<EgdPin>23456789</EgdPin>
|
||||
</GoPlayer>
|
||||
</Player>
|
||||
<Player>
|
||||
<Id>3</Id>
|
||||
<PreliminaryRegistration>false</PreliminaryRegistration>
|
||||
<SuperBarMember>true</SuperBarMember>
|
||||
<GoPlayer>
|
||||
<FirstName>Carol</FirstName>
|
||||
<Surname>White</Surname>
|
||||
<Club>Berlin</Club>
|
||||
<Country>DE</Country>
|
||||
<GoLevel>1d</GoLevel>
|
||||
<Rating>2000</Rating>
|
||||
<EgdPin>34567890</EgdPin>
|
||||
</GoPlayer>
|
||||
</Player>
|
||||
<Player>
|
||||
<Id>4</Id>
|
||||
<PreliminaryRegistration>true</PreliminaryRegistration>
|
||||
<SuperBarMember>false</SuperBarMember>
|
||||
<NotPlayingInRound>2</NotPlayingInRound>
|
||||
<GoPlayer>
|
||||
<FirstName>David</FirstName>
|
||||
<Surname>Brown</Surname>
|
||||
<Club>London</Club>
|
||||
<Country>UK</Country>
|
||||
<GoLevel>1k</GoLevel>
|
||||
<Rating>1900</Rating>
|
||||
<EgdPin>45678901</EgdPin>
|
||||
</GoPlayer>
|
||||
</Player>
|
||||
</Playerlist>
|
||||
|
||||
<Roundlist>
|
||||
<Round>
|
||||
<RoundNumber>1</RoundNumber>
|
||||
<Pairing>
|
||||
<BoardNumber>1</BoardNumber>
|
||||
<PairingWithBye>false</PairingWithBye>
|
||||
<White>1</White>
|
||||
<Black>2</Black>
|
||||
<Handicap>0</Handicap>
|
||||
<Result>1-0</Result>
|
||||
<ResultByReferee>false</ResultByReferee>
|
||||
</Pairing>
|
||||
<Pairing>
|
||||
<BoardNumber>2</BoardNumber>
|
||||
<PairingWithBye>false</PairingWithBye>
|
||||
<White>3</White>
|
||||
<Black>4</Black>
|
||||
<Handicap>0</Handicap>
|
||||
<Result>0-1</Result>
|
||||
<ResultByReferee>false</ResultByReferee>
|
||||
</Pairing>
|
||||
</Round>
|
||||
<Round>
|
||||
<RoundNumber>2</RoundNumber>
|
||||
<Pairing>
|
||||
<BoardNumber>1</BoardNumber>
|
||||
<PairingWithBye>false</PairingWithBye>
|
||||
<White>2</White>
|
||||
<Black>1</Black>
|
||||
<Handicap>0</Handicap>
|
||||
<Result>0-1</Result>
|
||||
<ResultByReferee>false</ResultByReferee>
|
||||
</Pairing>
|
||||
<Pairing>
|
||||
<BoardNumber>0</BoardNumber>
|
||||
<PairingWithBye>true</PairingWithBye>
|
||||
<White>0</White>
|
||||
<Black>3</Black>
|
||||
<Handicap>0</Handicap>
|
||||
<Result>0-1</Result>
|
||||
<ResultByReferee>false</ResultByReferee>
|
||||
</Pairing>
|
||||
</Round>
|
||||
</Roundlist>
|
||||
</TournamentData>
|
||||
Reference in New Issue
Block a user