1
2
3
4
5
6
7
8
9
10
11
12
13
14 package ch.qos.logback.classic.spi;
15
16 import ch.qos.logback.classic.ClassicConstants;
17 import org.junit.jupiter.api.Test;
18
19 import java.io.ByteArrayInputStream;
20 import java.io.ByteArrayOutputStream;
21 import java.io.IOException;
22 import java.io.ObjectInputStream;
23 import java.io.ObjectOutputStream;
24
25 import static org.junit.jupiter.api.Assertions.assertEquals;
26 import static org.junit.jupiter.api.Assertions.assertNotEquals;
27 import static org.junit.jupiter.api.Assertions.assertNotNull;
28 import static org.junit.jupiter.api.Assertions.assertSame;
29 import static org.junit.jupiter.api.Assertions.assertThrows;
30 import static org.junit.jupiter.api.Assertions.assertTrue;
31
32 public class StackTraceElementProxyTest {
33
34 @Test
35 public void nullStackTraceElementIsReplacedByNASubstitute() {
36 StackTraceElementProxy step = new StackTraceElementProxy(null);
37
38 assertNotNull(step.getStackTraceElement());
39 assertSame(StackTraceElementProxy.NA_SUBSTITUTE, step.getStackTraceElement());
40
41 StackTraceElement ste = step.getStackTraceElement();
42 assertEquals(ClassicConstants.DECLARING_CLASS_NA, ste.getClassName());
43 assertEquals(ClassicConstants.METHOD_NAME_NA, ste.getMethodName());
44 assertEquals(ClassicConstants.FILENAME_NA, ste.getFileName());
45 assertEquals(ClassicConstants.LINE_NUMBER_NA, ste.getLineNumber());
46 }
47
48 @Test
49 public void getSTEAsStringWorksWithNullInput() {
50 StackTraceElementProxy step = new StackTraceElementProxy(null);
51 String steAsString = step.getSTEAsString();
52 assertNotNull(steAsString);
53 assertTrue(steAsString.startsWith("at "));
54 assertTrue(steAsString.contains(ClassicConstants.DECLARING_CLASS_NA));
55 assertTrue(steAsString.contains(ClassicConstants.METHOD_NAME_NA));
56 }
57
58 @Test
59 public void toStringWorksWithNullInput() {
60 StackTraceElementProxy step = new StackTraceElementProxy(null);
61 assertEquals(step.getSTEAsString(), step.toString());
62 }
63
64 @Test
65 public void hashCodeAndEqualsWorkWithNullInput() {
66 StackTraceElementProxy step1 = new StackTraceElementProxy(null);
67 StackTraceElementProxy step2 = new StackTraceElementProxy(null);
68
69 assertEquals(step1, step2);
70 assertEquals(step1.hashCode(), step2.hashCode());
71
72 StackTraceElement realSTE = new StackTraceElement("com.example.Foo", "bar", "Foo.java", 42);
73 StackTraceElementProxy step3 = new StackTraceElementProxy(realSTE);
74
75 assertNotEquals(step1, step3);
76 assertNotEquals(step1.hashCode(), step3.hashCode());
77 }
78
79 @Test
80 public void equalsHandlesNullAndDifferentClass() {
81 StackTraceElementProxy step = new StackTraceElementProxy(null);
82 assertNotEquals(null, step);
83 assertEquals(step, step);
84 }
85
86 @Test
87 public void normalNonNullStackTraceElement() {
88 StackTraceElement realSTE = new StackTraceElement("com.example.MyClass", "doSomething", "MyClass.java", 123);
89 StackTraceElementProxy step = new StackTraceElementProxy(realSTE);
90
91 assertSame(realSTE, step.getStackTraceElement());
92 assertTrue(step.getSTEAsString().startsWith("at com.example.MyClass.doSomething(MyClass.java:123)"));
93 assertEquals(step.getSTEAsString(), step.toString());
94 }
95
96 @Test
97 public void classPackagingData() {
98 StackTraceElementProxy step = new StackTraceElementProxy(null);
99
100 assertEquals(null, step.getClassPackagingData());
101
102 ClassPackagingData cpd = new ClassPackagingData("some.jar", "1.0", true);
103 step.setClassPackagingData(cpd);
104 assertSame(cpd, step.getClassPackagingData());
105
106
107 assertThrows(IllegalStateException.class, () -> step.setClassPackagingData(new ClassPackagingData("x", "y")));
108
109
110 StackTraceElementProxy step2 = new StackTraceElementProxy(null);
111 step2.setClassPackagingData(new ClassPackagingData("some.jar", "1.0", true));
112 assertEquals(step, step2);
113
114 StackTraceElementProxy step3 = new StackTraceElementProxy(null);
115 step3.setClassPackagingData(new ClassPackagingData("other.jar", "2.0", false));
116 assertNotEquals(step, step3);
117 }
118
119 @Test
120 public void serializationRoundTripPreservesBehavior() throws IOException, ClassNotFoundException {
121
122 StackTraceElement realSTE = new StackTraceElement("p.q.R", "m", "R.java", 7);
123 StackTraceElementProxy original = new StackTraceElementProxy(realSTE);
124 original.setClassPackagingData(new ClassPackagingData("loc", "ver"));
125 String originalAsString = original.getSTEAsString();
126
127 StackTraceElementProxy deserialized = roundTripSerialize(original);
128 assertEquals(original, deserialized);
129 assertEquals(originalAsString, deserialized.getSTEAsString());
130 assertEquals(original.getClassPackagingData(), deserialized.getClassPackagingData());
131
132
133 StackTraceElementProxy originalNull = new StackTraceElementProxy(null);
134 String originalNullAsString = originalNull.getSTEAsString();
135
136 StackTraceElementProxy deserializedNull = roundTripSerialize(originalNull);
137 assertEquals(originalNull, deserializedNull);
138 assertEquals(StackTraceElementProxy.NA_SUBSTITUTE, deserializedNull.getStackTraceElement());
139 assertEquals(originalNullAsString, deserializedNull.getSTEAsString());
140 }
141
142 private StackTraceElementProxy roundTripSerialize(StackTraceElementProxy input) throws IOException, ClassNotFoundException {
143 ByteArrayOutputStream bos = new ByteArrayOutputStream();
144 try (ObjectOutputStream oos = new ObjectOutputStream(bos)) {
145 oos.writeObject(input);
146 }
147 try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()))) {
148 return (StackTraceElementProxy) ois.readObject();
149 }
150 }
151 }