Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

assert and require replacement #25

Merged
merged 2 commits into from
Nov 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,22 @@ plugins {
}

group = "org.jetbrains.academy.test.system"
version = "2.0.7"
version = "2.1.0"

allprojects {
apply {
plugin("kotlin")
plugin("io.gitlab.arturbosch.detekt")
}

dependencies {
val junitJupiterVersion = "5.9.0"
implementation("org.junit.jupiter:junit-jupiter-api:$junitJupiterVersion")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:$junitJupiterVersion")
testImplementation("org.junit.jupiter:junit-jupiter-params:$junitJupiterVersion")
testRuntimeOnly("org.junit.platform:junit-platform-console:1.9.2")
}

repositories {
mavenCentral()
}
Expand Down
5 changes: 0 additions & 5 deletions core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,6 @@ version = rootProject.version

dependencies {
implementation(kotlin("reflect"))
val junitJupiterVersion = "5.9.0"
implementation("org.junit.jupiter:junit-jupiter-api:$junitJupiterVersion")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:$junitJupiterVersion")
testImplementation("org.junit.jupiter:junit-jupiter-params:$junitJupiterVersion")
testRuntimeOnly("org.junit.platform:junit-platform-console:1.9.2")
}

tasks.test {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import org.jetbrains.academy.test.system.core.models.Visibility
import org.jetbrains.academy.test.system.core.models.classes.ClassType
import org.jetbrains.academy.test.system.core.models.classes.TestClass
import org.jetbrains.academy.test.system.core.models.getVisibility
import org.junit.jupiter.api.Assertions
import java.lang.reflect.Modifier
import kotlin.jvm.internal.DefaultConstructorMarker

Expand Down Expand Up @@ -51,24 +52,27 @@ fun Class<*>.checkIfIsDataClass(testClass: TestClass) {
"toString",
)
dataClassMethods.forEach { dataClassMethod ->
assert(dataClassMethod in methodsNames || methodsNames.any { dataClassMethod in it }) { "${testClass.getFullName()} must be a data class" }
Assertions.assertTrue(
dataClassMethod in methodsNames || methodsNames.any { dataClassMethod in it },
"${testClass.getFullName()} must be a data class"
)
}
val componentN = testClass.declaredFields.filter { it.isInPrimaryConstructor && it.visibility == Visibility.PUBLIC }
val componentNFunctions = methodsNames.filter { "component" in it }
val componentNErrorMessage =
"You must put only ${componentN.size} public fields into the primary constructor: ${componentN.joinToString(", ") { it.name }}."
assert(componentNFunctions.size == componentN.size) { componentNErrorMessage }
Assertions.assertEquals(componentNFunctions.size, componentN.size, componentNErrorMessage)
componentN.forEachIndexed { index, _ ->
val name = "component${index + 1}"
assert(name in methodsNames || methodsNames.any { name in it }) { componentNErrorMessage }
Assertions.assertTrue(name in methodsNames || methodsNames.any { name in it }, componentNErrorMessage)
}
val primary = testClass.declaredFields.filter { it.isInPrimaryConstructor }
val constructorErrorMessage =
"You must put only ${primary.size} fields into the primary constructor: ${primary.joinToString(", ") { it.name }}."
require(this.constructors.isNotEmpty()) { "The data class must have at least one constructor!" }
assert(this.constructors.any { constructor ->
Assertions.assertTrue(this.constructors.isNotEmpty(), "The data class must have at least one constructor!" )
Assertions.assertTrue(this.constructors.any { constructor ->
constructor.parameterTypes.filter { it != DefaultConstructorMarker::class.java }.size == primary.size
}) { constructorErrorMessage }
}, constructorErrorMessage)
}

private fun Class<*>.hasSameVisibilityWith(testClass: TestClass) = this.getVisibility() == testClass.visibility
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.jetbrains.academy.test.system.core

import org.jetbrains.academy.test.system.core.models.TestKotlinType
import org.junit.jupiter.api.Assertions
import kotlin.reflect.KType
import kotlin.reflect.jvm.javaType

Expand All @@ -21,20 +22,28 @@ fun KType.checkType(
// We have a parametrized type
if ("<" in this.javaType.toString() && kotlinType?.abbreviation == null) {
val type = kotlinType?.getTypePrettyString() ?: javaType
assert(type.lowercase() in this.javaType.toString().lowercase()) { message }
Assertions.assertTrue(type.lowercase() in this.javaType.toString().lowercase(), message)
} else {
assert(this.javaType.getShortName() == javaType.lowercase()) { message }
Assertions.assertEquals(this.javaType.getShortName(), javaType.lowercase(), message)
}
}
}

