package model.asn1; import model.asn1.exceptions.ParseException; import model.asn1.parsing.BytesReader; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; public class TagTest { @Test void testConstructor() { assertEquals(ASN1Object.TAG_SEQUENCE.getNumber(), new Tag(TagClass.UNIVERSAL, false, ASN1Object.TAG_SEQUENCE.getNumber()).getNumber()); assertEquals(ASN1Object.TAG_SEQUENCE.getCls(), new Tag(TagClass.UNIVERSAL, false, ASN1Object.TAG_SEQUENCE.getNumber()).getCls()); assertEquals(ASN1Object.TAG_SEQUENCE.isConstructive(), new Tag(TagClass.UNIVERSAL, ASN1Object.TAG_SEQUENCE.isConstructive(), ASN1Object.TAG_SEQUENCE.getNumber()) .isConstructive()); } @Test void testParseSuccess() throws ParseException { // Test basic parsing assertEquals(0x1, new Tag(new BytesReader(new Byte[]{ 0x1 })).getNumber()); assertEquals(TagClass.UNIVERSAL, new Tag(new BytesReader(new Byte[]{ 0x1 })).getCls()); assertFalse(new Tag(new BytesReader(new Byte[]{ 0x1 })).isConstructive()); // Test basic parsing with different class assertEquals(5, new Tag(new BytesReader(new Byte[]{ 101 })).getNumber()); assertEquals(TagClass.APPLICATION, new Tag(new BytesReader(new Byte[]{ 101 })).getCls()); assertTrue(new Tag(new BytesReader(new Byte[]{ 101 })).isConstructive()); // Test different classes assertEquals(TagClass.UNIVERSAL, new Tag(new BytesReader(new Byte[]{ 1 })).getCls()); // 0b00000001 assertEquals(TagClass.PRIVATE, new Tag(new BytesReader(new Byte[]{ -63 })).getCls()); // 0b11000001 assertEquals(TagClass.CONTEXT_SPECIFIC, new Tag(new BytesReader(new Byte[]{ -127 })).getCls()); // 0b10000001 assertEquals(TagClass.APPLICATION, new Tag(new BytesReader(new Byte[]{ 65 })).getCls()); // 0b01000001 // Test different numbers assertEquals(0x10, new Tag(new BytesReader(new Byte[]{ 0x10 })).getNumber()); assertEquals(31, new Tag(new BytesReader(new Byte[]{ 31 })).getNumber()); // Test constructive bit assertFalse(new Tag(new BytesReader(new Byte[]{ 0x1 })).isConstructive()); assertTrue(new Tag(new BytesReader(new Byte[]{ 33 })).isConstructive()); // Test modification BytesReader reader = new BytesReader(new Byte[]{ 33 }); assertEquals(0, reader.getIndex()); new Tag(reader); assertEquals(1, reader.getIndex()); } @Test void testParseFail() { // No enough bytes assertThrows(ParseException.class, () -> { BytesReader reader = new BytesReader(new Byte[]{ 33 }); reader.require(1, true); new Tag(reader); }); // Number zero assertThrows(ParseException.class, () -> new Tag(new BytesReader(new Byte[]{ 0 }))); } @Test void testEncode() { // Basic encoding assertArrayEquals(new Byte[]{ 1 }, new Tag(TagClass.UNIVERSAL, false, 1).encodeDER()); assertArrayEquals(new Byte[]{ 31 }, new Tag(TagClass.UNIVERSAL, false, 31).encodeDER()); // With different class assertArrayEquals(new Byte[]{ -127 }, new Tag(TagClass.CONTEXT_SPECIFIC, false, 1).encodeDER()); assertArrayEquals(new Byte[]{ -61 }, new Tag(TagClass.PRIVATE, false, 3).encodeDER()); assertArrayEquals(new Byte[]{ 71 }, new Tag(TagClass.APPLICATION, false, 7).encodeDER()); // With different constructive bit assertArrayEquals(new Byte[]{ 63 }, new Tag(TagClass.UNIVERSAL, true, 31).encodeDER()); } @Test void testEnforce() { assertThrows(ParseException.class, () -> new Tag(TagClass.UNIVERSAL, true, 10) .enforce(new Tag(TagClass.UNIVERSAL, true, 9))); assertThrows(ParseException.class, () -> new Tag(TagClass.UNIVERSAL, true, 10) .enforce(new Tag(TagClass.UNIVERSAL, true, 11))); assertThrows(ParseException.class, () -> new Tag(TagClass.UNIVERSAL, true, 10) .enforce(new Tag(TagClass.UNIVERSAL, false, 10))); assertThrows(ParseException.class, () -> new Tag(TagClass.UNIVERSAL, true, 10) .enforce(new Tag(TagClass.APPLICATION, true, 10))); assertThrows(ParseException.class, () -> new Tag(TagClass.UNIVERSAL, true, 10) .enforce(new Tag(TagClass.PRIVATE, true, 10))); assertThrows(ParseException.class, () -> new Tag(TagClass.UNIVERSAL, true, 10) .enforce(new Tag(TagClass.CONTEXT_SPECIFIC, true, 10))); } }