Skip to content

Commit 6615996

Browse files
authored
Merge pull request #5 from m0rk4/enumsandannotations-6
6: Use Enums instead of int constants
2 parents 6d5be4f + fc4cd53 commit 6615996

File tree

27 files changed

+852
-0
lines changed

27 files changed

+852
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package by.morka.effective.java.enumsandannotations.annotationsovernamingconventions.annotationwitharrayparameter;
2+
3+
import java.lang.annotation.ElementType;
4+
import java.lang.annotation.Retention;
5+
import java.lang.annotation.RetentionPolicy;
6+
import java.lang.annotation.Target;
7+
8+
// Annotation type with an array parameter
9+
@Retention(RetentionPolicy.RUNTIME)
10+
@Target(ElementType.METHOD)
11+
public @interface ExceptionTest {
12+
Class<? extends Exception>[] value();
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package by.morka.effective.java.enumsandannotations.annotationsovernamingconventions.annotationwitharrayparameter;
2+
3+
import by.morka.effective.java.enumsandannotations.annotationsovernamingconventions.markerannotation.Test;
4+
5+
import java.lang.reflect.InvocationTargetException;
6+
import java.lang.reflect.Method;
7+
8+
// Program to process marker annotations and annotations with array parameter
9+
public class RunTests {
10+
public static void main(String[] args) throws Exception {
11+
int tests = 0;
12+
int passed = 0;
13+
Class<?> testClass = Class.forName(args[0]);
14+
for (Method m : testClass.getDeclaredMethods()) {
15+
if (m.isAnnotationPresent(Test.class)) {
16+
tests++;
17+
try {
18+
m.invoke(null);
19+
passed++;
20+
} catch (InvocationTargetException wrappedExc) {
21+
Throwable exc = wrappedExc.getCause();
22+
System.out.println(m + " failed: " + exc);
23+
} catch (Exception exc) {
24+
System.out.println("Invalid @Test: " + m);
25+
}
26+
}
27+
28+
// Code to process annotations with array parameter (Page 185)
29+
if (m.isAnnotationPresent(ExceptionTest.class)) {
30+
tests++;
31+
try {
32+
m.invoke(null);
33+
System.out.printf("Test %s failed: no exception%n", m);
34+
} catch (Throwable wrappedExc) {
35+
Throwable exc = wrappedExc.getCause();
36+
int oldPassed = passed;
37+
Class<? extends Throwable>[] excTypes =
38+
m.getAnnotation(ExceptionTest.class).value();
39+
for (Class<? extends Throwable> excType : excTypes) {
40+
if (excType.isInstance(exc)) {
41+
passed++;
42+
break;
43+
}
44+
}
45+
if (passed == oldPassed)
46+
System.out.printf("Test %s failed: %s %n", m, exc);
47+
}
48+
}
49+
}
50+
System.out.printf("Passed: %d, Failed: %d%n",
51+
passed, tests - passed);
52+
}
53+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package by.morka.effective.java.enumsandannotations.annotationsovernamingconventions.annotationwitharrayparameter;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
6+
// Program containing an annotation with an array parameter
7+
public class Sample3 {
8+
// This variant can process annotations whose parameter is a single element
9+
@ExceptionTest(ArithmeticException.class)
10+
public static void m1() { // Test should pass
11+
int i = 0;
12+
i = i / i;
13+
}
14+
15+
@ExceptionTest(ArithmeticException.class)
16+
public static void m2() { // Should fail (wrong exception)
17+
int[] a = new int[0];
18+
int i = a[1];
19+
}
20+
21+
@ExceptionTest(ArithmeticException.class)
22+
public static void m3() {
23+
} // Should fail (no exception)
24+
25+
// Code containing an annotation with an array parameter
26+
@ExceptionTest({IndexOutOfBoundsException.class,
27+
NullPointerException.class})
28+
public static void doublyBad() { // Should pass
29+
List<String> list = new ArrayList<>();
30+
31+
// The spec permits this method to throw either
32+
// IndexOutOfBoundsException or NullPointerException
33+
list.addAll(5, null);
34+
}
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package by.morka.effective.java.enumsandannotations.annotationsovernamingconventions.annotationwithparameter;
2+
3+
// Annotation type with a parameter
4+
5+
import java.lang.annotation.ElementType;
6+
import java.lang.annotation.Retention;
7+
import java.lang.annotation.RetentionPolicy;
8+
import java.lang.annotation.Target;
9+
10+
/**
11+
* Indicates that the annotated method is a test method that
12+
* must throw the designated exception to succeed.
13+
*/
14+
@Retention(RetentionPolicy.RUNTIME)
15+
@Target(ElementType.METHOD)
16+
public @interface ExceptionTest {
17+
Class<? extends Throwable> value();
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package by.morka.effective.java.enumsandannotations.annotationsovernamingconventions.annotationwithparameter;
2+
3+
import by.morka.effective.java.enumsandannotations.annotationsovernamingconventions.markerannotation.Test;
4+
5+
import java.lang.reflect.InvocationTargetException;
6+
import java.lang.reflect.Method;
7+
8+
// Program to process marker annotations and annotations with a parameter (Page 184)
9+
public class RunTests {
10+
public static void main(String[] args) throws Exception {
11+
int tests = 0;
12+
int passed = 0;
13+
Class<?> testClass = Class.forName(args[0]);
14+
for (Method m : testClass.getDeclaredMethods()) {
15+
if (m.isAnnotationPresent(Test.class)) {
16+
tests++;
17+
try {
18+
m.invoke(null);
19+
passed++;
20+
} catch (InvocationTargetException wrappedExc) {
21+
Throwable exc = wrappedExc.getCause();
22+
System.out.println(m + " failed: " + exc);
23+
} catch (Exception exc) {
24+
System.out.println("Invalid @Test: " + m);
25+
}
26+
}
27+
28+
if (m.isAnnotationPresent(ExceptionTest.class)) {
29+
tests++;
30+
try {
31+
m.invoke(null);
32+
System.out.printf("Test %s failed: no exception%n", m);
33+
} catch (InvocationTargetException wrappedEx) {
34+
Throwable exc = wrappedEx.getCause();
35+
Class<? extends Throwable> excType =
36+
m.getAnnotation(ExceptionTest.class).value();
37+
if (excType.isInstance(exc)) {
38+
passed++;
39+
} else {
40+
System.out.printf(
41+
"Test %s failed: expected %s, got %s%n",
42+
m, excType.getName(), exc);
43+
}
44+
} catch (Exception exc) {
45+
System.out.println("Invalid @ExceptionTest: " + m);
46+
}
47+
}
48+
}
49+
50+
System.out.printf("Passed: %d, Failed: %d%n",
51+
passed, tests - passed);
52+
}
53+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package by.morka.effective.java.enumsandannotations.annotationsovernamingconventions.annotationwithparameter;
2+
3+
// Program containing annotations with a parameter (Page 183)
4+
public class Sample2 {
5+
@ExceptionTest(ArithmeticException.class)
6+
public static void m1() { // Test should pass
7+
int i = 0;
8+
i = i / i;
9+
}
10+
11+
@ExceptionTest(ArithmeticException.class)
12+
public static void m2() { // Should fail (wrong exception)
13+
int[] a = new int[0];
14+
int i = a[1];
15+
}
16+
17+
@ExceptionTest(ArithmeticException.class)
18+
public static void m3() {
19+
} // Should fail (no exception)
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package by.morka.effective.java.enumsandannotations.annotationsovernamingconventions.markerannotation;
2+
3+
// Program to process marker annotations (Page 182)
4+
5+
import java.lang.reflect.*;
6+
7+
public class RunTests {
8+
public static void main(String[] args) throws Exception {
9+
int tests = 0;
10+
int passed = 0;
11+
Class<?> testClass = Class.forName(args[0]);
12+
for (Method m : testClass.getDeclaredMethods()) {
13+
if (m.isAnnotationPresent(Test.class)) {
14+
tests++;
15+
try {
16+
m.invoke(null);
17+
passed++;
18+
} catch (InvocationTargetException wrappedExc) {
19+
Throwable exc = wrappedExc.getCause();
20+
System.out.println(m + " failed: " + exc);
21+
} catch (Exception exc) {
22+
System.out.println("Invalid @Test: " + m);
23+
}
24+
}
25+
}
26+
System.out.printf("Passed: %d, Failed: %d%n",
27+
passed, tests - passed);
28+
}
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package by.morka.effective.java.enumsandannotations.annotationsovernamingconventions.markerannotation;
2+
3+
// Program containing marker annotations (Page 181)
4+
public class Sample {
5+
@Test
6+
public static void m1() {
7+
} // Test should pass
8+
9+
public static void m2() {
10+
}
11+
12+
@Test
13+
public static void m3() { // Test should fail
14+
throw new RuntimeException("Boom");
15+
}
16+
17+
public static void m4() {
18+
} // Not a test
19+
20+
@Test
21+
public void m5() {
22+
} // INVALID USE: nonstatic method
23+
24+
public static void m6() {
25+
}
26+
27+
@Test
28+
public static void m7() { // Test should fail
29+
throw new RuntimeException("Crash");
30+
}
31+
32+
public static void m8() {
33+
}
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package by.morka.effective.java.enumsandannotations.annotationsovernamingconventions.markerannotation;
2+
3+
import java.lang.annotation.ElementType;
4+
import java.lang.annotation.Retention;
5+
import java.lang.annotation.RetentionPolicy;
6+
import java.lang.annotation.Target;
7+
8+
// Marker annotation type declaration (Page 180)
9+
10+
/**
11+
* Indicates that the annotated method is a test method.
12+
* Use only on parameterless static methods.
13+
*/
14+
@Retention(RetentionPolicy.RUNTIME)
15+
@Target(ElementType.METHOD)
16+
public @interface Test {
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package by.morka.effective.java.enumsandannotations.annotationsovernamingconventions.repeatableannotation;
2+
3+
import java.lang.annotation.*;
4+
5+
// Repeatable annotation type (Page 186)
6+
@Retention(RetentionPolicy.RUNTIME)
7+
@Target(ElementType.METHOD)
8+
@Repeatable(ExceptionTestContainer.class)
9+
public @interface ExceptionTest {
10+
Class<? extends Throwable> value();
11+
}

0 commit comments

Comments
 (0)