Skip to content

Commit

Permalink
Merge pull request #84 from jetbrains-academy/add-tests
Browse files Browse the repository at this point in the history
Add tests for the last two tasks
  • Loading branch information
nbirillo authored Oct 16, 2024
2 parents 2914544 + 2e851f5 commit 03f5d8b
Show file tree
Hide file tree
Showing 6 changed files with 192 additions and 35 deletions.
16 changes: 15 additions & 1 deletion culinaryServer/culinaryServerCookSalad/test/SaladFunctions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,25 @@ internal val cutMethod = TestMethod(
)
)

internal val mixVegetablesForSaladMethod = TestMethod(
"mixVegetablesForSalad",
TestKotlinType("Unit"),
arguments = listOf(
TestVariable(
name = "cutVegetables",
javaType = "List",
kotlinType = TestKotlinType("List", params = listOf("org.jetbrains.kotlin.course.culinary.ingredient.CutVegetable")),
),
),
returnTypeJava = "void",
)

internal val saladKtTestClass = TestClass(
"SaladKt",
"org.jetbrains.kotlin.course.culinary.game.recipes",
customMethods = listOf(
getFreshVegetablesMethod,
cutMethod
cutMethod,
mixVegetablesForSaladMethod
),
)
55 changes: 41 additions & 14 deletions culinaryServer/culinaryServerCookSalad/test/Tests.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import org.jetbrains.academy.test.system.core.findMethod
import org.jetbrains.academy.test.system.core.invokeWithArgs
import org.jetbrains.academy.test.system.core.invokeWithoutArgs
import org.jetbrains.academy.test.system.core.models.classes.ConstructorGetter
import org.jetbrains.kotlin.course.culinary.converters.buildAction
import org.jetbrains.kotlin.course.culinary.game.actions
import org.jetbrains.kotlin.course.culinary.game.clearActions
import org.jetbrains.kotlin.course.culinary.game.recipes.NUMBER_OF_TOMATOES
Expand All @@ -20,7 +19,6 @@ import org.junit.jupiter.api.Test
import java.lang.reflect.InvocationTargetException

class Test {
// TODO: add tests for mixVegetablesForSalad
@Test
fun getFreshVegetablesMethodTest() {
val randomVegetables = fillFridge()
Expand Down Expand Up @@ -48,33 +46,62 @@ class Test {
}
}

@Test
fun cutMethodTest() {
clearActions()
fillFridge()

private fun cutVegetablesInvoke(vegetables: List<Vegetable>): List<CutVegetable> {
val clazz = saladKtTestClass.checkBaseDefinition()
val method = clazz.declaredMethods.findMethod(cutMethod)
val vegetables = getFreshVegetables()
val expectedVegetables = vegetables.take(NUM_VEGETABLES_FOR_SALAD).map{ CutVegetable(it.type) }

val cutVegetables = try {
return try {
method(clazz, vegetables) as List<CutVegetable>
} catch(e: InvocationTargetException) {
assert(false) { "Can not invoke method ${method.name}. Please, add an implementation!" }
emptyList()
}
}

@Test
fun cutMethodTest() {
clearActions()
fillFridge()

val vegetables = getFreshVegetables()
val expectedVegetables = vegetables.take(NUM_VEGETABLES_FOR_SALAD).map{ CutVegetable(it.type) }

assert(expectedVegetables.size == cutVegetables.size) { "The ${method.name} method should take all vegetables from the list of vegetables and cut them!" }
assert(expectedVegetables.sortedBy { it.type } == cutVegetables.sortedBy { it.type }) { "The ${method.name} method should take vegetables and cut them!" }
val cutVegetables = cutVegetablesInvoke(vegetables)

assert(expectedVegetables.size == cutVegetables.size) { "The ${cutMethod.name} method should take all vegetables from the list of vegetables and cut them!" }
assert(expectedVegetables.sortedBy { it.type } == cutVegetables.sortedBy { it.type }) { "The ${cutMethod.name} method should take vegetables and cut them!" }

val expectedActions = buildList {
addAll(List(vegetables.size) { ActionType.SHOW_ON_COUNTER })
repeat(vegetables.size) {
addAll(listOf(ActionType.CUT_ON_COUNTER, ActionType.SHOW_ON_COUNTER))
}
}
assert(expectedActions == actions.map{ it.type }) { "The ${method.name} method should take vegetables and cut them: take each of them from the fridge, and then cut" }
assert(expectedActions == actions.map{ it.type }) { "The ${cutMethod.name} method should take vegetables and cut them: take each of them from the fridge, and then cut" }
}

@Test
fun mixVegetablesForSaladMethodTest() {
fillFridge()

val clazz = saladKtTestClass.checkBaseDefinition()
val method = clazz.declaredMethods.findMethod(mixVegetablesForSaladMethod)
val vegetables = getFreshVegetables()
val cutVegetables = cutVegetablesInvoke(vegetables)

val expectedActions = cutVegetables.groupBy { it.type }
.map { (_, cuts) ->
cuts.map{ c -> buildAction(ActionType.ADD_TO_SALAD, c) }
}.flatten()

clearActions()
try {
method(clazz, cutVegetables)
} catch(e: InvocationTargetException) {
assert(false) { "Can not invoke method ${method.name}. Please, add an implementation!" }
}

assert(expectedActions + Action(ActionType.MIX_SALAD) == actions) { "The ${method.name} method should group cut vegetables by their type, and then for each type add to the salad bowl" }
}

@Test
Expand Down
3 changes: 3 additions & 0 deletions culinaryServer/culinaryServerCookSmoothie/task-info.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,6 @@ files:
- name: test/TomatoSoupFunctions.kt
visible: false
propagatable: false
- name: test/SmoothieFunctions.kt
visible: false
propagatable: false
16 changes: 15 additions & 1 deletion culinaryServer/culinaryServerCookSmoothie/test/SaladFunctions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,25 @@ internal val cutMethod = TestMethod(
)
)

internal val mixVegetablesForSaladMethod = TestMethod(
"mixVegetablesForSalad",
TestKotlinType("Unit"),
arguments = listOf(
TestVariable(
name = "cutVegetables",
javaType = "List",
kotlinType = TestKotlinType("List", params = listOf("org.jetbrains.kotlin.course.culinary.ingredient.CutVegetable")),
),
),
returnTypeJava = "void",
)

internal val saladKtTestClass = TestClass(
"SaladKt",
"org.jetbrains.kotlin.course.culinary.game.recipes",
customMethods = listOf(
getFreshVegetablesMethod,
cutMethod
cutMethod,
mixVegetablesForSaladMethod
),
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import org.jetbrains.academy.test.system.core.models.TestKotlinType
import org.jetbrains.academy.test.system.core.models.classes.TestClass
import org.jetbrains.academy.test.system.core.models.method.TestMethod
import org.jetbrains.academy.test.system.core.models.variable.TestVariable

internal val getFruitsForSmoothieMethod = TestMethod(
"getFruitsForSmoothie",
TestKotlinType("List", params = listOf("org.jetbrains.kotlin.course.culinary.ingredient.Fruit")),
)

internal val cookSmoothieMethod = TestMethod(
"cookSmoothie",
TestKotlinType("Unit"),
arguments = listOf(
TestVariable(
name = "fruit",
javaType = "List",
kotlinType = TestKotlinType("List", params = listOf("org.jetbrains.kotlin.course.culinary.ingredient.Fruit")),
),
),
returnTypeJava = "void",
)

internal val smoothieKtTestClass = TestClass(
"SmoothieKt",
"org.jetbrains.kotlin.course.culinary.game.recipes",
customMethods = listOf(
getFruitsForSmoothieMethod,
cookSmoothieMethod
),
)
106 changes: 87 additions & 19 deletions culinaryServer/culinaryServerCookSmoothie/test/Tests.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import org.jetbrains.academy.test.system.core.findMethod
import org.jetbrains.academy.test.system.core.invokeWithArgs
import org.jetbrains.academy.test.system.core.invokeWithoutArgs
import org.jetbrains.academy.test.system.core.models.classes.ConstructorGetter
import org.jetbrains.kotlin.course.culinary.converters.buildAction
import org.jetbrains.kotlin.course.culinary.game.actions
import org.jetbrains.kotlin.course.culinary.game.clearActions
import org.jetbrains.kotlin.course.culinary.game.fridge
import org.jetbrains.kotlin.course.culinary.game.kitchen
import org.jetbrains.kotlin.course.culinary.game.recipes.NUMBER_OF_TOMATOES
import org.jetbrains.kotlin.course.culinary.game.recipes.NUM_VEGETABLES_FOR_SALAD
import org.jetbrains.kotlin.course.culinary.implementation.storage.FridgeImpl
Expand All @@ -12,15 +13,53 @@ import org.jetbrains.kotlin.course.culinary.implementation.storage.FridgeImpl.RA
import org.jetbrains.kotlin.course.culinary.models.ItemType
import org.jetbrains.kotlin.course.culinary.models.action.Action
import org.jetbrains.kotlin.course.culinary.models.action.ActionType
import org.jetbrains.kotlin.course.culinary.models.food.CutVegetable
import org.jetbrains.kotlin.course.culinary.models.food.SpiceType
import org.jetbrains.kotlin.course.culinary.models.food.Vegetable
import org.jetbrains.kotlin.course.culinary.models.food.VegetableType
import org.jetbrains.kotlin.course.culinary.models.food.*
import org.junit.jupiter.api.Test
import java.lang.reflect.InvocationTargetException

class Test {
// TODO: add tests for mixVegetablesForSalad
@Test
fun getFruitsForSmoothieMethodTest() {
clearActions()
val fruits = getFruitsForSmoothie()

assert(fruits.toSet().size == 2) { "The ${getFruitsForSmoothieMethod.name} method should return a lit of Citrus and Berry fruits only" }
val expectedActions = buildList{
add(Action(ActionType.SHOW_ON_COUNTER, ItemType.BERRY_BASKET))
add(Action(ActionType.SHOW_ON_COUNTER, ItemType.CITRUS_BASKET))
}
assert(expectedActions == actions) { "The ${getFruitsForSmoothieMethod.name} method should return a lit of fruits for smoothie, sorted by sugarContent amount" }
}

private fun getFruitsForSmoothie(): List<Fruit> {
val clazz = smoothieKtTestClass.checkBaseDefinition()
val method = clazz.declaredMethods.findMethod(getFruitsForSmoothieMethod)

return try {
method.invokeWithoutArgs(clazz = clazz) as List<Fruit>
} catch(e: InvocationTargetException) {
assert(false) { "Can not invoke method ${method.name}. Please, add an implementation!" }
emptyList()
}
}

@Test
fun cookSmoothieMethodTest() {
val fruits = getFruitsForSmoothie()

clearActions()
val clazz = smoothieKtTestClass.checkBaseDefinition()
val method = clazz.declaredMethods.findMethod(cookSmoothieMethod)
try {
method(clazz, fruits)
} catch(e: InvocationTargetException) {
assert(false) { "Can not invoke method ${method.name}. Please, add an implementation!" }
}

val expectedActions = fruits.map{ buildAction(ActionType.ADD_TO_BLENDER, it) }
assert(expectedActions + Action(ActionType.BLEND) == actions) { "The ${method.name} method should add to the blender all fruits and then blend them" }
}

@Test
fun getFreshVegetablesMethodTest() {
val randomVegetables = fillFridge()
Expand Down Expand Up @@ -48,40 +87,69 @@ class Test {
}
}

@Test
fun cutMethodTest() {
clearActions()
fillFridge()

private fun cutVegetablesInvoke(vegetables: List<Vegetable>): List<CutVegetable> {
val clazz = saladKtTestClass.checkBaseDefinition()
val method = clazz.declaredMethods.findMethod(cutMethod)
val vegetables = getFreshVegetables()
val expectedVegetables = vegetables.take(NUM_VEGETABLES_FOR_SALAD).map{ CutVegetable(it.type) }

val cutVegetables = try {
return try {
method(clazz, vegetables) as List<CutVegetable>
} catch(e: InvocationTargetException) {
assert(false) { "Can not invoke method ${method.name}. Please, add an implementation!" }
emptyList()
}
}

@Test
fun cutMethodTest() {
clearActions()
fillFridge()

assert(expectedVegetables.size == cutVegetables.size) { "The ${method.name} method should take all vegetables from the list of vegetables and cut them!" }
assert(expectedVegetables.sortedBy { it.type } == cutVegetables.sortedBy { it.type }) { "The ${method.name} method should take vegetables and cut them!" }
val vegetables = getFreshVegetables()
val expectedVegetables = vegetables.take(NUM_VEGETABLES_FOR_SALAD).map{ CutVegetable(it.type) }

val cutVegetables = cutVegetablesInvoke(vegetables)

assert(expectedVegetables.size == cutVegetables.size) { "The ${cutMethod.name} method should take all vegetables from the list of vegetables and cut them!" }
assert(expectedVegetables.sortedBy { it.type } == cutVegetables.sortedBy { it.type }) { "The ${cutMethod.name} method should take vegetables and cut them!" }

val expectedActions = buildList {
addAll(List(vegetables.size) { ActionType.SHOW_ON_COUNTER })
repeat(vegetables.size) {
addAll(listOf(ActionType.CUT_ON_COUNTER, ActionType.SHOW_ON_COUNTER))
}
}
assert(expectedActions == actions.map{ it.type }) { "The ${method.name} method should take vegetables and cut them: take each of them from the fridge, and then cut" }
assert(expectedActions == actions.map{ it.type }) { "The ${cutMethod.name} method should take vegetables and cut them: take each of them from the fridge, and then cut" }
}

@Test
fun mixVegetablesForSaladMethodTest() {
fillFridge()

val clazz = saladKtTestClass.checkBaseDefinition()
val method = clazz.declaredMethods.findMethod(mixVegetablesForSaladMethod)
val vegetables = getFreshVegetables()
val cutVegetables = cutVegetablesInvoke(vegetables)

val expectedActions = cutVegetables.groupBy { it.type }
.map { (_, cuts) ->
cuts.map{ c -> buildAction(ActionType.ADD_TO_SALAD, c) }
}.flatten()

clearActions()
try {
method(clazz, cutVegetables)
} catch(e: InvocationTargetException) {
assert(false) { "Can not invoke method ${method.name}. Please, add an implementation!" }
}

assert(expectedActions + Action(ActionType.MIX_SALAD) == actions) { "The ${method.name} method should group cut vegetables by their type, and then for each type add to the salad bowl" }
}

@Test
fun generateSpicesMethodTest() {
val spices = generateSpices().take(5).toList()
if (spices.isEmpty()) {
assert(false) { "The method ${generateSpicesMethod.name} should generate random spices! Now you always generate an empty sequence!" }
assert(false) { "The method ${generateSpicesMethod.name} should generate random spices! Now you always generate an empty sequence!" }
}
assert(spices.toSet().size > 1) { "The method ${generateSpicesMethod.name} should generate random spices! Now you always generate ${spices.first()}" }
}
Expand Down

0 comments on commit 03f5d8b

Please sign in to comment.