diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..5d39588 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,10 @@ +language: java +jdk: + - oraclejdk8 +os: + - linux +env: + - SOURCE_DIR_1=006-Xunit +script: + - cd $SOURCE_DIR_1 && gradle check + diff --git a/006-Xunit/.idea/kotlinc.xml b/006-Xunit/.idea/kotlinc.xml new file mode 100644 index 0000000..1c24f9a --- /dev/null +++ b/006-Xunit/.idea/kotlinc.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/006-Xunit/build.gradle b/006-Xunit/build.gradle new file mode 100644 index 0000000..0b7b52e --- /dev/null +++ b/006-Xunit/build.gradle @@ -0,0 +1,16 @@ +version '1.0-SNAPSHOT' + +apply plugin: 'java' + +sourceCompatibility = 1.8 + +repositories { + mavenCentral() +} + +dependencies { + testCompile group: 'junit', name: 'junit', version: '4.12' + compile group: 'org.hamcrest', name: 'hamcrest-all', version: '1.3' + compile 'com.intellij:annotations:+@jar' + compile group: 'com.google.guava', name: 'guava', version: '19.0' +} diff --git a/006-Xunit/gradle/wrapper/gradle-wrapper.jar b/006-Xunit/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..04bfabe Binary files /dev/null and b/006-Xunit/gradle/wrapper/gradle-wrapper.jar differ diff --git a/006-Xunit/gradle/wrapper/gradle-wrapper.properties b/006-Xunit/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..983eb22 --- /dev/null +++ b/006-Xunit/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Mon May 15 12:42:24 MSK 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-bin.zip diff --git a/006-Xunit/gradlew b/006-Xunit/gradlew new file mode 100755 index 0000000..4453cce --- /dev/null +++ b/006-Xunit/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# 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 + ;; + 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" + which java >/dev/null 2>&1 || 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 + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save ( ) { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/006-Xunit/gradlew.bat b/006-Xunit/gradlew.bat new file mode 100644 index 0000000..f955316 --- /dev/null +++ b/006-Xunit/gradlew.bat @@ -0,0 +1,84 @@ +@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=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@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= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +: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 %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="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! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/006-Xunit/settings.gradle b/006-Xunit/settings.gradle new file mode 100644 index 0000000..f9fc5b3 --- /dev/null +++ b/006-Xunit/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = '006-junit' + diff --git a/006-Xunit/src/main/java/task/Tester/TestResult.java b/006-Xunit/src/main/java/task/Tester/TestResult.java new file mode 100644 index 0000000..b1eb357 --- /dev/null +++ b/006-Xunit/src/main/java/task/Tester/TestResult.java @@ -0,0 +1,62 @@ +package task.Tester; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.PrintStream; +import java.lang.reflect.Method; + +/** + * Stores result run some test. + */ +public class TestResult { + public final @NotNull Method method; + public final boolean ok; + public final @NotNull String message; + public final @Nullable Throwable exception; + public final long time; + + private TestResult(@NotNull Method method, boolean ok, @NotNull String message, @Nullable Throwable exception, long time) { + this.method = method; + this.ok = ok; + this.message = message; + this.exception = exception; + this.time = time; + } + + static TestResult ok(@NotNull Method method, long time) { + return new TestResult(method, true, "ok.", null, time); + } + + static TestResult expectedException(@NotNull Method method, @NotNull Class exceptionClass, long time) { + return new TestResult(method, false, "expected " + exceptionClass.getName(), null, time); + } + + static TestResult exception(@NotNull Method method, @NotNull Throwable exception, long time) { + return new TestResult(method, false, "exception: ", exception, time); + } + + static TestResult ignored(@NotNull Method method, @NotNull String message) { + return new TestResult(method, true, "ignore. \ncause:" + message, null, 0); + } + + /** + * Prints report of result to out + */ + public void print(PrintStream out) { + out.println("Testing " + method); + if (ok) { + out.println("Ok"); + out.println(message); + } else { + out.println("Fail"); + out.println(message); + if (exception != null) { + exception.printStackTrace(out); + } + } + out.println("time: "+ time + "ms"); + out.println(); + out.println(); + } +} \ No newline at end of file diff --git a/006-Xunit/src/main/java/task/Tester/Tester.java b/006-Xunit/src/main/java/task/Tester/Tester.java new file mode 100644 index 0000000..47a7bec --- /dev/null +++ b/006-Xunit/src/main/java/task/Tester/Tester.java @@ -0,0 +1,146 @@ +package task.Tester; + +import com.google.common.collect.ImmutableList; +import org.jetbrains.annotations.NotNull; +import task.annotations.*; + +import javax.sound.midi.SysexMessage; +import java.lang.annotation.Annotation; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.*; +import java.util.concurrent.Callable; + +/** + * Class for running tests from clazz + */ +public class Tester implements Callable> { + private final static List > supportedAnnotations = ImmutableList.of( + Test.class, + After.class, + Before.class, + AfterClass.class, + BeforeClass.class); + + private final Constructor constructor; + private final Map, ArrayList> annotatedMethods; + + public Tester(@NotNull Class clazz) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { + constructor = clazz.getConstructor(); + + Method[] methods = clazz.getMethods(); + annotatedMethods = new HashMap<>(); + + supportedAnnotations.forEach(clazz1 -> annotatedMethods.put(clazz1, new ArrayList())); + + for (Method method : methods) { + for (Annotation annotation : method.getAnnotations()) { + Class key = annotation.annotationType(); + if (annotatedMethods.get(annotation.annotationType()) != null) { + annotatedMethods.get(key).add(method); + } + } + } + } + + /** + * Runs test class methods of clazz annotated @Test, @Before, @After, @BeforeClass, @AfterClass + * @see Test + * @see Before + * @see After + * @see BeforeClass + * @see AfterClass + */ + public List call() { + List res = new ArrayList<>(); + try { + for (Method method : annotatedMethods.get(BeforeClass.class)) { + if (isStatic(method)) { + runMethodReport(null, method); + } + } + + for (@NotNull Method method : annotatedMethods.get(Test.class)) { + Object test = constructor.newInstance(); + + for (Method method1 : annotatedMethods.get(Before.class)) { + runMethodReport(test, method1); + } + + TestResult testResult = runTest(test, method); + res.add(testResult); + testResult.print(System.out); + + for (Method method1 : annotatedMethods.get(After.class)) { + runMethodReport(test, method1); + } + } + + for (Method method : annotatedMethods.get(AfterClass.class)) { + if (isStatic(method)) { + runMethodReport(null, method); + } + } + + } catch (Throwable throwable) { + throwable.printStackTrace(System.out); + return new ArrayList<>(); + } + return res; + } + + private static void runMethod(Object object, Method method) throws Throwable { + try { + method.invoke(object); + } catch (InvocationTargetException e) { + throw e.getCause(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + + private static void runMethodReport(Object object, Method method) { + try { + runMethod(object, method); + } catch (Throwable e) { + System.out.println("error executing method: " + method); + e.printStackTrace(System.out); + } + } + + private static TestResult runTest(@NotNull Object test, @NotNull Method method) { + @NotNull Test annotation = method.getAnnotation(Test.class); + + if (!Checks.isIgnored(annotation)) { + long startTime = System.currentTimeMillis(); + + Class expectedClass = annotation.exception(); + Throwable throwable = null; + try { + runMethod(test, method); + } catch (Throwable e) { + throwable = e; + } + + long time = System.currentTimeMillis() - startTime; + + if (throwable != null) { + if (!Checks.hasException(annotation) || throwable.getClass() != expectedClass) { + return TestResult.exception(method, throwable, time); + } + } else if (Checks.hasException(annotation)) { + return TestResult.expectedException(method, annotation.exception(), time); + } + + return TestResult.ok(method, time); + } else { + return TestResult.ignored(method, annotation.ignore()); + } + } + + private boolean isStatic(@NotNull Method method) { + return Modifier.isStatic(method.getModifiers()); + } +} diff --git a/006-Xunit/src/main/java/task/Tester/TestsRunner.java b/006-Xunit/src/main/java/task/Tester/TestsRunner.java new file mode 100644 index 0000000..5189a42 --- /dev/null +++ b/006-Xunit/src/main/java/task/Tester/TestsRunner.java @@ -0,0 +1,23 @@ +package task.Tester; + +import org.jetbrains.annotations.NotNull; +import task.classesLoader.Loader; + +import java.lang.reflect.InvocationTargetException; +import java.nio.file.Path; +import java.util.List; + + +public class TestsRunner { + /** + * Runs test classes from path, which are located in package rootPackage + */ + + public static void run(@NotNull Path path, @NotNull String rootPackage) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException { + Loader loader = new Loader(); + List> testClasses = loader.load(path, rootPackage); + for (Class clazz : testClasses) { + new Tester(clazz).call(); + } + } +} diff --git a/006-Xunit/src/main/java/task/annotations/After.java b/006-Xunit/src/main/java/task/annotations/After.java new file mode 100644 index 0000000..753e1b3 --- /dev/null +++ b/006-Xunit/src/main/java/task/annotations/After.java @@ -0,0 +1,14 @@ +package task.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Marks public method, that runs before After every test + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface After { +} diff --git a/006-Xunit/src/main/java/task/annotations/AfterClass.java b/006-Xunit/src/main/java/task/annotations/AfterClass.java new file mode 100644 index 0000000..8934b67 --- /dev/null +++ b/006-Xunit/src/main/java/task/annotations/AfterClass.java @@ -0,0 +1,15 @@ +package task.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Marks public static method, that runs once after all tests tests in class + * @see Test + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface AfterClass { +} diff --git a/006-Xunit/src/main/java/task/annotations/Before.java b/006-Xunit/src/main/java/task/annotations/Before.java new file mode 100644 index 0000000..e871659 --- /dev/null +++ b/006-Xunit/src/main/java/task/annotations/Before.java @@ -0,0 +1,15 @@ +package task.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Marks public method, that runs before every test method + * @see Test + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Before { +} diff --git a/006-Xunit/src/main/java/task/annotations/BeforeClass.java b/006-Xunit/src/main/java/task/annotations/BeforeClass.java new file mode 100644 index 0000000..d6eaf8f --- /dev/null +++ b/006-Xunit/src/main/java/task/annotations/BeforeClass.java @@ -0,0 +1,15 @@ +package task.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Marks public static method, that runs once before all tests tests in class + * @see Test + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface BeforeClass { +} diff --git a/006-Xunit/src/main/java/task/annotations/Checks.java b/006-Xunit/src/main/java/task/annotations/Checks.java new file mode 100644 index 0000000..928880b --- /dev/null +++ b/006-Xunit/src/main/java/task/annotations/Checks.java @@ -0,0 +1,27 @@ +package task.annotations; + +import org.jetbrains.annotations.NotNull; + +/** + * Encapsulates default values for Test + * @see Test + */ +public class Checks { + final static @NotNull String nullString = ""; + final class MyThrowable extends Throwable {} + + /** + * checks is exception set in test + */ + public static boolean hasException(Test test) { + return test.exception() != MyThrowable.class; + } + + /** + * checks is ignored set in test + */ + public static boolean isIgnored(Test test) { + return !test.ignore().equals(nullString); + } + +} diff --git a/006-Xunit/src/main/java/task/annotations/Test.java b/006-Xunit/src/main/java/task/annotations/Test.java new file mode 100644 index 0000000..ad19fe0 --- /dev/null +++ b/006-Xunit/src/main/java/task/annotations/Test.java @@ -0,0 +1,19 @@ +package task.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Marks test method, where + * ignore -- cause of ignore this test, if set execution of test will be denied + * exception -- if set, test pass if and only if that kind exception thrown + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Test { + String ignore() default Checks.nullString; + Class exception() default Checks.MyThrowable.class; +} + diff --git a/006-Xunit/src/main/java/task/classesLoader/Loader.java b/006-Xunit/src/main/java/task/classesLoader/Loader.java new file mode 100644 index 0000000..cea037a --- /dev/null +++ b/006-Xunit/src/main/java/task/classesLoader/Loader.java @@ -0,0 +1,60 @@ +package task.classesLoader; + +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import java.util.Spliterator; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + + +public class Loader { + /** + * Loads classes from path, which are located in package rootPackage + */ + public static List> load(@NotNull final Path path, @NotNull String rootPackage) { + List> classes = new ArrayList<>(); + try { + URL[] urls = new URL[] {path.toUri().toURL()}; + ClassLoader classLoader = new URLClassLoader(urls); + + try { + Files.walk(path).filter(Files::isRegularFile) + .filter(path1 -> path1.toString().endsWith(".class")) + .map(path::relativize) + .map(path1 -> { + String res = StreamSupport.stream(path1.spliterator(), false) + .map(Path::toString) + .collect(Collectors.joining(".")); + res = rootPackage + "." + res.substring(0, res.length() - ".class".length()); + return res; + }) + .forEach((String name) -> { + try { + Class clazz = classLoader.loadClass(name); + classes.add(clazz); + } catch (ClassNotFoundException e) { + // e.printStackTrace(); + } + } + ); + } catch (IOException e) { + e.printStackTrace(); + } + } catch (IOException e) { + e.printStackTrace(); + } + return classes; + } +} diff --git a/006-Xunit/src/test/java/Test.java b/006-Xunit/src/test/java/Test.java new file mode 100644 index 0000000..c2f2fc7 --- /dev/null +++ b/006-Xunit/src/test/java/Test.java @@ -0,0 +1,68 @@ +import task.Tester.TestResult; +import task.Tester.Tester; +import task.Tester.TestsRunner; +import testClasses.*; +import testClasses.package1.TestObjects; + +import java.lang.reflect.InvocationTargetException; +import java.nio.file.Paths; +import java.util.Arrays; + + +import static org.hamcrest.CoreMatchers.*; +import static org.hamcrest.core.IsEqual.equalTo; +import static org.junit.Assert.*; + +public class Test { + @org.junit.Test + public void testTestsRunner() throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException { + TestsRunner.run(Paths.get("./build/classes/test/testClasses"), "testClasses"); + + assertThat(TestMetodOrder.res, is(equalTo(Arrays.asList("BeforeClass", + "Before", + "test", + "After", + "Before", + "test", + "After", + "AfterClass")))); + + assertThat(TestObjects.results, is(equalTo(Arrays.asList(1, 1)))); + } + + @org.junit.Test + public void testException() throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException { + TestResult result = new Tester(TestException.class).call().get(0); + assertThat(result.ok, is(equalTo(false))); + assertThat(result.exception, allOf(is(instanceOf(RuntimeException.class)), not(is(nullValue())))); + } + + @org.junit.Test + public void testExpectedException() throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException { + TestResult result = new Tester(TestExpectedExcetion.class).call().get(0); + assertThat(result.ok, is(equalTo(true))); + assertThat(result.exception, is(nullValue())); + } + + @org.junit.Test + public void testUnexpectedException() throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException { + TestResult result = new Tester(TestUnexpectedExcetion.class).call().get(0); + assertThat(result.ok, is(equalTo(false))); + assertThat(result.exception, allOf(is(instanceOf(UnsupportedOperationException.class)), not(is(nullValue())))); + } + + @org.junit.Test + public void testPassed() throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException { + TestResult result = new Tester(TestPassed.class).call().get(0); + assertThat(result.ok, is(equalTo(true))); + assertThat(result.exception, is(nullValue())); + } + + @org.junit.Test + public void testIgnored() throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException { + TestResult result = new Tester(TestIgnored.class).call().get(0); + assertThat(result.ok, is(equalTo(true))); + assertThat(result.exception, is(nullValue())); + assertThat(result.message, containsString("ignore")); + } +} diff --git a/006-Xunit/src/test/java/testClasses/TestException.java b/006-Xunit/src/test/java/testClasses/TestException.java new file mode 100644 index 0000000..158afd3 --- /dev/null +++ b/006-Xunit/src/test/java/testClasses/TestException.java @@ -0,0 +1,10 @@ +package testClasses; + +import task.annotations.Test; + +public class TestException { + @Test + public void test() { + throw new RuntimeException(); + } +} diff --git a/006-Xunit/src/test/java/testClasses/TestExpectedExcetion.java b/006-Xunit/src/test/java/testClasses/TestExpectedExcetion.java new file mode 100644 index 0000000..040b401 --- /dev/null +++ b/006-Xunit/src/test/java/testClasses/TestExpectedExcetion.java @@ -0,0 +1,10 @@ +package testClasses; + +import task.annotations.Test; + +public class TestExpectedExcetion { + @Test(exception = IllegalArgumentException.class) + public void test() { + throw new IllegalArgumentException(); + } +} diff --git a/006-Xunit/src/test/java/testClasses/TestIgnored.java b/006-Xunit/src/test/java/testClasses/TestIgnored.java new file mode 100644 index 0000000..b7de2ab --- /dev/null +++ b/006-Xunit/src/test/java/testClasses/TestIgnored.java @@ -0,0 +1,14 @@ +package testClasses; + +import task.annotations.Test; + +import java.util.ArrayList; +import java.util.List; + +public class TestIgnored { + @Test(ignore = "ignore") + public void test() { + List list = new ArrayList<>(); + list.get(2); + } +} diff --git a/006-Xunit/src/test/java/testClasses/TestMetodOrder.java b/006-Xunit/src/test/java/testClasses/TestMetodOrder.java new file mode 100644 index 0000000..2149e4f --- /dev/null +++ b/006-Xunit/src/test/java/testClasses/TestMetodOrder.java @@ -0,0 +1,40 @@ +package testClasses; + +import task.annotations.*; + +import java.util.ArrayList; +import java.util.List; + +public class TestMetodOrder { + public static final List res = new ArrayList(); + + @Before + public void before() { + res.add("Before"); + } + + @After + public void after() { + res.add("After"); + } + + @BeforeClass + public static void beforeClass() { + res.add("BeforeClass"); + } + + @AfterClass + public static void afterClass() { + res.add("AfterClass"); + } + + @Test + public void test1() { + res.add("test"); + } + + @Test + public void test2() { + res.add("test"); + } +} diff --git a/006-Xunit/src/test/java/testClasses/TestPassed.java b/006-Xunit/src/test/java/testClasses/TestPassed.java new file mode 100644 index 0000000..272ec11 --- /dev/null +++ b/006-Xunit/src/test/java/testClasses/TestPassed.java @@ -0,0 +1,9 @@ +package testClasses; + +import task.annotations.Test; + +public class TestPassed { + @Test + public void test() { + } +} diff --git a/006-Xunit/src/test/java/testClasses/TestUnexpectedExcetion.java b/006-Xunit/src/test/java/testClasses/TestUnexpectedExcetion.java new file mode 100644 index 0000000..b4e67b1 --- /dev/null +++ b/006-Xunit/src/test/java/testClasses/TestUnexpectedExcetion.java @@ -0,0 +1,10 @@ +package testClasses; + +import task.annotations.Test; + +public class TestUnexpectedExcetion { + @Test(exception = IllegalAccessError.class) + public void test() { + throw new UnsupportedOperationException(); + } +} diff --git a/006-Xunit/src/test/java/testClasses/package1/TestObjects.java b/006-Xunit/src/test/java/testClasses/package1/TestObjects.java new file mode 100644 index 0000000..983e37c --- /dev/null +++ b/006-Xunit/src/test/java/testClasses/package1/TestObjects.java @@ -0,0 +1,21 @@ +package testClasses.package1; + +import task.annotations.Test; + +import java.util.ArrayList; +import java.util.List; + +public class TestObjects { + private int a = 0; + public static final List results = new ArrayList<>(); + + @Test + public void test1() { + results.add(++a); + } + + @Test + public void test2() { + results.add(++a); + } +}