1 |
| |
2 |
| |
3 |
| |
4 |
| |
5 |
| |
6 |
| |
7 |
| |
8 |
| |
9 |
| |
10 |
| |
11 |
| |
12 |
| |
13 |
| |
14 |
| |
15 |
| |
16 |
| |
17 |
| |
18 |
| |
19 |
| |
20 |
| |
21 |
| |
22 |
| |
23 |
| |
24 |
| |
25 |
| |
26 |
| |
27 |
| |
28 |
| |
29 |
| |
30 |
| |
31 |
| |
32 |
| |
33 |
| package com.jeantessier.classreader.impl; |
34 |
| |
35 |
| import org.jmock.*; |
36 |
| import org.jmock.api.*; |
37 |
| import org.jmock.integration.junit3.*; |
38 |
| import org.jmock.lib.action.*; |
39 |
| import org.jmock.lib.legacy.*; |
40 |
| |
41 |
| import com.jeantessier.classreader.*; |
42 |
| |
43 |
| public class TestInstruction extends MockObjectTestCase { |
44 |
| private static final byte ICONST_0_INSTRUCTION = (byte) 0x03; |
45 |
| private static final byte LDC_INSTRUCTION = (byte) 0x12; |
46 |
| private static final byte ILOAD_INSTRUCTION = (byte) 0x15; |
47 |
| private static final byte ISTORE_INSTRUCTION = (byte) 0x36; |
48 |
| private static final byte WIDE_INSTRUCTION = (byte) 0xc4; |
49 |
| private static final byte INDEX = (byte) 0x02; |
50 |
| private static final int START_PC = 0; |
51 |
| private static final int LENGTH = 10; |
52 |
| |
53 |
| private Code_attribute mockCode_attribute; |
54 |
| |
55 |
19
| protected void setUp() throws Exception {
|
56 |
19
| super.setUp();
|
57 |
| |
58 |
19
| setImposteriser(ClassImposteriser.INSTANCE);
|
59 |
| |
60 |
19
| mockCode_attribute = mock(Code_attribute.class);
|
61 |
| } |
62 |
| |
63 |
1
| public void testEquals_Same() {
|
64 |
1
| Instruction sut = new Instruction(mockCode_attribute, null, 0);
|
65 |
1
| assertTrue(sut.equals(sut));
|
66 |
| } |
67 |
| |
68 |
1
| public void testEquals_DifferentClasses() {
|
69 |
1
| Instruction sut = new Instruction(mockCode_attribute, null, 0);
|
70 |
1
| Object other = new Object();
|
71 |
| |
72 |
1
| assertFalse(sut.equals(other));
|
73 |
1
| assertFalse(other.equals(sut));
|
74 |
| } |
75 |
| |
76 |
1
| public void testEquals_Identical() {
|
77 |
1
| final ConstantPool mockConstantPool = mock(ConstantPool.class);
|
78 |
1
| final ConstantPoolEntry mockEntry = mock(ConstantPoolEntry.class);
|
79 |
| |
80 |
1
| byte[] code = new byte[] {LDC_INSTRUCTION, INDEX};
|
81 |
| |
82 |
1
| Instruction sut = new Instruction(mockCode_attribute, code, 0);
|
83 |
1
| Instruction other = new Instruction(mockCode_attribute, code, 0);
|
84 |
| |
85 |
1
| checking(new Expectations() {{
|
86 |
1
| atLeast(2).of (mockCode_attribute).getConstantPool();
|
87 |
1
| will(returnValue(mockConstantPool));
|
88 |
1
| atLeast(2).of (mockConstantPool).get(INDEX);
|
89 |
1
| will(returnValue(mockEntry));
|
90 |
| }}); |
91 |
| |
92 |
1
| assertTrue(sut.equals(other));
|
93 |
1
| assertTrue(other.equals(sut));
|
94 |
| } |
95 |
| |
96 |
1
| public void testEquals_DifferentOpCode() {
|
97 |
1
| byte[] code1 = new byte[] {(byte) 0xAC};
|
98 |
1
| byte[] code2 = new byte[] {(byte) 0xAD};
|
99 |
| |
100 |
1
| Instruction sut = new Instruction(mockCode_attribute, code1, 0);
|
101 |
1
| Instruction other = new Instruction(mockCode_attribute, code2, 0);
|
102 |
| |
103 |
1
| assertFalse("different opcode", sut.equals(other));
|
104 |
1
| assertFalse("different opcode", other.equals(sut));
|
105 |
| } |
106 |
| |
107 |
1
| public void testEquals_Offset() {
|
108 |
1
| final ConstantPool mockConstantPool = mock(ConstantPool.class);
|
109 |
1
| final ConstantPoolEntry mockEntry = mock(ConstantPoolEntry.class);
|
110 |
| |
111 |
1
| byte[] code2 = new byte[] {LDC_INSTRUCTION, INDEX};
|
112 |
1
| byte[] code3 = new byte[] {(byte) 0xB6, (byte) 0x00, (byte) 0xFF, LDC_INSTRUCTION, INDEX};
|
113 |
| |
114 |
| |
115 |
1
| Instruction sut = new Instruction(mockCode_attribute, code2, 0);
|
116 |
1
| Instruction other = new Instruction(mockCode_attribute, code3, 3);
|
117 |
| |
118 |
1
| checking(new Expectations() {{
|
119 |
1
| atLeast(2).of (mockCode_attribute).getConstantPool();
|
120 |
1
| will(returnValue(mockConstantPool));
|
121 |
1
| atLeast(2).of (mockConstantPool).get(INDEX);
|
122 |
1
| will(returnValue(mockEntry));
|
123 |
| }}); |
124 |
| |
125 |
1
| assertTrue(sut.equals(other));
|
126 |
1
| assertTrue(other.equals(sut));
|
127 |
| } |
128 |
| |
129 |
1
| public void testEquals_DifferentIndex_SameValue() {
|
130 |
1
| final ConstantPool mockConstantPool = mock(ConstantPool.class);
|
131 |
1
| final ConstantPoolEntry mockEntry = mock(ConstantPoolEntry.class);
|
132 |
| |
133 |
1
| byte[] code2 = new byte[] {LDC_INSTRUCTION, INDEX};
|
134 |
1
| byte[] code5 = new byte[] {LDC_INSTRUCTION, INDEX + 1};
|
135 |
| |
136 |
1
| Instruction sut = new Instruction(mockCode_attribute, code2, 0);
|
137 |
1
| Instruction other = new Instruction(mockCode_attribute, code5, 0);
|
138 |
| |
139 |
1
| checking(new Expectations() {{
|
140 |
1
| atLeast(2).of (mockCode_attribute).getConstantPool();
|
141 |
1
| will(returnValue(mockConstantPool));
|
142 |
1
| atLeast(1).of (mockConstantPool).get(INDEX);
|
143 |
1
| will(returnValue(mockEntry));
|
144 |
1
| atLeast(1).of (mockConstantPool).get(INDEX + 1);
|
145 |
1
| will(returnValue(mockEntry));
|
146 |
| }}); |
147 |
| |
148 |
1
| assertTrue(sut.equals(other));
|
149 |
1
| assertTrue(other.equals(sut));
|
150 |
| } |
151 |
| |
152 |
1
| public void testEquals_DifferentIndex_DifferentValue() {
|
153 |
1
| final ConstantPool mockConstantPool = mock(ConstantPool.class);
|
154 |
1
| final ConstantPoolEntry mockEntry1 = mock(ConstantPoolEntry.class, "SUT entry");
|
155 |
1
| final ConstantPoolEntry mockEntry2 = mock(ConstantPoolEntry.class, "other entry");
|
156 |
| |
157 |
1
| byte[] code2 = new byte[] {LDC_INSTRUCTION, INDEX};
|
158 |
1
| byte[] code5 = new byte[] {LDC_INSTRUCTION, INDEX + 1};
|
159 |
| |
160 |
1
| Instruction sut = new Instruction(mockCode_attribute, code2, 0);
|
161 |
1
| Instruction other = new Instruction(mockCode_attribute, code5, 0);
|
162 |
| |
163 |
1
| checking(new Expectations() {{
|
164 |
1
| atLeast(2).of (mockCode_attribute).getConstantPool();
|
165 |
1
| will(returnValue(mockConstantPool));
|
166 |
1
| atLeast(1).of (mockConstantPool).get(INDEX);
|
167 |
1
| will(returnValue(mockEntry1));
|
168 |
1
| atLeast(1).of (mockConstantPool).get(INDEX + 1);
|
169 |
1
| will(returnValue(mockEntry2));
|
170 |
| }}); |
171 |
| |
172 |
1
| assertFalse(sut.equals(other));
|
173 |
1
| assertFalse(other.equals(sut));
|
174 |
| } |
175 |
| |
176 |
1
| public void testEquals_DifferentCode_attribute() {
|
177 |
1
| final ConstantPool mockConstantPool1 = mock(ConstantPool.class, "SUT constant pool");
|
178 |
1
| final ConstantPool mockConstantPool2 = mock(ConstantPool.class, "other constant pool");
|
179 |
1
| final ConstantPoolEntry mockEntry1 = mock(ConstantPoolEntry.class, "SUT entry");
|
180 |
1
| final ConstantPoolEntry mockEntry2 = mock(ConstantPoolEntry.class, "other entry");
|
181 |
1
| final Code_attribute otherCode_attribute = mock(Code_attribute.class, "other");
|
182 |
| |
183 |
1
| byte[] code = new byte[] {LDC_INSTRUCTION, INDEX};
|
184 |
| |
185 |
1
| checking(new Expectations() {{
|
186 |
1
| atLeast(1).of (mockCode_attribute).getConstantPool();
|
187 |
1
| will(returnValue(mockConstantPool1));
|
188 |
1
| atLeast(1).of (mockConstantPool1).get(INDEX);
|
189 |
1
| will(returnValue(mockEntry1));
|
190 |
1
| atLeast(1).of (otherCode_attribute).getConstantPool();
|
191 |
1
| will(returnValue(mockConstantPool2));
|
192 |
1
| atLeast(1).of (mockConstantPool2).get(INDEX);
|
193 |
1
| will(returnValue(mockEntry2));
|
194 |
| }}); |
195 |
| |
196 |
1
| Instruction sut = new Instruction(mockCode_attribute, code, 0);
|
197 |
1
| Instruction other = new Instruction(otherCode_attribute, code, 0);
|
198 |
| |
199 |
1
| assertFalse(sut.equals(other));
|
200 |
1
| assertFalse(other.equals(sut));
|
201 |
| } |
202 |
| |
203 |
1
| public void testGetIndexedConstantPoolEntry() {
|
204 |
1
| final ConstantPool mockConstantPool = mock(ConstantPool.class);
|
205 |
1
| final ConstantPoolEntry mockEntry = mock(ConstantPoolEntry.class);
|
206 |
| |
207 |
1
| checking (new Expectations() {{
|
208 |
1
| one (mockCode_attribute).getConstantPool();
|
209 |
1
| will(returnValue(mockConstantPool));
|
210 |
1
| one (mockConstantPool).get(INDEX);
|
211 |
1
| will(returnValue(mockEntry));
|
212 |
| }}); |
213 |
| |
214 |
1
| byte[] bytecode = new byte[] {LDC_INSTRUCTION, INDEX};
|
215 |
| |
216 |
1
| Instruction sut = new Instruction(mockCode_attribute, bytecode, 0);
|
217 |
1
| ConstantPoolEntry actualEntry = (ConstantPoolEntry) sut.getIndexedConstantPoolEntry();
|
218 |
1
| assertSame(mockEntry, actualEntry);
|
219 |
| } |
220 |
| |
221 |
1
| public void testGetIndexedLocalVariable_NotMatchingIndex() {
|
222 |
1
| final LocalVariable mockLocalVariable = mock(LocalVariable.class);
|
223 |
| |
224 |
1
| checking(new Expectations() {{
|
225 |
1
| one (mockCode_attribute).accept(with(any(LocalVariableFinder.class)));
|
226 |
1
| will(visitLocalVariable(mockLocalVariable));
|
227 |
1
| one (mockLocalVariable).getIndex();
|
228 |
1
| will(returnValue(INDEX + 1));
|
229 |
| }}); |
230 |
| |
231 |
1
| byte[] bytecode = {ILOAD_INSTRUCTION, INDEX};
|
232 |
| |
233 |
1
| Instruction sut = new Instruction(mockCode_attribute, bytecode, 0);
|
234 |
| |
235 |
1
| LocalVariable actualLocalVariable = (LocalVariable) sut.getIndexedLocalVariable();
|
236 |
1
| assertNull(actualLocalVariable);
|
237 |
| } |
238 |
| |
239 |
1
| public void testGetIndexedLocalVariable_LoadInstructionInsideMatchingIndexMatchingPcRange() {
|
240 |
1
| final LocalVariable mockLocalVariable = mock(LocalVariable.class);
|
241 |
| |
242 |
1
| final byte[] bytecode = {ILOAD_INSTRUCTION, INDEX};
|
243 |
| |
244 |
1
| checking(new Expectations() {{
|
245 |
1
| one (mockCode_attribute).accept(with(any(LocalVariableFinder.class)));
|
246 |
1
| will(visitLocalVariable(mockLocalVariable));
|
247 |
1
| one (mockLocalVariable).getIndex();
|
248 |
1
| will(returnValue((int) INDEX));
|
249 |
1
| atLeast(1).of (mockLocalVariable).getStartPC();
|
250 |
1
| will(returnValue(START_PC));
|
251 |
1
| atLeast(1).of (mockLocalVariable).getLength();
|
252 |
1
| will(returnValue(LENGTH));
|
253 |
| }}); |
254 |
| |
255 |
1
| Instruction sut = new Instruction(mockCode_attribute, bytecode, 0);
|
256 |
| |
257 |
1
| LocalVariable actualLocalVariable = (LocalVariable) sut.getIndexedLocalVariable();
|
258 |
1
| assertSame(mockLocalVariable, actualLocalVariable);
|
259 |
| } |
260 |
| |
261 |
1
| public void testGetIndexedLocalVariable_LoadInstructionImmediatelyBeforePcRange() {
|
262 |
1
| final LocalVariable mockLocalVariable = mock(LocalVariable.class);
|
263 |
| |
264 |
1
| final byte[] bytecode = {ILOAD_INSTRUCTION, INDEX};
|
265 |
| |
266 |
1
| checking(new Expectations() {{
|
267 |
1
| one (mockCode_attribute).accept(with(any(LocalVariableFinder.class)));
|
268 |
1
| will(visitLocalVariable(mockLocalVariable));
|
269 |
1
| one (mockLocalVariable).getIndex();
|
270 |
1
| will(returnValue((int) INDEX));
|
271 |
1
| one (mockLocalVariable).getStartPC();
|
272 |
1
| will(returnValue(START_PC + bytecode.length));
|
273 |
| }}); |
274 |
| |
275 |
1
| Instruction sut = new Instruction(mockCode_attribute, bytecode, 0);
|
276 |
| |
277 |
1
| LocalVariable actualLocalVariable = (LocalVariable) sut.getIndexedLocalVariable();
|
278 |
1
| assertNull(actualLocalVariable);
|
279 |
| } |
280 |
| |
281 |
1
| public void testGetIndexedLocalVariable_StoreInstructionInsidePcRange() {
|
282 |
1
| final LocalVariable mockLocalVariable = mock(LocalVariable.class);
|
283 |
| |
284 |
1
| final byte[] bytecode = {ISTORE_INSTRUCTION, INDEX};
|
285 |
| |
286 |
1
| checking(new Expectations() {{
|
287 |
1
| one (mockCode_attribute).accept(with(any(LocalVariableFinder.class)));
|
288 |
1
| will(visitLocalVariable(mockLocalVariable));
|
289 |
1
| one (mockLocalVariable).getIndex();
|
290 |
1
| will(returnValue((int) INDEX));
|
291 |
1
| atLeast(1).of (mockLocalVariable).getStartPC();
|
292 |
1
| will(returnValue(START_PC));
|
293 |
1
| atLeast(1).of (mockLocalVariable).getLength();
|
294 |
1
| will(returnValue(LENGTH));
|
295 |
| }}); |
296 |
| |
297 |
1
| Instruction sut = new Instruction(mockCode_attribute, bytecode, 0);
|
298 |
| |
299 |
1
| LocalVariable actualLocalVariable = (LocalVariable) sut.getIndexedLocalVariable();
|
300 |
1
| assertSame(mockLocalVariable, actualLocalVariable);
|
301 |
| } |
302 |
| |
303 |
1
| public void testGetIndexedLocalVariable_StoreInstructionImmediatelyBeforePcRange() {
|
304 |
1
| final LocalVariable mockLocalVariable = mock(LocalVariable.class);
|
305 |
| |
306 |
1
| final byte[] bytecode = {ISTORE_INSTRUCTION, INDEX};
|
307 |
| |
308 |
1
| checking(new Expectations() {{
|
309 |
1
| one (mockCode_attribute).accept(with(any(LocalVariableFinder.class)));
|
310 |
1
| will(visitLocalVariable(mockLocalVariable));
|
311 |
1
| atLeast(1).of (mockLocalVariable).getIndex();
|
312 |
1
| will(returnValue((int) INDEX));
|
313 |
1
| atLeast(1).of (mockLocalVariable).getStartPC();
|
314 |
1
| will(returnValue(START_PC + bytecode.length));
|
315 |
1
| atLeast(1).of (mockLocalVariable).getLength();
|
316 |
1
| will(returnValue(LENGTH));
|
317 |
| }}); |
318 |
| |
319 |
1
| Instruction sut = new Instruction(mockCode_attribute, bytecode, 0);
|
320 |
| |
321 |
1
| LocalVariable actualLocalVariable = (LocalVariable) sut.getIndexedLocalVariable();
|
322 |
1
| assertSame(mockLocalVariable, actualLocalVariable);
|
323 |
| } |
324 |
| |
325 |
1
| public void testGetIndexedLocalVariable_WideLoadInstructionInsideMatchingIndexMatchingPcRange() {
|
326 |
1
| final LocalVariable mockLocalVariable = mock(LocalVariable.class);
|
327 |
| |
328 |
1
| final byte[] bytecode = {WIDE_INSTRUCTION, ILOAD_INSTRUCTION, 0x00, INDEX};
|
329 |
| |
330 |
1
| checking(new Expectations() {{
|
331 |
1
| one (mockCode_attribute).accept(with(any(LocalVariableFinder.class)));
|
332 |
1
| will(visitLocalVariable(mockLocalVariable));
|
333 |
1
| one (mockLocalVariable).getIndex();
|
334 |
1
| will(returnValue((int) INDEX));
|
335 |
1
| atLeast(1).of (mockLocalVariable).getStartPC();
|
336 |
1
| will(returnValue(START_PC));
|
337 |
1
| atLeast(1).of (mockLocalVariable).getLength();
|
338 |
1
| will(returnValue(LENGTH));
|
339 |
| }}); |
340 |
| |
341 |
1
| Instruction sut = new Instruction(mockCode_attribute, bytecode, 0);
|
342 |
| |
343 |
1
| LocalVariable actualLocalVariable = (LocalVariable) sut.getIndexedLocalVariable();
|
344 |
1
| assertSame(mockLocalVariable, actualLocalVariable);
|
345 |
| } |
346 |
| |
347 |
1
| public void testGetIndexedLocalVariable_WideLoadInstructionImmediatelyBeforePcRange() {
|
348 |
1
| final LocalVariable mockLocalVariable = mock(LocalVariable.class);
|
349 |
| |
350 |
1
| final byte[] bytecode = {WIDE_INSTRUCTION, ILOAD_INSTRUCTION, 0x00, INDEX};
|
351 |
| |
352 |
1
| checking(new Expectations() {{
|
353 |
1
| one (mockCode_attribute).accept(with(any(LocalVariableFinder.class)));
|
354 |
1
| will(visitLocalVariable(mockLocalVariable));
|
355 |
1
| one (mockLocalVariable).getIndex();
|
356 |
1
| will(returnValue((int) INDEX));
|
357 |
1
| one (mockLocalVariable).getStartPC();
|
358 |
1
| will(returnValue(START_PC + bytecode.length));
|
359 |
| }}); |
360 |
| |
361 |
1
| Instruction sut = new Instruction(mockCode_attribute, bytecode, 0);
|
362 |
| |
363 |
1
| LocalVariable actualLocalVariable = (LocalVariable) sut.getIndexedLocalVariable();
|
364 |
1
| assertNull(actualLocalVariable);
|
365 |
| } |
366 |
| |
367 |
1
| public void testGetIndexedLocalVariable_WideStoreInstructionInsidePcRange() {
|
368 |
1
| final LocalVariable mockLocalVariable = mock(LocalVariable.class);
|
369 |
| |
370 |
1
| final byte[] bytecode = {WIDE_INSTRUCTION, ISTORE_INSTRUCTION, 0x00, INDEX};
|
371 |
| |
372 |
1
| checking(new Expectations() {{
|
373 |
1
| one (mockCode_attribute).accept(with(any(LocalVariableFinder.class)));
|
374 |
1
| will(visitLocalVariable(mockLocalVariable));
|
375 |
1
| one (mockLocalVariable).getIndex();
|
376 |
1
| will(returnValue((int) INDEX));
|
377 |
1
| atLeast(1).of (mockLocalVariable).getStartPC();
|
378 |
1
| will(returnValue(START_PC));
|
379 |
1
| atLeast(1).of (mockLocalVariable).getLength();
|
380 |
1
| will(returnValue(LENGTH));
|
381 |
| }}); |
382 |
| |
383 |
1
| Instruction sut = new Instruction(mockCode_attribute, bytecode, 0);
|
384 |
| |
385 |
1
| LocalVariable actualLocalVariable = (LocalVariable) sut.getIndexedLocalVariable();
|
386 |
1
| assertSame(mockLocalVariable, actualLocalVariable);
|
387 |
| } |
388 |
| |
389 |
1
| public void testGetIndexedLocalVariable_WideStoreInstructionImmediatelyBeforePcRange() {
|
390 |
1
| final LocalVariable mockLocalVariable = mock(LocalVariable.class);
|
391 |
| |
392 |
1
| final byte[] bytecode = {WIDE_INSTRUCTION, ISTORE_INSTRUCTION, 0x00, INDEX};
|
393 |
| |
394 |
1
| checking(new Expectations() {{
|
395 |
1
| one (mockCode_attribute).accept(with(any(LocalVariableFinder.class)));
|
396 |
1
| will(visitLocalVariable(mockLocalVariable));
|
397 |
1
| atLeast(1).of (mockLocalVariable).getIndex();
|
398 |
1
| will(returnValue((int) INDEX));
|
399 |
1
| atLeast(1).of (mockLocalVariable).getStartPC();
|
400 |
1
| will(returnValue(START_PC + bytecode.length));
|
401 |
1
| atLeast(1).of (mockLocalVariable).getLength();
|
402 |
1
| will(returnValue(LENGTH));
|
403 |
| }}); |
404 |
| |
405 |
1
| Instruction sut = new Instruction(mockCode_attribute, bytecode, 0);
|
406 |
| |
407 |
1
| LocalVariable actualLocalVariable = (LocalVariable) sut.getIndexedLocalVariable();
|
408 |
1
| assertSame(mockLocalVariable, actualLocalVariable);
|
409 |
| } |
410 |
| |
411 |
1
| public void testGetIndexedLocalVariable_WrongOpCode() {
|
412 |
1
| byte[] bytecode = {ICONST_0_INSTRUCTION};
|
413 |
| |
414 |
1
| Instruction sut = new Instruction(mockCode_attribute, bytecode, 0);
|
415 |
| |
416 |
1
| LocalVariable actualLocalVariable = (LocalVariable) sut.getIndexedLocalVariable();
|
417 |
1
| assertNull(actualLocalVariable);
|
418 |
| } |
419 |
| |
420 |
9
| private CustomAction visitLocalVariable(final LocalVariable mockLocalVariable) {
|
421 |
9
| return new CustomAction("Visit local variable") {
|
422 |
9
| public Object invoke(Invocation invocation) throws Throwable {
|
423 |
9
| ((Visitor) invocation.getParameter(0)).visitLocalVariable(mockLocalVariable);
|
424 |
9
| return null;
|
425 |
| } |
426 |
| }; |
427 |
| } |
428 |
| } |