diff --git a/.travis.yml b/.travis.yml index 93fbcdb..a4a95a0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,5 @@ jdk: branches: - /.*/ env: - - PROJECT_DIR=hw01 - - PROJECT_DIR=hw02 - - PROJECT_DIR=hw03 + - PROJECT_DIR=hw10 script: cd $PROJECT_DIR && ./gradlew check diff --git a/hw10/.idea/.name b/hw10/.idea/.name new file mode 100644 index 0000000..7ba62ea --- /dev/null +++ b/hw10/.idea/.name @@ -0,0 +1 @@ +MyJUnit \ No newline at end of file diff --git a/hw10/.idea/gradle.xml b/hw10/.idea/gradle.xml new file mode 100644 index 0000000..f125908 --- /dev/null +++ b/hw10/.idea/gradle.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/hw10/.idea/misc.xml b/hw10/.idea/misc.xml new file mode 100644 index 0000000..29af3ee --- /dev/null +++ b/hw10/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/hw10/.idea/uiDesigner.xml b/hw10/.idea/uiDesigner.xml new file mode 100644 index 0000000..e96534f --- /dev/null +++ b/hw10/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/hw10/.idea/vcs.xml b/hw10/.idea/vcs.xml new file mode 100644 index 0000000..6c0b863 --- /dev/null +++ b/hw10/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/hw10/build.gradle b/hw10/build.gradle new file mode 100644 index 0000000..0ddf1b3 --- /dev/null +++ b/hw10/build.gradle @@ -0,0 +1,33 @@ +plugins { + id 'java' + id 'application' +} + +sourceCompatibility = 11 +mainClassName = 'ru.hse.myjunit.MyJUnit' + +repositories { + mavenCentral() +} + +jar { + baseName = 'MyJUnit' + manifest { + attributes ( + 'Main-Class': 'ru.hse.myjunit.MyJUnit' + ) + } +} + +dependencies { + testCompile('org.junit.jupiter:junit-jupiter-api:5.3.2') + testRuntime('org.junit.jupiter:junit-jupiter-engine:5.3.2') + compile('org.jetbrains:annotations:16.0.2') +} + +test { + useJUnitPlatform() + testLogging { + events 'PASSED', 'FAILED', 'SKIPPED' + } +} \ No newline at end of file diff --git a/hw10/gradle/wrapper/gradle-wrapper.jar b/hw10/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..94336fc Binary files /dev/null and b/hw10/gradle/wrapper/gradle-wrapper.jar differ diff --git a/hw10/gradle/wrapper/gradle-wrapper.properties b/hw10/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..290541c --- /dev/null +++ b/hw10/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/hw10/gradlew b/hw10/gradlew new file mode 100755 index 0000000..cccdd3d --- /dev/null +++ b/hw10/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/hw10/gradlew.bat b/hw10/gradlew.bat new file mode 100644 index 0000000..e95643d --- /dev/null +++ b/hw10/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/hw10/settings.gradle b/hw10/settings.gradle new file mode 100644 index 0000000..f506bf1 --- /dev/null +++ b/hw10/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = 'MyJUnit' + diff --git a/hw10/src/main/java/ru/hse/myjunit/After.java b/hw10/src/main/java/ru/hse/myjunit/After.java new file mode 100644 index 0000000..919834e --- /dev/null +++ b/hw10/src/main/java/ru/hse/myjunit/After.java @@ -0,0 +1,14 @@ +package ru.hse.myjunit; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Methods with this annotation run after every test + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface After { +} diff --git a/hw10/src/main/java/ru/hse/myjunit/AfterClass.java b/hw10/src/main/java/ru/hse/myjunit/AfterClass.java new file mode 100644 index 0000000..768624b --- /dev/null +++ b/hw10/src/main/java/ru/hse/myjunit/AfterClass.java @@ -0,0 +1,14 @@ +package ru.hse.myjunit; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Methods with this annotation run after all tests in declaring class + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface AfterClass { +} diff --git a/hw10/src/main/java/ru/hse/myjunit/Before.java b/hw10/src/main/java/ru/hse/myjunit/Before.java new file mode 100644 index 0000000..b5e9d56 --- /dev/null +++ b/hw10/src/main/java/ru/hse/myjunit/Before.java @@ -0,0 +1,14 @@ +package ru.hse.myjunit; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Methods with this annotation run before every test + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Before { +} diff --git a/hw10/src/main/java/ru/hse/myjunit/BeforeClass.java b/hw10/src/main/java/ru/hse/myjunit/BeforeClass.java new file mode 100644 index 0000000..10cdaea --- /dev/null +++ b/hw10/src/main/java/ru/hse/myjunit/BeforeClass.java @@ -0,0 +1,14 @@ +package ru.hse.myjunit; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Methods with this annotation run before all tests in declaring class + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface BeforeClass { +} diff --git a/hw10/src/main/java/ru/hse/myjunit/MyJUnit.java b/hw10/src/main/java/ru/hse/myjunit/MyJUnit.java new file mode 100644 index 0000000..7080109 --- /dev/null +++ b/hw10/src/main/java/ru/hse/myjunit/MyJUnit.java @@ -0,0 +1,201 @@ +package ru.hse.myjunit; + +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.lang.reflect.InvocationTargetException; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.LinkedList; +import java.util.concurrent.Callable; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.jar.JarFile; + +public final class MyJUnit { + + protected static LinkedList instancesForTest = new LinkedList<>(); + + /** + * Loads test classes from file, path of which is given in first argument + * @param args first argument must be path to .class test file or to .jar, whih contains some .class test files + */ + public static void main(String[] args) { + if (args.length < 1) { + System.out.println("Specify test file"); + return; + } + runAllTests(args[0]); + } + + /** + * Loads classes from given path and runs methods from those classes with annotation Test + * @param path path to .class test file or to .jar, whih contains some .class test files + */ + public static void runAllTests(@NotNull String path) { + instancesForTest.clear(); + + if (path.endsWith(".jar")) { + try { + var jar = new JarFile(path); + var entries = jar.entries(); + URL[] urls = {new URL("jar:file:" + path + "!/")}; + var cl = URLClassLoader.newInstance(urls); + while (entries.hasMoreElements()) { + var entry = entries.nextElement(); + if (entry.isDirectory() || !entry.getName().endsWith(".class")) { + continue; + } + var className = entry.getName().substring(0, entry.getName().length() - 6) + .replace('/', '.'); + try { + runClassTests(cl.loadClass(className)); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + + } + } catch (IOException e) { + e.printStackTrace(); + } + } else if (path.endsWith(".class")) { + var file = new File(path); + try { + URL[] urls = {file.toURI().toURL()}; + var cl = URLClassLoader.newInstance(urls); + var className = file.getName().substring(0, file.getName().length() - 6) + .replace('/', '.'); + System.out.println(className + ":"); + runClassTests(cl.loadClass(className)); + } catch (MalformedURLException | ClassNotFoundException e) { + e.printStackTrace(); + } + } else { + System.out.println("Wrong file format"); + } + } + + private static void runClassTests(Class c) { + if (c.isAnnotation()) { + return; + } + + Object instance = null; + for (var constructor: c.getDeclaredConstructors()) { + try { + instance = constructor.newInstance(); + } catch (InstantiationException | IllegalAccessException | InvocationTargetException ignored) { + } + } + if (instance == null) { + printLine("There is no callable constructor"); + System.out.println(); + return; + } + instancesForTest.add(instance); + + System.out.println(c.getName() + ":"); + System.out.println(); + + var threadPool = Executors.newCachedThreadPool(); + var tasks = new LinkedList>(); + runBeforeOrAfter(c, instance, BeforeClass.class); + for (var method: c.getDeclaredMethods()) { + var annotations = method.getDeclaredAnnotations(); + + boolean run = false; + Object expected = void.class; + String reason = ""; + for (var a: annotations) { + if (a instanceof Test) { + run = true; + reason = ((Test) a).ignore(); + expected = ((Test) a).expected(); + } + } + if (!reason.equals("")) { + printLine("Test '" + method.getName() + "' disabled: " + reason); + System.out.println(); + continue; + } + if (run) { + Object finalInstance = instance; + Object finalExpected = expected; + var task = new Callable() { + @Override + public String call() { + runBeforeOrAfter(c, finalInstance, Before.class); + String result = "Test '" + method.getName() + "' "; + var time = System.currentTimeMillis(); + try { + method.setAccessible(true); + method.invoke(finalInstance, (Object[]) null); + time = System.currentTimeMillis() - time; + result += "passed\n\t"; + } catch (InvocationTargetException e) { + var testException = e.getTargetException(); + time = System.currentTimeMillis() - time; + if (testException.getClass().equals(finalExpected)) { + result += "passed\n\t"; + } else { + result += "failed:\n\t"; + var sw = new StringWriter(); + var pw = new PrintWriter(sw); + testException.printStackTrace(pw); + result += sw.toString().replace("\n", "\n\t"); + } + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + runBeforeOrAfter(c, finalInstance, After.class); + result += "Time: "; + result += String.valueOf(time); + result += "ms"; + return result; + } + }; + tasks.add(threadPool.submit(task)); + } + } + threadPool.shutdown(); + for (var task: tasks) { + try { + printLine(task.get()); + } catch (Exception e) { + e.printStackTrace(); + } + System.out.println(); + } + runBeforeOrAfter(c, instance, AfterClass.class); + } + + private static void runBeforeOrAfter(Class c, Object instance, Class expected) { + for (var method: c.getDeclaredMethods()) { + var annotations = method.getDeclaredAnnotations(); + boolean run = false; + for (var a: annotations) { + if (expected.isAssignableFrom(a.getClass())) { + run = true; + } + } + if (run) { + try { + method.setAccessible(true); + method.invoke(instance, (Object[]) null); + } catch (InvocationTargetException e) { + e.getTargetException().printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + } + } + + private static void printLine(String s) { + System.out.println("\t" + s); + } +} \ No newline at end of file diff --git a/hw10/src/main/java/ru/hse/myjunit/Test.java b/hw10/src/main/java/ru/hse/myjunit/Test.java new file mode 100644 index 0000000..45fbea2 --- /dev/null +++ b/hw10/src/main/java/ru/hse/myjunit/Test.java @@ -0,0 +1,25 @@ +package ru.hse.myjunit; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Methods with this annotation are treated as tests + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Test { + /** + * Expected exception class + * @return expected exception class or void.class if not expected + */ + Class expected() default void.class; + + /** + * Reason for disabled tests + * @return reason for disabled tests or empty string for enabled + */ + String ignore() default ""; +} \ No newline at end of file diff --git a/hw10/src/test/java/ru/hse/myjunit/MyJUnitTest.java b/hw10/src/test/java/ru/hse/myjunit/MyJUnitTest.java new file mode 100644 index 0000000..3d2d97d --- /dev/null +++ b/hw10/src/test/java/ru/hse/myjunit/MyJUnitTest.java @@ -0,0 +1,33 @@ +package ru.hse.myjunit; + +import org.junit.jupiter.api.Test; + +import java.io.IOException; + +import ru.hse.myjunit.example.*; + +import static org.junit.jupiter.api.Assertions.*; + +class MyJUnitTest { + + @Test + void testMyJUnitUsingJarFile() throws IOException, InterruptedException, NoSuchFieldException, IllegalAccessException { + var path = "src/test/java/ru/hse/myjunit/example/*.java"; + var pb = new ProcessBuilder("bash", "-c", "javac -d . " + path); + pb.start().waitFor(); + pb = new ProcessBuilder("bash", "-c", "jar cvf Classes.jar ru"); + pb.start().waitFor(); + MyJUnit.runAllTests("Classes.jar"); + for (var o: MyJUnit.instancesForTest) { + if (o.getClass().getName().endsWith("Example")) { + var c = o.getClass(); + assertEquals(c.getField("acExpected").getInt(o), c.getField("ac").getInt(o)); + assertEquals(c.getField("bcExpected").getInt(o), c.getField("bc").getInt(o)); + assertEquals(c.getField("aExpected").getInt(o), c.getField("a").getInt(o)); + assertEquals(c.getField("bExpected").getInt(o), c.getField("b").getInt(o)); + assertEquals(c.getField("tExpected").getInt(o), c.getField("t").getInt(o)); + } + } + } + +} \ No newline at end of file diff --git a/hw10/src/test/java/ru/hse/myjunit/example/Example.java b/hw10/src/test/java/ru/hse/myjunit/example/Example.java new file mode 100644 index 0000000..e22b165 --- /dev/null +++ b/hw10/src/test/java/ru/hse/myjunit/example/Example.java @@ -0,0 +1,75 @@ +package ru.hse.myjunit.example; + +import ru.hse.myjunit.*; + +public class Example { + + public int bcExpected = 2; + public int acExpected = 2; + public int bExpected = 3; + public int aExpected = 3; + public int tExpected = 3; + + public int bc = 0; + public int ac = 0; + public int b = 0; + public int a = 0; + public int t = 0; + + @BeforeClass + void before1() { + bc++; + } + + @BeforeClass + void before2() { + bc++; + } + + @AfterClass + void after1() { + ac++; + } + + @AfterClass + void after2() { + ac++; + } + + @Before + synchronized void before() { + b++; + } + + @After + synchronized void after() { + a++; + } + + @Test(expected = ArithmeticException.class) + synchronized void test1() { + t++; + int x = 1 / 0; + } + + @Test(ignore = "Some reason") + synchronized void test2() { + t++; + } + + @Test + synchronized void test3() { + int d = 1; + for (int i = 1; i < 1000000; i++) { + d *= i; + } + t++; + } + + @Test + synchronized void test4() { + t++; + assert(0 == 1); + } + +} \ No newline at end of file