Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b8545748b3 | |||
| 61f2129650 | |||
| 3b1a9b4713 | |||
| 53d538ca92 |
@@ -49,10 +49,9 @@ dependencies {
|
|||||||
|
|
||||||
testImplementation(platform("org.junit:junit-bom:5.13.4"))
|
testImplementation(platform("org.junit:junit-bom:5.13.4"))
|
||||||
testImplementation("org.junit.jupiter:junit-jupiter")
|
testImplementation("org.junit.jupiter:junit-jupiter")
|
||||||
|
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
|
||||||
testImplementation("org.scalatest:scalatest_3:${versions["SCALATEST"]!!}")
|
testImplementation("org.scalatest:scalatest_3:${versions["SCALATEST"]!!}")
|
||||||
testImplementation("co.helmethair:scalatest-junit-runner:${versions["SCALATEST_JUNIT"]!!}")
|
testImplementation("co.helmethair:scalatest-junit-runner:${versions["SCALATEST_JUNIT"]!!}")
|
||||||
|
|
||||||
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.test {
|
tasks.test {
|
||||||
|
|||||||
@@ -1,102 +0,0 @@
|
|||||||
package de.nowchess.api.board
|
|
||||||
|
|
||||||
import org.scalatest.funsuite.AnyFunSuite
|
|
||||||
import org.scalatest.matchers.should.Matchers
|
|
||||||
|
|
||||||
class BoardTest extends AnyFunSuite with Matchers:
|
|
||||||
|
|
||||||
private val e2 = Square(File.E, Rank.R2)
|
|
||||||
private val e4 = Square(File.E, Rank.R4)
|
|
||||||
private val d7 = Square(File.D, Rank.R7)
|
|
||||||
|
|
||||||
test("pieceAt returns Some for occupied square") {
|
|
||||||
Board.initial.pieceAt(e2) shouldBe Some(Piece.WhitePawn)
|
|
||||||
}
|
|
||||||
|
|
||||||
test("pieceAt returns None for empty square") {
|
|
||||||
Board.initial.pieceAt(e4) shouldBe None
|
|
||||||
}
|
|
||||||
|
|
||||||
test("withMove moves piece and vacates origin") {
|
|
||||||
val (board, captured) = Board.initial.withMove(e2, e4)
|
|
||||||
captured shouldBe None
|
|
||||||
board.pieceAt(e4) shouldBe Some(Piece.WhitePawn)
|
|
||||||
board.pieceAt(e2) shouldBe None
|
|
||||||
}
|
|
||||||
|
|
||||||
test("withMove returns captured piece when destination is occupied") {
|
|
||||||
val from = Square(File.A, Rank.R1)
|
|
||||||
val to = Square(File.A, Rank.R8)
|
|
||||||
val b = Board(Map(from -> Piece.WhiteRook, to -> Piece.BlackRook))
|
|
||||||
val (board, captured) = b.withMove(from, to)
|
|
||||||
captured shouldBe Some(Piece.BlackRook)
|
|
||||||
board.pieceAt(to) shouldBe Some(Piece.WhiteRook)
|
|
||||||
board.pieceAt(from) shouldBe None
|
|
||||||
}
|
|
||||||
|
|
||||||
test("pieces returns the underlying map") {
|
|
||||||
val map = Map(e2 -> Piece.WhitePawn)
|
|
||||||
val b = Board(map)
|
|
||||||
b.pieces shouldBe map
|
|
||||||
}
|
|
||||||
|
|
||||||
test("Board.apply constructs board from map") {
|
|
||||||
val map = Map(e2 -> Piece.WhitePawn)
|
|
||||||
val b = Board(map)
|
|
||||||
b.pieceAt(e2) shouldBe Some(Piece.WhitePawn)
|
|
||||||
}
|
|
||||||
|
|
||||||
test("initial board has 32 pieces") {
|
|
||||||
Board.initial.pieces should have size 32
|
|
||||||
}
|
|
||||||
|
|
||||||
test("initial board has 16 white pieces") {
|
|
||||||
Board.initial.pieces.values.count(_.color == Color.White) shouldBe 16
|
|
||||||
}
|
|
||||||
|
|
||||||
test("initial board has 16 black pieces") {
|
|
||||||
Board.initial.pieces.values.count(_.color == Color.Black) shouldBe 16
|
|
||||||
}
|
|
||||||
|
|
||||||
test("initial board white pawns on rank 2") {
|
|
||||||
File.values.foreach { file =>
|
|
||||||
Board.initial.pieceAt(Square(file, Rank.R2)) shouldBe Some(Piece.WhitePawn)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
test("initial board black pawns on rank 7") {
|
|
||||||
File.values.foreach { file =>
|
|
||||||
Board.initial.pieceAt(Square(file, Rank.R7)) shouldBe Some(Piece.BlackPawn)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
test("initial board white back rank") {
|
|
||||||
val expectedBackRank = Vector(
|
|
||||||
PieceType.Rook, PieceType.Knight, PieceType.Bishop, PieceType.Queen,
|
|
||||||
PieceType.King, PieceType.Bishop, PieceType.Knight, PieceType.Rook
|
|
||||||
)
|
|
||||||
File.values.zipWithIndex.foreach { (file, i) =>
|
|
||||||
Board.initial.pieceAt(Square(file, Rank.R1)) shouldBe
|
|
||||||
Some(Piece(Color.White, expectedBackRank(i)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
test("initial board black back rank") {
|
|
||||||
val expectedBackRank = Vector(
|
|
||||||
PieceType.Rook, PieceType.Knight, PieceType.Bishop, PieceType.Queen,
|
|
||||||
PieceType.King, PieceType.Bishop, PieceType.Knight, PieceType.Rook
|
|
||||||
)
|
|
||||||
File.values.zipWithIndex.foreach { (file, i) =>
|
|
||||||
Board.initial.pieceAt(Square(file, Rank.R8)) shouldBe
|
|
||||||
Some(Piece(Color.Black, expectedBackRank(i)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
test("ranks 3-6 are empty on initial board") {
|
|
||||||
val emptyRanks = Seq(Rank.R3, Rank.R4, Rank.R5, Rank.R6)
|
|
||||||
for
|
|
||||||
rank <- emptyRanks
|
|
||||||
file <- File.values
|
|
||||||
do
|
|
||||||
Board.initial.pieceAt(Square(file, rank)) shouldBe None
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
package de.nowchess.api.board
|
|
||||||
|
|
||||||
import org.scalatest.funsuite.AnyFunSuite
|
|
||||||
import org.scalatest.matchers.should.Matchers
|
|
||||||
|
|
||||||
class ColorTest extends AnyFunSuite with Matchers:
|
|
||||||
|
|
||||||
test("White.opposite returns Black") {
|
|
||||||
Color.White.opposite shouldBe Color.Black
|
|
||||||
}
|
|
||||||
|
|
||||||
test("Black.opposite returns White") {
|
|
||||||
Color.Black.opposite shouldBe Color.White
|
|
||||||
}
|
|
||||||
|
|
||||||
test("White.label returns 'White'") {
|
|
||||||
Color.White.label shouldBe "White"
|
|
||||||
}
|
|
||||||
|
|
||||||
test("Black.label returns 'Black'") {
|
|
||||||
Color.Black.label shouldBe "Black"
|
|
||||||
}
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
package de.nowchess.api.board
|
|
||||||
|
|
||||||
import org.scalatest.funsuite.AnyFunSuite
|
|
||||||
import org.scalatest.matchers.should.Matchers
|
|
||||||
|
|
||||||
class PieceTest extends AnyFunSuite with Matchers:
|
|
||||||
|
|
||||||
test("Piece holds color and pieceType") {
|
|
||||||
val p = Piece(Color.White, PieceType.Queen)
|
|
||||||
p.color shouldBe Color.White
|
|
||||||
p.pieceType shouldBe PieceType.Queen
|
|
||||||
}
|
|
||||||
|
|
||||||
test("WhitePawn convenience constant") {
|
|
||||||
Piece.WhitePawn shouldBe Piece(Color.White, PieceType.Pawn)
|
|
||||||
}
|
|
||||||
|
|
||||||
test("WhiteKnight convenience constant") {
|
|
||||||
Piece.WhiteKnight shouldBe Piece(Color.White, PieceType.Knight)
|
|
||||||
}
|
|
||||||
|
|
||||||
test("WhiteBishop convenience constant") {
|
|
||||||
Piece.WhiteBishop shouldBe Piece(Color.White, PieceType.Bishop)
|
|
||||||
}
|
|
||||||
|
|
||||||
test("WhiteRook convenience constant") {
|
|
||||||
Piece.WhiteRook shouldBe Piece(Color.White, PieceType.Rook)
|
|
||||||
}
|
|
||||||
|
|
||||||
test("WhiteQueen convenience constant") {
|
|
||||||
Piece.WhiteQueen shouldBe Piece(Color.White, PieceType.Queen)
|
|
||||||
}
|
|
||||||
|
|
||||||
test("WhiteKing convenience constant") {
|
|
||||||
Piece.WhiteKing shouldBe Piece(Color.White, PieceType.King)
|
|
||||||
}
|
|
||||||
|
|
||||||
test("BlackPawn convenience constant") {
|
|
||||||
Piece.BlackPawn shouldBe Piece(Color.Black, PieceType.Pawn)
|
|
||||||
}
|
|
||||||
|
|
||||||
test("BlackKnight convenience constant") {
|
|
||||||
Piece.BlackKnight shouldBe Piece(Color.Black, PieceType.Knight)
|
|
||||||
}
|
|
||||||
|
|
||||||
test("BlackBishop convenience constant") {
|
|
||||||
Piece.BlackBishop shouldBe Piece(Color.Black, PieceType.Bishop)
|
|
||||||
}
|
|
||||||
|
|
||||||
test("BlackRook convenience constant") {
|
|
||||||
Piece.BlackRook shouldBe Piece(Color.Black, PieceType.Rook)
|
|
||||||
}
|
|
||||||
|
|
||||||
test("BlackQueen convenience constant") {
|
|
||||||
Piece.BlackQueen shouldBe Piece(Color.Black, PieceType.Queen)
|
|
||||||
}
|
|
||||||
|
|
||||||
test("BlackKing convenience constant") {
|
|
||||||
Piece.BlackKing shouldBe Piece(Color.Black, PieceType.King)
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
package de.nowchess.api.board
|
|
||||||
|
|
||||||
import org.scalatest.funsuite.AnyFunSuite
|
|
||||||
import org.scalatest.matchers.should.Matchers
|
|
||||||
|
|
||||||
class PieceTypeTest extends AnyFunSuite with Matchers:
|
|
||||||
|
|
||||||
test("Pawn.label returns 'Pawn'") {
|
|
||||||
PieceType.Pawn.label shouldBe "Pawn"
|
|
||||||
}
|
|
||||||
|
|
||||||
test("Knight.label returns 'Knight'") {
|
|
||||||
PieceType.Knight.label shouldBe "Knight"
|
|
||||||
}
|
|
||||||
|
|
||||||
test("Bishop.label returns 'Bishop'") {
|
|
||||||
PieceType.Bishop.label shouldBe "Bishop"
|
|
||||||
}
|
|
||||||
|
|
||||||
test("Rook.label returns 'Rook'") {
|
|
||||||
PieceType.Rook.label shouldBe "Rook"
|
|
||||||
}
|
|
||||||
|
|
||||||
test("Queen.label returns 'Queen'") {
|
|
||||||
PieceType.Queen.label shouldBe "Queen"
|
|
||||||
}
|
|
||||||
|
|
||||||
test("King.label returns 'King'") {
|
|
||||||
PieceType.King.label shouldBe "King"
|
|
||||||
}
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
package de.nowchess.api.board
|
|
||||||
|
|
||||||
import org.scalatest.funsuite.AnyFunSuite
|
|
||||||
import org.scalatest.matchers.should.Matchers
|
|
||||||
|
|
||||||
class SquareTest extends AnyFunSuite with Matchers:
|
|
||||||
|
|
||||||
test("Square.toString produces lowercase file and rank number") {
|
|
||||||
Square(File.E, Rank.R4).toString shouldBe "e4"
|
|
||||||
}
|
|
||||||
|
|
||||||
test("Square.toString for a1") {
|
|
||||||
Square(File.A, Rank.R1).toString shouldBe "a1"
|
|
||||||
}
|
|
||||||
|
|
||||||
test("Square.toString for h8") {
|
|
||||||
Square(File.H, Rank.R8).toString shouldBe "h8"
|
|
||||||
}
|
|
||||||
|
|
||||||
test("fromAlgebraic parses valid square e4") {
|
|
||||||
Square.fromAlgebraic("e4") shouldBe Some(Square(File.E, Rank.R4))
|
|
||||||
}
|
|
||||||
|
|
||||||
test("fromAlgebraic parses valid square a1") {
|
|
||||||
Square.fromAlgebraic("a1") shouldBe Some(Square(File.A, Rank.R1))
|
|
||||||
}
|
|
||||||
|
|
||||||
test("fromAlgebraic parses valid square h8") {
|
|
||||||
Square.fromAlgebraic("h8") shouldBe Some(Square(File.H, Rank.R8))
|
|
||||||
}
|
|
||||||
|
|
||||||
test("fromAlgebraic is case-insensitive for file") {
|
|
||||||
Square.fromAlgebraic("E4") shouldBe Some(Square(File.E, Rank.R4))
|
|
||||||
}
|
|
||||||
|
|
||||||
test("fromAlgebraic returns None for empty string") {
|
|
||||||
Square.fromAlgebraic("") shouldBe None
|
|
||||||
}
|
|
||||||
|
|
||||||
test("fromAlgebraic returns None for string too short") {
|
|
||||||
Square.fromAlgebraic("e") shouldBe None
|
|
||||||
}
|
|
||||||
|
|
||||||
test("fromAlgebraic returns None for string too long") {
|
|
||||||
Square.fromAlgebraic("e42") shouldBe None
|
|
||||||
}
|
|
||||||
|
|
||||||
test("fromAlgebraic returns None for invalid file character") {
|
|
||||||
Square.fromAlgebraic("z4") shouldBe None
|
|
||||||
}
|
|
||||||
|
|
||||||
test("fromAlgebraic returns None for non-digit rank") {
|
|
||||||
Square.fromAlgebraic("ex") shouldBe None
|
|
||||||
}
|
|
||||||
|
|
||||||
test("fromAlgebraic returns None for rank 0") {
|
|
||||||
Square.fromAlgebraic("e0") shouldBe None
|
|
||||||
}
|
|
||||||
|
|
||||||
test("fromAlgebraic returns None for rank 9") {
|
|
||||||
Square.fromAlgebraic("e9") shouldBe None
|
|
||||||
}
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
package de.nowchess.api.game
|
|
||||||
|
|
||||||
import de.nowchess.api.board.Color
|
|
||||||
import org.scalatest.funsuite.AnyFunSuite
|
|
||||||
import org.scalatest.matchers.should.Matchers
|
|
||||||
|
|
||||||
class GameStateTest extends AnyFunSuite with Matchers:
|
|
||||||
|
|
||||||
test("CastlingRights.None has both flags false") {
|
|
||||||
CastlingRights.None.kingSide shouldBe false
|
|
||||||
CastlingRights.None.queenSide shouldBe false
|
|
||||||
}
|
|
||||||
|
|
||||||
test("CastlingRights.Both has both flags true") {
|
|
||||||
CastlingRights.Both.kingSide shouldBe true
|
|
||||||
CastlingRights.Both.queenSide shouldBe true
|
|
||||||
}
|
|
||||||
|
|
||||||
test("CastlingRights constructor sets fields") {
|
|
||||||
val cr = CastlingRights(kingSide = true, queenSide = false)
|
|
||||||
cr.kingSide shouldBe true
|
|
||||||
cr.queenSide shouldBe false
|
|
||||||
}
|
|
||||||
|
|
||||||
test("GameResult cases exist") {
|
|
||||||
GameResult.WhiteWins shouldBe GameResult.WhiteWins
|
|
||||||
GameResult.BlackWins shouldBe GameResult.BlackWins
|
|
||||||
GameResult.Draw shouldBe GameResult.Draw
|
|
||||||
}
|
|
||||||
|
|
||||||
test("GameStatus.NotStarted") {
|
|
||||||
GameStatus.NotStarted shouldBe GameStatus.NotStarted
|
|
||||||
}
|
|
||||||
|
|
||||||
test("GameStatus.InProgress") {
|
|
||||||
GameStatus.InProgress shouldBe GameStatus.InProgress
|
|
||||||
}
|
|
||||||
|
|
||||||
test("GameStatus.Finished carries result") {
|
|
||||||
val status = GameStatus.Finished(GameResult.Draw)
|
|
||||||
status shouldBe GameStatus.Finished(GameResult.Draw)
|
|
||||||
status match
|
|
||||||
case GameStatus.Finished(r) => r shouldBe GameResult.Draw
|
|
||||||
case _ => fail("expected Finished")
|
|
||||||
}
|
|
||||||
|
|
||||||
test("GameState.initial has standard FEN piece placement") {
|
|
||||||
GameState.initial.piecePlacement shouldBe "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR"
|
|
||||||
}
|
|
||||||
|
|
||||||
test("GameState.initial active color is White") {
|
|
||||||
GameState.initial.activeColor shouldBe Color.White
|
|
||||||
}
|
|
||||||
|
|
||||||
test("GameState.initial white has full castling rights") {
|
|
||||||
GameState.initial.castlingWhite shouldBe CastlingRights.Both
|
|
||||||
}
|
|
||||||
|
|
||||||
test("GameState.initial black has full castling rights") {
|
|
||||||
GameState.initial.castlingBlack shouldBe CastlingRights.Both
|
|
||||||
}
|
|
||||||
|
|
||||||
test("GameState.initial en-passant target is None") {
|
|
||||||
GameState.initial.enPassantTarget shouldBe None
|
|
||||||
}
|
|
||||||
|
|
||||||
test("GameState.initial half-move clock is 0") {
|
|
||||||
GameState.initial.halfMoveClock shouldBe 0
|
|
||||||
}
|
|
||||||
|
|
||||||
test("GameState.initial full-move number is 1") {
|
|
||||||
GameState.initial.fullMoveNumber shouldBe 1
|
|
||||||
}
|
|
||||||
|
|
||||||
test("GameState.initial status is InProgress") {
|
|
||||||
GameState.initial.status shouldBe GameStatus.InProgress
|
|
||||||
}
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
package de.nowchess.api.move
|
|
||||||
|
|
||||||
import de.nowchess.api.board.{File, Rank, Square}
|
|
||||||
import org.scalatest.funsuite.AnyFunSuite
|
|
||||||
import org.scalatest.matchers.should.Matchers
|
|
||||||
|
|
||||||
class MoveTest extends AnyFunSuite with Matchers:
|
|
||||||
|
|
||||||
private val e2 = Square(File.E, Rank.R2)
|
|
||||||
private val e4 = Square(File.E, Rank.R4)
|
|
||||||
|
|
||||||
test("Move defaults moveType to Normal") {
|
|
||||||
val m = Move(e2, e4)
|
|
||||||
m.moveType shouldBe MoveType.Normal
|
|
||||||
}
|
|
||||||
|
|
||||||
test("Move stores from and to squares") {
|
|
||||||
val m = Move(e2, e4)
|
|
||||||
m.from shouldBe e2
|
|
||||||
m.to shouldBe e4
|
|
||||||
}
|
|
||||||
|
|
||||||
test("Move with CastleKingside moveType") {
|
|
||||||
val m = Move(e2, e4, MoveType.CastleKingside)
|
|
||||||
m.moveType shouldBe MoveType.CastleKingside
|
|
||||||
}
|
|
||||||
|
|
||||||
test("Move with CastleQueenside moveType") {
|
|
||||||
val m = Move(e2, e4, MoveType.CastleQueenside)
|
|
||||||
m.moveType shouldBe MoveType.CastleQueenside
|
|
||||||
}
|
|
||||||
|
|
||||||
test("Move with EnPassant moveType") {
|
|
||||||
val m = Move(e2, e4, MoveType.EnPassant)
|
|
||||||
m.moveType shouldBe MoveType.EnPassant
|
|
||||||
}
|
|
||||||
|
|
||||||
test("Move with Promotion to Queen") {
|
|
||||||
val m = Move(e2, e4, MoveType.Promotion(PromotionPiece.Queen))
|
|
||||||
m.moveType shouldBe MoveType.Promotion(PromotionPiece.Queen)
|
|
||||||
}
|
|
||||||
|
|
||||||
test("Move with Promotion to Knight") {
|
|
||||||
val m = Move(e2, e4, MoveType.Promotion(PromotionPiece.Knight))
|
|
||||||
m.moveType shouldBe MoveType.Promotion(PromotionPiece.Knight)
|
|
||||||
}
|
|
||||||
|
|
||||||
test("Move with Promotion to Bishop") {
|
|
||||||
val m = Move(e2, e4, MoveType.Promotion(PromotionPiece.Bishop))
|
|
||||||
m.moveType shouldBe MoveType.Promotion(PromotionPiece.Bishop)
|
|
||||||
}
|
|
||||||
|
|
||||||
test("Move with Promotion to Rook") {
|
|
||||||
val m = Move(e2, e4, MoveType.Promotion(PromotionPiece.Rook))
|
|
||||||
m.moveType shouldBe MoveType.Promotion(PromotionPiece.Rook)
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
package de.nowchess.api.player
|
|
||||||
|
|
||||||
import org.scalatest.funsuite.AnyFunSuite
|
|
||||||
import org.scalatest.matchers.should.Matchers
|
|
||||||
|
|
||||||
class PlayerInfoTest extends AnyFunSuite with Matchers:
|
|
||||||
|
|
||||||
test("PlayerId.apply wraps a string") {
|
|
||||||
val id = PlayerId("player-123")
|
|
||||||
id.value shouldBe "player-123"
|
|
||||||
}
|
|
||||||
|
|
||||||
test("PlayerId.value unwraps to original string") {
|
|
||||||
val raw = "abc-456"
|
|
||||||
PlayerId(raw).value shouldBe raw
|
|
||||||
}
|
|
||||||
|
|
||||||
test("PlayerInfo holds id and displayName") {
|
|
||||||
val id = PlayerId("p1")
|
|
||||||
val info = PlayerInfo(id, "Magnus")
|
|
||||||
info.id.value shouldBe "p1"
|
|
||||||
info.displayName shouldBe "Magnus"
|
|
||||||
}
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
package de.nowchess.api.response
|
|
||||||
|
|
||||||
import org.scalatest.funsuite.AnyFunSuite
|
|
||||||
import org.scalatest.matchers.should.Matchers
|
|
||||||
|
|
||||||
class ApiResponseTest extends AnyFunSuite with Matchers:
|
|
||||||
|
|
||||||
test("ApiResponse.Success carries data") {
|
|
||||||
val r = ApiResponse.Success(42)
|
|
||||||
r.data shouldBe 42
|
|
||||||
}
|
|
||||||
|
|
||||||
test("ApiResponse.Failure carries error list") {
|
|
||||||
val err = ApiError("CODE", "msg")
|
|
||||||
val r = ApiResponse.Failure(List(err))
|
|
||||||
r.errors shouldBe List(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
test("ApiResponse.error creates single-error Failure") {
|
|
||||||
val err = ApiError("NOT_FOUND", "not found")
|
|
||||||
val f = ApiResponse.error(err)
|
|
||||||
f shouldBe ApiResponse.Failure(List(err))
|
|
||||||
}
|
|
||||||
|
|
||||||
test("ApiError holds code and message") {
|
|
||||||
val e = ApiError("CODE", "message")
|
|
||||||
e.code shouldBe "CODE"
|
|
||||||
e.message shouldBe "message"
|
|
||||||
e.field shouldBe None
|
|
||||||
}
|
|
||||||
|
|
||||||
test("ApiError holds optional field") {
|
|
||||||
val e = ApiError("INVALID", "bad value", Some("email"))
|
|
||||||
e.field shouldBe Some("email")
|
|
||||||
}
|
|
||||||
|
|
||||||
test("Pagination.totalPages with exact division") {
|
|
||||||
Pagination(page = 0, pageSize = 10, totalItems = 30).totalPages shouldBe 3
|
|
||||||
}
|
|
||||||
|
|
||||||
test("Pagination.totalPages rounds up") {
|
|
||||||
Pagination(page = 0, pageSize = 10, totalItems = 25).totalPages shouldBe 3
|
|
||||||
}
|
|
||||||
|
|
||||||
test("Pagination.totalPages is 0 when totalItems is 0") {
|
|
||||||
Pagination(page = 0, pageSize = 10, totalItems = 0).totalPages shouldBe 0
|
|
||||||
}
|
|
||||||
|
|
||||||
test("Pagination.totalPages is 0 when pageSize is 0") {
|
|
||||||
Pagination(page = 0, pageSize = 0, totalItems = 100).totalPages shouldBe 0
|
|
||||||
}
|
|
||||||
|
|
||||||
test("Pagination.totalPages is 0 when pageSize is negative") {
|
|
||||||
Pagination(page = 0, pageSize = -1, totalItems = 100).totalPages shouldBe 0
|
|
||||||
}
|
|
||||||
|
|
||||||
test("PagedResponse holds items and pagination") {
|
|
||||||
val pagination = Pagination(page = 1, pageSize = 5, totalItems = 20)
|
|
||||||
val pr = PagedResponse(List("a", "b"), pagination)
|
|
||||||
pr.items shouldBe List("a", "b")
|
|
||||||
pr.pagination shouldBe pagination
|
|
||||||
}
|
|
||||||
@@ -52,10 +52,9 @@ dependencies {
|
|||||||
|
|
||||||
testImplementation(platform("org.junit:junit-bom:5.13.4"))
|
testImplementation(platform("org.junit:junit-bom:5.13.4"))
|
||||||
testImplementation("org.junit.jupiter:junit-jupiter")
|
testImplementation("org.junit.jupiter:junit-jupiter")
|
||||||
|
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
|
||||||
testImplementation("org.scalatest:scalatest_3:${versions["SCALATEST"]!!}")
|
testImplementation("org.scalatest:scalatest_3:${versions["SCALATEST"]!!}")
|
||||||
testImplementation("co.helmethair:scalatest-junit-runner:${versions["SCALATEST_JUNIT"]!!}")
|
testImplementation("co.helmethair:scalatest-junit-runner:${versions["SCALATEST_JUNIT"]!!}")
|
||||||
|
|
||||||
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.test {
|
tasks.test {
|
||||||
|
|||||||
Reference in New Issue
Block a user