View Javadoc
1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one or more
3    *  contributor license agreements.  See the NOTICE file distributed with
4    *  this work for additional information regarding copyright ownership.
5    *  The ASF licenses this file to You under the Apache License, Version 2.0
6    *  (the "License"); you may not use this file except in compliance with
7    *  the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   *  Unless required by applicable law or agreed to in writing, software
12   *  distributed under the License is distributed on an "AS IS" BASIS,
13   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   *  See the License for the specific language governing permissions and
15   *  limitations under the License.
16   */
17  package org.apache.commons.compress.harmony.unpack200;
18  
19  import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
20  import static org.junit.jupiter.api.Assertions.assertEquals;
21  import static org.junit.jupiter.api.Assertions.assertNull;
22  import static org.junit.jupiter.api.Assertions.assertThrows;
23  
24  import java.util.stream.Stream;
25  
26  import org.apache.commons.compress.harmony.pack200.Codec;
27  import org.apache.commons.compress.harmony.pack200.Pack200Exception;
28  import org.apache.commons.compress.harmony.unpack200.bytecode.CPUTF8;
29  import org.apache.commons.compress.harmony.unpack200.bytecode.ClassFileEntry;
30  import org.junit.jupiter.api.Test;
31  import org.junit.jupiter.params.ParameterizedTest;
32  import org.junit.jupiter.params.provider.Arguments;
33  import org.junit.jupiter.params.provider.MethodSource;
34  
35  public class AttributeLayoutTest {
36  
37      public class TestSegment extends Segment {
38  
39          private ClassFileEntry entry(final String string) {
40              return new CPUTF8(string);
41          }
42  
43          @Override
44          public SegmentConstantPool getConstantPool() {
45              final ClassFileEntry[][] data = { {}, // ALL
46                      { entry("Zero"), entry("One"), entry("Two"), entry("Three"), entry("Four"), entry("Five"), entry("Six"), entry("Seven"), entry("Eight"),
47                              entry("Nine") }, // UTF-8
48                      {}, {}, {}, {}, {}, {}, { entry("Eins"), entry("Zwei"), entry("Drei"), entry("Vier"), entry("Funf"), entry("Sechs"), entry("Sieben"),
49                              entry("Acht"), entry("Neun") }, // Signature
50              };
51              return new SegmentConstantPool(null) {
52  
53                  @Override
54                  public ClassFileEntry getValue(final int cp, final long index) {
55                      if (index == -1) {
56                          return null;
57                      }
58                      return data[cp][(int) index];
59                  }
60  
61              };
62          }
63      }
64  
65      static Stream<Arguments> badData() {
66          return Stream.of(Arguments.of(null, AttributeLayout.CONTEXT_CLASS, ""), Arguments.of("", AttributeLayout.CONTEXT_CLASS, ""),
67                  Arguments.of("name", -1, ""), Arguments.of("name", 1234, ""));
68      }
69  
70      static Stream<Arguments> codec() {
71          return Stream.of(Arguments.of("O", AttributeLayout.CONTEXT_CLASS, "HOBS", Codec.BRANCH5),
72                  Arguments.of("P", AttributeLayout.CONTEXT_METHOD, "PIN", Codec.BCI5), Arguments.of("S", AttributeLayout.CONTEXT_FIELD, "HS", Codec.SIGNED5),
73                  Arguments.of("RS", AttributeLayout.CONTEXT_CODE, "RRRS", Codec.UNSIGNED5),
74                  Arguments.of("KS", AttributeLayout.CONTEXT_CLASS, "RKS", Codec.UNSIGNED5),
75                  Arguments.of("B", AttributeLayout.CONTEXT_CLASS, "TRKSB", Codec.BYTE1));
76      }
77  
78      static Stream<Arguments> okData() {
79          return Stream.of(Arguments.of("name", AttributeLayout.CONTEXT_CLASS, ""), Arguments.of("name", AttributeLayout.CONTEXT_METHOD, ""),
80                  Arguments.of("name", AttributeLayout.CONTEXT_FIELD, ""), Arguments.of("name", AttributeLayout.CONTEXT_CODE, ""));
81      }
82  
83      @ParameterizedTest
84      @MethodSource("badData")
85      public void testBadData(final String name, final int context, final String layout) {
86          assertThrows(Pack200Exception.class, () -> new AttributeLayout(name, context, layout, -1));
87      }
88  
89      @ParameterizedTest
90      @MethodSource("codec")
91      public void testGetCodec(final String name, final int context, final String layout, final Codec expectedCodec) throws Pack200Exception {
92          final AttributeLayout attributeLayout = new AttributeLayout(name, context, layout, 1);
93          assertEquals(expectedCodec, attributeLayout.getCodec());
94      }
95  
96      @Test
97      public void testLayoutRS() throws Pack200Exception {
98          final AttributeLayout layout = new AttributeLayout("RS", AttributeLayout.CONTEXT_CLASS, "RS", 1);
99          final Segment segment = new TestSegment();
100         assertNull(layout.getValue(-1, segment.getConstantPool()));
101         assertEquals("Eins", ((CPUTF8) layout.getValue(0, segment.getConstantPool())).underlyingString());
102         assertEquals("Zwei", ((CPUTF8) layout.getValue(1, segment.getConstantPool())).underlyingString());
103     }
104 
105     @Test
106     public void testLayoutRSN() throws Pack200Exception {
107         final AttributeLayout layout = new AttributeLayout("RSN", AttributeLayout.CONTEXT_CLASS, "RSN", 1);
108         final Segment segment = new TestSegment();
109         assertNull(layout.getValue(0, segment.getConstantPool()));
110         assertEquals("Eins", ((CPUTF8) layout.getValue(1, segment.getConstantPool())).underlyingString());
111         assertEquals("Zwei", ((CPUTF8) layout.getValue(2, segment.getConstantPool())).underlyingString());
112     }
113 
114     @Test
115     public void testLayoutRU() throws Pack200Exception {
116         final AttributeLayout layout = new AttributeLayout("RU", AttributeLayout.CONTEXT_CLASS, "RU", 1);
117         final Segment segment = new TestSegment();
118         assertNull(layout.getValue(-1, segment.getConstantPool()));
119         assertEquals("Zero", ((CPUTF8) layout.getValue(0, segment.getConstantPool())).underlyingString());
120         assertEquals("One", ((CPUTF8) layout.getValue(1, segment.getConstantPool())).underlyingString());
121     }
122 
123     @Test
124     public void testLayoutRUN() throws Pack200Exception {
125         final AttributeLayout layout = new AttributeLayout("RUN", AttributeLayout.CONTEXT_CLASS, "RUN", 1);
126         final Segment segment = new TestSegment();
127         assertNull(layout.getValue(0, segment.getConstantPool()));
128         assertEquals("Zero", ((CPUTF8) layout.getValue(1, segment.getConstantPool())).underlyingString());
129         assertEquals("One", ((CPUTF8) layout.getValue(2, segment.getConstantPool())).underlyingString());
130     }
131 
132     @ParameterizedTest
133     @MethodSource("okData")
134     public void testOkData(final String name, final int context, final String layout) {
135         assertDoesNotThrow(() -> new AttributeLayout(name, context, layout, -1));
136     }
137 }