private fun KType.checkNullability(kotlinType: TestKotlinType, errorMessagePrefix: String) {
val nullablePrefix = if (!kotlinType.isNullable) "" else "not"
assert(this.isMarkedNullable == kotlinType.isNullable) { "Error, $errorMessagePrefix must be $nullablePrefix nullable" }
Assertions.assertEquals(
this.isMarkedNullable,
kotlinType.isNullable,
"Error, $errorMessagePrefix must be $nullablePrefix nullable"
)
}

private fun KType.checkAbbreviation(abbreviation: String, errorMessagePrefix: String) {
assert(this.getAbbreviation() == abbreviation) { "The return type for $errorMessagePrefix must contain $abbreviation" }
Assertions.assertEquals(
this.getAbbreviation(),
abbreviation,
"The return type for $errorMessagePrefix must contain $abbreviation"
)
}

private fun KType.getAbbreviation(): String {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.jetbrains.academy.test.system.core

import org.jetbrains.academy.test.system.core.models.method.TestMethod
import org.junit.jupiter.api.Assertions
import java.lang.reflect.Method

fun Method.invokeWithoutArgs(
Expand All @@ -24,9 +25,7 @@ fun Method.invokeWithArgs(

private fun List<Method>.filterByCondition(errorMessage: String, condition: (Method) -> Boolean): List<Method> {
val filteredByCondition = this.filter { condition(it) }
if (filteredByCondition.isEmpty()) {
assert(false) { errorMessage }
}
Assertions.assertTrue(filteredByCondition.isNotEmpty(), errorMessage)
return filteredByCondition
}

Expand All @@ -49,6 +48,11 @@ fun Array<Method>.findMethod(method: TestMethod, customErrorMessage: String? = n
filteredByType.filterByCondition(customErrorMessage ?: "The method ${method.name} should have ${method.arguments.size} arguments") { it.parameterCount == method.arguments.size }
val args = method.arguments.map { it.javaType.lowercase() }
val methods = filteredByArgumentsCount.filterByCondition(customErrorMessage ?: "The method ${method.prettyString()} is missed. Check it's arguments properly." ) { m -> m.parameterTypes.map { it.name.getShortName().lowercase() } == args }
require(methods.size == 1) { customErrorMessage ?: "The method ${method.name} should have ${method.arguments.size} arguments: $args. The full signature is: ${method.prettyString()}." }
Assertions.assertEquals(
methods.size,
1,
customErrorMessage
?: "The method ${method.name} should have ${method.arguments.size} arguments: $args. The full signature is: ${method.prettyString()}."
)
return methods.first()
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import org.jetbrains.academy.test.system.core.models.Visibility
import org.jetbrains.academy.test.system.core.models.method.TestMethod
import org.jetbrains.academy.test.system.core.models.method.TestMethodInvokeData
import org.jetbrains.academy.test.system.core.models.variable.TestVariable
import org.junit.jupiter.api.Assertions
import java.lang.reflect.Constructor
import java.lang.reflect.Method

Expand Down Expand Up @@ -43,14 +44,13 @@ data class TestClass(
fun checkBaseDefinition(): Class<*> {
val clazz = this.findClassSafe()
val errorMessage = "You need to add: ${this.getBaseDefinition()}"
assert(clazz != null) { errorMessage }
assert(
clazz!!.isSameWith(this)
) {
Assertions.assertNotNull(clazz, errorMessage)
Assertions.assertTrue(
clazz!!.isSameWith(this),
"$errorMessage, but currently you added: ${
clazz.toTestClass(this.name, this.classPackage).getBaseDefinition()
}"
}
)
if (isDataClass) {
clazz.checkIfIsDataClass(this)
}
Expand All @@ -62,10 +62,17 @@ data class TestClass(

private fun checkInterfaces(clazz: Class<*>) {
val clazzInterfaces = clazz.interfaces
assert(this.interfaces.size == clazzInterfaces.size) { "The class ${getFullName()} must have ${this.interfaces.size} direct superclasses" }
Assertions.assertEquals(
this.interfaces.size,
clazzInterfaces.size,
"The class ${getFullName()} must have ${this.interfaces.size} direct superclasses"
)
this.interfaces.forEach {
val currentClazz = it.findClass()
assert(currentClazz in clazzInterfaces) { "The class ${getFullName()} must have ${it.getFullName()} as a direct superclass" }
Assertions.assertTrue(
currentClazz in clazzInterfaces,
"The class ${getFullName()} must have ${it.getFullName()} as a direct superclass"
)
}
}

Expand All @@ -75,7 +82,7 @@ data class TestClass(
val declaredFields = clazz.getDeclaredFieldsWithoutCompanion()
variables.forEach { field ->
val currentField = declaredFields.find { it.name == field.name }
assert(currentField != null) { "Can not find the field with name ${field.name}" }
Assertions.assertNotNull(currentField, "Can not find the field with name ${field.name}")
field.checkField(currentField!!, toCheckMutability)
}
}
Expand All @@ -84,42 +91,48 @@ data class TestClass(

fun checkFieldsDefinition(clazz: Class<*>, toCheckDeclaredFieldsSize: Boolean = true) {
if (toCheckDeclaredFieldsSize) {
assert(clazz.getDeclaredFieldsWithoutCompanion().size == this.declaredFields.size) { "You need to declare the following fields: ${this.getFieldsListPrettyString()}" }
Assertions.assertEquals(
clazz.getDeclaredFieldsWithoutCompanion().size,
this.declaredFields.size,
"You need to declare the following fields: ${this.getFieldsListPrettyString()}"
)
}
this.checkFields(clazz)
}

fun getJavaClass(): Class<*> {
val clazz = this.findClassSafe()
assert(clazz != null) { "You need to add: ${this.getBaseDefinition()}" }
Assertions.assertNotNull(clazz, "You need to add: ${this.getBaseDefinition()}")
return clazz!!
}

fun checkNoConstructors(clazz: Class<*>) {
assert(clazz.constructors.isEmpty()) { "The ${getBaseDefinition()} must not have any constructors" }
Assertions.assertTrue(clazz.constructors.isEmpty(), "The ${getBaseDefinition()} must not have any constructors")
}

fun getObjectInstance(clazz: Class<*>): Any {
val field = clazz.getInstanceFiled()
require(field != null) { "Did not find the INSTANCE of the ${getFullName()}" }
return field.get(clazz) ?: error("Did not get the INSTANCE of the ${getFullName()}")
Assertions.assertNotNull(field, "Did not find the INSTANCE of the ${getFullName()}")
return field!!.get(clazz) ?: error("Did not get the INSTANCE of the ${getFullName()}")
}

fun checkConstructors(clazz: Class<*>, constructorGetters: List<ConstructorGetter>): Constructor<out Any> {
require(constructorGetters.isNotEmpty())
Assertions.assertTrue(constructorGetters.isNotEmpty())
val arguments = constructorGetters.map { it.parameterTypes }.toSet()
val constructors = mutableListOf<Constructor<*>>()
constructorGetters.forEach {
it.getConstructorWithDefaultArguments(clazz)?.let { constructor ->
constructors.add(constructor)
}
}
assert(constructors.isNotEmpty()) {

Assertions.assertTrue(
constructors.isNotEmpty(),
"""
You don't have any constructors with ${arguments.first().size} arguments in the class $name.
Please, check the arguments, probably you need to add the default values.
"""
}
)
return constructors.first()
}

Expand All @@ -136,7 +149,10 @@ data class TestClass(
}

fun findMethod(clazz: Class<*>, method: TestMethod): Method {
assert(method in customMethods) { "The method ${method.name} was not found in the class ${getFullName()}" }
Assertions.assertTrue(
method in customMethods,
"The method ${method.name} was not found in the class ${getFullName()}"
)
return clazz.methods.findMethod(method)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import org.jetbrains.academy.test.system.core.checkType
import org.jetbrains.academy.test.system.core.models.TestKotlinType
import org.jetbrains.academy.test.system.core.models.Visibility
import org.jetbrains.academy.test.system.core.models.variable.TestVariable
import org.junit.jupiter.api.Assertions
import java.lang.reflect.Method
import kotlin.reflect.jvm.kotlinFunction

Expand Down Expand Up @@ -40,9 +41,13 @@ data class TestMethod(
fun checkMethod(method: Method) {
val kotlinFunction =
method.kotlinFunction ?: error("Can not find Kotlin method for the method ${this.prettyString()}")
assert(kotlinFunction.name == name) { "The function name must be: $name" }
Assertions.assertEquals(kotlinFunction.name, name, "The function name must be: $name")
val visibility = kotlinFunction.visibility?.name?.lowercase()
assert(visibility == this.visibility.key) { "The visibility of the method $name must be ${this.visibility.key}" }
Assertions.assertEquals(
visibility,
this.visibility.key,
"\"The visibility of the method $name must be ${this.visibility.key}\""
)
kotlinFunction.returnType.checkType(returnType, returnTypeJava ?: returnType.type, "the function $name")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import org.jetbrains.academy.test.system.core.getShortName
import org.jetbrains.academy.test.system.core.models.Visibility
import org.jetbrains.academy.test.system.core.models.asVisibility
import org.jetbrains.academy.test.system.core.models.getVisibility
import org.junit.jupiter.api.Assertions
import java.lang.reflect.Field
import java.lang.reflect.Modifier
import kotlin.reflect.KProperty
Expand Down Expand Up @@ -46,17 +47,21 @@ internal data class FieldProperties(
}

fun checkProperties(variable: TestVariable, toCheckMutability: Boolean) {
assert(name == variable.name) { "The field name must be: ${variable.name}" }
Assertions.assertEquals(name, variable.name, "The field name must be: ${variable.name}")
val visibilityErrorMessage = variable.visibility?.let {
"The visibility of the field ${variable.name} must be ${it.key}"
} ?: "The filed ${variable.name} should not have any modifiers"
assert(visibility?.key?.lowercase() == variable.visibility?.key) { visibilityErrorMessage }
Assertions.assertEquals(visibility?.key?.lowercase(), variable.visibility?.key, visibilityErrorMessage)
if (toCheckMutability) {
val mutabilityErrorMessage = variable.mutability?.let {
"The field ${variable.name} must be ${it.key}"
} ?: "The filed ${variable.name} should not have val or var key words"
assert(mutability.compareWith(variable.mutability)) { mutabilityErrorMessage }
Assertions.assertTrue(mutability.compareWith(variable.mutability), mutabilityErrorMessage)
}
assert(javaType == variable.javaType.lowercase()) { "The return type of the field ${variable.name} must be ${variable.javaType.lowercase()}" }
Assertions.assertEquals(
javaType,
variable.javaType.lowercase(),
"The return type of the field ${variable.name} must be ${variable.javaType.lowercase()}"
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import org.jetbrains.academy.test.system.core.checkType
import org.jetbrains.academy.test.system.core.models.TestKotlinType
import org.jetbrains.academy.test.system.core.models.Visibility
import org.jetbrains.academy.test.system.core.throwInternalLibError
import org.junit.jupiter.api.Assertions
import java.io.File
import java.lang.reflect.Field
import java.lang.reflect.Modifier
Expand Down Expand Up @@ -55,13 +56,16 @@ data class TestVariable(
)
commonProp.checkProperties(this, toCheckMutability)
if (isStatic) {
assert(Modifier.isStatic(field.modifiers)) { "The field $name must be defined into an object or a companion object." }
Assertions.assertTrue(
Modifier.isStatic(field.modifiers),
"The field $name must be defined into an object or a companion object."
)
}
if (isConst) {
val errorMessage = "The field $name must be a const value."
assert(Modifier.isFinal(field.modifiers)) { errorMessage }
Assertions.assertTrue(Modifier.isFinal(field.modifiers), errorMessage)
field.kotlinProperty?.isConst?.let {
assert(it) { errorMessage }
Assertions.assertTrue(it, errorMessage)
}
}
field.kotlinProperty?.returnType?.checkType(
Expand Down Expand Up @@ -93,7 +97,7 @@ fun checkListOfVariables(sourceCodeFile: File, variables: List<TestVariable>) {
if (sourceCodeFile.exists()) {
val content = sourceCodeFile.readText()
for (variable in variables) {
assert(variable.isVariableExist(content))
Assertions.assertTrue(variable.isVariableExist(content))
}
} else {
// TODO: log some errors?
Expand Down
Loading
Loading