Skip to content

Commit

Permalink
feat: #81 #102 Convert Car to Kotlin. Move CarTest to kg-common.
Browse files Browse the repository at this point in the history
  • Loading branch information
dmitry-weirdo committed Nov 25, 2024
1 parent faf58ce commit 61a3fec
Show file tree
Hide file tree
Showing 5 changed files with 165 additions and 168 deletions.
2 changes: 2 additions & 0 deletions kgCommon/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@
<version>${kotlin.version}</version>
<extensions>true</extensions> <!-- You can set this option to automatically take information about lifecycles -->

<!--
<configuration>
<compilerPlugins>
<plugin>lombok</plugin>
Expand All @@ -145,6 +146,7 @@
<option>lombok:config=${project.basedir}/src/main/java/lombok.config</option>
</pluginOptions>
</configuration>
-->

<executions>
<execution>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
package ru.klavogonki.common;

import java.util.Arrays;
import java.util.List;
package ru.klavogonki.common

/**
* List of cars with ids and Russian names.
*/
public enum Car {
@SuppressWarnings("MagicNumber")
enum class Car {
// common/public autos
ZAZ_965(1, "ЗАЗ 965"),
VAZ_2104(2, "ВАЗ 2104"),
Expand All @@ -23,11 +21,13 @@ public enum Car {
BMW_X6(12, "BMW X6"),
AUDI_TT(13, "Audi TT"),
BUGATTI_VEYRON(14, "Bugatti Veyron"),

/**
* Notably, car 21 is also the F1 car.
* Looks like car 21 is now a tuning option for car 15.
* @see <a href="http://klavogonki.ru/img/cars/15.png">Image for car 15</a>
* @see <a href="http://klavogonki.ru/img/cars/21.png">Image for car 21</a>
* @see [Image for car 15](http://klavogonki.ru/img/cars/15.png)
*
* @see [Image for car 21](http://klavogonki.ru/img/cars/21.png)
*/
F1(15, "Болид F1"), // Notably, car 21 is also the F1 car,
LAMBORGHINI_MURCIELAGO(16, "Lamborghini Murcielago"),
Expand All @@ -36,6 +36,7 @@ public enum Car {
DUESENBERG_SPEEDSTER(19, "Duesenberg Speedster"),

UFO(20, "НЛО"),

// car 21 became a tuning for car 15
FERRARI_FX_CONCEPT(22, "Ferrari FX Concept"),
SMART_FORTWO(23, "Smart Fortwo"),
Expand Down Expand Up @@ -72,25 +73,31 @@ public enum Car {
HENNESSEY_VENOM_GT1(1001, "Hennessey Venom GT1", 30297), // http://klavogonki.ru/u/#/30297/car/
DE_LOREAN_TIME_MACHINE(1002, "DeLorean Time Machine", 151752), // http://klavogonki.ru/u/#/151752/car/
SUBMARINE(1003, "Submarine", 100600), // http://klavogonki.ru/u/#/100600/car/

// car 1004 made public
// car 1005 made public
MOTORCITY_EUROPE_MC1(1006, "Motorcity Europe MC1", 1596), // http://klavogonki.ru/u/#/1596/car/

// car 1007 made public
MERCEDES_BENZ_SL_600(1008, "Mercedes-Benz SL 600", 157594), // http://klavogonki.ru/u/#/157594/car/

// car 1009 made public
PAGANI_ZONDA_R(1010, "Pagani Zonda R", 235269), // http://klavogonki.ru/u/#/235269/car/
BATPOD(1011, "Бэтпод", 195256), // http://klavogonki.ru/u/#/195256/car/
ZIS_155(1012, "ЗИС-155", 306936), // http://klavogonki.ru/u/#/306936/car/

/**
* 2 exclusive owners: Fenex &amp; Аромат
* @see <a href="http://klavogonki.ru/u/#/82885/car/">Fenex' cars</a>
* @see <a href="http://klavogonki.ru/u/#/101646/car/">Аромат's cars</a>
* @see [Fenex' cars](http://klavogonki.ru/u/./82885/car/)
*
* @see [Аромат's cars](http://klavogonki.ru/u/./101646/car/)
*/
VOLKSWAGEN_CORRADO(1013, "Volkswagen Corrado", 101646), // http://klavogonki.ru/u/#/101646/car/
RED_EAGLE(1015, "Red Eagle", 24119), // http://klavogonki.ru/u/#/24119/car/ // ! From Carmageddon!
IHOUE(1016, "ΙΧΘΥΣ", 73879), // http://klavogonki.ru/u/#/73879/car/
PARASAILING(1017, "Parasailing", 291992), // http://klavogonki.ru/u/#/291992/car/
DRAGON(1018, "Дракон", 211962), // http://klavogonki.ru/u/#/211962/car/

// car 1019 made public
N_BAR(1020, "N-Bar", 20106), // http://klavogonki.ru/u/#/20106/car/
DU_49(1021, "ДУ-49", 173903), // http://klavogonki.ru/u/#/173903/car/
Expand All @@ -99,70 +106,72 @@ public enum Car {
FERRARI_F2(1024, "Ferrari F12", 320247), // http://klavogonki.ru/u/#/320247/car/
;

Car(final int id, final String name) {
this.id = id;
this.name = name;
this.ownerId = null;
this.personalId = null;
}

Car(final int id, final String name, final int ownerId) { // for personal cars that have not been made public
this.id = id;
this.name = name;
this.ownerId = ownerId;
this.personalId = null;
constructor(id: Int, displayName: String) {
this.id = id
this.displayName = displayName
this.ownerId = null
this.personalId = null
}

Car(final int id, final String name, final Integer ownerId, final Integer personalId) { // for personal cars that have not been made public
this.id = id;
this.name = name;
this.ownerId = ownerId;
this.personalId = personalId;
constructor(id: Int, displayName: String, ownerId: Int) { // for personal cars that have not been made public
this.id = id
this.displayName = displayName
this.ownerId = ownerId
this.personalId = null
}

public boolean isPersonalOnly() {
return (ownerId != null) && (personalId == null);
constructor(
id: Int,
displayName: String,
ownerId: Int,
personalId: Int
) { // for personal cars that have not been made public
this.id = id
this.displayName = displayName
this.ownerId = ownerId
this.personalId = personalId
}

public boolean wasPersonalButMadePublic() {
return (personalId != null);
}
@Suppress("Unused")
fun isPersonalOnly() = (ownerId != null) && (personalId == null)

public boolean isPublic() {
return (id < FIRST_PERSONAL_CAR_ID);
}
@Suppress("Unused")
fun wasPersonalButMadePublic() = (personalId != null)

public static boolean isPersonalId(int carId) {
return carId >= FIRST_PERSONAL_CAR_ID;
}
@Suppress("Unused")
fun isPublic() = (id < FIRST_PERSONAL_CAR_ID)

public static Car getById(int carId) {
List<Car> carsWithId = Arrays
.stream(Car.values())
.filter(car -> car.id == carId)
.toList();
val id: Int
val displayName: String
val ownerId: Int? // for personal autos
val personalId: Int? // for personal autos that have been made public

if (carsWithId.size() == 1) {
return carsWithId.get(0);
companion object {
fun isPersonalId(carId: Int): Boolean {
return carId >= FIRST_PERSONAL_CAR_ID
}

// original owners might have cars with personalId ids!
List<Car> carsWithPersonalId = Arrays
.stream(Car.values())
.filter(car -> (car.personalId != null) && (car.personalId == carId))
.toList();
fun getById(carId: Int): Car {
val carsWithId = entries
.filter { it.id == carId }

if (carsWithPersonalId.size() == 1) {
return carsWithPersonalId.get(0);
}
if (carsWithId.size == 1) {
return carsWithId[0]
}

throw new IllegalArgumentException(String.format("Found %d cars with id or personalId = %d.", carsWithId.size(), carId));
}
// original owners might have cars with personalId ids!
val carsWithPersonalId = entries
.filter { (it.personalId != null) && (it.personalId == carId) }

if (carsWithPersonalId.size == 1) {
return carsWithPersonalId[0]
}

public static final int FIRST_PERSONAL_CAR_ID = 1000;
// todo: understand what does it mean - no cars? More than 1 cars?
// more than one car by
error("Found ${carsWithId.size} cars with id or personalId = $carId.")
}

public final int id;
public final String name;
public final Integer ownerId; // for personal autos
public final Integer personalId; // for personal autos that have been made public
const val FIRST_PERSONAL_CAR_ID: Int = 1000
}
}
94 changes: 94 additions & 0 deletions kgCommon/src/test/kotlin/ru/klavogonki/common/CarTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package ru.klavogonki.common

import org.apache.logging.log4j.kotlin.Logging
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatThrownBy
import org.junit.jupiter.api.Test

internal class CarTest : Logging {

@Test
fun testCarIdsAreUnique() {
val cars = Car.entries

val uniqueCarIds = cars
.map { car: Car -> car.id }
.distinct()
.sorted()

logger.info("Unique car ids: \n$uniqueCarIds")

assertThat(uniqueCarIds).hasSameSizeAs(cars)
}

@Test
fun testCarNamesAreUnique() {
val cars = Car.entries

val uniqueCarNames = cars
.map { it.name }
.distinct()
.sorted()

logger.info("Unique car names: \n$uniqueCarNames")

assertThat(uniqueCarNames).hasSameSizeAs(cars)
}

@Test
fun testAllPersonalCarIdsArePersonalIds() {
val cars = Car.entries

val carPersonalIds = cars
.filter { it.personalId != null }
.map { it.personalId!! }
.distinct()
.sorted()

logger.info("Personal car ids for cars that have been made public: \n$carPersonalIds")

carPersonalIds.forEach {
assertThat(Car.isPersonalId(it)).isTrue()
}
}

@Test
fun testAllPersonalCarsThatWereMadePublicHaveOriginalOwnerFilled() {
val cars = Car.entries

val personalCarsThatWereMadePublic = cars
.filter { it.wasPersonalButMadePublic() }
.distinct()
.sorted()

logger.info("Cars that were personal but have been made public: \n$personalCarsThatWereMadePublic")

personalCarsThatWereMadePublic.forEach {
assertThat(it.ownerId).isNotNull()
assertThat(it.personalId).isNotNull()
}
}

@Test
fun testCarById() {
val publicCarById = Car.getById(Car.NISSAN_ROUND_BOX.id)
assertThat(publicCarById).isEqualTo(Car.NISSAN_ROUND_BOX)

val personalCarById = Car.getById(Car.DUCATI_848_2010.id)
assertThat(personalCarById).isEqualTo(Car.DUCATI_848_2010)

val publishedPersonalCarById = Car.getById(Car.TRAM.id)
assertThat(publishedPersonalCarById).isEqualTo(Car.TRAM)

assertThat(Car.TRAM.personalId).isNotNull()
val publishedPersonalCarByPersonalId = Car.getById(Car.TRAM.personalId!!)
assertThat(publishedPersonalCarByPersonalId).isEqualTo(Car.TRAM)

assertThatThrownBy {
Car.getById(0) // non-existing car id
}
.isInstanceOf(IllegalStateException::class.java)
.hasMessageContaining("0 cars")
.hasMessageContaining(" = 0")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ public static String dictionaryPage(int dictionaryId) {

// car images
public static String basicCarImage(Car car) {
return getLink("/img/cars/%d.png", car.id);
return getLink("/img/cars/%d.png", car.getId());
}

// todo: maybe extract API to a separate class
Expand Down
Loading

0 comments on commit 61a3fec

Please sign in to comment.