Merge commit '25a4097aa2387883075cf763b55e63f1b57f0334' as 'H07'
This commit is contained in:
commit
1a62ebbf1b
125 changed files with 729 additions and 2894 deletions
12
H07/.editorconfig
Normal file
12
H07/.editorconfig
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
# Editor configuration, see https://editorconfig.org
|
||||||
|
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
end_of_line = lf
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
[{*.yml,*.json}]
|
||||||
|
indent_size = 2
|
86
H07/.gitignore
vendored
Normal file
86
H07/.gitignore
vendored
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
### Intellij ###
|
||||||
|
.idea/
|
||||||
|
*.iws
|
||||||
|
/out/
|
||||||
|
*.iml
|
||||||
|
.idea_modules/
|
||||||
|
atlassian-ide-plugin.xml
|
||||||
|
|
||||||
|
### VS-Code ###
|
||||||
|
.vscode/
|
||||||
|
.VSCodeCounter/
|
||||||
|
|
||||||
|
### Eclipse ###
|
||||||
|
.metadata
|
||||||
|
bin/
|
||||||
|
tmp/
|
||||||
|
*.tmp
|
||||||
|
*.bak
|
||||||
|
*.swp
|
||||||
|
*~.nib
|
||||||
|
local.properties
|
||||||
|
.settings/
|
||||||
|
.loadpath
|
||||||
|
.recommenders
|
||||||
|
.externalToolBuilders/
|
||||||
|
*.launch
|
||||||
|
.factorypath
|
||||||
|
.recommenders/
|
||||||
|
.apt_generated/
|
||||||
|
.project
|
||||||
|
.classpath
|
||||||
|
|
||||||
|
### Linux ###
|
||||||
|
*~
|
||||||
|
.fuse_hidden*
|
||||||
|
.directory
|
||||||
|
.Trash-*
|
||||||
|
.nfs*
|
||||||
|
|
||||||
|
### macOS ###
|
||||||
|
.DS_Store
|
||||||
|
.AppleDouble
|
||||||
|
.LSOverride
|
||||||
|
Icon
|
||||||
|
._*
|
||||||
|
.DocumentRevisions-V100
|
||||||
|
.fseventsd
|
||||||
|
.Spotlight-V100
|
||||||
|
.TemporaryItems
|
||||||
|
.Trashes
|
||||||
|
.VolumeIcon.icns
|
||||||
|
.com.apple.timemachine.donotpresent
|
||||||
|
.AppleDB
|
||||||
|
.AppleDesktop
|
||||||
|
Network Trash Folder
|
||||||
|
Temporary Items
|
||||||
|
.apdisk
|
||||||
|
|
||||||
|
### NetBeans ###
|
||||||
|
nbproject/private/
|
||||||
|
build/
|
||||||
|
nbbuild/
|
||||||
|
dist/
|
||||||
|
nbdist/
|
||||||
|
.nb-gradle/
|
||||||
|
|
||||||
|
### Windows ###
|
||||||
|
# Windows thumbnail cache files
|
||||||
|
Thumbs.db
|
||||||
|
ehthumbs.db
|
||||||
|
ehthumbs_vista.db
|
||||||
|
*.stackdump
|
||||||
|
[Dd]esktop.ini
|
||||||
|
$RECYCLE.BIN/
|
||||||
|
*.lnk
|
||||||
|
|
||||||
|
### Gradle ###
|
||||||
|
.gradle
|
||||||
|
/build/
|
||||||
|
out/
|
||||||
|
gradle-app.setting
|
||||||
|
!gradle-wrapper.jar
|
||||||
|
.gradletasknamecache
|
||||||
|
|
||||||
|
*.hprof
|
||||||
|
jagr.conf
|
4
H07/README.md
Normal file
4
H07/README.md
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
# Vorlage zu Hausübung 07
|
||||||
|
|
||||||
|
Beachten Sie die Hinweise zum Herunterladen, Importieren, Bearbeitern, Exportieren und Hochladen in unserem
|
||||||
|
[Studierenden-Guide](https://wiki.tudalgo.org/)
|
33
H07/build.gradle.kts
Normal file
33
H07/build.gradle.kts
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
import org.sourcegrade.jagr.gradle.task.grader.GraderRunTask
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
alias(libs.plugins.algomate)
|
||||||
|
}
|
||||||
|
|
||||||
|
exercise {
|
||||||
|
assignmentId.set("h07")
|
||||||
|
}
|
||||||
|
|
||||||
|
submission {
|
||||||
|
// ACHTUNG!
|
||||||
|
// Setzen Sie im folgenden Bereich Ihre TU-ID (NICHT Ihre Matrikelnummer!), Ihren Nachnamen und Ihren Vornamen
|
||||||
|
// in Anführungszeichen (z.B. "ab12cdef" für Ihre TU-ID) ein!
|
||||||
|
// BEISPIEL:
|
||||||
|
// studentId = "ab12cdef"
|
||||||
|
// firstName = "sol_first"
|
||||||
|
// lastName = "sol_last"
|
||||||
|
studentId = ""
|
||||||
|
firstName = ""
|
||||||
|
lastName = ""
|
||||||
|
|
||||||
|
// Optionally require own tests for mainBuildSubmission task. Default is false
|
||||||
|
requireTests = false
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks {
|
||||||
|
withType<GraderRunTask> {
|
||||||
|
doFirst {
|
||||||
|
throw GradleException("No public tests are provided for this exercise! For more information go to https://moodle.informatik.tu-darmstadt.de/mod/page/view.php?id=68766")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
2
H07/gradle/libs.versions.toml
Normal file
2
H07/gradle/libs.versions.toml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[plugins]
|
||||||
|
algomate = { id = "org.tudalgo.algomate", version = "0.7.1" }
|
BIN
H07/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
H07/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
7
H07/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
7
H07/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip
|
||||||
|
networkTimeout=10000
|
||||||
|
validateDistributionUrl=true
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
249
H07/gradlew
vendored
Executable file
249
H07/gradlew
vendored
Executable file
|
@ -0,0 +1,249 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright © 2015-2021 the original authors.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
#
|
||||||
|
# Gradle start up script for POSIX generated by Gradle.
|
||||||
|
#
|
||||||
|
# Important for running:
|
||||||
|
#
|
||||||
|
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||||
|
# noncompliant, but you have some other compliant shell such as ksh or
|
||||||
|
# bash, then to run this script, type that shell name before the whole
|
||||||
|
# command line, like:
|
||||||
|
#
|
||||||
|
# ksh Gradle
|
||||||
|
#
|
||||||
|
# Busybox and similar reduced shells will NOT work, because this script
|
||||||
|
# requires all of these POSIX shell features:
|
||||||
|
# * functions;
|
||||||
|
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||||
|
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||||
|
# * compound commands having a testable exit status, especially «case»;
|
||||||
|
# * various built-in commands including «command», «set», and «ulimit».
|
||||||
|
#
|
||||||
|
# Important for patching:
|
||||||
|
#
|
||||||
|
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||||
|
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||||
|
#
|
||||||
|
# The "traditional" practice of packing multiple parameters into a
|
||||||
|
# space-separated string is a well documented source of bugs and security
|
||||||
|
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||||
|
# options in "$@", and eventually passing that to Java.
|
||||||
|
#
|
||||||
|
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||||
|
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||||
|
# see the in-line comments for details.
|
||||||
|
#
|
||||||
|
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||||
|
# Darwin, MinGW, and NonStop.
|
||||||
|
#
|
||||||
|
# (3) This script is generated from the Groovy template
|
||||||
|
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||||
|
# within the Gradle project.
|
||||||
|
#
|
||||||
|
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||||
|
#
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
# Attempt to set APP_HOME
|
||||||
|
|
||||||
|
# Resolve links: $0 may be a link
|
||||||
|
app_path=$0
|
||||||
|
|
||||||
|
# Need this for daisy-chained symlinks.
|
||||||
|
while
|
||||||
|
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||||
|
[ -h "$app_path" ]
|
||||||
|
do
|
||||||
|
ls=$( ls -ld "$app_path" )
|
||||||
|
link=${ls#*' -> '}
|
||||||
|
case $link in #(
|
||||||
|
/*) app_path=$link ;; #(
|
||||||
|
*) app_path=$APP_HOME$link ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# This is normally unused
|
||||||
|
# shellcheck disable=SC2034
|
||||||
|
APP_BASE_NAME=${0##*/}
|
||||||
|
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||||
|
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
|
||||||
|
|
||||||
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
|
MAX_FD=maximum
|
||||||
|
|
||||||
|
warn () {
|
||||||
|
echo "$*"
|
||||||
|
} >&2
|
||||||
|
|
||||||
|
die () {
|
||||||
|
echo
|
||||||
|
echo "$*"
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
|
} >&2
|
||||||
|
|
||||||
|
# OS specific support (must be 'true' or 'false').
|
||||||
|
cygwin=false
|
||||||
|
msys=false
|
||||||
|
darwin=false
|
||||||
|
nonstop=false
|
||||||
|
case "$( uname )" in #(
|
||||||
|
CYGWIN* ) cygwin=true ;; #(
|
||||||
|
Darwin* ) darwin=true ;; #(
|
||||||
|
MSYS* | MINGW* ) msys=true ;; #(
|
||||||
|
NONSTOP* ) nonstop=true ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
|
|
||||||
|
# Determine the Java command to use to start the JVM.
|
||||||
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
|
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||||
|
else
|
||||||
|
JAVACMD=$JAVA_HOME/bin/java
|
||||||
|
fi
|
||||||
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
JAVACMD=java
|
||||||
|
if ! command -v java >/dev/null 2>&1
|
||||||
|
then
|
||||||
|
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Increase the maximum file descriptors if we can.
|
||||||
|
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||||
|
case $MAX_FD in #(
|
||||||
|
max*)
|
||||||
|
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||||
|
# shellcheck disable=SC2039,SC3045
|
||||||
|
MAX_FD=$( ulimit -H -n ) ||
|
||||||
|
warn "Could not query maximum file descriptor limit"
|
||||||
|
esac
|
||||||
|
case $MAX_FD in #(
|
||||||
|
'' | soft) :;; #(
|
||||||
|
*)
|
||||||
|
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||||
|
# shellcheck disable=SC2039,SC3045
|
||||||
|
ulimit -n "$MAX_FD" ||
|
||||||
|
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Collect all arguments for the java command, stacking in reverse order:
|
||||||
|
# * args from the command line
|
||||||
|
# * the main class name
|
||||||
|
# * -classpath
|
||||||
|
# * -D...appname settings
|
||||||
|
# * --module-path (only if needed)
|
||||||
|
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||||
|
|
||||||
|
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||||
|
if "$cygwin" || "$msys" ; then
|
||||||
|
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||||
|
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||||
|
|
||||||
|
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||||
|
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
for arg do
|
||||||
|
if
|
||||||
|
case $arg in #(
|
||||||
|
-*) false ;; # don't mess with options #(
|
||||||
|
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||||
|
[ -e "$t" ] ;; #(
|
||||||
|
*) false ;;
|
||||||
|
esac
|
||||||
|
then
|
||||||
|
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||||
|
fi
|
||||||
|
# Roll the args list around exactly as many times as the number of
|
||||||
|
# args, so each arg winds up back in the position where it started, but
|
||||||
|
# possibly modified.
|
||||||
|
#
|
||||||
|
# NB: a `for` loop captures its iteration list before it begins, so
|
||||||
|
# changing the positional parameters here affects neither the number of
|
||||||
|
# iterations, nor the values presented in `arg`.
|
||||||
|
shift # remove old arg
|
||||||
|
set -- "$@" "$arg" # push replacement arg
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
|
|
||||||
|
# Collect all arguments for the java command:
|
||||||
|
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||||
|
# and any embedded shellness will be escaped.
|
||||||
|
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
||||||
|
# treated as '${Hostname}' itself on the command line.
|
||||||
|
|
||||||
|
set -- \
|
||||||
|
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||||
|
-classpath "$CLASSPATH" \
|
||||||
|
org.gradle.wrapper.GradleWrapperMain \
|
||||||
|
"$@"
|
||||||
|
|
||||||
|
# Stop when "xargs" is not available.
|
||||||
|
if ! command -v xargs >/dev/null 2>&1
|
||||||
|
then
|
||||||
|
die "xargs is not available"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Use "xargs" to parse quoted args.
|
||||||
|
#
|
||||||
|
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||||
|
#
|
||||||
|
# In Bash we could simply go:
|
||||||
|
#
|
||||||
|
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||||
|
# set -- "${ARGS[@]}" "$@"
|
||||||
|
#
|
||||||
|
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||||
|
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||||
|
# character that might be a shell metacharacter, then use eval to reverse
|
||||||
|
# that process (while maintaining the separation between arguments), and wrap
|
||||||
|
# the whole thing up as a single "set" statement.
|
||||||
|
#
|
||||||
|
# This will of course break if any of these variables contains a newline or
|
||||||
|
# an unmatched quote.
|
||||||
|
#
|
||||||
|
|
||||||
|
eval "set -- $(
|
||||||
|
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||||
|
xargs -n1 |
|
||||||
|
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||||
|
tr '\n' ' '
|
||||||
|
)" '"$@"'
|
||||||
|
|
||||||
|
exec "$JAVACMD" "$@"
|
92
H07/gradlew.bat
vendored
Normal file
92
H07/gradlew.bat
vendored
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
@rem
|
||||||
|
@rem Copyright 2015 the original author or authors.
|
||||||
|
@rem
|
||||||
|
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@rem you may not use this file except in compliance with the License.
|
||||||
|
@rem You may obtain a copy of the License at
|
||||||
|
@rem
|
||||||
|
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
@rem
|
||||||
|
@rem Unless required by applicable law or agreed to in writing, software
|
||||||
|
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@rem See the License for the specific language governing permissions and
|
||||||
|
@rem limitations under the License.
|
||||||
|
@rem
|
||||||
|
|
||||||
|
@if "%DEBUG%"=="" @echo off
|
||||||
|
@rem ##########################################################################
|
||||||
|
@rem
|
||||||
|
@rem Gradle startup script for Windows
|
||||||
|
@rem
|
||||||
|
@rem ##########################################################################
|
||||||
|
|
||||||
|
@rem Set local scope for the variables with windows NT shell
|
||||||
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
|
set DIRNAME=%~dp0
|
||||||
|
if "%DIRNAME%"=="" set DIRNAME=.
|
||||||
|
@rem This is normally unused
|
||||||
|
set APP_BASE_NAME=%~n0
|
||||||
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
|
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||||
|
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||||
|
|
||||||
|
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||||
|
|
||||||
|
@rem Find java.exe
|
||||||
|
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||||
|
|
||||||
|
set JAVA_EXE=java.exe
|
||||||
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
|
if %ERRORLEVEL% equ 0 goto execute
|
||||||
|
|
||||||
|
echo. 1>&2
|
||||||
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
|
||||||
|
echo. 1>&2
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||||
|
echo location of your Java installation. 1>&2
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:findJavaFromJavaHome
|
||||||
|
set JAVA_HOME=%JAVA_HOME:"=%
|
||||||
|
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||||
|
|
||||||
|
if exist "%JAVA_EXE%" goto execute
|
||||||
|
|
||||||
|
echo. 1>&2
|
||||||
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
||||||
|
echo. 1>&2
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||||
|
echo location of your Java installation. 1>&2
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:execute
|
||||||
|
@rem Setup the command line
|
||||||
|
|
||||||
|
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||||
|
|
||||||
|
|
||||||
|
@rem Execute Gradle
|
||||||
|
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||||
|
|
||||||
|
:end
|
||||||
|
@rem End local scope for the variables with windows NT shell
|
||||||
|
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||||
|
|
||||||
|
:fail
|
||||||
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
|
rem the _cmd.exe /c_ return code!
|
||||||
|
set EXIT_CODE=%ERRORLEVEL%
|
||||||
|
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||||
|
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||||
|
exit /b %EXIT_CODE%
|
||||||
|
|
||||||
|
:mainEnd
|
||||||
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
|
||||||
|
:omega
|
11
H07/settings.gradle.kts
Normal file
11
H07/settings.gradle.kts
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
dependencyResolutionManagement {
|
||||||
|
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
|
||||||
|
repositories {
|
||||||
|
// mavenLocal()
|
||||||
|
maven("https://s01.oss.sonatype.org/content/repositories/snapshots")
|
||||||
|
maven("https://jitpack.io")
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rootProject.name = "H07-Student"
|
66
H07/src/main/java/h07/Main.java
Normal file
66
H07/src/main/java/h07/Main.java
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
package h07;
|
||||||
|
|
||||||
|
import org.tudalgo.algoutils.student.annotation.DoNotTouch;
|
||||||
|
import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired;
|
||||||
|
|
||||||
|
import h07.peano.NaturalNumber;
|
||||||
|
import h07.peano.Successor;
|
||||||
|
import h07.peano.Zero;
|
||||||
|
|
||||||
|
import static org.tudalgo.algoutils.student.Student.crash;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main entry point in executing the program.
|
||||||
|
*/
|
||||||
|
public class Main {
|
||||||
|
/**
|
||||||
|
* Main entry point in executing the program.
|
||||||
|
*
|
||||||
|
* @param args program arguments, currently ignored
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) {
|
||||||
|
testHeader("Multiplication Table");
|
||||||
|
numberExpressionMultiplicationTableTests();
|
||||||
|
|
||||||
|
testHeader("Peano Number Expressions");
|
||||||
|
peanoNumberExpressionTests();
|
||||||
|
|
||||||
|
testHeader("Filter, Fold, Map");
|
||||||
|
filterFoldMapTests();
|
||||||
|
}
|
||||||
|
|
||||||
|
@DoNotTouch
|
||||||
|
private static void testHeader(String testName) {
|
||||||
|
System.out.println("-----------------------------------");
|
||||||
|
System.out.println("Running test: " + testName);
|
||||||
|
System.out.println("-----------------------------------");
|
||||||
|
}
|
||||||
|
|
||||||
|
@DoNotTouch
|
||||||
|
private static void numberExpressionMultiplicationTableTests() {
|
||||||
|
// TODO: H2.2 - uncomment to test
|
||||||
|
// int lowerBound = 1;
|
||||||
|
// int upperBound = 10;
|
||||||
|
// NumberExpression[] multiplicationTable = NumberExpressionFactory.multiplicationTable(lowerBound, upperBound);
|
||||||
|
//
|
||||||
|
// for (int i = lowerBound; i <= upperBound; i++) {
|
||||||
|
// for (int j = lowerBound; j <= upperBound; j++) {
|
||||||
|
// System.out.printf("| %4s ", multiplicationTable[(i - lowerBound) * (upperBound - lowerBound + 1) + (j - lowerBound)].evaluate());
|
||||||
|
// }
|
||||||
|
// System.out.println("|");
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final NaturalNumber THREE = new Successor(new Successor(new Successor(new Zero())));
|
||||||
|
private static final NaturalNumber SEVEN = new Successor(new Successor(new Successor(new Successor(new Successor(new Successor(new Successor(new Zero())))))));
|
||||||
|
|
||||||
|
@StudentImplementationRequired
|
||||||
|
private static void peanoNumberExpressionTests() {
|
||||||
|
crash(); // TODO: H3.3 - remove if implemented
|
||||||
|
}
|
||||||
|
|
||||||
|
@StudentImplementationRequired
|
||||||
|
private static void filterFoldMapTests() {
|
||||||
|
crash(); // TODO: H4.6 - remove if implemented
|
||||||
|
}
|
||||||
|
}
|
65
H07/src/main/java/h07/NumberExpressionFactory.java
Normal file
65
H07/src/main/java/h07/NumberExpressionFactory.java
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
package h07;
|
||||||
|
|
||||||
|
import java.util.function.IntPredicate;
|
||||||
|
|
||||||
|
import org.tudalgo.algoutils.student.annotation.DoNotTouch;
|
||||||
|
import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired;
|
||||||
|
|
||||||
|
import static org.tudalgo.algoutils.student.Student.crash;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A factory class for creating number expressions.
|
||||||
|
*/
|
||||||
|
public class NumberExpressionFactory {
|
||||||
|
/**
|
||||||
|
* Calculates the product of all possible pairs of numbers in the given array.
|
||||||
|
*
|
||||||
|
* @param numbers the array of number expressions to calculate the multiplication table
|
||||||
|
* @return An array of number expressions representing the result of the
|
||||||
|
* multiplication table of the given numbers.
|
||||||
|
*/
|
||||||
|
// @StudentImplementationRequired
|
||||||
|
// public static NumberExpression[] multiplicationTable(NumberExpression[] numbers) {
|
||||||
|
// return crash(); // TODO: H2.1 - remove if implemented
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: H2.2 - uncomment for testing
|
||||||
|
/**
|
||||||
|
* Calculates the product of all possible pairs of numbers in the given range.
|
||||||
|
*
|
||||||
|
* @param lowerBound the lower bound of the multiplication table, inclusive
|
||||||
|
* @param upperBound the upper bound of the multiplication table, inclusive
|
||||||
|
* @return An array of number expressions representing the result of the
|
||||||
|
* multiplication table of the numbers from lowerBound to upperBound.
|
||||||
|
*/
|
||||||
|
// @DoNotTouch
|
||||||
|
// public static NumberExpression[] multiplicationTable(int lowerBound, int upperBound) {
|
||||||
|
// int numberOfNumbers = upperBound - lowerBound + 1;
|
||||||
|
// NumberExpression[] baseNumbers = new NumberExpression[numberOfNumbers];
|
||||||
|
//
|
||||||
|
// for (int i = lowerBound; i <= upperBound; i++) {
|
||||||
|
// // Copy to local variable to make it effectively final, so it can be used in
|
||||||
|
// // lambda
|
||||||
|
// int finalI = i;
|
||||||
|
// baseNumbers[i - lowerBound] = () -> finalI;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return multiplicationTable(baseNumbers);
|
||||||
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filters the given array of number expressions based on the given predicate.
|
||||||
|
* The returned array should contain only the number expressions that satisfy
|
||||||
|
* the predicate in the same order as they appear in the input array.
|
||||||
|
* This means there should be no null values in the returned array.
|
||||||
|
*
|
||||||
|
* @param numbers the array of number expressions to filter
|
||||||
|
* @param predicate the predicate to filter the number expressions
|
||||||
|
* @return An array of number expressions that satisfy the predicate.
|
||||||
|
*/
|
||||||
|
// @StudentImplementationRequired
|
||||||
|
// public static NumberExpression[] filter(NumberExpression[] numbers, IntPredicate predicate) {
|
||||||
|
// return crash(); // TODO: H4.4 - remove if implemented
|
||||||
|
// }
|
||||||
|
}
|
17
H07/src/main/java/h07/peano/NaturalNumber.java
Normal file
17
H07/src/main/java/h07/peano/NaturalNumber.java
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
package h07.peano;
|
||||||
|
|
||||||
|
import org.tudalgo.algoutils.student.annotation.DoNotTouch;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a natural number.
|
||||||
|
*/
|
||||||
|
@DoNotTouch
|
||||||
|
public abstract class NaturalNumber {
|
||||||
|
/**
|
||||||
|
* Returns the string representation of the natural number.
|
||||||
|
*
|
||||||
|
* @return the string representation of the natural number
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public abstract String toString();
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
package h07.peano;
|
||||||
|
|
||||||
|
|
||||||
|
import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired;
|
||||||
|
|
||||||
|
import static org.tudalgo.algoutils.student.Student.crash;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a factory for Peano number expressions.
|
||||||
|
*/
|
||||||
|
public class PeanoNumberExpressionFactory {
|
||||||
|
/**
|
||||||
|
* Converts an array of number expressions to an array of Peano number expressions.
|
||||||
|
*
|
||||||
|
* @param numberExpressions the number expressions to convert
|
||||||
|
* @return the converted Peano number expressions
|
||||||
|
*/
|
||||||
|
// @StudentImplementationRequired
|
||||||
|
// public static PeanoNumberExpression[] fromNumberExpressions(NumberExpression[] numberExpressions) {
|
||||||
|
// return crash(); // TODO: H4.3 - remove if implemented
|
||||||
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Folds an array of Peano number expressions into a single Peano number expression.
|
||||||
|
*
|
||||||
|
* @param peanoNumberExpressions the Peano number expressions to fold
|
||||||
|
* @param initial the initial Peano number expression
|
||||||
|
* @param operation the operation to apply
|
||||||
|
* @return the folded Peano number expression
|
||||||
|
*/
|
||||||
|
// @StudentImplementationRequired
|
||||||
|
// public static PeanoNumberExpression fold(PeanoNumberExpression[] peanoNumberExpressions, PeanoNumberExpression initial, PeanoArithmeticExpression operation) {
|
||||||
|
// return crash(); // TODO: H4.5 - remove if implemented
|
||||||
|
// }
|
||||||
|
}
|
20
H07/src/main/java/h07/peano/Successor.java
Normal file
20
H07/src/main/java/h07/peano/Successor.java
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
package h07.peano;
|
||||||
|
|
||||||
|
import org.tudalgo.algoutils.student.annotation.DoNotTouch;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a successor of a natural number in Peano arithmetic.
|
||||||
|
*/
|
||||||
|
@DoNotTouch
|
||||||
|
public class Successor extends NaturalNumber {
|
||||||
|
public final NaturalNumber predecessor;
|
||||||
|
|
||||||
|
public Successor(NaturalNumber predecessor) {
|
||||||
|
this.predecessor = predecessor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "S(" + predecessor.toString() + ")";
|
||||||
|
}
|
||||||
|
}
|
14
H07/src/main/java/h07/peano/Zero.java
Normal file
14
H07/src/main/java/h07/peano/Zero.java
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
package h07.peano;
|
||||||
|
|
||||||
|
import org.tudalgo.algoutils.student.annotation.DoNotTouch;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the number zero in Peano arithmetic.
|
||||||
|
*/
|
||||||
|
@DoNotTouch
|
||||||
|
public class Zero extends NaturalNumber {
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Z";
|
||||||
|
}
|
||||||
|
}
|
16
H07/src/test/java/h07/ExampleJUnitTest.java
Normal file
16
H07/src/test/java/h07/ExampleJUnitTest.java
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
package h07;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An example JUnit test class.
|
||||||
|
*/
|
||||||
|
public class ExampleJUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddition() {
|
||||||
|
assertEquals(2, 1 + 1);
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1 +0,0 @@
|
||||||
›tajbjehwvzefbn4rpr56ei3key—æŠÚA'ÿœ–š*m÷I:ˆclassesˆ•>ˆ#D¿18#<23>¬´aˆsources.<Ò°—ÔŸÁbQª0Úˆ
|
|
|
@ -1,89 +0,0 @@
|
||||||
package org.gradle.accessors.dm;
|
|
||||||
|
|
||||||
import org.gradle.api.NonNullApi;
|
|
||||||
import org.gradle.api.artifacts.MinimalExternalModuleDependency;
|
|
||||||
import org.gradle.plugin.use.PluginDependency;
|
|
||||||
import org.gradle.api.artifacts.ExternalModuleDependencyBundle;
|
|
||||||
import org.gradle.api.artifacts.MutableVersionConstraint;
|
|
||||||
import org.gradle.api.provider.Provider;
|
|
||||||
import org.gradle.api.model.ObjectFactory;
|
|
||||||
import org.gradle.api.provider.ProviderFactory;
|
|
||||||
import org.gradle.api.internal.catalog.AbstractExternalDependencyFactory;
|
|
||||||
import org.gradle.api.internal.catalog.DefaultVersionCatalog;
|
|
||||||
import java.util.Map;
|
|
||||||
import org.gradle.api.internal.attributes.ImmutableAttributesFactory;
|
|
||||||
import org.gradle.api.internal.artifacts.dsl.CapabilityNotationParser;
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A catalog of dependencies accessible via the {@code libs} extension.
|
|
||||||
*/
|
|
||||||
@NonNullApi
|
|
||||||
public class LibrariesForLibs extends AbstractExternalDependencyFactory {
|
|
||||||
|
|
||||||
private final AbstractExternalDependencyFactory owner = this;
|
|
||||||
private final VersionAccessors vaccForVersionAccessors = new VersionAccessors(providers, config);
|
|
||||||
private final BundleAccessors baccForBundleAccessors = new BundleAccessors(objects, providers, config, attributesFactory, capabilityNotationParser);
|
|
||||||
private final PluginAccessors paccForPluginAccessors = new PluginAccessors(providers, config);
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public LibrariesForLibs(DefaultVersionCatalog config, ProviderFactory providers, ObjectFactory objects, ImmutableAttributesFactory attributesFactory, CapabilityNotationParser capabilityNotationParser) {
|
|
||||||
super(config, providers, objects, attributesFactory, capabilityNotationParser);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Group of versions at <b>versions</b>
|
|
||||||
*/
|
|
||||||
public VersionAccessors getVersions() {
|
|
||||||
return vaccForVersionAccessors;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Group of bundles at <b>bundles</b>
|
|
||||||
*/
|
|
||||||
public BundleAccessors getBundles() {
|
|
||||||
return baccForBundleAccessors;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Group of plugins at <b>plugins</b>
|
|
||||||
*/
|
|
||||||
public PluginAccessors getPlugins() {
|
|
||||||
return paccForPluginAccessors;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class VersionAccessors extends VersionFactory {
|
|
||||||
|
|
||||||
public VersionAccessors(ProviderFactory providers, DefaultVersionCatalog config) { super(providers, config); }
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class BundleAccessors extends BundleFactory {
|
|
||||||
|
|
||||||
public BundleAccessors(ObjectFactory objects, ProviderFactory providers, DefaultVersionCatalog config, ImmutableAttributesFactory attributesFactory, CapabilityNotationParser capabilityNotationParser) { super(objects, providers, config, attributesFactory, capabilityNotationParser); }
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class PluginAccessors extends PluginFactory {
|
|
||||||
|
|
||||||
public PluginAccessors(ProviderFactory providers, DefaultVersionCatalog config) { super(providers, config); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Plugin provider for <b>algomate</b> with plugin id <b>org.tudalgo.algomate</b> and
|
|
||||||
* with version <b>0.7.1</b>
|
|
||||||
* <p>
|
|
||||||
* This plugin was declared in catalog libs.versions.toml
|
|
||||||
*/
|
|
||||||
public Provider<PluginDependency> getAlgomate() { return createPlugin("algomate"); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Plugin provider for <b>style</b> with plugin id <b>org.sourcegrade.style</b> and
|
|
||||||
* with version <b>3.0.0</b>
|
|
||||||
* <p>
|
|
||||||
* This plugin was declared in catalog libs.versions.toml
|
|
||||||
*/
|
|
||||||
public Provider<PluginDependency> getStyle() { return createPlugin("style"); }
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,97 +0,0 @@
|
||||||
package org.gradle.accessors.dm;
|
|
||||||
|
|
||||||
import org.gradle.api.NonNullApi;
|
|
||||||
import org.gradle.api.artifacts.MinimalExternalModuleDependency;
|
|
||||||
import org.gradle.plugin.use.PluginDependency;
|
|
||||||
import org.gradle.api.artifacts.ExternalModuleDependencyBundle;
|
|
||||||
import org.gradle.api.artifacts.MutableVersionConstraint;
|
|
||||||
import org.gradle.api.provider.Provider;
|
|
||||||
import org.gradle.api.model.ObjectFactory;
|
|
||||||
import org.gradle.api.provider.ProviderFactory;
|
|
||||||
import org.gradle.api.internal.catalog.AbstractExternalDependencyFactory;
|
|
||||||
import org.gradle.api.internal.catalog.DefaultVersionCatalog;
|
|
||||||
import java.util.Map;
|
|
||||||
import org.gradle.api.internal.attributes.ImmutableAttributesFactory;
|
|
||||||
import org.gradle.api.internal.artifacts.dsl.CapabilityNotationParser;
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A catalog of dependencies accessible via the {@code libs} extension.
|
|
||||||
*/
|
|
||||||
@NonNullApi
|
|
||||||
public class LibrariesForLibsInPluginsBlock extends AbstractExternalDependencyFactory {
|
|
||||||
|
|
||||||
private final AbstractExternalDependencyFactory owner = this;
|
|
||||||
private final VersionAccessors vaccForVersionAccessors = new VersionAccessors(providers, config);
|
|
||||||
private final BundleAccessors baccForBundleAccessors = new BundleAccessors(objects, providers, config, attributesFactory, capabilityNotationParser);
|
|
||||||
private final PluginAccessors paccForPluginAccessors = new PluginAccessors(providers, config);
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public LibrariesForLibsInPluginsBlock(DefaultVersionCatalog config, ProviderFactory providers, ObjectFactory objects, ImmutableAttributesFactory attributesFactory, CapabilityNotationParser capabilityNotationParser) {
|
|
||||||
super(config, providers, objects, attributesFactory, capabilityNotationParser);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Group of versions at <b>versions</b>
|
|
||||||
*/
|
|
||||||
public VersionAccessors getVersions() {
|
|
||||||
return vaccForVersionAccessors;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Group of bundles at <b>bundles</b>
|
|
||||||
*
|
|
||||||
* @deprecated Will be removed in Gradle 9.0.
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public BundleAccessors getBundles() {
|
|
||||||
org.gradle.internal.deprecation.DeprecationLogger.deprecateBehaviour("Accessing libraries or bundles from version catalogs in the plugins block.").withAdvice("Only use versions or plugins from catalogs in the plugins block.").willBeRemovedInGradle9().withUpgradeGuideSection(8, "kotlin_dsl_deprecated_catalogs_plugins_block").nagUser();
|
|
||||||
return baccForBundleAccessors;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Group of plugins at <b>plugins</b>
|
|
||||||
*/
|
|
||||||
public PluginAccessors getPlugins() {
|
|
||||||
return paccForPluginAccessors;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class VersionAccessors extends VersionFactory {
|
|
||||||
|
|
||||||
public VersionAccessors(ProviderFactory providers, DefaultVersionCatalog config) { super(providers, config); }
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated Will be removed in Gradle 9.0.
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public static class BundleAccessors extends BundleFactory {
|
|
||||||
|
|
||||||
public BundleAccessors(ObjectFactory objects, ProviderFactory providers, DefaultVersionCatalog config, ImmutableAttributesFactory attributesFactory, CapabilityNotationParser capabilityNotationParser) { super(objects, providers, config, attributesFactory, capabilityNotationParser); }
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class PluginAccessors extends PluginFactory {
|
|
||||||
|
|
||||||
public PluginAccessors(ProviderFactory providers, DefaultVersionCatalog config) { super(providers, config); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Plugin provider for <b>algomate</b> with plugin id <b>org.tudalgo.algomate</b> and
|
|
||||||
* with version <b>0.7.1</b>
|
|
||||||
* <p>
|
|
||||||
* This plugin was declared in catalog libs.versions.toml
|
|
||||||
*/
|
|
||||||
public Provider<PluginDependency> getAlgomate() { return createPlugin("algomate"); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Plugin provider for <b>style</b> with plugin id <b>org.sourcegrade.style</b> and
|
|
||||||
* with version <b>3.0.0</b>
|
|
||||||
* <p>
|
|
||||||
* This plugin was declared in catalog libs.versions.toml
|
|
||||||
*/
|
|
||||||
public Provider<PluginDependency> getStyle() { return createPlugin("style"); }
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,2 +0,0 @@
|
||||||
#Sun Mar 16 16:24:15 CET 2025
|
|
||||||
gradle.version=8.10.2
|
|
Binary file not shown.
5
solution/H07/.idea/.gitignore
generated
vendored
5
solution/H07/.idea/.gitignore
generated
vendored
|
@ -1,5 +0,0 @@
|
||||||
# Default ignored files
|
|
||||||
/shelf/
|
|
||||||
/workspace.xml
|
|
||||||
# Editor-based HTTP Client requests
|
|
||||||
/httpRequests/
|
|
1
solution/H07/.idea/.name
generated
1
solution/H07/.idea/.name
generated
|
@ -1 +0,0 @@
|
||||||
H07-Root
|
|
7
solution/H07/.idea/codeStyles/Project.xml
generated
7
solution/H07/.idea/codeStyles/Project.xml
generated
|
@ -1,7 +0,0 @@
|
||||||
<component name="ProjectCodeStyleConfiguration">
|
|
||||||
<code_scheme name="Project" version="173">
|
|
||||||
<ScalaCodeStyleSettings>
|
|
||||||
<option name="MULTILINE_STRING_CLOSING_QUOTES_ON_NEW_LINE" value="true" />
|
|
||||||
</ScalaCodeStyleSettings>
|
|
||||||
</code_scheme>
|
|
||||||
</component>
|
|
|
@ -1,5 +0,0 @@
|
||||||
<component name="ProjectCodeStyleConfiguration">
|
|
||||||
<state>
|
|
||||||
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
|
|
||||||
</state>
|
|
||||||
</component>
|
|
6
solution/H07/.idea/compiler.xml
generated
6
solution/H07/.idea/compiler.xml
generated
|
@ -1,6 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="CompilerConfiguration">
|
|
||||||
<bytecodeTargetLevel target="21" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
16
solution/H07/.idea/gradle.xml
generated
16
solution/H07/.idea/gradle.xml
generated
|
@ -1,16 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="GradleMigrationSettings" migrationVersion="1" />
|
|
||||||
<component name="GradleSettings">
|
|
||||||
<option name="linkedExternalProjectsSettings">
|
|
||||||
<GradleProjectSettings>
|
|
||||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
|
||||||
<option name="modules">
|
|
||||||
<set>
|
|
||||||
<option value="$PROJECT_DIR$" />
|
|
||||||
</set>
|
|
||||||
</option>
|
|
||||||
</GradleProjectSettings>
|
|
||||||
</option>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
8
solution/H07/.idea/misc.xml
generated
8
solution/H07/.idea/misc.xml
generated
|
@ -1,8 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
|
||||||
<component name="FrameworkDetectionExcludesConfiguration">
|
|
||||||
<file type="web" url="file://$PROJECT_DIR$" />
|
|
||||||
</component>
|
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="21" project-jdk-type="JavaSDK" />
|
|
||||||
</project>
|
|
7
solution/H07/.idea/sbt.xml
generated
7
solution/H07/.idea/sbt.xml
generated
|
@ -1,7 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="ScalaSbtSettings">
|
|
||||||
<option name="customLauncherPath" />
|
|
||||||
<option name="customVMPath" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
6
solution/H07/.idea/vcs.xml
generated
6
solution/H07/.idea/vcs.xml
generated
|
@ -1,6 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="VcsDirectoryMappings">
|
|
||||||
<mapping directory="$PROJECT_DIR$/../.." vcs="Git" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1 +0,0 @@
|
||||||
{"assignmentId":"h07","jagrVersion":"0.10.3","sourceSets":[{"name":"grader","files":{"resources":["h07/NumberExpressionFactory_filter_true.json","h07/ConvertNumberToPeanoExpressionImpl_0.json","h07/PeanoMultiplyExpression_X0.json","h07/PeanoNumberExpressionFactory_filled.json","h07/NumberExpressionFactory_filter_false.json","h07/ConvertNumberToPeanoExpressionImpl_X.json","h07/NumberExpressionFactory_filter_complex.json","h07/NumberExpressionFactory_multiply_Complex.json","h07/PeanoAddExpression_0X.json","h07/PeanoMultiplyExpression_XY.json","h07/NumberExpressionFactory_multiply_Simple.json","h07/PeanoNumberExpressionFactory_fromNumber.json","h07/PeanoMultiplyExpression_0X.json","h07/PeanoAddExpression_X0.json","h07/PeanoNumberExpressionFactory_empty.json","h07/NumberExpressionFactory_filter_empty.json","h07/ConvertPeanoToNumberExpressionImpl_0.json","h07/ConvertPeanoToNumberExpressionImpl_X.json","h07/PeanoAddExpression_XY.json"],"java":["h07/ConvertPeanoToNumberExpressionTest.java","h07/ArithmeticExpressionTest.java","h07/ConvertNumberToPeanoExpressionTest.java","h07/PeanoMultiplyExpressionTest.java","h07/MethodReference.java","h07/ClassReference.java","h07/PeanoNumberExpressionFactoryTest.java","h07/PeanoNumberExpressionTest.java","h07/PeanoArithmeticExpressionTest.java","h07/H07Test.java","h07/Tests.java","h07/PeanoAddExpressionTest.java","h07/NumberExpressionFactoryTest.java","h07/ConvertNumberToPeanoExpressionImplTest.java","h07/NumberExpressionTest.java","h07/NumberConverter.java","h07/H07_RubricProvider.java","h07/ConvertPeanoToNumberExpressionImplTest.java"]}},{"name":"main","files":{"java":["h07/NumberExpressionFactory.java","h07/peano/Successor.java","h07/peano/Zero.java","h07/peano/NaturalNumber.java","h07/peano/PeanoNumberExpressionFactory.java","h07/Main.java"]}},{"name":"test","files":{"java":["h07/ExampleJUnitTest.java"]}}],"dependencyConfigurations":{"graderImplementation":["org.tudalgo:algoutils-tutor:0.7.2","org.junit-pioneer:junit-pioneer:2.3.0","org.sourcegrade:jagr-launcher:0.10.3"],"implementation":["org.tudalgo:algoutils-student:0.7.2","org.jetbrains:annotations:26.0.0"],"testImplementation":["org.junit.jupiter:junit-jupiter:5.11.2"]},"repositoryConfigurations":[{"name":"maven","url":"https://s01.oss.sonatype.org/content/repositories/snapshots"},{"name":"maven2","url":"https://jitpack.io"},{"name":"MavenRepo","url":"https://repo.maven.apache.org/maven2/"}],"name":"FOP-2425-H07-Private","rubricProviderName":"h07.H07_RubricProvider"}
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1 +0,0 @@
|
||||||
{"assignmentId":"h07","jagrVersion":"0.10.3","sourceSets":[{"name":"main","files":{"java":["h07/NumberExpressionFactory.java","h07/peano/Successor.java","h07/peano/Zero.java","h07/peano/NaturalNumber.java","h07/peano/PeanoNumberExpressionFactory.java","h07/Main.java"]}},{"name":"test","files":{"java":["h07/ExampleJUnitTest.java"]}}],"dependencyConfigurations":{"implementation":["org.tudalgo:algoutils-student:0.7.2","org.jetbrains:annotations:26.0.0"],"testImplementation":["org.junit.jupiter:junit-jupiter:5.11.2"]},"repositoryConfigurations":[{"name":"maven","url":"https://s01.oss.sonatype.org/content/repositories/snapshots"},{"name":"maven2","url":"https://jitpack.io"},{"name":"MavenRepo","url":"https://repo.maven.apache.org/maven2/"}],"studentId":"ab12cdef","firstName":"sol_first","lastName":"sol_last"}
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,70 +0,0 @@
|
||||||
# The locations of the following directories may be configured here
|
|
||||||
dir {
|
|
||||||
# Grader jar ingest directory
|
|
||||||
graders=graders
|
|
||||||
# Runtime dependencies for submissions
|
|
||||||
libs=libs
|
|
||||||
# Rubrics export directory
|
|
||||||
rubrics=rubrics
|
|
||||||
# Submissions ingest directory
|
|
||||||
submissions=submissions
|
|
||||||
# Submission export directory
|
|
||||||
submissions-export=submissions-export
|
|
||||||
}
|
|
||||||
executor {
|
|
||||||
#
|
|
||||||
# The maximum amount of concurrency to use for grading.
|
|
||||||
# For a given concurrency n, Jagr will ensure that a maximum of n threads or processes are used concurrently that actively run
|
|
||||||
# submission code.
|
|
||||||
concurrency=4
|
|
||||||
#
|
|
||||||
# The JVM arguments to use for grading. These arguments are passed to the JVM that runs the grading code.
|
|
||||||
# This only applies to the "process" mode, as the "thread" and "single" modes do not spawn a new JVM.
|
|
||||||
#
|
|
||||||
jvm-args=[]
|
|
||||||
#
|
|
||||||
# The executor mode to use. The following options are available:
|
|
||||||
# - "single" ::
|
|
||||||
# Runs every TestCycle consecutively in the main thread. This mode does not create any extra processes or threads for grading.
|
|
||||||
#
|
|
||||||
# - "thread" ::
|
|
||||||
# Creates a separate thread for every TestCycle. This mode greatly speeds up the grading process, especially with a large
|
|
||||||
# amount of submissions. The overhead of creating, managing and synchronizing threads is minimal compared to the performance
|
|
||||||
# benefits. However, this mode has the danger of creating "unkillable" threads (e.g. from certain kinds of infinite loops)
|
|
||||||
# which dramatically slow down the grading process through resource starvation of the host machine.
|
|
||||||
#
|
|
||||||
# The maximum number of concurrent threads used for grading is defined by the option "concurrency".
|
|
||||||
#
|
|
||||||
# - "process" ::
|
|
||||||
# Creates a separate process for every TestCycle. This mode has the most overhead, but is also the most defensive against
|
|
||||||
# "badly behaving" code. A certain amount of sandboxing can be achieved in this mode, which is not possible in the other modes
|
|
||||||
# such as "thread" or "single".
|
|
||||||
#
|
|
||||||
# The maximum number of concurrent child process used for grading is defined by the option "concurrency".
|
|
||||||
mode=process
|
|
||||||
#
|
|
||||||
# The grading thread's maximum permitted elapsed userTime in milliseconds since the last timeout before an
|
|
||||||
# AssertionFailedError is thrown. If a thread's userTime satisfies
|
|
||||||
# (userTime - lastTimeout) > individualTimeout,
|
|
||||||
# the current userTime is stored for comparison later, and an AssertionFailedError is thrown to be caught by JUnit.
|
|
||||||
timeout-individual=10000
|
|
||||||
#
|
|
||||||
# The grading thread's maximum permitted elapsed userTime in milliseconds (from thread start) before an
|
|
||||||
# AssertionFailedError is thrown. If a thread's userTime satisfies
|
|
||||||
# ((userTime - lastTimeout) > individualTimeout) && (userTime > totalTimeout),
|
|
||||||
# an AssertionFailedError is thrown to be caught by JUnit. Note that lastTimeout is not reset in this case, and all further
|
|
||||||
# invocations of checkTimeout() will result in an AssertionFailedError
|
|
||||||
timeout-total=150000
|
|
||||||
}
|
|
||||||
extras {
|
|
||||||
moodle-unpack {
|
|
||||||
assignment-id-regex=".*Abgabe[^0-9]*(?<assignmentId>[0-9]{1,2}).*[.]zip"
|
|
||||||
enabled=true
|
|
||||||
student-regex=".* - (?<studentId>([a-z]{2}[0-9]{2}[a-z]{4})|([a-z]+_[a-z]+))/submissions/.*[.]jar"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
transformers {
|
|
||||||
timeout {
|
|
||||||
enabled=true
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
package h07;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.sourcegrade.jagr.api.rubric.TestForSubmission;
|
|
||||||
|
|
||||||
@TestForSubmission
|
|
||||||
public class ArithmeticExpressionTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDefinition() {
|
|
||||||
ClassReference.ARITHMETIC_EXPRESSION.assertCorrectlyDefined();
|
|
||||||
MethodReference.ARITHMETIC_EXPRESSION_EVALUATE.assertCorrectlyDefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testNaming() {
|
|
||||||
ClassReference.ARITHMETIC_EXPRESSION.assertNamedCorrectly();
|
|
||||||
MethodReference.ARITHMETIC_EXPRESSION_EVALUATE.assertNamedCorrectly();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testPackage() {
|
|
||||||
ClassReference.ARITHMETIC_EXPRESSION.assertDefinedInCorrectPackage();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,187 +0,0 @@
|
||||||
package h07;
|
|
||||||
|
|
||||||
import org.tudalgo.algoutils.tutor.general.assertions.Context;
|
|
||||||
import org.tudalgo.algoutils.tutor.general.reflections.BasicPackageLink;
|
|
||||||
import org.tudalgo.algoutils.tutor.general.reflections.BasicTypeLink;
|
|
||||||
import org.tudalgo.algoutils.tutor.general.reflections.Link;
|
|
||||||
import org.tudalgo.algoutils.tutor.general.reflections.Modifier;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import static org.tudalgo.algoutils.tutor.general.assertions.Assertions2.*;
|
|
||||||
|
|
||||||
|
|
||||||
public class ClassReference {
|
|
||||||
|
|
||||||
public static final List<String> PREDEFINED_PACKAGES = List.of("h07", "h07.Peano", "h07.peano");
|
|
||||||
|
|
||||||
public static final ClassReference NUMBER_EXPRESSION = new ClassReference("h07", "NumberExpression", Link.Kind.INTERFACE);
|
|
||||||
public static final ClassReference PEANO_NUMBER_EXPRESSION =
|
|
||||||
new ClassReference("h07.peano", "PeanoNumberExpression", Link.Kind.INTERFACE);
|
|
||||||
public static final ClassReference ARITHMETIC_EXPRESSION =
|
|
||||||
new ClassReference("h07", "ArithmeticExpression", Link.Kind.INTERFACE);
|
|
||||||
public static final ClassReference PEANO_ARITHMETIC_EXPRESSION =
|
|
||||||
new ClassReference("h07.peano", "PeanoArithmeticExpression", Link.Kind.INTERFACE);
|
|
||||||
public static final ClassReference PEANO_ADD_EXPRESSION = new ClassReference("h07.peano",
|
|
||||||
"PeanoAddExpression",
|
|
||||||
Link.Kind.CLASS,
|
|
||||||
new BasicTypeLink[] {PEANO_ARITHMETIC_EXPRESSION.link},
|
|
||||||
Modifier.PUBLIC,
|
|
||||||
Modifier.NON_FINAL
|
|
||||||
);
|
|
||||||
public static final ClassReference PEANO_MULTIPLY_EXPRESSION = new ClassReference("h07.peano",
|
|
||||||
"PeanoMultiplyExpression",
|
|
||||||
Link.Kind.CLASS,
|
|
||||||
new BasicTypeLink[] {PEANO_ARITHMETIC_EXPRESSION.link},
|
|
||||||
Modifier.PUBLIC,
|
|
||||||
Modifier.NON_FINAL
|
|
||||||
);
|
|
||||||
public static final ClassReference CONVERT_NUMBER_TO_PEANO_EXPRESSION =
|
|
||||||
new ClassReference("h07", "ConvertNumberToPeanoExpression", Link.Kind.INTERFACE);
|
|
||||||
public static final ClassReference CONVERT_PEANO_TO_NUMBER_EXPRESSION =
|
|
||||||
new ClassReference("h07", "ConvertPeanoToNumberExpression", Link.Kind.INTERFACE);
|
|
||||||
public static final ClassReference CONVERT_NUMBER_TO_PEANO_EXPRESSION_IMPL = new ClassReference("h07",
|
|
||||||
"ConvertNumberToPeanoExpressionImpl",
|
|
||||||
Link.Kind.CLASS,
|
|
||||||
new BasicTypeLink[] {CONVERT_NUMBER_TO_PEANO_EXPRESSION.link},
|
|
||||||
Modifier.PUBLIC,
|
|
||||||
Modifier.NON_FINAL
|
|
||||||
);
|
|
||||||
public static final ClassReference CONVERT_PEANO_TO_NUMBER_EXPRESSION_IMPL = new ClassReference("h07",
|
|
||||||
"ConvertPeanoToNumberExpressionImpl",
|
|
||||||
Link.Kind.CLASS,
|
|
||||||
new BasicTypeLink[] {CONVERT_PEANO_TO_NUMBER_EXPRESSION.link},
|
|
||||||
Modifier.PUBLIC,
|
|
||||||
Modifier.NON_FINAL
|
|
||||||
);
|
|
||||||
|
|
||||||
public static final ClassReference ZERO = new ClassReference("h07.peano",
|
|
||||||
"Zero",
|
|
||||||
Link.Kind.CLASS
|
|
||||||
);
|
|
||||||
|
|
||||||
public static final ClassReference SUCCESSOR = new ClassReference("h07.peano",
|
|
||||||
"Successor",
|
|
||||||
Link.Kind.CLASS
|
|
||||||
);
|
|
||||||
|
|
||||||
public static final ClassReference NATURAL_NUMBER = new ClassReference("h07.peano",
|
|
||||||
"NaturalNumber",
|
|
||||||
Link.Kind.CLASS
|
|
||||||
);
|
|
||||||
|
|
||||||
public static final ClassReference PEANO_NUMBER_EXPRESSION_FACTORY = new ClassReference("h07.peano",
|
|
||||||
"PeanoNumberExpressionFactory",
|
|
||||||
Link.Kind.CLASS
|
|
||||||
);
|
|
||||||
|
|
||||||
private final String pack;
|
|
||||||
private final String name;
|
|
||||||
private final Link.Kind kind;
|
|
||||||
private final BasicTypeLink[] superClasses;
|
|
||||||
private final Modifier[] modifiers;
|
|
||||||
private BasicTypeLink link;
|
|
||||||
|
|
||||||
public ClassReference(String pack, String name, Link.Kind kind, BasicTypeLink... superClasses) {
|
|
||||||
this(pack, name, kind, superClasses, new Modifier[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ClassReference(String pack, String name, Link.Kind kind, BasicTypeLink[] superClasses,
|
|
||||||
Modifier... modifiers) {
|
|
||||||
this.pack = pack;
|
|
||||||
this.name = name;
|
|
||||||
this.kind = kind;
|
|
||||||
this.superClasses = superClasses;
|
|
||||||
this.modifiers = modifiers;
|
|
||||||
|
|
||||||
try {
|
|
||||||
for (String packageName : PREDEFINED_PACKAGES) {
|
|
||||||
link = (BasicTypeLink) BasicPackageLink.of(packageName).getType(Tests.stringMatcher(name));
|
|
||||||
if (link != null && !link.reflection().getName().endsWith("Test")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
link = null;
|
|
||||||
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isDefined() {
|
|
||||||
return link != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void assertDefined() {
|
|
||||||
assertTrue(
|
|
||||||
isDefined(),
|
|
||||||
emptyContext(),
|
|
||||||
r -> String.format("Could not find Type %s. Type is not defined or could not be found.", name)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void assertCorrectlyDefined() {
|
|
||||||
assertDefined();
|
|
||||||
Context context = contextBuilder()
|
|
||||||
.add("expected package", pack)
|
|
||||||
.add("expected kind", kind)
|
|
||||||
.add("expected name", name)
|
|
||||||
.add("expected modifier", Arrays.stream(modifiers).map(Modifier::keyword).collect(Collectors.joining(", ")))
|
|
||||||
.add("package", link.reflection().getPackage().getName())
|
|
||||||
.add("kind", link.kind())
|
|
||||||
.add("name", link.name())
|
|
||||||
.build();
|
|
||||||
|
|
||||||
assertNotNull(link, context, r -> "Could not find class %s.".formatted(name));
|
|
||||||
assertEquals(kind, link.kind(), context, r -> "Kind does not match expected kind.");
|
|
||||||
assertTrue(
|
|
||||||
Arrays.stream(modifiers).allMatch(m -> m.is(link.modifiers())),
|
|
||||||
context,
|
|
||||||
r -> "The modifiers of the type do not match the expected modifiers."
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void assertNamedCorrectly() {
|
|
||||||
if (!isDefined()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Context context = contextBuilder()
|
|
||||||
.add("expected name", name)
|
|
||||||
.add("name", link.name())
|
|
||||||
.build();
|
|
||||||
|
|
||||||
assertNotNull(link, context, r -> "Could not find class %s.".formatted(name));
|
|
||||||
assertEquals(name, link.name(), context, r -> "The name of the Type does not match the expected name.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void assertDefinedInCorrectPackage() {
|
|
||||||
assertDefined();
|
|
||||||
Context context = contextBuilder()
|
|
||||||
.add("expected package", pack)
|
|
||||||
.add("expected kind", kind)
|
|
||||||
.add("expected name", name)
|
|
||||||
.add("expected modifier", Arrays.stream(modifiers).map(Modifier::keyword).collect(Collectors.joining(", ")))
|
|
||||||
.add("package", link.reflection().getPackage().getName())
|
|
||||||
.add("kind", link.kind())
|
|
||||||
.add("name", link.name())
|
|
||||||
.build();
|
|
||||||
|
|
||||||
assertNotNull(link, context, r -> "Could not find class %s.".formatted(name));
|
|
||||||
assertEquals(
|
|
||||||
pack.toLowerCase(),
|
|
||||||
link.reflection().getPackage().getName().toLowerCase(),
|
|
||||||
context,
|
|
||||||
r -> "Package name does not match expected package name."
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public BasicTypeLink getLink() {
|
|
||||||
assertDefined();
|
|
||||||
return link;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,92 +0,0 @@
|
||||||
package h07;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.junit.jupiter.params.ParameterizedTest;
|
|
||||||
import org.sourcegrade.jagr.api.rubric.TestForSubmission;
|
|
||||||
import org.tudalgo.algoutils.tutor.general.assertions.Assertions2;
|
|
||||||
import org.tudalgo.algoutils.tutor.general.assertions.Context;
|
|
||||||
import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet;
|
|
||||||
import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest;
|
|
||||||
import org.tudalgo.algoutils.tutor.general.reflections.BasicMethodLink;
|
|
||||||
import spoon.reflect.code.CtLambda;
|
|
||||||
import spoon.reflect.declaration.CtMethod;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static h07.ClassReference.CONVERT_NUMBER_TO_PEANO_EXPRESSION_IMPL;
|
|
||||||
import static h07.ClassReference.NUMBER_EXPRESSION;
|
|
||||||
import static h07.H07Test.getCtElements;
|
|
||||||
import static h07.MethodReference.CONVERT_NUMBER_TO_PEANO_EXPRESSION_CONVERT;
|
|
||||||
import static h07.MethodReference.PEANO_NUMBER_EXPRESSION_EVALUATE;
|
|
||||||
import static org.mockito.Mockito.CALLS_REAL_METHODS;
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.tudalgo.algoutils.tutor.general.assertions.Assertions2.assertEquals;
|
|
||||||
import static org.tudalgo.algoutils.tutor.general.assertions.Assertions2.contextBuilder;
|
|
||||||
|
|
||||||
@TestForSubmission
|
|
||||||
public class ConvertNumberToPeanoExpressionImplTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDefinition() {
|
|
||||||
CONVERT_NUMBER_TO_PEANO_EXPRESSION_IMPL.assertCorrectlyDefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testNaming() {
|
|
||||||
CONVERT_NUMBER_TO_PEANO_EXPRESSION_IMPL.assertNamedCorrectly();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testPackage() {
|
|
||||||
CONVERT_NUMBER_TO_PEANO_EXPRESSION_IMPL.assertDefinedInCorrectPackage();
|
|
||||||
}
|
|
||||||
|
|
||||||
@ParameterizedTest
|
|
||||||
@JsonParameterSetTest(value = "ConvertNumberToPeanoExpressionImpl_X.json")
|
|
||||||
public void testEvaluate_X(JsonParameterSet params) throws Throwable {
|
|
||||||
performTest(params);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ParameterizedTest
|
|
||||||
@JsonParameterSetTest(value = "ConvertNumberToPeanoExpressionImpl_0.json")
|
|
||||||
public void testEvaluate_0(JsonParameterSet params) throws Throwable {
|
|
||||||
performTest(params);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void performTest(JsonParameterSet params) throws Throwable {
|
|
||||||
int x = params.getInt("x");
|
|
||||||
|
|
||||||
Object numberExpression = NumberConverter.toNumberExpression(x);
|
|
||||||
|
|
||||||
Object mock = mock(CONVERT_NUMBER_TO_PEANO_EXPRESSION_IMPL.getLink().reflection(), CALLS_REAL_METHODS);
|
|
||||||
Object returned = CONVERT_NUMBER_TO_PEANO_EXPRESSION_CONVERT.invoke(mock.getClass(), mock, numberExpression);
|
|
||||||
|
|
||||||
Object actualPeano = PEANO_NUMBER_EXPRESSION_EVALUATE.invoke(returned.getClass(), returned);
|
|
||||||
|
|
||||||
int actual = NumberConverter.toNaturalNumber(actualPeano);
|
|
||||||
|
|
||||||
assertEquals(x, actual, params.toContext(), r -> "Value returned by convert() does not match expected.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testConvertRequirements() {
|
|
||||||
CtMethod<?> evaluate =
|
|
||||||
((BasicMethodLink) CONVERT_NUMBER_TO_PEANO_EXPRESSION_CONVERT.getLink(
|
|
||||||
CONVERT_NUMBER_TO_PEANO_EXPRESSION_IMPL.getLink().reflection(),
|
|
||||||
NUMBER_EXPRESSION.getLink().reflection()
|
|
||||||
)).getCtElement();
|
|
||||||
|
|
||||||
getCtElements(List.of(CONVERT_NUMBER_TO_PEANO_EXPRESSION_IMPL.getLink().reflection()), CtLambda.class, evaluate)
|
|
||||||
.forEach(ctLambda -> {
|
|
||||||
String body = ctLambda.toStringDebug();
|
|
||||||
Context context = contextBuilder().add("Lambda", body).build();
|
|
||||||
|
|
||||||
Assertions2.assertNull(
|
|
||||||
ctLambda.getBody(),
|
|
||||||
context,
|
|
||||||
r -> "convert() does not use correct lambdas."
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
package h07;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.sourcegrade.jagr.api.rubric.TestForSubmission;
|
|
||||||
|
|
||||||
@TestForSubmission
|
|
||||||
public class ConvertNumberToPeanoExpressionTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDefinition() {
|
|
||||||
ClassReference.CONVERT_NUMBER_TO_PEANO_EXPRESSION.assertCorrectlyDefined();
|
|
||||||
MethodReference.CONVERT_NUMBER_TO_PEANO_EXPRESSION_CONVERT.assertCorrectlyDefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testNaming() {
|
|
||||||
ClassReference.CONVERT_NUMBER_TO_PEANO_EXPRESSION.assertNamedCorrectly();
|
|
||||||
MethodReference.CONVERT_NUMBER_TO_PEANO_EXPRESSION_CONVERT.assertNamedCorrectly();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testPackage() {
|
|
||||||
ClassReference.CONVERT_NUMBER_TO_PEANO_EXPRESSION.assertDefinedInCorrectPackage();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,96 +0,0 @@
|
||||||
package h07;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.junit.jupiter.params.ParameterizedTest;
|
|
||||||
import org.sourcegrade.jagr.api.rubric.TestForSubmission;
|
|
||||||
import org.tudalgo.algoutils.tutor.general.assertions.Assertions2;
|
|
||||||
import org.tudalgo.algoutils.tutor.general.assertions.Context;
|
|
||||||
import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet;
|
|
||||||
import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest;
|
|
||||||
import org.tudalgo.algoutils.tutor.general.reflections.BasicMethodLink;
|
|
||||||
import spoon.reflect.code.CtLambda;
|
|
||||||
import spoon.reflect.declaration.CtMethod;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static h07.ClassReference.CONVERT_PEANO_TO_NUMBER_EXPRESSION_IMPL;
|
|
||||||
import static h07.ClassReference.PEANO_NUMBER_EXPRESSION;
|
|
||||||
import static h07.H07Test.getCtElements;
|
|
||||||
import static h07.MethodReference.CONVERT_PEANO_TO_NUMBER_EXPRESSION_CONVERT;
|
|
||||||
import static h07.MethodReference.NUMBER_EXPRESSION_EVALUATE;
|
|
||||||
import static h07.MethodReference.PEANO_NUMBER_EXPRESSION_EVALUATE;
|
|
||||||
import static org.mockito.Mockito.CALLS_REAL_METHODS;
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
import static org.tudalgo.algoutils.tutor.general.assertions.Assertions2.assertEquals;
|
|
||||||
import static org.tudalgo.algoutils.tutor.general.assertions.Assertions2.contextBuilder;
|
|
||||||
|
|
||||||
@TestForSubmission
|
|
||||||
public class ConvertPeanoToNumberExpressionImplTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDefinition() {
|
|
||||||
ClassReference.CONVERT_PEANO_TO_NUMBER_EXPRESSION_IMPL.assertCorrectlyDefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testNaming() {
|
|
||||||
ClassReference.CONVERT_PEANO_TO_NUMBER_EXPRESSION_IMPL.assertNamedCorrectly();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testPackage() {
|
|
||||||
ClassReference.CONVERT_PEANO_TO_NUMBER_EXPRESSION_IMPL.assertDefinedInCorrectPackage();
|
|
||||||
}
|
|
||||||
|
|
||||||
@ParameterizedTest
|
|
||||||
@JsonParameterSetTest(value = "ConvertPeanoToNumberExpressionImpl_X.json")
|
|
||||||
public void testEvaluate_X(JsonParameterSet params) throws Throwable {
|
|
||||||
performTest(params);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ParameterizedTest
|
|
||||||
@JsonParameterSetTest(value = "ConvertPeanoToNumberExpressionImpl_0.json")
|
|
||||||
public void testEvaluate_0(JsonParameterSet params) throws Throwable {
|
|
||||||
performTest(params);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void performTest(JsonParameterSet params) throws Throwable {
|
|
||||||
int x = params.getInt("x");
|
|
||||||
|
|
||||||
Object numberExpression = mock(PEANO_NUMBER_EXPRESSION.getLink().reflection());
|
|
||||||
when(PEANO_NUMBER_EXPRESSION_EVALUATE.invoke(
|
|
||||||
numberExpression.getClass(),
|
|
||||||
numberExpression
|
|
||||||
)).thenReturn(NumberConverter.toPeanoNumber(x));
|
|
||||||
|
|
||||||
Object mock = mock(CONVERT_PEANO_TO_NUMBER_EXPRESSION_IMPL.getLink().reflection(), CALLS_REAL_METHODS);
|
|
||||||
Object returned = CONVERT_PEANO_TO_NUMBER_EXPRESSION_CONVERT.invoke(mock.getClass(), mock, numberExpression);
|
|
||||||
|
|
||||||
int actual = NUMBER_EXPRESSION_EVALUATE.invoke(returned.getClass(), returned);
|
|
||||||
|
|
||||||
assertEquals(x, actual, params.toContext("expected"), r -> "Value returned by convert() does not match expected.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testConvertRequirements() {
|
|
||||||
CtMethod<?> evaluate =
|
|
||||||
((BasicMethodLink) CONVERT_PEANO_TO_NUMBER_EXPRESSION_CONVERT.getLink(
|
|
||||||
CONVERT_PEANO_TO_NUMBER_EXPRESSION_IMPL.getLink().reflection(),
|
|
||||||
PEANO_NUMBER_EXPRESSION.getLink().reflection()
|
|
||||||
)).getCtElement();
|
|
||||||
|
|
||||||
getCtElements(List.of(CONVERT_PEANO_TO_NUMBER_EXPRESSION_IMPL.getLink().reflection()), CtLambda.class, evaluate)
|
|
||||||
.forEach(ctLambda -> {
|
|
||||||
String body = ctLambda.toStringDebug();
|
|
||||||
Context context = contextBuilder().add("Lambda", body).build();
|
|
||||||
|
|
||||||
Assertions2.assertNull(
|
|
||||||
ctLambda.getBody(),
|
|
||||||
context,
|
|
||||||
r -> "convert() does not use correct lambdas."
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
package h07;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.sourcegrade.jagr.api.rubric.TestForSubmission;
|
|
||||||
|
|
||||||
@TestForSubmission
|
|
||||||
public class ConvertPeanoToNumberExpressionTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDefinition() {
|
|
||||||
ClassReference.CONVERT_PEANO_TO_NUMBER_EXPRESSION.assertCorrectlyDefined();
|
|
||||||
MethodReference.CONVERT_PEANO_TO_NUMBER_EXPRESSION_CONVERT.assertCorrectlyDefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testNaming() {
|
|
||||||
ClassReference.CONVERT_PEANO_TO_NUMBER_EXPRESSION.assertNamedCorrectly();
|
|
||||||
MethodReference.CONVERT_PEANO_TO_NUMBER_EXPRESSION_CONVERT.assertNamedCorrectly();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testPackage() {
|
|
||||||
ClassReference.CONVERT_PEANO_TO_NUMBER_EXPRESSION.assertDefinedInCorrectPackage();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,59 +0,0 @@
|
||||||
package h07;
|
|
||||||
|
|
||||||
import org.mockito.MockMakers;
|
|
||||||
import org.mockito.MockSettings;
|
|
||||||
import org.sourcegrade.jagr.api.testing.TestCycle;
|
|
||||||
import org.sourcegrade.jagr.api.testing.extension.TestCycleResolver;
|
|
||||||
import org.tudalgo.algoutils.tutor.general.reflections.BasicMethodLink;
|
|
||||||
import spoon.reflect.code.CtBodyHolder;
|
|
||||||
import spoon.reflect.code.CtInvocation;
|
|
||||||
import spoon.reflect.declaration.CtElement;
|
|
||||||
import spoon.reflect.declaration.CtMethod;
|
|
||||||
import spoon.reflect.visitor.filter.TypeFilter;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
import static org.mockito.Mockito.withSettings;
|
|
||||||
|
|
||||||
public class H07Test {
|
|
||||||
|
|
||||||
public MockSettings getSettings() {
|
|
||||||
|
|
||||||
TestCycle cycle = TestCycleResolver.getTestCycle();
|
|
||||||
|
|
||||||
if (cycle != null) {
|
|
||||||
Thread.currentThread()
|
|
||||||
.setContextClassLoader((ClassLoader) TestCycleResolver.getTestCycle().getClassLoader());
|
|
||||||
return withSettings().mockMaker(MockMakers.PROXY);
|
|
||||||
}
|
|
||||||
|
|
||||||
return withSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T extends CtElement> Stream<T> getCtElements(final List<Class<?>> classesToSearch, final Class<T> toSearch,
|
|
||||||
final CtBodyHolder bodyHolder) {
|
|
||||||
return bodyHolder.getElements(new TypeFilter<>(CtElement.class) {
|
|
||||||
@Override
|
|
||||||
public boolean matches(final CtElement element) {
|
|
||||||
return (toSearch.isInstance(element) || (element instanceof CtInvocation<?>))
|
|
||||||
&& classesToSearch.contains(element.getParent(CtMethod.class).getDeclaringType().getActualClass());
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.stream()
|
|
||||||
.filter(ctElement -> !ctElement.equals(bodyHolder))
|
|
||||||
.flatMap(element -> {
|
|
||||||
if (element instanceof final CtInvocation<?> call) {
|
|
||||||
final var calledMethod = call.getExecutable();
|
|
||||||
if (calledMethod.getDeclaringType() == null
|
|
||||||
|| !calledMethod.getDeclaringType().getQualifiedName().startsWith("h00.")) {
|
|
||||||
return Stream.of();
|
|
||||||
}
|
|
||||||
final var actualCalledMethod = calledMethod.getActualMethod();
|
|
||||||
final CtMethod<?> calledMethodCt = BasicMethodLink.of(actualCalledMethod).getCtElement();
|
|
||||||
return getCtElements(classesToSearch, toSearch, calledMethodCt);
|
|
||||||
}
|
|
||||||
return Stream.of((T) element);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,333 +0,0 @@
|
||||||
package h07;
|
|
||||||
|
|
||||||
import static org.tudalgo.algoutils.tutor.general.jagr.RubricUtils.criterion;
|
|
||||||
|
|
||||||
import org.sourcegrade.jagr.api.rubric.Criterion;
|
|
||||||
import org.sourcegrade.jagr.api.rubric.JUnitTestRef;
|
|
||||||
import org.sourcegrade.jagr.api.rubric.Rubric;
|
|
||||||
import org.sourcegrade.jagr.api.rubric.RubricProvider;
|
|
||||||
import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet;
|
|
||||||
|
|
||||||
public class H07_RubricProvider implements RubricProvider {
|
|
||||||
|
|
||||||
private static final Criterion H7_1_1 = Criterion.builder()
|
|
||||||
.shortDescription("H7.1.1 | NumberExpression")
|
|
||||||
.maxPoints(2)
|
|
||||||
.minPoints(0)
|
|
||||||
.addChildCriteria(
|
|
||||||
criterion(
|
|
||||||
"Das Interface NumberExpression wurde korrekt erstellt.",
|
|
||||||
JUnitTestRef.ofMethod(() -> NumberExpressionTest.class.getMethod("testDefinition"))),
|
|
||||||
criterion(
|
|
||||||
"Das Interface PeanoNumberExpression wurde korrekt erstellt.",
|
|
||||||
JUnitTestRef.ofMethod(() -> PeanoNumberExpressionTest.class.getMethod("testDefinition"))))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
private static final Criterion H7_1_2 = Criterion.builder()
|
|
||||||
.shortDescription("H7.1.2 | ArithmeticExpression")
|
|
||||||
.maxPoints(2)
|
|
||||||
.minPoints(0)
|
|
||||||
.addChildCriteria(
|
|
||||||
criterion(
|
|
||||||
"Das Interface ArithmeticExpression wurde korrekt erstellt.",
|
|
||||||
JUnitTestRef.ofMethod(() -> ArithmeticExpressionTest.class.getMethod("testDefinition"))),
|
|
||||||
criterion(
|
|
||||||
"Das Interface PeanoArithmeticExpression wurde korrekt erstellt.",
|
|
||||||
JUnitTestRef
|
|
||||||
.ofMethod(() -> PeanoArithmeticExpressionTest.class.getMethod("testDefinition"))))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
private static final Criterion H7_1 = Criterion.builder()
|
|
||||||
.shortDescription("H7.1 | Interfaces definieren")
|
|
||||||
.minPoints(0)
|
|
||||||
.addChildCriteria(
|
|
||||||
H7_1_1,
|
|
||||||
H7_1_2,
|
|
||||||
criterion(
|
|
||||||
"Alle Klassen und Methoden wurden korrekt benannt.",
|
|
||||||
-1,
|
|
||||||
JUnitTestRef.and(
|
|
||||||
JUnitTestRef.ofMethod(() -> NumberExpressionTest.class.getMethod("testNaming")),
|
|
||||||
JUnitTestRef
|
|
||||||
.ofMethod(() -> PeanoNumberExpressionTest.class.getMethod("testNaming")),
|
|
||||||
JUnitTestRef.ofMethod(() -> ArithmeticExpressionTest.class.getMethod("testNaming")),
|
|
||||||
JUnitTestRef.ofMethod(
|
|
||||||
() -> PeanoArithmeticExpressionTest.class.getMethod("testNaming")))),
|
|
||||||
criterion(
|
|
||||||
"Alle Klassen wurden im korrekten package definiert.",
|
|
||||||
-1,
|
|
||||||
JUnitTestRef.and(
|
|
||||||
JUnitTestRef.ofMethod(() -> NumberExpressionTest.class.getMethod("testPackage")),
|
|
||||||
JUnitTestRef
|
|
||||||
.ofMethod(() -> PeanoNumberExpressionTest.class.getMethod("testPackage")),
|
|
||||||
JUnitTestRef
|
|
||||||
.ofMethod(() -> ArithmeticExpressionTest.class.getMethod("testPackage")),
|
|
||||||
JUnitTestRef.ofMethod(
|
|
||||||
() -> PeanoArithmeticExpressionTest.class.getMethod("testPackage")))))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
private static final Criterion H7_2_1 = Criterion.builder()
|
|
||||||
.shortDescription("H7.2.1 | Multiplikationstabelle")
|
|
||||||
.maxPoints(3)
|
|
||||||
.minPoints(0)
|
|
||||||
.addChildCriteria(
|
|
||||||
criterion(
|
|
||||||
"Für ArithmeticExpression wurden nur Lambda-Ausdrücke in Standardform und für NumberExpression nur "
|
|
||||||
+ "Lambda-Ausdrücke in Kurzform verwendet.",
|
|
||||||
JUnitTestRef.ofMethod(() -> NumberExpressionFactoryTest.class
|
|
||||||
.getMethod("testMultiplicationTableRequirements"))),
|
|
||||||
criterion(
|
|
||||||
"Die Multiplikationstabelle gibt für lowerBound = upperBound die korrekten Werte aus.",
|
|
||||||
JUnitTestRef.ofMethod(() -> NumberExpressionFactoryTest.class.getMethod(
|
|
||||||
"multiplicationTableSimple",
|
|
||||||
JsonParameterSet.class))),
|
|
||||||
criterion(
|
|
||||||
"Die Multiplikationstabelle gibt für komplexere lowerBound und upperBound Werte die korrekten Werte aus.",
|
|
||||||
JUnitTestRef.ofMethod(() -> NumberExpressionFactoryTest.class.getMethod(
|
|
||||||
"multiplicationTableComplex",
|
|
||||||
JsonParameterSet.class))))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
private static final Criterion H7_2 = Criterion.builder()
|
|
||||||
.shortDescription("H7.2 | Multiplikationstabelle")
|
|
||||||
.minPoints(0)
|
|
||||||
.addChildCriteria(
|
|
||||||
H7_2_1)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
private static final Criterion H7_3_1 = Criterion.builder()
|
|
||||||
.shortDescription("H7.3.1 | PeanoAddExpression")
|
|
||||||
.minPoints(0)
|
|
||||||
.maxPoints(5)
|
|
||||||
.addChildCriteria(
|
|
||||||
criterion(
|
|
||||||
"Die Klasse PeanoAddExpression wurde korrekt erstellt.",
|
|
||||||
JUnitTestRef.ofMethod(() -> PeanoAddExpressionTest.class.getMethod("testDefinition"))),
|
|
||||||
criterion(
|
|
||||||
"Die Methode evaluate gibt für X + 0 das korrekte Ergebnis zurück.",
|
|
||||||
JUnitTestRef.ofMethod(() -> PeanoAddExpressionTest.class.getMethod("testEvaluate_X0",
|
|
||||||
JsonParameterSet.class))),
|
|
||||||
criterion(
|
|
||||||
"Die Methode evaluate gibt für 0 + X das korrekte Ergebnis zurück.",
|
|
||||||
JUnitTestRef.ofMethod(() -> PeanoAddExpressionTest.class.getMethod("testEvaluate_0X",
|
|
||||||
JsonParameterSet.class))),
|
|
||||||
criterion(
|
|
||||||
"Die Methode evaluate gibt für X + Y das korrekte Ergebnis zurück.",
|
|
||||||
2,
|
|
||||||
JUnitTestRef.ofMethod(() -> PeanoAddExpressionTest.class.getMethod("testEvaluate_XY",
|
|
||||||
JsonParameterSet.class))),
|
|
||||||
criterion(
|
|
||||||
"Verbindliche Anforderung nicht erfüllt",
|
|
||||||
-2,
|
|
||||||
JUnitTestRef.ofMethod(
|
|
||||||
() -> PeanoAddExpressionTest.class.getMethod("testEvaluateRequirements"))))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
private static final Criterion H7_3_2 = Criterion.builder()
|
|
||||||
.shortDescription("H7.3.2 | PeanoMultiplyExpression")
|
|
||||||
.minPoints(0)
|
|
||||||
.maxPoints(5)
|
|
||||||
.addChildCriteria(
|
|
||||||
criterion(
|
|
||||||
"Die Klasse PeanoMultiplyExpression wurde korrekt erstellt.",
|
|
||||||
JUnitTestRef.ofMethod(() -> PeanoMultiplyExpressionTest.class.getMethod("testDefinition"))),
|
|
||||||
criterion(
|
|
||||||
"Die Methode evaluate gibt für X * 0 das korrekte Ergebnis zurück.",
|
|
||||||
JUnitTestRef.ofMethod(() -> PeanoMultiplyExpressionTest.class.getMethod(
|
|
||||||
"testEvaluate_X0",
|
|
||||||
JsonParameterSet.class))),
|
|
||||||
criterion(
|
|
||||||
"Die Methode evaluate gibt für 0 * X das korrekte Ergebnis zurück.",
|
|
||||||
JUnitTestRef.ofMethod(() -> PeanoMultiplyExpressionTest.class.getMethod(
|
|
||||||
"testEvaluate_0X",
|
|
||||||
JsonParameterSet.class))),
|
|
||||||
criterion(
|
|
||||||
"Die Methode evaluate gibt für X * Y das korrekte Ergebnis zurück.",
|
|
||||||
2,
|
|
||||||
JUnitTestRef.ofMethod(() -> PeanoMultiplyExpressionTest.class.getMethod(
|
|
||||||
"testEvaluate_XY",
|
|
||||||
JsonParameterSet.class))),
|
|
||||||
criterion(
|
|
||||||
"Verbindliche Anforderung nicht erfüllt",
|
|
||||||
-2,
|
|
||||||
JUnitTestRef.ofMethod(
|
|
||||||
() -> PeanoMultiplyExpressionTest.class.getMethod("testEvaluateRequirements"))))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
private static final Criterion H7_3 = Criterion.builder()
|
|
||||||
.shortDescription("H7.3 | Peano Arithmetik")
|
|
||||||
.minPoints(0)
|
|
||||||
.addChildCriteria(
|
|
||||||
H7_3_1,
|
|
||||||
H7_3_2,
|
|
||||||
criterion(
|
|
||||||
"Alle Klassen und Methoden wurden korrekt benannt.",
|
|
||||||
-1,
|
|
||||||
JUnitTestRef.and(
|
|
||||||
JUnitTestRef.ofMethod(() -> PeanoAddExpressionTest.class.getMethod("testNaming")),
|
|
||||||
JUnitTestRef.ofMethod(
|
|
||||||
() -> PeanoMultiplyExpressionTest.class.getMethod("testNaming")))),
|
|
||||||
criterion(
|
|
||||||
"Alle Klassen wurden im korrekten package definiert.",
|
|
||||||
-1,
|
|
||||||
JUnitTestRef.and(
|
|
||||||
JUnitTestRef.ofMethod(() -> PeanoAddExpressionTest.class.getMethod("testPackage")),
|
|
||||||
JUnitTestRef.ofMethod(
|
|
||||||
() -> PeanoMultiplyExpressionTest.class.getMethod("testPackage")))))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
private static final Criterion H7_4_1 = Criterion.builder()
|
|
||||||
.shortDescription("H7.4.1 | Interfaces für Map erstellen")
|
|
||||||
.maxPoints(2)
|
|
||||||
.minPoints(0)
|
|
||||||
.addChildCriteria(
|
|
||||||
criterion(
|
|
||||||
"Das Interface ConvertNumberToPeanoExpression wurde korrekt erstellt.",
|
|
||||||
JUnitTestRef.ofMethod(
|
|
||||||
() -> ConvertNumberToPeanoExpressionTest.class.getMethod("testDefinition"))),
|
|
||||||
criterion(
|
|
||||||
"Das Interface ConvertPeanoToNumberExpression wurde korrekt erstellt.",
|
|
||||||
JUnitTestRef.ofMethod(
|
|
||||||
() -> ConvertPeanoToNumberExpressionTest.class.getMethod("testDefinition"))))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
private static final Criterion H7_4_2 = Criterion.builder()
|
|
||||||
.shortDescription("H7.4.2 | Conversions Implementieren")
|
|
||||||
.maxPoints(7)
|
|
||||||
.minPoints(0)
|
|
||||||
.addChildCriteria(
|
|
||||||
criterion(
|
|
||||||
"Die Klasse ConvertNumberToPeanoExpressionImpl wurde korrekt erstellt.",
|
|
||||||
JUnitTestRef.ofMethod(
|
|
||||||
() -> ConvertNumberToPeanoExpressionImplTest.class.getMethod("testDefinition"))),
|
|
||||||
criterion(
|
|
||||||
"Die Methode convert von ConvertNumberToPeanoExpressionImpl gibt für 0 das korrekte Ergebnis zurück.",
|
|
||||||
JUnitTestRef.ofMethod(() -> ConvertNumberToPeanoExpressionImplTest.class.getMethod(
|
|
||||||
"testEvaluate_0",
|
|
||||||
JsonParameterSet.class))),
|
|
||||||
criterion(
|
|
||||||
"Die Methode convert von ConvertNumberToPeanoExpressionImpl gibt für X das korrekte Ergebnis zurück.",
|
|
||||||
JUnitTestRef.ofMethod(() -> ConvertNumberToPeanoExpressionImplTest.class.getMethod(
|
|
||||||
"testEvaluate_X",
|
|
||||||
JsonParameterSet.class))),
|
|
||||||
criterion(
|
|
||||||
"Die Klasse ConvertPeanoToNumberExpressionImpl wurde korrekt erstellt.",
|
|
||||||
JUnitTestRef.ofMethod(
|
|
||||||
() -> ConvertPeanoToNumberExpressionImplTest.class.getMethod("testDefinition"))),
|
|
||||||
criterion(
|
|
||||||
"Die Methode convert von ConvertPeanoToNumberExpressionImpl gibt für 0 das korrekte Ergebnis zurück.",
|
|
||||||
JUnitTestRef.ofMethod(() -> ConvertPeanoToNumberExpressionImplTest.class.getMethod(
|
|
||||||
"testEvaluate_0",
|
|
||||||
JsonParameterSet.class))),
|
|
||||||
criterion(
|
|
||||||
"Die Methode convert von ConvertPeanoToNumberExpressionImpl gibt für X das korrekte Ergebnis zurück.",
|
|
||||||
2,
|
|
||||||
JUnitTestRef.ofMethod(() -> ConvertPeanoToNumberExpressionImplTest.class.getMethod(
|
|
||||||
"testEvaluate_X",
|
|
||||||
JsonParameterSet.class))))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
private static final Criterion H7_4_3 = Criterion.builder()
|
|
||||||
.shortDescription("H7.4.3 | Von Zahlen zu Peano-Zahlen")
|
|
||||||
.maxPoints(1)
|
|
||||||
.minPoints(0)
|
|
||||||
.addChildCriteria(
|
|
||||||
criterion(
|
|
||||||
"Die Methode fromNumberExpressions in PeanoNumberExpressionFactory wandelt einen Array von NumberExpressions "
|
|
||||||
+ "korrekt um.",
|
|
||||||
JUnitTestRef.ofMethod(() -> PeanoNumberExpressionFactoryTest.class
|
|
||||||
.getMethod("testFromNumberExpressions", JsonParameterSet.class))))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
private static final Criterion H7_4_4 = Criterion.builder()
|
|
||||||
.shortDescription("H7.4.4 | Filter")
|
|
||||||
.maxPoints(3)
|
|
||||||
.minPoints(0)
|
|
||||||
.addChildCriteria(
|
|
||||||
criterion(
|
|
||||||
"Filter gibt für ein leeres Array ein leeres Array zurück.",
|
|
||||||
JUnitTestRef.ofMethod(() -> NumberExpressionFactoryTest.class.getMethod("filter_empty",
|
|
||||||
JsonParameterSet.class))),
|
|
||||||
criterion(
|
|
||||||
"Filter gibt für ein Predicate, das immer true ist, das gesamte Array zurück und für ein Predicate, das immer "
|
|
||||||
+ "false ist, ein leeres Array.",
|
|
||||||
JUnitTestRef.and(
|
|
||||||
JUnitTestRef.ofMethod(() -> NumberExpressionFactoryTest.class.getMethod(
|
|
||||||
"filter_true",
|
|
||||||
JsonParameterSet.class)),
|
|
||||||
JUnitTestRef.ofMethod(() -> NumberExpressionFactoryTest.class.getMethod(
|
|
||||||
"filter_false",
|
|
||||||
JsonParameterSet.class)))),
|
|
||||||
criterion(
|
|
||||||
"Filter gibt für ein Predicate, welches nur durch vier teilbare Zahlen akzeptiert, nur die durch drei teilbaren"
|
|
||||||
+ " Zahlen zurück.",
|
|
||||||
JUnitTestRef.ofMethod(() -> NumberExpressionFactoryTest.class.getMethod("filter_complex",
|
|
||||||
JsonParameterSet.class))))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
private static final Criterion H7_4_5 = Criterion.builder()
|
|
||||||
.shortDescription("H7.4.5 | Fold")
|
|
||||||
.maxPoints(2)
|
|
||||||
.minPoints(0)
|
|
||||||
.addChildCriteria(
|
|
||||||
criterion(
|
|
||||||
"Fold gibt für ein leeres Array das Initial zurück.",
|
|
||||||
JUnitTestRef.ofMethod(() -> PeanoNumberExpressionFactoryTest.class.getMethod(
|
|
||||||
"fold_empty",
|
|
||||||
JsonParameterSet.class))),
|
|
||||||
criterion(
|
|
||||||
"Fold gibt für ein Array mit mehreren Elementen das korrekte Ergebnis zurück.",
|
|
||||||
JUnitTestRef.ofMethod(() -> PeanoNumberExpressionFactoryTest.class.getMethod(
|
|
||||||
"fold_filled",
|
|
||||||
JsonParameterSet.class))))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
private static final Criterion H7_4 = Criterion.builder()
|
|
||||||
.shortDescription("H7.4 | Funktionen höherer Ordnung")
|
|
||||||
.minPoints(0)
|
|
||||||
.addChildCriteria(
|
|
||||||
H7_4_1,
|
|
||||||
H7_4_2,
|
|
||||||
H7_4_3,
|
|
||||||
H7_4_4,
|
|
||||||
H7_4_5,
|
|
||||||
criterion(
|
|
||||||
"Alle Klassen und Methoden wurden korrekt benannt.",
|
|
||||||
-1,
|
|
||||||
JUnitTestRef.and(
|
|
||||||
JUnitTestRef.ofMethod(
|
|
||||||
() -> ConvertNumberToPeanoExpressionTest.class.getMethod("testNaming")),
|
|
||||||
JUnitTestRef.ofMethod(
|
|
||||||
() -> ConvertPeanoToNumberExpressionTest.class.getMethod("testNaming")),
|
|
||||||
JUnitTestRef.ofMethod(
|
|
||||||
() -> ConvertNumberToPeanoExpressionImplTest.class.getMethod("testNaming")),
|
|
||||||
JUnitTestRef.ofMethod(() -> ConvertPeanoToNumberExpressionImplTest.class
|
|
||||||
.getMethod("testNaming")))),
|
|
||||||
criterion(
|
|
||||||
"Alle Klassen wurden im korrekten package definiert.",
|
|
||||||
-1,
|
|
||||||
JUnitTestRef.and(
|
|
||||||
JUnitTestRef.ofMethod(
|
|
||||||
() -> ConvertNumberToPeanoExpressionTest.class.getMethod("testPackage")),
|
|
||||||
JUnitTestRef.ofMethod(
|
|
||||||
() -> ConvertPeanoToNumberExpressionTest.class.getMethod("testPackage")),
|
|
||||||
JUnitTestRef.ofMethod(() -> ConvertNumberToPeanoExpressionImplTest.class
|
|
||||||
.getMethod("testPackage")),
|
|
||||||
JUnitTestRef.ofMethod(() -> ConvertPeanoToNumberExpressionImplTest.class
|
|
||||||
.getMethod("testPackage")))))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
public static final Rubric RUBRIC = Rubric.builder()
|
|
||||||
.title("H07 | Peano Arithmetik")
|
|
||||||
.addChildCriteria(
|
|
||||||
H7_1,
|
|
||||||
H7_2,
|
|
||||||
H7_3,
|
|
||||||
H7_4)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Rubric getRubric() {
|
|
||||||
return RUBRIC;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,446 +0,0 @@
|
||||||
package h07;
|
|
||||||
|
|
||||||
import org.tudalgo.algoutils.tutor.general.assertions.Context;
|
|
||||||
import org.tudalgo.algoutils.tutor.general.match.Matcher;
|
|
||||||
import org.tudalgo.algoutils.tutor.general.reflections.BasicConstructorLink;
|
|
||||||
import org.tudalgo.algoutils.tutor.general.reflections.BasicTypeLink;
|
|
||||||
import org.tudalgo.algoutils.tutor.general.reflections.ConstructorLink;
|
|
||||||
import org.tudalgo.algoutils.tutor.general.reflections.Link;
|
|
||||||
import org.tudalgo.algoutils.tutor.general.reflections.MethodLink;
|
|
||||||
import org.tudalgo.algoutils.tutor.general.reflections.Modifier;
|
|
||||||
import org.tudalgo.algoutils.tutor.general.reflections.TypeLink;
|
|
||||||
import org.tudalgo.algoutils.tutor.general.reflections.WithModifiers;
|
|
||||||
|
|
||||||
import java.lang.reflect.Executable;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import static h07.ClassReference.ARITHMETIC_EXPRESSION;
|
|
||||||
import static h07.ClassReference.CONVERT_NUMBER_TO_PEANO_EXPRESSION;
|
|
||||||
import static h07.ClassReference.CONVERT_PEANO_TO_NUMBER_EXPRESSION;
|
|
||||||
import static h07.ClassReference.NUMBER_EXPRESSION;
|
|
||||||
import static h07.ClassReference.PEANO_ARITHMETIC_EXPRESSION;
|
|
||||||
import static h07.ClassReference.PEANO_NUMBER_EXPRESSION;
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.tudalgo.algoutils.tutor.general.assertions.Assertions2.assertEquals;
|
|
||||||
import static org.tudalgo.algoutils.tutor.general.assertions.Assertions2.assertNotNull;
|
|
||||||
import static org.tudalgo.algoutils.tutor.general.assertions.Assertions2.assertTrue;
|
|
||||||
import static org.tudalgo.algoutils.tutor.general.assertions.Assertions2.contextBuilder;
|
|
||||||
import static org.tudalgo.algoutils.tutor.general.assertions.Assertions2.fail;
|
|
||||||
import static org.tudalgo.algoutils.tutor.general.reflections.Modifier.PUBLIC;
|
|
||||||
|
|
||||||
public class MethodReference {
|
|
||||||
|
|
||||||
public static final MethodReference NUMBER_EXPRESSION_EVALUATE =
|
|
||||||
new MethodReference(NUMBER_EXPRESSION, "evaluate", new Modifier[] {PUBLIC}, int.class, new Class[] {});
|
|
||||||
public static final MethodReference PEANO_NUMBER_EXPRESSION_EVALUATE =
|
|
||||||
new MethodReference(PEANO_NUMBER_EXPRESSION, "evaluate", new Modifier[] {PUBLIC}, ClassReference.NATURAL_NUMBER.getLink().reflection(), new Class[] {});
|
|
||||||
public static final MethodReference ARITHMETIC_EXPRESSION_EVALUATE = new MethodReference(ARITHMETIC_EXPRESSION,
|
|
||||||
"evaluate",
|
|
||||||
new Modifier[] {PUBLIC},
|
|
||||||
NUMBER_EXPRESSION.getLink().reflection(),
|
|
||||||
NUMBER_EXPRESSION,
|
|
||||||
NUMBER_EXPRESSION
|
|
||||||
);
|
|
||||||
public static final MethodReference PEANO_ARITHMETIC_EXPRESSION_EVALUATE = new MethodReference(PEANO_ARITHMETIC_EXPRESSION,
|
|
||||||
"evaluate",
|
|
||||||
new Modifier[] {PUBLIC},
|
|
||||||
PEANO_NUMBER_EXPRESSION.getLink().reflection(),
|
|
||||||
PEANO_NUMBER_EXPRESSION,
|
|
||||||
PEANO_NUMBER_EXPRESSION
|
|
||||||
);
|
|
||||||
public static final MethodReference CONVERT_NUMBER_TO_PEANO_EXPRESSION_CONVERT = new MethodReference(
|
|
||||||
CONVERT_NUMBER_TO_PEANO_EXPRESSION,
|
|
||||||
"convert",
|
|
||||||
new Modifier[] {PUBLIC},
|
|
||||||
PEANO_NUMBER_EXPRESSION.getLink().reflection(),
|
|
||||||
NUMBER_EXPRESSION
|
|
||||||
);
|
|
||||||
public static final MethodReference CONVERT_PEANO_TO_NUMBER_EXPRESSION_CONVERT = new MethodReference(
|
|
||||||
CONVERT_PEANO_TO_NUMBER_EXPRESSION,
|
|
||||||
"convert",
|
|
||||||
new Modifier[] {PUBLIC},
|
|
||||||
NUMBER_EXPRESSION.getLink().reflection(),
|
|
||||||
PEANO_NUMBER_EXPRESSION
|
|
||||||
);
|
|
||||||
|
|
||||||
private final boolean isConstructor;
|
|
||||||
private final String name;
|
|
||||||
private final List<String> parameterClassNames;
|
|
||||||
private final Modifier[] expectedModifiers;
|
|
||||||
private final Link.Kind kind;
|
|
||||||
private final ClassReference clazz;
|
|
||||||
private Class<?>[] parameters;
|
|
||||||
private MethodLink methodLink;
|
|
||||||
private ConstructorLink constructorLink;
|
|
||||||
|
|
||||||
public MethodReference(ClassReference clazz, Modifier[] expectedModifiers, Class<?>... parameters) {
|
|
||||||
this.name = Link.Kind.CONSTRUCTOR.name();
|
|
||||||
this.parameters = parameters;
|
|
||||||
this.parameterClassNames = Arrays.stream(parameters).map(Class::getName).toList();
|
|
||||||
this.isConstructor = true;
|
|
||||||
this.expectedModifiers = expectedModifiers;
|
|
||||||
this.kind = Link.Kind.CONSTRUCTOR;
|
|
||||||
this.clazz = clazz;
|
|
||||||
if (!clazz.isDefined()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
constructorLink = BasicConstructorLink.of(clazz.getLink().reflection().getDeclaredConstructor(parameters));
|
|
||||||
} catch (NoSuchMethodException ignored) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public MethodReference(ClassReference clazz, Modifier[] expectedModifiers, ClassReference... parameters) {
|
|
||||||
this.name = Link.Kind.CONSTRUCTOR.name();
|
|
||||||
this.parameterClassNames = Arrays.stream(parameters).map(ClassReference::getName).toList();
|
|
||||||
this.isConstructor = true;
|
|
||||||
this.expectedModifiers = expectedModifiers;
|
|
||||||
this.kind = Link.Kind.CONSTRUCTOR;
|
|
||||||
this.clazz = clazz;
|
|
||||||
if (!clazz.isDefined()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (ClassReference ref : parameters) {
|
|
||||||
if (!ref.isDefined()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.parameters = Arrays.stream(parameters).map(p -> p.getLink().reflection()).toArray(Class[]::new);
|
|
||||||
try {
|
|
||||||
constructorLink = BasicConstructorLink.of(
|
|
||||||
clazz.getLink().reflection().getDeclaredConstructor(
|
|
||||||
Arrays.stream(parameters).map(p -> p.getLink().reflection()).toArray(Class[]::new)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
} catch (NoSuchMethodException ignored) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public MethodReference(ClassReference clazz, String name, Modifier[] expectedModifiers, Class<?> returnValue,
|
|
||||||
Class<?>... parameters) {
|
|
||||||
this.name = name;
|
|
||||||
this.parameters = parameters;
|
|
||||||
this.parameterClassNames = Arrays.stream(parameters).map(Class::getName).toList();
|
|
||||||
this.isConstructor = false;
|
|
||||||
this.expectedModifiers = expectedModifiers;
|
|
||||||
this.kind = Link.Kind.METHOD;
|
|
||||||
this.clazz = clazz;
|
|
||||||
if (!clazz.isDefined()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
methodLink = clazz.getLink().getMethod(Tests.stringMatcher(name));
|
|
||||||
}
|
|
||||||
|
|
||||||
public MethodReference(ClassReference clazz, String name, Modifier[] expectedModifiers, Class<?> returnValue,
|
|
||||||
ClassReference... parameters) {
|
|
||||||
this.name = name;
|
|
||||||
this.isConstructor = false;
|
|
||||||
this.expectedModifiers = expectedModifiers;
|
|
||||||
this.parameterClassNames = Arrays.stream(parameters).map(ClassReference::getName).toList();
|
|
||||||
this.kind = Link.Kind.METHOD;
|
|
||||||
this.clazz = clazz;
|
|
||||||
if (!clazz.isDefined()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (ClassReference ref : parameters) {
|
|
||||||
if (!ref.isDefined()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.parameters = Arrays.stream(parameters).map(p -> p.getLink().reflection()).toArray(Class[]::new);
|
|
||||||
methodLink = clazz.getLink().getMethod(Tests.stringMatcher(name));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public WithModifiers getLink() {
|
|
||||||
return methodLink != null ? methodLink : constructorLink;
|
|
||||||
}
|
|
||||||
|
|
||||||
public WithModifiers getLink(Class<?> calledClass, Class<?>... parameters) {
|
|
||||||
MethodLink actual = BasicTypeLink.of(calledClass).getMethod(Tests.stringMatcher(name));
|
|
||||||
if (actual != null) {
|
|
||||||
List<Class<?>> actualParameters = actual.typeList().stream().map(TypeLink::reflection).collect(Collectors.toList());
|
|
||||||
|
|
||||||
Map<Class<?>, Integer> occurrencesActual = actualParameters.stream().collect(Collectors.groupingBy(
|
|
||||||
obj -> obj,
|
|
||||||
Collectors.summingInt(obj -> 1)
|
|
||||||
));
|
|
||||||
Map<Class<?>, Integer> occurrencesExpected = Arrays.stream(parameters).collect(Collectors.groupingBy(
|
|
||||||
obj -> obj == null ? MethodReference.class : obj,
|
|
||||||
Collectors.summingInt(obj -> 1)
|
|
||||||
));
|
|
||||||
|
|
||||||
boolean hasCorrectParams = Arrays.stream(parameters).allMatch(
|
|
||||||
param -> actualParameters.stream().anyMatch(
|
|
||||||
actualParam -> param == null || (actualParam.isAssignableFrom(param)
|
|
||||||
&& occurrencesActual.getOrDefault(actualParam, 0) >= occurrencesExpected.getOrDefault(param, 0))
|
|
||||||
)
|
|
||||||
);
|
|
||||||
if (parameters.length != actualParameters.size() || !hasCorrectParams) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
methodLink = actual;
|
|
||||||
return actual;
|
|
||||||
}
|
|
||||||
if (!clazz.isDefined()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (isConstructor) {
|
|
||||||
ConstructorLink link = clazz.getLink().getConstructor(
|
|
||||||
Matcher.of(
|
|
||||||
(c) -> {
|
|
||||||
List<? extends Class<?>> types = c.typeList().stream().map(TypeLink::reflection).toList();
|
|
||||||
if (parameters == null || types.size() != parameters.length) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (int i = 0; i < types.size(); i++) {
|
|
||||||
if (parameters[i] == null || !types.get(i).isAssignableFrom(parameters[i])) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
constructorLink = link;
|
|
||||||
return link;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public WithModifiers assertDefined(Class<?> calledClass, Class<?>... parameters) {
|
|
||||||
Context context = contextBuilder()
|
|
||||||
.add("expected class", clazz.getName())
|
|
||||||
.add("expected kind", kind)
|
|
||||||
.add("expected name", name)
|
|
||||||
.add("expected parameter", parameterClassNames)
|
|
||||||
.build();
|
|
||||||
MethodLink actual = BasicTypeLink.of(calledClass).getMethod(Tests.stringMatcher(name));
|
|
||||||
if (actual != null) {
|
|
||||||
|
|
||||||
List<Class<?>> actualParameters = actual.typeList().stream().map(TypeLink::reflection).collect(Collectors.toList());
|
|
||||||
|
|
||||||
Map<Class<?>, Integer> occurrencesActual = actualParameters.stream().collect(Collectors.groupingBy(
|
|
||||||
obj -> obj,
|
|
||||||
Collectors.summingInt(obj -> 1)
|
|
||||||
));
|
|
||||||
Map<Class<?>, Integer> occurrencesExpected = Arrays.stream(parameters).collect(Collectors.groupingBy(
|
|
||||||
obj -> obj == null ? MethodReference.class : obj,
|
|
||||||
Collectors.summingInt(obj -> 1)
|
|
||||||
));
|
|
||||||
|
|
||||||
boolean hasCorrectParams = Arrays.stream(parameters).allMatch(
|
|
||||||
param -> actualParameters.stream().anyMatch(
|
|
||||||
actualParam -> param == null || (actualParam.isAssignableFrom(param)
|
|
||||||
&& occurrencesActual.getOrDefault(actualParam, 0) >= occurrencesExpected.getOrDefault(param, 0))
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
context = contextBuilder()
|
|
||||||
.add(context)
|
|
||||||
.add("actual Parameters", actualParameters)
|
|
||||||
.add("called with", Arrays.toString(parameters))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
assertEquals(
|
|
||||||
parameters.length,
|
|
||||||
actualParameters.size(),
|
|
||||||
context,
|
|
||||||
r -> String.format("%s does not have the right number of parameters", name)
|
|
||||||
);
|
|
||||||
|
|
||||||
assertTrue(
|
|
||||||
hasCorrectParams,
|
|
||||||
context,
|
|
||||||
r -> String.format("%s does not have the right parameters", name)
|
|
||||||
);
|
|
||||||
methodLink = actual;
|
|
||||||
return actual;
|
|
||||||
}
|
|
||||||
if (!clazz.isDefined()) {
|
|
||||||
fail(
|
|
||||||
context,
|
|
||||||
r -> String.format(
|
|
||||||
"Can not find %s. The Class of the method does not exist or could not be found.",
|
|
||||||
name
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (isConstructor) {
|
|
||||||
ConstructorLink link = clazz.getLink().getConstructor(
|
|
||||||
Matcher.of(
|
|
||||||
(c) -> {
|
|
||||||
List<? extends Class<?>> types = c.typeList().stream().map(TypeLink::reflection).toList();
|
|
||||||
if (parameters == null || types.size() != parameters.length) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (int i = 0; i < types.size(); i++) {
|
|
||||||
if (parameters[i] == null || !types.get(i).isAssignableFrom(parameters[i])) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
if (link != null) {
|
|
||||||
return link;
|
|
||||||
}
|
|
||||||
return fail(
|
|
||||||
context,
|
|
||||||
r -> String.format(
|
|
||||||
"Could not find %s in class %s. The constructor does not exist or has wrong Parameters.",
|
|
||||||
name,
|
|
||||||
clazz.getLink().name()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return fail(
|
|
||||||
context,
|
|
||||||
r -> String.format(
|
|
||||||
"Can not find %s in class %s. The Method does not exist or could not be found.",
|
|
||||||
name,
|
|
||||||
calledClass.getName()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void assertCorrectlyDefined() {
|
|
||||||
assertDefined(clazz.getLink().reflection(), parameters);
|
|
||||||
|
|
||||||
WithModifiers link = assertDefined(clazz.getLink().reflection(), parameters);
|
|
||||||
String name =
|
|
||||||
link.kind() == Link.Kind.METHOD ? ((MethodLink) link).reflection().getName() : Link.Kind.CONSTRUCTOR.name();
|
|
||||||
Modifier[] actualModifiers =
|
|
||||||
Arrays.stream(Modifier.values()).filter(m -> m.is(link.modifiers())).toArray(Modifier[]::new);
|
|
||||||
Context context = contextBuilder()
|
|
||||||
.add("expected class", clazz.getLink().name())
|
|
||||||
.add("expected kind", kind)
|
|
||||||
.add("expected name", name)
|
|
||||||
.add(
|
|
||||||
"expected modifier",
|
|
||||||
Arrays.stream(expectedModifiers).map(Modifier::keyword).collect(Collectors.joining(", "))
|
|
||||||
)
|
|
||||||
.add("class", ((Executable) link.reflection()).getDeclaringClass().getName())
|
|
||||||
.add("kind", link.kind())
|
|
||||||
.add("name", name)
|
|
||||||
.add("modifier", Arrays.stream(actualModifiers).map(Modifier::keyword).collect(Collectors.joining(", ")))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
assertNotNull(link, context, r -> "Could not find method %s.".formatted(name));
|
|
||||||
assertEquals(
|
|
||||||
clazz.getLink().reflection(),
|
|
||||||
((Executable) link.reflection()).getDeclaringClass(),
|
|
||||||
context,
|
|
||||||
r -> "Declaring Class does not match expected Class."
|
|
||||||
);
|
|
||||||
assertEquals(link.kind(), link.kind(), context, r -> "Kind does not match expected kind.");
|
|
||||||
|
|
||||||
assertTrue(
|
|
||||||
Set.of(actualModifiers).containsAll(Set.of(expectedModifiers)),
|
|
||||||
context,
|
|
||||||
r -> "The modifiers of the Method do not match the expected modifiers."
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void assertNamedCorrectly() {
|
|
||||||
WithModifiers link = getLink(clazz.getLink().reflection(), parameters);
|
|
||||||
if (link == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String name =
|
|
||||||
link.kind() == Link.Kind.METHOD ? ((MethodLink) link).reflection().getName() : Link.Kind.CONSTRUCTOR.name();
|
|
||||||
Context context = contextBuilder()
|
|
||||||
.add("expected name", name)
|
|
||||||
.add("name", name)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
assertEquals(this.name, name, context, r -> "The name of the Method does not match the expected name.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public <T> T invoke(Class<?> calledClass, Object instance, Object... parameter) throws Throwable {
|
|
||||||
Link link = assertDefined(
|
|
||||||
calledClass,
|
|
||||||
Arrays.stream(parameter).map(o -> o != null ? o.getClass() : null).toArray(Class[]::new)
|
|
||||||
);
|
|
||||||
if (instance == null && !(link instanceof ConstructorLink)) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Could not invoke %s.%s() as object that the function should have been called on is null.".formatted(
|
|
||||||
clazz.getName(),
|
|
||||||
name
|
|
||||||
));
|
|
||||||
}
|
|
||||||
if (link instanceof MethodLink l) {
|
|
||||||
return l.invoke(instance, parameter);
|
|
||||||
} else if (link instanceof ConstructorLink l) {
|
|
||||||
return l.invoke(parameter);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public <T> T invokeBestEffort(Class<?> calledClass, Object instance, Object... parameter) throws Throwable {
|
|
||||||
WithModifiers link = getLink();
|
|
||||||
|
|
||||||
if (link == null) {
|
|
||||||
Context context = contextBuilder()
|
|
||||||
.add("expected class", clazz.getName())
|
|
||||||
.add("expected kind", kind)
|
|
||||||
.add("expected name", name)
|
|
||||||
.add("expected parameter", parameterClassNames)
|
|
||||||
.build();
|
|
||||||
fail(
|
|
||||||
context,
|
|
||||||
r -> String.format(
|
|
||||||
"Can not find %s in class %s. The Method does not exist or could not be found.",
|
|
||||||
name,
|
|
||||||
calledClass.getName()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Class<?>[] actualParameter = ((Executable) link.reflection()).getParameterTypes();
|
|
||||||
|
|
||||||
try {
|
|
||||||
return invoke(calledClass, instance, parameter);
|
|
||||||
} catch (Throwable ignored) {
|
|
||||||
ignored.printStackTrace();
|
|
||||||
}
|
|
||||||
if (actualParameter.length == 0) {
|
|
||||||
if (link instanceof MethodLink l) {
|
|
||||||
return l.invoke(instance);
|
|
||||||
} else if (link instanceof ConstructorLink l) {
|
|
||||||
return l.invoke();
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Object[] mocks = Arrays.stream(actualParameter)
|
|
||||||
.map(p -> {
|
|
||||||
if (p.equals(String.class)) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
return mock(p);
|
|
||||||
})
|
|
||||||
.toArray();
|
|
||||||
for (int i = 0; i < parameter.length && i < mocks.length; i++) {
|
|
||||||
if (mocks[i].getClass().isAssignableFrom(parameter[i].getClass())) {
|
|
||||||
mocks[i] = parameter[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (link instanceof MethodLink l) {
|
|
||||||
return l.invoke(instance, mocks);
|
|
||||||
} else if (link instanceof ConstructorLink l) {
|
|
||||||
return l.invoke(mocks);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
package h07;
|
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
|
|
||||||
import static h07.ClassReference.NUMBER_EXPRESSION;
|
|
||||||
import static h07.ClassReference.PEANO_NUMBER_EXPRESSION;
|
|
||||||
import static h07.MethodReference.NUMBER_EXPRESSION_EVALUATE;
|
|
||||||
import static h07.MethodReference.PEANO_NUMBER_EXPRESSION_EVALUATE;
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
public class NumberConverter {
|
|
||||||
|
|
||||||
public static int toNaturalNumber(Object peanoNumber) {
|
|
||||||
String representation = peanoNumber.toString();
|
|
||||||
return representation.length() - representation.replace("S", "").length();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Object toPeanoNumber(int number) {
|
|
||||||
Object peanoNumber = null;
|
|
||||||
try {
|
|
||||||
peanoNumber = ClassReference.ZERO.getLink().reflection().getConstructor().newInstance();
|
|
||||||
|
|
||||||
for (int i = 0; i < number; i++) {
|
|
||||||
peanoNumber = ClassReference.SUCCESSOR.getLink().reflection().getConstructor(ClassReference.NATURAL_NUMBER.getLink().reflection()).newInstance(peanoNumber);
|
|
||||||
}
|
|
||||||
return peanoNumber;
|
|
||||||
} catch (InstantiationException | NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Object toNumberExpression(int number) throws Throwable {
|
|
||||||
Object numberExpression = mock(NUMBER_EXPRESSION.getLink().reflection());
|
|
||||||
when(NUMBER_EXPRESSION_EVALUATE.invoke(numberExpression.getClass(), numberExpression)).thenReturn(number);
|
|
||||||
return numberExpression;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Object toPeanoNumberExpression(int number) throws Throwable {
|
|
||||||
Object numberExpression = mock(PEANO_NUMBER_EXPRESSION.getLink().reflection());
|
|
||||||
when(PEANO_NUMBER_EXPRESSION_EVALUATE.invoke(numberExpression.getClass(), numberExpression)).thenReturn(toPeanoNumber(number));
|
|
||||||
return numberExpression;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,219 +0,0 @@
|
||||||
package h07;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.junit.jupiter.params.ParameterizedTest;
|
|
||||||
import org.sourcegrade.jagr.api.rubric.TestForSubmission;
|
|
||||||
import org.tudalgo.algoutils.tutor.general.assertions.Assertions2;
|
|
||||||
import org.tudalgo.algoutils.tutor.general.assertions.Context;
|
|
||||||
import org.tudalgo.algoutils.tutor.general.json.JsonParameterSet;
|
|
||||||
import org.tudalgo.algoutils.tutor.general.json.JsonParameterSetTest;
|
|
||||||
import org.tudalgo.algoutils.tutor.general.match.BasicStringMatchers;
|
|
||||||
import org.tudalgo.algoutils.tutor.general.reflections.BasicMethodLink;
|
|
||||||
import org.tudalgo.algoutils.tutor.general.reflections.BasicTypeLink;
|
|
||||||
import org.tudalgo.algoutils.tutor.general.reflections.MethodLink;
|
|
||||||
import spoon.reflect.code.CtLambda;
|
|
||||||
import spoon.reflect.declaration.CtMethod;
|
|
||||||
|
|
||||||
import java.lang.reflect.Array;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
import java.util.function.IntPredicate;
|
|
||||||
|
|
||||||
import static h07.ClassReference.NUMBER_EXPRESSION;
|
|
||||||
import static h07.H07Test.getCtElements;
|
|
||||||
import static h07.MethodReference.NUMBER_EXPRESSION_EVALUATE;
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
import static org.tudalgo.algoutils.tutor.general.assertions.Assertions2.*;
|
|
||||||
|
|
||||||
@TestForSubmission
|
|
||||||
public class NumberExpressionFactoryTest {
|
|
||||||
|
|
||||||
@ParameterizedTest
|
|
||||||
@JsonParameterSetTest(value = "NumberExpressionFactory_multiply_Simple.json")
|
|
||||||
public void multiplicationTableSimple(JsonParameterSet params) throws Throwable {
|
|
||||||
performTest_multiplication(params);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ParameterizedTest
|
|
||||||
@JsonParameterSetTest(value = "NumberExpressionFactory_multiply_Complex.json")
|
|
||||||
public void multiplicationTableComplex(JsonParameterSet params) throws Throwable {
|
|
||||||
performTest_multiplication(params);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void performTest_multiplication(JsonParameterSet params) throws Throwable {
|
|
||||||
int lowerBound = params.getInt("lowerBound");
|
|
||||||
int upperBound = params.getInt("upperBound");
|
|
||||||
|
|
||||||
List<Integer> expected = new ArrayList<>();
|
|
||||||
params.getRootNode().get("expected").forEach(value -> expected.add(value.intValue()));
|
|
||||||
|
|
||||||
Context context = params.toContext();
|
|
||||||
|
|
||||||
List<Object> actualExpressions = multiplicationTable(lowerBound, upperBound);
|
|
||||||
List<Integer> actual = actualExpressions.stream().map(expr -> {
|
|
||||||
try {
|
|
||||||
return NUMBER_EXPRESSION_EVALUATE.<Integer>invoke(expr.getClass(), expr);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}).toList();
|
|
||||||
|
|
||||||
assertEquals(expected, actual, context, r -> "Returned multiplication table does not match expected.");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<Object> multiplicationTable(int lowerBound, int upperBound) throws Throwable {
|
|
||||||
int numberOfNumbers = upperBound - lowerBound + 1;
|
|
||||||
List<Object> baseNumbers = new ArrayList<>(numberOfNumbers);
|
|
||||||
|
|
||||||
for (int i = lowerBound; i <= upperBound; i++) {
|
|
||||||
|
|
||||||
Object expression = NumberConverter.toNumberExpression(i);
|
|
||||||
baseNumbers.add(expression);
|
|
||||||
}
|
|
||||||
|
|
||||||
MethodLink multiplicationLink = BasicMethodLink.of(Arrays.stream(NumberExpressionFactory.class.getMethods())
|
|
||||||
.filter(method -> method.getParameterCount() == 1 && method.getName().equals("multiplicationTable"))
|
|
||||||
.findFirst()
|
|
||||||
.get());
|
|
||||||
|
|
||||||
if (multiplicationLink == null) {
|
|
||||||
throw new RuntimeException("Could not find method NumberExpressionFactory.multiplicationTable()");
|
|
||||||
}
|
|
||||||
|
|
||||||
Object returned = multiplicationLink.invokeStatic((Object) (baseNumbers.toArray((Object[]) Array.newInstance(
|
|
||||||
NUMBER_EXPRESSION.getLink().reflection(),
|
|
||||||
0
|
|
||||||
))));
|
|
||||||
|
|
||||||
try {
|
|
||||||
return List.of((Object[]) returned);
|
|
||||||
} catch (NullPointerException e) {
|
|
||||||
fail(emptyContext(), r -> "multiplicationTable() returned null or an array containing null");
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@ParameterizedTest
|
|
||||||
@JsonParameterSetTest(value = "NumberExpressionFactory_filter_empty.json")
|
|
||||||
public void filter_empty(JsonParameterSet params) throws Throwable {
|
|
||||||
performTest_filter(params);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ParameterizedTest
|
|
||||||
@JsonParameterSetTest(value = "NumberExpressionFactory_filter_true.json")
|
|
||||||
public void filter_true(JsonParameterSet params) throws Throwable {
|
|
||||||
performTest_filter(params);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ParameterizedTest
|
|
||||||
@JsonParameterSetTest(value = "NumberExpressionFactory_filter_false.json")
|
|
||||||
public void filter_false(JsonParameterSet params) throws Throwable {
|
|
||||||
performTest_filter(params);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ParameterizedTest
|
|
||||||
@JsonParameterSetTest(value = "NumberExpressionFactory_filter_complex.json")
|
|
||||||
public void filter_complex(JsonParameterSet params) throws Throwable {
|
|
||||||
performTest_filter(params);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void performTest_filter(JsonParameterSet params) throws Throwable {
|
|
||||||
List<Integer> inputs = new ArrayList<>();
|
|
||||||
params.getRootNode().get("inputs").forEach(value -> inputs.add(value.intValue()));
|
|
||||||
|
|
||||||
Map<Integer, Boolean> filterMappings = new HashMap<>();
|
|
||||||
AtomicInteger currentElem = new AtomicInteger();
|
|
||||||
params.getRootNode()
|
|
||||||
.get("filter")
|
|
||||||
.forEach(value -> filterMappings.put(inputs.get(currentElem.getAndIncrement()), value.booleanValue()));
|
|
||||||
|
|
||||||
List<Integer> expected = new ArrayList<>();
|
|
||||||
params.getRootNode().get("expected").forEach(value -> expected.add(value.intValue()));
|
|
||||||
|
|
||||||
IntPredicate predicate = filterMappings::get;
|
|
||||||
|
|
||||||
List<Object> baseNumbers = new ArrayList<>();
|
|
||||||
inputs.forEach(input -> {
|
|
||||||
Object expression = mock(NUMBER_EXPRESSION.getLink().reflection());
|
|
||||||
try {
|
|
||||||
when(NUMBER_EXPRESSION_EVALUATE.invoke(NUMBER_EXPRESSION.getLink().reflection(), expression)).thenReturn(input);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
baseNumbers.add(expression);
|
|
||||||
});
|
|
||||||
|
|
||||||
MethodLink filterLink = BasicTypeLink.of(NumberExpressionFactory.class)
|
|
||||||
.getMethod(BasicStringMatchers.identical("filter"));
|
|
||||||
|
|
||||||
if (filterLink == null) {
|
|
||||||
fail(emptyContext(), r -> "Could not find method NumberExpressionFactory.filter()");
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Object> actualExpressions = List.of(
|
|
||||||
filterLink.invokeStatic(
|
|
||||||
baseNumbers.toArray((Object[]) Array.newInstance(NUMBER_EXPRESSION.getLink().reflection(), 0)),
|
|
||||||
predicate
|
|
||||||
)
|
|
||||||
);
|
|
||||||
List<Integer> actual = actualExpressions.stream().map(expr -> {
|
|
||||||
try {
|
|
||||||
return NUMBER_EXPRESSION_EVALUATE.<Integer>invoke(expr.getClass(), expr);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}).toList();
|
|
||||||
|
|
||||||
Context context = contextBuilder()
|
|
||||||
.add("inputs", inputs)
|
|
||||||
.add("filter", filterMappings)
|
|
||||||
.add("expected", expected)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
assertEquals(expected, actual, context, r -> "Returned List of expressions does not match expected list.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testMultiplicationTableRequirements() throws Throwable {
|
|
||||||
CtMethod<?> multiplicationTable = BasicMethodLink.of(Arrays.stream(NumberExpressionFactory.class.getMethods())
|
|
||||||
.filter(method -> method.getParameterCount() == 1 && method.getName().equals("multiplicationTable"))
|
|
||||||
.findFirst()
|
|
||||||
.get())
|
|
||||||
.getCtElement();
|
|
||||||
|
|
||||||
List<CtLambda> lambdas =
|
|
||||||
getCtElements(List.of(NumberExpressionFactory.class), CtLambda.class, multiplicationTable).toList();
|
|
||||||
boolean hasCorrectLambdas = lambdas.stream()
|
|
||||||
.anyMatch(ctLambda -> {
|
|
||||||
if (ctLambda.getBody() == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<CtLambda> innerLambdas =
|
|
||||||
getCtElements(List.of(NumberExpressionFactory.class), CtLambda.class, ctLambda).toList();
|
|
||||||
|
|
||||||
return innerLambdas.size() == 1 && innerLambdas.get(0).getBody() == null;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
Assertions2.assertTrue(
|
|
||||||
hasCorrectLambdas,
|
|
||||||
contextBuilder().add("Lambdas", lambdas.stream().map(CtLambda::toStringDebug).toList()).build(),
|
|
||||||
r -> "multiplicationTable() does not use correct lambdas."
|
|
||||||
);
|
|
||||||
|
|
||||||
boolean returnsArrayOfLambda =
|
|
||||||
multiplicationTable(0, 2).stream().allMatch(it -> it.getClass().getName().contains("$$Lambda"));
|
|
||||||
|
|
||||||
Assertions2.assertTrue(
|
|
||||||
returnsArrayOfLambda,
|
|
||||||
emptyContext(),
|
|
||||||
r -> "multiplicationTable() does not return array of objects created from lambdas."
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
package h07;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.sourcegrade.jagr.api.rubric.TestForSubmission;
|
|
||||||
|
|
||||||
@TestForSubmission
|
|
||||||
public class NumberExpressionTest extends H07Test {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDefinition() {
|
|
||||||
ClassReference.NUMBER_EXPRESSION.assertCorrectlyDefined();
|
|
||||||
MethodReference.NUMBER_EXPRESSION_EVALUATE.assertCorrectlyDefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testNaming() {
|
|
||||||
ClassReference.NUMBER_EXPRESSION.assertNamedCorrectly();
|
|
||||||
MethodReference.NUMBER_EXPRESSION_EVALUATE.assertNamedCorrectly();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testPackage() {
|
|
||||||
ClassReference.NUMBER_EXPRESSION.assertDefinedInCorrectPackage();
|
|
||||||
}
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue